Procedurally generated terrain with tilesets and walls

Getting to a question I’ve been itching to ask since I discovered the engine. One of the things I love doing are procedurally generated worlds. In particular top-down RPG environments with procedural tileset terrains, and if it’s easy enough I may just consider isometric too at some point.

In fact I’ve already attempted to create such a thing in pure HTML / CSS / JS using a few sets from OpenGameArt and got places: Seed based terrain works with a simple sine function for noise, you can move between different maps using straight roads, the player collides with cliff walls, and you switch to different heights as you climb on various pieces of terrain. If anyone wants to see the latest live demo you can run it on Github pages at the following link:

https://mirceakitsune.github.io/world

Of course it’s very primitive and lacks remaining features while also being filled with bugs I’d need to solve: Especially coding the remaining stuff will be a nightmare considering the complexity required. Now that I discovered GDevelop which automates 95% of what I need, it feels foolish to continue that particular project: I’d rather continue it here and benefit from all the important features provided.

That’s definitely going to be easier but not all that easy still: I’m not able to find an existing example of exactly what I’m trying to achieve here. I found a tutorial a starter project and an extension that offer the basics, but adding the remaining touches is going to be tricky.

https://wiki.gdevelop.io/gdevelop5/tutorials/procedural-generation

They provide an explanation in using noise to spawn items on a grid. This is great! But there’s a major difference from what I want to achieve here. Most notably:

  • Every item is an identical sprite or a box of one color. I want to use a tileset for each material, containing the 8 corners / edges and a center tile, with the ability to randomize each type. The 9-patch Panel Sprite with repeat enabled technically does what I want, but has the fatal flaw of only being a rectangle instead of meshing multiple points in a 2D grid.
  • As terrains have elevation, I’ll want each island to contain a wall extruding down from under the floor. As you can see in my screenshot some walls even have caves that lead to underground caverns and are meant to connect with one another. When generating walls they’d also need to detect and avoid patches under them, meaning at each vertical line the cliff stops going down based on the height of the floor that was touched.
  • The player is meant to be able to climb on terrain of higher or lower elevation using gaps that occasionally spawn over walls (eg: ladders). In my project the camera also zooms in and out based on this elevation, and of course the sprite’s Z order is changed so items standing on terrain below a given patch are covered by it. One goal is to allow overhead islands acting as bridges, where players can walk under them at ground level but if they climb up they’ll be walking on the bridge, meaning both the Z order must change as well as the collisions experienced by objects based on their height.

That’s not getting into generating houses with interiors and more, which I’ll be dealing with once the rest is ready. For now I’m not sure how to even start and could use some pointers and advice. I’ll probably need to create my own custom function / behavior which seems doable but I’d need to know what to do.

The first immediate problem is how to represent tiles. Picking the correct image should be easy to do the way I did it before: At each position I check neighbors and pick a center / edge / corner based on which noise density is solid enough. The big problem is that if I if I spawn an object for each tile I’ll be creating a ton of them which would greatly harm performance on large maps: A 64 x 64 map for instance would spawn 4096 sprite objects! I’d need to combine them into one tileset image and sprite. GDevelop has a Tilemap object, but apart from not being finished yet and still in experimental phase, it only accepts fixed tilemaps exported from Tiled or LDTK: For this it would need the ability to set tiles at various positions in realtime. I looked at the actions of the tilemap in the event editor and don’t see any action of the type “add tile Z at position X Y”, thus I presume I’m out of luck.

What do you suggest considering, what is the best I can currently get? Based on how I would do this I also need to think of how I’ll extrude the walls down which makes this even more complicated. Please let me know what you think and suggest going for! Thank you.

Quick self correction: As each tile will need to have not just collisions but also effects and specific triggers, like different footstep sounds / particles or changing the walk animation / speed of the player, I may in fact want to define every tile as a sprite and have the generator add it as an object at each position. Tilesets would only be visual even if combined them into one image: I’d still need to put a collision box on pretty much everything, so considering this I may as well make each tile a box.

But if I do I’d definitely want to derender tiles that are off-screen so only what’s in view of the camera gets processed. I assume this happens automatically and I don’t need custom events or behaviors for it? I remember now it’s supposed to be a default feature, in which case it may not be so bad of an approach.