(no title)
gcau | 5 months ago
I want a kind of tree structure of bitflag values, and I'm trying to think of a good way to do it. For example a Grass /Stone tile, maybe 4 bits for the tile type (0001 = Grass), and then from that point forward, the remaining flags depend on the tile type (Grass having the next 2 bits for the grass colour, stone having 1 bit for whether it's cracked or not, etc), but in a safe and efficient abstraction where I can't accidentally mix them up. I don't want a pirate software monstrosity where I can't keep track of the different combinations.
neg4n|5 months ago
Regarding your case, I'm pretty sure that such type safety can be achieved. It is depending on the ecosystem you're working but if its C++ I would go for CRTP implementation with heavy load of template meta programming - like defining TYPE_ID=1 for grass, TYPE_ID=2 for stone and creating BaseTile -> GrassTile/StoneTile with polymorphism on std::variant.
I think this is not exactly the tree structure, but your minimal case can be achieved by assigning different "concern" to different set of bits in the number. For instance bits 31..24 will be TYPE_ID and 23..0 will be attributes (color of the grass, is the stone cracked). However it will quickly become to small to build anything reliable, but then I would change the structure of tiles to have one non-bit flag integer for block type and the one placed sequentially next to it to the attributes bitflag (max. 31 attributes per block? should be quite enough)
You would also need to establish the whole map format - header of the file (version could possibly be stored per map and exist in header, not per tile?), chunks (per-chunk header, chunk data), optimization strategies like RLE, unique separators, serialization and deserialization, endianness auto-conversion and probably more.
Anyways, please correct me if I am wrong but compiler will help you with types only after static_asserts - as I imagine it would be useful mostly for defining interactions between blocks (which ones are allowed and which ones are not). For every other case the compiler would need to know your map at the compile time to help, and it can't be done.
In TypeScript (its a main example of language in the article, I'm not 100% sure if its possible to do such compile time checking but arktype.io would be an excellent choice for this kind of implementation. I really encourage you to check out their solutions as really complex systems can be built on top of it)