One of the pillars of my game Witchcrafter: Empire Legends I want to have is fire spreading.
I started tinkering with it one year ago as you can see here and recently I got back to this feature with fresh mind and new ideas.
About this topic - a lot of things changed, I learned a lot about cellular automata, AABB and many other game dev crucial topics. Like from the beginning, the biggest inspiration is still Far Cry fire spreading made in Dunia (derivative of CryEngine)
2D board of cells/tiles
So I decided to make it simple - it’s for the 2D game, so everything is like a simple board with cartesian coordinates. I finally managed to use tilemaps for this purpose. Every tile in a tilesource in Defold has its ID, so I can have the crucial information about any tile and recognise that object easily. I can get the tile ID by calculating the tilemap coordinates easily, when it has its left bottom corner in the origin of the world coordinates:
local function convert_world_to_tilemap_coords(x,y)
return math.ceil(math.ceil(x)/M.TILE_SIZE), math.ceil(math.ceil(y)/M.TILE_SIZE) + 1
end
local function convert_tile_to_world_coords(x,y)
return ((x*M.TILE_SIZE) + (M.TILE_SIZE/2)), ((y*M.TILE_SIZE) + (M.TILE_SIZE/2))
end
M.TILE_SIZE which is 16 is my game is enough for the size of the cell.
So if I want to interact with or change the particular tiles I can use both position of the player or something or use a small collision object like this fireball:
–gif here-
I can get the position of collision object and translate it to tilemap coordinates and check what the tile id or adjacent tiles ids are and change that tile to another tile id - this is a basic idea of changing the visual representation of the tile - but also using another tile id, we can have some other information about the tile saved now. How we can use that information?
Things that burn
Some simple assumptions about spreading fire in games are that “burnable” things are made of wood or fabrics or are part of flora. Those things can catch fire and in some cases, fire can propagate over them (like on grass and leaves in Far Cry games). Using information about tile ids we can associate the information about the tile “material” with tile id. To simplify it, I made a “sections” in a tile source:
- You can see that first line is used to specify the “form” of the tilemap - it is used for collisions - you can take a look at True Tile Collision to have a glimpse at the idea behind it.
- The second section represents the burnable grass tiles (those are also animated using Defold Tilemap Animator, thus that alignment)
- Third section represents wooden objects that will be burnable too and fire can spread over them, but not so easily as over the grass.
- Forth section represents the ground - I think one should be able to put a fire over it, but shouldn’t allow to propagate the fire - this is something to consider probably.
- Last section includes not burnable tiles such as rocks, stones, walls, background elements and water.
Now I have a module that includes the information about the starting and ending tile id of each section and I can now get any tile and check to which section it belongs!
Visual representation of burning
In many games fire is only the visual effect (shader vfx or particle fx, as I made it above as well) and deals some damage in contact with lifeforms - be it player or mobs/enemies in the game and vanishes after some time. But in some cases devs decide to add visual representation of damage taken to the actual object - burnt wooden box, burnt grass, “burnout stain” on the floor or wall. It can be a shader thing (with texture or procedural) or change of the whole texture of the object to the manualy drawn one. The latter demands a lot of work, while the first could be very tricky. I tried both:
Shader approach:
With shading the basic idea I had in my mind was drawing “burnout stains” in a separate render target the blending it with the tilemap:
I am not satisfied with the results above, so I tinkered a little bit with the texture and shader used this, but I can’t get better results It’s rather more appropriate for some paint stains than burnouts. And though I used particles here to attain the irregular shape, the shader should still modify the animation and shape of the tile to look realistic. If you have any ideas here, I would be glad to hear them. Take a look how Remedy managed to do something analogical with cracks in Control (a mix of a HD texture and a great shader (+Ray Tracing
):
Tilesource approach:
So I tried with hand-drawn textures:
The idea is simple here, because you have that part of tilesource below the regular ones and you change the tile to the burnt version of the same tile:
tile_id = start_tile_of_burnt_section + (current_tile_id - start_tile_of_current_section)
tilemap.set_tile(M.PATH, "above", i, j, tile_id)
What is the problem? Take a look:
We naturally want that “burnout stain” to have irregular shape, not rectangular shape I know of course, what the solution for this looks like - I should create a tilesource that has all the versions of one burnt tile in regards to its adjacent tiles - if it is burnt or not - something, that I could “autotile” later. And drawing this will take hours and I will need to realign tiles in the tilesource and maintain the proper autotiling for each tile that is burnable. In the point I am, I don’t wont to draw this
So now I’m at the crossroads - where should I go?