Faux 3D

I had a request some time ago for a blog entry dealing with programming in a z-level to a top-down, 2D game. It’s been delayed by several weeks due to working on the release, and now it’s been delayed by a day because I spent almost all of Monday on academic work. Now, however, I’ve managed to find a moment between editing chapters to put something about this up.

URR does not use cubes. Which is to say, a hypothetical map with a top height of 10, with some sky and some ground, does not look like the thing on the left, with cubes of each substance stacked upon each other, Minecraft style. I obviously considered doing this, but then realized I was using up an unnecessary amount of memory if I did it that way. This isn’t a construction game, and this isn’t one where you can dig. Those are the two fundamental reasons why cubes of terrain are simply unneeded, and inefficient.

Instead, URR actually only has one cube of terrain in each x/y coordinate square, regardless of the height of that square. So, square [0][0] might have a ‘z’ value of 1, square [0][1] might have a ‘z’ value of 2, and so on. Each square has its own z value. Squares then have a ‘true z’ value, which reflects if something has been ‘built’ on them, for instance a tree, or a wall, or whatever. These are almost exclusively things you cannot see through.

Thus, when then generating the field of view each turn, the game ignores any squares that are blocked and on your level – for instance, by a tree – or any square with a true z level greater than that of your head (the player is two levels high, as are all humans). Monsters, in turn, cannot see creatures with the same requirements, and like you can climb or not up areas of various z levels depending on their height.

But, I hear you cry – what if you have a wall on a square, and the square’s z level is 10, and the wall is 5 squares high, so that square has a true z of 15. If the wall is destroyed, giving that the true z is the important value, surely the true z is still 15? When a structure is destroyed, the game recalculates what the true z of that square should be according to the height of the thing on the square, and then sets it.

But, I hear you cry (again) – what if you have a BUILDING, with multiple floors? What if you have a tower with sixteen different floors in, but the square can only store one z level? Well, buildings – although in their very early stages – are simply loaded separately. There is still fluid movement between buildings – there’s no load screen, things can go in/out of buildings at will, and for gameplay purposes, there will be (once buildings are fully implemented) no gameplay difference between a building here and a building in, say, Dwarf Fortress. The data is simply stored differently. While splitting ‘land’ and ‘interiors’ up has provided extra work in the short term, I deemed the massive reduction in required storage and the massive increase in game speed that game with it to be more than worth it.

And with that, our next update will be in a fortnight, when I will unveil a skill tree. Excitement!

Map Generation Redux

Welcome back! Development is going to start back up some time next week; I also intend to add a development plan to the blog very soon so everybody can see a) what I have left to do for the first alpha, and b) track progress across these. The current intention is for another fortnight of programming, followed by a break, and then a final ‘push’ from around approximately the middle of June to the first release.

In the mean time, to resume blog entries, I’ve had a few requests/questions about the exact map generation mechanics, so I thought I’d start off with an entry on those. If you want a gif of the full process, scroll to the bottom of the entry; otherwise, here’s each step with a little explanation. This was a map with all values (terrain, forest, tectonic activity, rivers etc) on ‘average’. As ever, click a picture to view full-size.

First, a rough outline of the continents and islands is created. The number of initial blocks is dependent upon the terrain value; the higher, the more initial landmasses are created. Some of the clumps of land generate in locations dependent upon previous land, while other areas are placed randomly.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Next, bands of terrain are added. I originally considered having a simulation which included things like rainfall, but then I realized that since I’m not creating the kind of ‘world simulation’ of the sort that DF is (i.e. factors of that sort are important for the player), there was actually no need. Instead, the game creates semi-random ‘bands’ of terrain, starting with tropical areas and then expanding to include desert, savannah, temperate areas, and then taiga/tundra/polar at the edge of the map. The final look of the map looks just as random and varied as a different technique, while this one saves on time and means I’m not adding any functionality into the game which won’t actually have an effect on gameplay (and, if it does one day, I’ll just add it in then). This also ensures that all climate zones should appear on any given map, which will be important for civilizations/species, and – I think – allows for greater variation on smaller landmasses and areas. Desert is ‘zigzagged’ around tropical areas, which ensures a different variation of desert across hemispheres (in this case predominantly in the south) whereas the earlier maps (if you go back and look) simply contain desert as a band above/below tropical.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

After this, the landmass is then expanded and dithered significantly to remove the straight lines of the climate areas shown above. A lot of extra land is added in this stage. Subsequently, forests are added, with a regularity which depends upon the ‘Forest’ variable and different climate zones. Tropical areas get a ton of forest; temperate zones and taiga get some; desert gets very, very rare ‘forest’ areas, and these are actually oases. Also at this stage, one-square ocean areas are removed, since lakes function differently and will be added later in the process when rivers start to appear.

 

 

 

 

 

 

