Things are heating up because fire is coming in the next update! Let’s dive into fire logic and how we developed it. We did a similar breakdown when working on water behavior, and you all seemed to enjoy that. Hopefully, you’ll find this just as interesting—and maybe even learn something new!
We needed a fire mechanic that works similar to real life situations but can be adapted to work well inside our game world. For inspiration, we looked at forest fire models which are used to simulate actual forest fires in order to determine where a fire will likely start, how quickly and in what direction will it spread, how much heat will it generate, etc. Forest fire models are usually developed as code, often documented and studied in research papers, and sometimes accompanied by guides, data, or software tools for practical use in wildfire management. These simulations save lives, prevent fire occurrences and additional financial damage.
Fire propagation is typically simulated using two main approaches: Cellular Automata and Wave Propagation. Here’s a simplified breakdown of both:
Take the Going Medieval grid system, where each square represents a voxel and something like grass, tree or a wall.
With Cellular Automata, think of each square (or cell) on the grid as a little computer that follows simple rules. For example, a square might say, "If one of my neighbors is on fire, I’ll catch on fire too!" Then, the fire spreads from square to square across the grid. Each cell just looks at its neighbors and updates itself, and by doing this over and over, you can see how the fire grows and moves across the whole grid.
With Wave Propagation , think about when you drop a stone into a pond and see ripples spreading out. That’s a bit like wave propagation! In a fire model, instead of water waves, we’re imagining “fire waves.” When one part of the forest catches fire, this wave of fire moves outward. It spreads from the burning area in all directions, like the ripples from the stone, but faster or slower depending on conditions like wind or fuel (more trees).
For Going Medieval, we went with using just the cellular automata approach because:
- It works on a 2D grid. Now, Going Medieval's terrain is made out of voxels, which is a 3d grid, but it's easy to add a 3rd dimension into the existing algorithm. Having fantastic programmers helps, too.
- These models are generally simpler and require less computing power. This makes them ideal for quick simulations, where you can change the rules to explore different fire behaviors without needing complex calculations.
- It's easy to add randomness due to its adaptability to different patterns. Cellular Automata is great for capturing irregular patterns of fire spread, like when the fire jumps between patches of vegetation or changes shape due to obstacles. It handles these kinds of “messy” patterns better than wave propagation, which is more suited for smooth, continuous waves.
Our version of the fire mechanic is adapted to the game’s world. That way it runs in real time and can work with other systems of the game. To ensure the fire mechanic worked smoothly with other game systems, we started by developing the algorithm as a standalone project. This allowed for fast experimentation and iteration in the early stages.
All voxels that have fire on them are updated across multiple frames.If we updated the fire on every single frame, it would look like it’s moving super quickly and could end up spreading too fast or looking too intense. Instead, the game only updates the fire’s behavior every 3-4 frames. This means the fire isn’t constantly changing, just changing every few frames, but it still looks smooth and realistic.
By updating the fire only every few frames, the game saves a bit of power (so it runs better) without you noticing any big difference. Since fire doesn’t suddenly grow really fast in this game, you won’t see any delay in the fire growing. So, even though fire updates 3-4 times less often than other things, it still looks like it’s burning smoothly, just like real fire.
For Going Medieval, it doesn't need to be updated every frame, but it needs to be updated frequently enough so the fire doesn't appear like it's lagging.
The fire mechanic sees the whole world as a 3d grid with each voxel having these properties:
- Voxel health - Anything burnable (trees, grass, buildings) has health > 0
- Flammability - Indicates how fast things should burn.
- Flame intensity - Represents size and strength of fire and is between the range of 0.0 - 1.0. If the value is greater than 0, fire will burn. It will appear as a small fire with less strength if it has lower values. The closer it gets to 1.0, the bigger the size is and its strength.
- Wetness - Affects voxels that are moist. This moisture slows down burning, may even stop it.
With that being said, here is the fire logic in (theoretical) action: Algorithm passes through all of the voxels that are detected to be in a burning state. Flame intensity of one voxel will be increased if there is something burnable on that voxel (like a wooden wall on a grassy ground) or be decreased if nothing is burnable at the voxel (very wet ground). Flammability is used to boost flame growth, but wetness slows it down. Rain and snow also slow down flame growth here. Water puts out fire almost instantly.
After a certain time, fire tries to spread to neighboring voxels. On one hand - we don't need it to spread after every time flame intensity is updated - that would burn your settlement too fast and we like to have fun in our game. On the other hand, it requires more calculations than increasing/decreasing flame intensity, so it's better to do it as rarely as possible (game designer is going to play around with this and come up with the appropriate value).
Here is the video of that in action on a 2d surface:
[previewyoutube=8Sfb26spjiw;full][/previewyoutube]
On the left, red channel is fire, green is grid health, blue channel is flammability. On the right, flammability and grid health are multiplied, showing how quickly things can get out of control if not properly set.
Cool, now to test how the fire looks in the 3d:
[previewyoutube=R01DaAiAFOE;full][/previewyoutube]
It’s getting there. We’ll use existing fire assets (ie the one from campfire) and use it within our gameworld. Let’s see how it looks now:
[previewyoutube=7HSKIUcL9i8;full][/previewyoutube]
Okay, a bit extreme, but we’ll tame it.
So to recap spreading: fire goes through all already burning voxels and finds all the neighbors the fire could spread to. For spreading to occur, those neighbors should not have fire on them, should be flammable and have health > 0, should not have too much wetness on them. Also, flame intensity should be higher than 0.4 to be able to spread fire to its neighbors. If the voxel passes all of these tests, it catches fire - its flame intensity will become larger than zero. This is how fire works in a nutshell, but without proper visuals it looked like this:
With a couple of shaders, it was time to upgrade it visually:
[previewyoutube=8dtioSjziqQ;full][/previewyoutube]
As the fire burns, it gradually damages the objects around it. However, to keep the game running smoothly, this damage isn’t applied immediately inside the fire system. Instead, fire damage is collected and applied later, outside the main fire logic, to avoid slowing down the game.
The game waits a few frames before applying this accumulated damage to objects in the world, which helps spread out the computational work. When the damage is finally applied, the health and flammability of each affected voxel are updated, so the fire system stays in sync with the current state of the world. Once applied, the accumulated damage resets to zero, and the process repeats as the fire continues.
Because of this, fire data will be stored in the save file the same way we store water - separated from data of all other game systems. That means if you get into an overwhelmingly heated situation and don’t want to deal with it gameplay wise, you will be able to delete all of the fire from your save. More on that once the update goes live.
But there is also still so much to talk about! This was just a fun (we hope it was fun) talk about fire movements. Next week we’ll discuss how to control fire spreading in the game. While you wait, let us know if this MMT was understandable as it went into more behind-the-scenes detail than we usually do. See ya in seven days and until then…
Stay medieval!
Foxy Voxel
Discord Reddit X/Twitter Bluesky TikTok Facebook