Individual tiles, like in Terraria that require variables (toughness, HP). How should this be approached?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By mattkw80

Working on a 2D game like Terraria or Rim World.

Every single tile matters… ie: mud, tree, rock, fire, steel, water.

They will all have properties… HP, an item drop on destruction, value, toughness, etc.

And I further ahead to:

a. Put all of these in a tilemap and then somehow give them the values by their names when a payer approaches them

or

b. Create a unique scene for each and every piece, and then bring them into a map 1 by 1 either by instancing them into the ‘game scene’ or proc_generation code

Anyone have any thoughts on the best way to approach this?

:bust_in_silhouette: Reply From: Zylann

I don’t have a definitive answer due to the fact such big worlds are approaching the limit of “easyness” provided by Godot, but it’s still doable with some research (depends how big your world is of course).

Approach a seems more scalable for the amount of tiles you’ll need. Also, you may start to consider TileMap like only the “graphics and physics” part of your map. Those tiles can’t hold information, so I’d suggest you keep a 2D array of the same size in script, with data stored in the places you need it. Those would hold game-specific data. Eventually, you might need chunks too, if your world is really really big.

With super-high tile density such as Terraria though, you could also consider GPU tilemaps, but it may require more knowledge on the technique used for this. I think there is a plugin on the assetlib.

Also, “fly-weighting” may be used if some of your tiles data is constant. Indeed, if all dirt tiles have the same resistance, it doesnt need to be stored in every single block. The only thing you need is to store the type of the tile in the grid, and lookup the constant in an array of tile types.

Some data may be occasional. For example, if a tile can have temporary health, it sounds wasteful to store health in 99% of the other tiles in the world. So it may be stored in a dictionary indexed by tile position, and be removed once the temporary delay has passed for example.

I have other ideas how to handle huge worlds like this, but with the tools given by GDScript I’m not as confident as if I had C# or C++, mostly because memory efficiency and processing speed going through those tiles are going to matter. A cell may normally be just 16 bytes at most, while a class instance in GDScript with just 4 fields is 921 bytes already (because it’s all dynamic typed, stored on the heap etc). The memory of a Terraria map stored with class instances would count in gigabytes (you’d definitely need to stream it).
Using layers of PoolIntArray instead can help tighten the data, but it depends how comfortable you are working with 2D flat arrays.

Anyways… you can try small first, and see how it scales, and find different approaches for what your game actually needs.