alchementalist alchementalist devlog Games personal blog

Alchementalog #7: Mining for Content

How do ore be? Today, we’ll find out as we generate our ore deposits!

All Alchementalogs

Table of Contents


In the previous devlog, we talked how to assign different “types” to the generated rooms, which is good and all, but eagle-eyed people may have noticed something going on in the background: the funny little sections of floor that were differently coloured.

Circled in red

What is that? Well, that’s the area that will hold ore deposits, which is what we’re going to tackle today. It’ll be a bit of a shorter devlog, but still packed with juicy generation goodness.

To Be Ore Not To Be

Where do we begin? The first thing to do is, of course, set up a new cellular automata map (I’ll call it the ore map from now on). This one will ignore all the previous stuff we’ve created and just do it’s own little cellular thing. However, the process the ore map will go through is very similar to the process our regions went through in Alchementalog #4: Delving the Deeps (Part 1).

We’ll generate the ore map, using some tweaked settings so it creates lot of empty space and a few little pockets of ore area, then we’ll loop through the map, flood filling the ore regions as we find them and adding them to a new array I name veins. Then we find the borders of the ore deposits and add them in. So far, exactly the same as the regions. But the slight differences start here. For one, we don’t care about the “center” of the ore maps, as we won’t be doing any pathfinding or anything on them, so we can ignore the process we went through to get the center of the regions. However, we do want the distance map from the borders of the ore regions.

This is because I want ore to spawn more heavily the “deeper” into an ore region we go. The cells closest to the edge of the ore deposits should have a slim chance of generating ore, while the cells closer to the center should have a relatively higher chance of generating ore. So we’ll run through and build a distance map for each of the ore deposits stored in the veins array. Once that is done, we’ll start a loop through each of the deposits stored in the veins array and start looking at each cell in the distance map.

If we remember how the distance map worked, we’ll get a value of 1 in the cell if it is directly next to a border cell, a value of 2 if the nearest border cell is 1 cell away, a value of 3 if the nearest border cell is 2 cells away and so on. What this means is we can effectively use the distance map value as a multiplier to increase the chances of ore being generated on a cell as the distance map gets higher (meaning the cell is closer to the center of the ore deposit).

Please Sir, Can I Have Some Code

Let’s have a look at the code for that:

SpawnOre = function(pos) {
	var xx = border_distance_map[pos][0][X];
	var yy = border_distance_map[pos][0][Y];
	if (other.cell_floor_map[xx][yy] == EMPTY) {
		var border_chance = border_distance_map[pos][1];
		var roll = random(100);
		var spawn_chance = base_spawn_chance*border_chance;
		if (roll < spawn_chance) {
			var _inst = instance_create_layer(xx*CELLSIZE,yy*CELLSIZE,"ore",obj_ore);
			_inst.image_index = ore_type;
			_inst.ore_type = ore_type;
			_inst.vein_id = vein_id;

First, we’ve got a function called SpawnOre, that takes an integer as an argument (pos). This integer is the position in the border_distance_map array that we want to check. So we grab the X and Y positions stored there and we compare them to the floor map.

Why are we comparing them to the floor map? Well, we don’t want to spawn ore inside any of the walls in our game, so we have to make sure the floor map is empty before we start trying to spawn the ore.

If it is empty, we grab the value stored in the distance map and save it into the local variable called border_chance. This is now our multiplier. We roll a random number and then we work out the actual spawn chance by multiplying our border_chance by a flat number stored in a variable called base_spawn_chance. We store the result in the local variable spawn_chance. Right now, I have base_spawn_chance set to 3. We then compare spawn_chance to our random roll and we know if we should generate ore or not. If the distance map cell we are checking holds 1, we’ll have a 3 percent chance of spawning ore (1 x 3 = 3 compared to a roll of 100), if it holds 2, we’ll have a 6% chance of spawning ore and so on. Even in the center of the ore region, I don’t want to have too high a chance to spawn ore, which is why the base_spawn_chance is set so low.

Then we’re just creating the ore instance and giving it some values so it knows what type it is and so on. Previously, as we saved the veins in our ore map, we also assigned each vein an ore type which is where this ore instance gets it’s type from. We also save the vein id that spawned the ore instance and stuff like that.

A sidenote about the veins being assigned an ore type is that for each “floor” in the Alchementalist mine I want to have a “primary” ore type that spawns on that floor. So as the veins are picking their type, they have a high chance to pick the “primary” type for that floor, and a low chance to pick from one of the other ore types.

Now Look Here

Here’s the newly updated map creation process with the ore being generated as well:

So, the gif starts from after the walls have been drilled. To begin with, every ore cell is coloured dark blue, which means they haven’t been assigned to a vein yet.

Then the flood fill does its thing and as each vein gets populated it gets assigned a type, which is shown by the colouring of the cells (red is fire, aqua is water, grey is wind and brown, which isn’t shown, is earth).

After that, the rest of the generation plays out and we’re left with the completed map. The ore deposits themselves are the large crystals and you can see that they are more likely to spawn near the center of the vein of ore that spawned them, rather than the edges (however, it’s not impossible for them to be on the edge). They also can’t spawn inside a wall section. You can also see the the primary ore type for this floor is probably fire, because there are a lot more fire deposits than any others. When I mouse over the deposits, the numbers shown in each cell is the value the distance map for that cell holds. Everything is as we’ve already discussed.

We’re getting close to completing the basic map generator now (although, like with everything, change will probably come in one form or another over time), but we’ve still got to think up a good way to place enemies and also deal with the fact that there will be more than one level to the Alchementalist mines. In fact, the very next blog post is going to be about how we extend the ore deposits to run through multiple levels. I’m kinda excited about that one, it definitely has some fun visuals to show! Till then!


By RefresherTowel

I'm a solo indie game developer, based in Innisfail, Australia.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s