Mountains will Crumble! Seas will rise!
Tada! Finished my #LD35Jam game, Atlantis Dare
itch.io Download Link + Source Code
Gameplay
The premise is of a civlisation-type turn-based, tile-based strategy game. where every 12 turns, the terrain is re-generated at random. The land changes completely, with big consequences for the player.
Players build up their civilisation in the preceding turns, accumulating food, stone and prayer points from the cities, farms and mines they’ve built. When the land changes, prayer points are spent to “pray to the Gods” to rescue the cities, mines and farms that have ended up in the ocean. I.e. the player can move their sunken cities, mines and farms back to new locations on dry land (or otherwise let them drown and be destroyed).
Inspiration & Design
I was inspired by the idea of “winters” in the game Endless Legend, and wanted to take that a step further. Having the landscape change so radically at regular intervals forces players to plan ahead and get a good balance between building their civilisation and accumulating prayer points so they can rescue at least something when the land changes suddenly dump all their hard work in the oceans. It forces players to also rethink their civlisation’s plans, and maybe change strategy on the fly, if, say, the next landmass has far more mountainous terrain than before, or is just a single small island. There’s also a few sneaky tactics I’ve already found when playing, such as building new cities just before the land changes, then rescuing only those newly build cities with small populations. That way I can get away with needing only relatively few farms for the next few turns. However, if all my cities end up on dry land when the land changes, I’m then lumbered with more cities than I really want or can support. So there are risks or unexpected downsides to many strategies.
Balancing
This is the second Ludum Dare that I’ve actually finished, and ahead of time, so quite happy. Plus I spend yesterday watching the football and a large chunk of today doing DIY (that’s my excuse at least if anything is horribly broken in the game that I’ve not yet found). There are a few bugs in there. I couldn’t quite pin down all of the scenarios where you’ll lose unexpectedly. Sometimes a city will be destroyed even though the player just built a new mine or farm. This is largely due to the order in which things are checked at the end of the turn, which I’ll need to sort out at some point.
Also I’ve not actually managed (and so tested) a victory yet. Hoping some people will have victories and that it’s just a matter of taking a bit of time, rather than the game being too difficult. The game seems to have a good balance otherwise. Players can sometimes paint themselves into a corner, and there are a few scenarios where they end up totally screwed (such as running out of stone and not having enough mines). I decided not to include special temple buildings in the end as players seem to accumulate prayer points fairly easily just from cities.
Other Issues
The game probably needs a better tutorial. I know how to play because I made the thing, but I suspect a lot of people will struggle with figuring it all out. Again, if I come back to the game at a later time, that’ll be one of the things I look to add in as a priority.
The art work is also super-crappy. The building sprites are too small to really see what they actually are, and that’s not even accounting for my less than amazing art skills. The blocky square terrain has a certain aesthetic to it at least, but it’s not obvious that the “grey” blocks are mountains, so again, if I come back to the game at a later time, I’ll be looking to make that more obvious
Construction
I started off with the terrain generator and setting up a simple isometric camera in Unity3d. To generate the terrain, firstly, I use a random perlin noise generator. This is a fairly standard technique for generating random terrain heights. Separately, I pick a random, non-edge “origin” tile. Finally, I have a graph (an animation curve in Unity) that looks like the image below:
The bottom axis is the distance of any one tile from the origin tile, and the left axis, the number that tile will get at any set distance. I add that graph number to the perlin noise number for the tile. If the resulting number is greater than a threshhold variable, then that tile is grassy plain. Otherwise it’s watery ocean:
// generate new plains
float perlinSeed = Random.Range (0f, 1f);
Vector2 oriVec = new Vector2(originTile.x,originTile.y);
for(int i = 0;i<tiles.Length;i++){
for(int j = 0;j<tiles[i].Length;j++){
if(i==0 || j==0 || i==tiles.Length-1 || j==tiles[i].Length-1){
//edge tile. remains as sea
} else {
Vector2 currentVec = new Vector2(tiles[i][j].x,tiles[i][j].y);
float distToOrigin = Vector2.Distance(oriVec,currentVec);
float perlin = Mathf.PerlinNoise((currentVec.x/landDimensions) + perlinSeed,(currentVec.y/landDimensions) + perlinSeed); //landDimensions is the square dimension of the tiles (20)
if(perlin + landDistanceFactor.Evaluate(distToOrigin)>waterFactor){ //landDistanceFactor is the Unity animation curve. waterFactor is the threshold, usually 0.7f
// make a land tile
tiles[i][j].terrainType = Tile.TerrainType.plains;
landTiles.Add(tiles[i][j]);
}
}
}
}
For subsequent land shifts, the origin tile is picked from one of the current land tiles. That gives an extra bit of continuity and makes the game more likely to dump just half of the player’s stuff in the water, rather than all or none of it.
Next came generating the mountains. For this, I took a similar idea. I pick 3 random grassy plain / land tiles as mountain range origins. Then I pick a random direction for the mountain range to run in, and a random angle between 60 and 30 degrees. For each of the neighbouring tiles to the mountain range origin tile, I find the angle between the vector from the neighbour to the mountain origin tile, and the mountain range’s general direction vector. If that angle is less than my random angle, that neighbouring tile is made into grey mountain and added to the range. I then just iterate through all the newly created mountain tiles until the mountain range hits the sea and no new mountains are added.
This seems to produce a good balance of mountain and plains in vaguely “mountain chain/range”-like formations. Sometimes if the angle is too large, then there ends up being a big patch of mountain, but even that can be its own challenge / opportunity for a player, and I’ve yet to come across an entire island of just mountain or just grassy plain.
After terrain generation, the civ part of the game was made in tandem with the UI. I started off with just a basic building type and it took a while to get a UI that would let me pick a tile and create the building on that tile. But once that was done, was just a case of extending the basic “building” type in an object oriented manner for the city, farm, mine etc. Finally, each time I added something like cost to build to those building objects, I made sure the UI reflected that.