Next up: mountains. Mountain ranges are created, again primarily depending on the ‘Tectonic Activity’ variable but also varying a little according to biome. In the example below, there’s actually unusually few mountain ranges given the ‘average’ value I gave Tectonic Activity in this generation, but it’s still representative of the process. Once mountain ranges exist, they are then broadened, and the height of surrounding areas adjusted appropriately as the land is yanked upwards.

 

 

 

 

 

 

Lastly, volcanoes are added and then rivers are added and connected, all sourced from mountains and terminating in either lakes or the ocean. Both of these are tricky to see in this size, so I suggest zooming in to have a look. Rivers currently only generate from mountains, but I am considering allowing them to generate from high hills which aren’t mountains in the future too.

 

 

 

 

 

 

And, lastly, here’s a gif of the entire process. In a later version once territory and cities and things exist, I will do an equivalent to show how they (and creature settlements) are generated, but since terrain is the focus of the first alpha, I’ve only reflected that here. Next week, I’ll be uploading the development plan, and saying a little bit on each component of the first alpha I’m working on at the moment…

Building a Creature, Part 2

In continuing on from last week’s discussion of new creature dynamics in URR, we have a few more new factors being added to creatures. These are being coded at the moment at the same time as all the fixes I’m putting into the map; I expect the fixes to be done by the end of this week, hopefully, though obviously redoing creatures from the ground up is a rather larger task.

Resistances

I’ve thought long and hard about how I want resistances to work in URR. I considered at first having fire/ice/shock resistance; then I added in things like poison/acid; but I felt this was getting too close to NetHack, and further away from the strategy game I was after. However, I knew there were two resistances I thought were particularly vital: there had to be creatures who took no damage from fire or lava (Fiends) and those who were unconcerned by the most deadly of poisons (Hydras, for example). Thus, there are only two resistances in URR; the ability to resist fires, and to resist poisons. These are not absolutes – they are on a scale, and while Fiends may have perfect fire resistances, some creatures have only partial. Same goes for poisons. There’s also going to be a variety of poisons with different sources and effects, but these will be the topic for a far future blog entry. As for how humanoids deal with these resistances; there will be some items that bestow varying levels of fire resistance, but poison resistance is a matter of finding the right cure/preventatives.

Climate

Different creatures like to live in different climates. You’ll never find a Cyclops or a Naga in the polar regions, and you’ll never find Yetis wandering around the desert. In general, this means creatures stick to their preferred biome as they become gradually less skillful and less willing to fight the further they go. This will have an impact if you recruit certain creatures from one biome to your army, then intend to march into another; Cyclopes will become increasingly unwilling to fight, and find it increasingly difficult to fight, the further towards the poles you go. It will take some time to become an issue due to the distances involved, but this is effectively to stop the player (or an AI commander) creating a stack of units that can win every battle, Civilization-style, and then simply moving it around the map. Similarly, humanoids recruited to your army will need slightly more appeasing the further from home you are. As for monsters, you may have to respond to the local fauna as you move…

Encumbrance

Just as I wanted to get rid of the clear cut-off between “alive” and “dead” for health – hence the application of limbs – I’ve thought more now about how I want encumbrance to work. Each creature has a maximum encumbrance, which is determined by their endurance. This is for everything they carry, from money (which does have a weight) to armor, weapons and everything else. This is also modeled as a scale – the closer to your maximum encumbrance you get, your attacks become gradually slower, and gradually less powerful, and for creatures with a speed advantage, that speed advantage becomes very gradually reduced too. This decrease in skills increases in speed the closer you get to your maximum encumbrance, and when you pass that threshold, there is a risk of hurting yourself from moving or attacking, or performing any too-complex action. Will you be able to kill yourself falling down stairs like in NetHack? Probably not to that extent, but we’ll have to see…

Building a Creature, Part 1

This entry starts a series intended to discuss what goes into each creature in URR, and what stats they – and therefore you – have. Originally, creatures had a huge number of stats and were each uniquely constructed in the game – each had its own selection of limbs and its own unique code that handled when it was attacked. This was massively inefficient, and there’s a bunch of changes I’m making at the moment which should speed the game up; allow for a much greater variety of creatures; and make far more explicit to the player the strengths/weaknesses of each foe, and reduce some of the uncertainty and unknowns in combat. Here’s a few of the changes I’m currently programming in. Some of them were implemented in a simpler form before-hand, but some are entirely new:

Names.

Originally, messages of the following sort came up:

You slash the male Cyclops`s upper left arm with your steel longsword.

The male Cyclops hits your torso with his fists.

However, what if you were friends with that Orc? Or if you had been told to kill that Orc in particular? Which is to say, Orcs are an intelligent species (well, nominally), and have names like any other sentient race. However, you won’t automatically know a sentient creature’s name when you meet them, unlike pretty much every other RPG or Roguelike I can think of. Instead, if you encounter any sentient creature without foreknowledge, you get messages like the above. If you know their name, then you’ll get (with an output from the Cyclops name generator):

You slash the Cyclops Pylopedes` upper left arm with your steel longsword.

