-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
Problem
During a recent discussion about persistent unique object IDs (see PR #14135), I suggested that we should rethink object data storage in Luanti. Several other issues highlight the underlying design limitations of the engine as it relates to object data storage:
- Add parameter to core.clear_objects to ignore objects with a specific attribute #6124
- Add APIs for offline players and entities #15659
- Node bound entities #6963
In order to simplify management of static objects and to fully benefit from persistent unique object IDs, I believe it would be beneficial to migrate static objects into a separate table. The existing database architecture is clearly an impediment to the long-term needs and goal of mod developers. And we should find a solution that is scalable and robust.
For example, the only means of removing objects from the entire database is by reading, decompressing and deserializing every mapblock. Since most mapblocks do not contain any objects, this can be extremely time-consuming. And even for mapblocks with objects, they must still be reserialized, recompressed, and rewritten. However, by storing all objects in a separate table, a single SQL statement would allow for efficient removal.
Similarly, it is only possible for mods to create and remove entities within loaded mapblocks. Once the parent mapblock is unloaded, then all of the associated entities become inaccessible to mods. Forceloading is one workaround to this problem, but that has the side effect of reactivating all entities within the same mapblock. However, if objects were stored in a separate table, then the engine could provide an API to manage unloaded entities.
Solutions
The most important design decision will be the database schema. Some viable options include:
-
Migrate all static objects into a separate "objects" table. Retain the existing BLOB format for each object. Include an automaticaly incrementing ID column as the primary key. Store the list of corresponding object IDs within the BLOB of each mapblock.
-
Migrate all static objects into a separate "objects" table. Retain the existing BLOB format for each object in a data column. Also include an automaticaly incrementing ID column as the primary key in addition to columns for the parent mapblock position.
-
Migrate all static objects into a separate "objects" table. Include columns for each object property (position, name, hp, etc.). Also include an automaticaly incrementing ID column as the primary key in addition to columns for the parent mapblock position.
There are pros and cons to each of these alternatives. Some considerations include:
- The BLOB format is ideal for data compression. However, since objects tend to have limited data requirements in comparison to mapblocks anyway, the benefits would be marginal.
- Storing a list of object IDs within each parent mapblock is potentially redundant, It could also lead to inconsistencies if the objects and blocks tables are not properly synchronized.
- Having distinct columns for the name, staticdata, position, velocity, etc. could allow for easily filtering objects either as part of a new entity management API or by external map tools.
- The BLOB format could allow for multiple types and versions of entities to co-exist within the same table, each with different sets of properties or with an entirely custom specification.
It should be noted that the automatically incrementing IDs would be managed by the engine, not internally by the database, since we need these unique IDs to be generated at the time of object creation (prior to being stored in the database).
I personally favour automatically incrementing IDs over UUIDs or other random strings of numbers because they can be stored in 64-bits and are fast to generate. However, I'm otherwise ambivalent about whether to use integers or strings for object IDs.
Alternatives
There are no straightforward alternatives, other than to continue adapting the existing database architecture with band-aid approaches, which I do not consider an ideal solution for the long-term.
Additional context
No response