I originally imagined the levels of Copod to be a lot more open than they are now. I thought it would be fun to have long paths that twist and turn. I also thought it would be cool to make the terrain have a more natural shape rather than a rigid grid based one (like in Spelunky for example). To generate these caves, I made a little program that would export procedurally generated caves that my game would then load at runtime. However, as I continued with the development of Copod, it became clear that the combat played a much bigger role than exploration, so I sized down the levels to make the combat tighter and the level layout less distracting and confusing. This meant I had to repurpose the existing cave generation to generate the caves that you find in Copod today.
The program (creatively named CopodWorldTool) goes through a number of steps to generate a cave. Some of these are independent from each other so can be processed in parallel to get a nice little speed up.
By starting off with a random seed, a “bubble map” is formed. This is merely a group of circles laid out and connected in way that you desire, randomised by a given seed and your specification. ArenaBubbleMap is the class used to generate most of the caves found in Copod. It simply starts with a bubble of a random size within a given threshold and surrounds it with one to four bubbles at each cardinal point. Each of these surrounding bubbles have a random size and are all rotated slightly off from their cardinal direction.
The bubble map is then given to the path map stage that then creates a path that links the bubbles together, like stations in a tube map. This can be used to make a random paths by ignoring some bubbles, but arenas just need all the bubbles linked together to look good, so nothing fancy is required here.
With a path laid out, an outline of the new cave can be made. The program takes each branch of the path (a prerequisite is that no loops in the path can exist) and creates a small polygon that wrap rounds it. You can see the four loops of each of the four branches below.
These are then merged together, the insides striped away. To do this, each poly is triangulated so it is easy to test whether a point on is inside a poly. Then program then marches along a polygon’s outline starting at any point that is outside of any other poly. When it detects a line intersecting with another line (a polygons outline simply being made out of line segments), it creates a new point where they intersect. It then and continues marching along the poly outline it collides with, in the direction away from the intersecting point. Each new and visited point is pushed onto a stack, building up a completely merged outline. This process is repeated until the program is back where it started. We now have an outline that looks like this:
By triangulating this composite outline, we can get a navigation mesh. This is used for pathfinding in the game, allowing creatures to move around without getting stuck behind walls (in theory at least). I also use the navigation mesh to make some floors that you can see in some caves.
Here in this screenshot, you can see the floor that is generated using a navigation mesh in the background.
The physics mesh represents the boundaries of the cave and is used by the physics engine to stop you from phasing through walls. This is made in the way that navigation mesh is created, but the negative space is triangulated instead.
Contours are used to make the mesh of what you see in the game. Each one is at a different height and is scaled based on the normal of each point.
Below is an example of this scaling. The blue and red lines represent the normals at each point and the solid black line represents part of an outline. You can see the left outline being scaled up along the normals to meet the dotted line, the result of the scaling is on the right.
Cracks and slight variations are also applied in this stage. You can see this in the image below. Red lines are closer while yellow are further away.
With these contours, a visual mesh can be created. First the code finds each matching point between two contours. This is trivial since each contour is just a resized version of another. From this, a list of ordered lines can be created, which in turn can create a list of quads between these lines. Triangulate this quads to get the visual mesh. The order of the points in these triangles is important since their order determines which face is visible when rendering.
In the diagram below, the two red lines are two contours being used to create the triangle mesh between them.
Above is a preview of the visual mesh that is created at this stage.
The Regions and Entities stages are responsible for placing gameplay objects and spawning positions. The circles outlines represent each gameplay region, green for whirlpool, a place where enemies should not spawn, and white for a nonspecific region where enemies can spawn. The solid circles represent entity placement locations. White circles are wall entities such as plants, green for places where eggs and flowers can spawn, lilac for whirlpool placement and their ejection direction and finally pink for enemy spawn positions.
And finally the colour scheme. A colour ramp is made in photoshop and then is assigned and applied to a cave at runtime. Each layer is assigned a different colour based on its height.
And there you have it, how procedural cave generation works in Copod. A bit complicated for what it is, but its done now and I’m happy with the end result. I also use the same process to generate other cave types, but they are just different configurations of some stages.
Bonus! Here is a gif of all the stages.
Stay tuned for more updates and don’t forget to vote of Copod on Steam Greenlight.
Here are the latest changes:
The biggest change has been the introduction of the new progression system. Definitely the feature that took the longest to implement in this update. But now its in I can focus on expanding upon it. Only 5 unlocks are available now, but more are soon to come.
Here is a little preview of the new power “Tongue Twister”. It lets you control a very long tongue with a deadly tip. I was surprised by how much fun it was to use!
You can now get copod over at IndieGameStand! 20% off this week!
Made some new screenshots for it too.
Working on a new progression systems at the moment where new content is added to the game as you play to keep it fresh. You’ll be able to check that out in the next update.
Here are the major changes:
I also did some interviews for two youtubers. Here is one where I talk about my future ideas for Copod and here is one where I talk about game design in general.
In one of the interviews I talked about adding some sort of ending scene to Copod. I gave it a go this week and what I made didn’t fit. I’m far more content with the simple ending that is currently present in the game.
In the next update, I plan on introducing a cross-run progression system where the game increases in variety and complexity as you play it.
Download the latest build here.
Here are the latest changes found in the new Greenlight build.
Working on the new enemy variations was the hardest change, but it should make the game a lot more interesting.
You can get the latest alpha for free here!
If you like what you see, you can vote for Copod over at steam greenlight.
Version 0.2.9 alpha is out now.
Here is a little preview of the new enemy:
Another new version is out now. Download it here.
Major changes made since version 0.2.7 alpha:
Here is a little preview of the new laser enemy:
Copod is a weird game I’m working on that has rogue-like elements.
Its a 2.5d game where you have a melee attack and you can mix and match powers to improve your odds of survival.
Here is a little preview of my upcoming game Copod.
You can see one of the simple electrical powers being used to kill the red creature. At the moment, I’m working adding more powers that synergise well with each other (size growth increases the attack radius of many attacks for example).
1 / 2 Next