The Cyclops Pylopedes hits your torso with his fists.

Lastly, if a creature is of your species, you won’t get its species listed there, simply its name. If a creature is any other species, it will note the species – which is to say, if you are human, you won’t get “the human <human name>”, but you will get “the dwarf <dwarf name>”, and so on.

Height and weight.

Creatures have both a height and a weight. The taller they are, the more z levels they occupy, and that gives them a variety of benefits outlined in a previous entry. However, weight has also been fully added, which has a variety of effects – it determines the weight of a limb if chopped off; whether particularly large creatures can walk safely across certain surfaces; and is a major factor in whether they can be knocked back, thrown to the ground, wrestled with, etc.

Experience.

Finally (for this entry), Experience has been entirely redone. When a creature is spawned (this includes you), its experience for each of the five base stats is calculated by squaring that particular stat. They are currently five of the traditional base stats – Strength, Endurance, Dexterity, Intelligence, and Willpower. Stronger creatures give more experience; weaker give less; and your current level of experience also determines how much more experience is required, and how much experience you get from each creature. Other creatures will also gain experience in combat; the more of your forces your enemies kill, the stronger, more experienced and more skilled they will become. Battles that occur which you aren’t part of will calculate appropriate numbers of surviving creatures and assign experience based on that. There is currently no upper limit to these stats – I intend to leave it that way, though when any stat reaches a sufficiently high point, finding and killing enough high-level creatures to raise it will become increasingly challenging. This, of course, does not cover the 80+ skills in the game, which are a topic for a future entry in this series…

Adventures on the z-axis

At first, I saw no need for a z-axis. Nethack, Angband and ADOM all do perfectly well without one. However, I gradually realized that URR was looking closer to Dwarf Fortress than others, and the z-axis is a crucial part of that game. While I have no need to model it to the same extent as in DF – URR having no interest in ‘construction’ – I realised that towers, forts, castles and the like couldn’t be created in the depth I wanted without a z-axis. And that’s not to mention how strange and unrealistic vast, endless tracts of perfectly flat land would look.

So, without further ado, here’s a screenshot of how the z-axis plays out. The up and down arrows show that on that square, you will go up or down by a floor. You cannot see up a floor, but you can see down a floor, but the land is shown as darker than the floor you are currently on. This is the most basic implementation – variation in land height in general terrain.

Trees temporarily removed to add in variety of tree species, and change how they are stored in-game…

Beyond this, however, there are three other important ways in which height affects gameplay. I hope in the near future to be able to produce screenshots of valleys, mountains and hopefully even volcanoes, but those are taking a lot more work. In the mean time, then:

Buildings

I hope to have a screenshot of this to demonstrate shortly, but buildings will be drawn using the z-axis. Depending on your height, you will see the side of that building at that height. Which is to say, if you have a tower in a valley (strange, but bear with me) you will be unable to see the door until you are at its level, and as you descend, you will see its walls. Similarly, this means you can climb a spiral staircase outside a building, and ascertain the height of a building by trying to climb something nearby and look over it. Things that take you to another map – building interiors, caves, etc – will be visible as doors, holes, etc, and can be entered just like any other square on the map. For the initla alpha, ruins will exist, but I’m not yet sure what else, as many of the other buildings/settlements planned required a lot more work on NPC and interaction AI. You will also be able to reach the roof of any given building (well… almost any), and this brings me on to:

Falling/climbing

If a square is just one step down from your current height, you can descend it fine. Otherwise, it is a drop – think of a change in z as being roughly a meter. If you drop too far, you will take damage, which depends on your health, your armor, and also what you’re falling onto. Falling onto sand hurts less than gravel; falling onto ice might break you straight through it! Falling from too great a height might even result in instant death. However, because there are attacks that can push creatures back, knocking your foe from a high ledge can be an excellent way to kill a particularly troublesome foe. However, AI can notice this, and will try and reposition themselves if they fear being knocked off.

Climbing, on the other hand, is your way of ascending great height. As long as you have a working pair of arms, you can try and climb any surface, your success being dependent on your dexterity and the surface (climbing rough stone is easier than smooth marble). Other creatures can also climb, but will generally prefer not to. However, some creatures don’t need to climb:

Creature height

If you are positioned on a square 3 z levels above the square next to you, on which is an Orc, it cannot hit you. Orcs and humans are basically the same height. However, if a Titan is stood on that square, it will still tower over you by a mile. Tall creatures (and people on horseback) and reach and attack up to far greater heights than smaller creatures. Quickly scuttling up a wall might get you away from wolves, but a dragon isn’t going to be put off so quickly. If you back off, of course, then a creature would have to climb to follow you; but what might be a long climb for a human might just be like a single stair for a Titan…

Coming Monday 5th: Cyclops creature profile…

Coming Monday 12th: The first constructions in the alpha – Ruins.