HexDecimal / python-tcod-engine-2023

MIT License
4 stars 1 forks source link

Map tile database. #3

Closed HexDecimal closed 1 year ago

HexDecimal commented 1 year ago

The issue with this not quite as trivial. I need to add a better system for map tiles without breaking the open–closed principle and without hardcoding them to specific numbered identifiers like in every single engine I've mode so far.

One idea is to use strings to identify tiles, but I need them stored in NumPy and using Python objects will likely be too slow. So I can make a string ID module which converts strings into temporary unique numbers and then either converts these back into strings when serializing them or serialize the string ID database along with the world and map data.

A tile database with a string lookup might handle this in an even simpler way. The main problem is how to handle changes in the database between versions. Saving the database with the world means that new tiles are not in the database of an old save, but a global database could have entirely new integers between versions.

HexDecimal commented 1 year ago

Possible example?

db = TileDB()
db.register("floor", ...)
floor_id: int = db["floor"]
floor_data: NDArray = db.tiles[floor_id]
floor_transparent: NDArray = db.tiles["transparent"][floor_id]

To easy for int to change between runs. A string ID database would solve this.

db.register("floor", ...)
floor_id = StringID("floor")
# floor_id is serialized as StringID("floor"), but can be converted into int.
tile_array: StringIDArray  # Numpy array subtype, stores ints but serializes as StringID's.
floor_transparent: NDArray = db.tiles["transparent"][tile_array]

Maybe a unique TileID class:

db.register("floor", ...)
floor_id: TileID = db["floor"]

It seems the database must be global to handle save migration cleanly. Maybe it can be stored with the world if it's updated on load and all references to tiles always use the string names for them.