Persistence and data attachments
Status: Implemented (API 1.20). Data attachments on entities, players and chunks, saved data per level, as NBT values (Lua values, SNBT text or binary NBT) (API 1.12), and typed attachments with defaults, always-synced keys and copy on death (API 1.20). Schemas that validate a value’s shape are Planned.
Guide: Saved Data. Function tables: entity, level, events.
Values
A value is one NBT value under a namespaced key ("my_mod:quests"; a bare key gets the mod’s namespace). C and C++ pass SNBT text (the *_get / *_set functions, what /data get prints) or binary NBT in a cl_buf (the *_get_nbt / *_set_nbt functions, network framing: type byte, then payload). Lua converts: booleans are bytes 1b / 0b, integers ints (longs beyond the int range), floats doubles, tables with keys 1…n lists, other tables compounds; reading turns bytes 0 / 1 into booleans. CL_E_PARSE: bad SNBT or NBT; CL_E_NOT_FOUND: no value under the key.
Entities and players
cl_entity_data_get, cl_entity_data_set, cl_entity_data_get_nbt, cl_entity_data_set_nbt, cl_entity_data_remove, cl_entity_data_keys (Lua e:data(key), e:set_data(key, value, { sync = true }), e:data_keys()). Saved with the entity under clight:data (players: in the player file), at most 256 keys and 1 MiB per value. CL_DATA_SYNC also sends the value to every Celestial client with CLight that sees the entity (at most 32 KiB); on clients the get and keys functions read the synced copies and entity.data_changed fires. Vanilla clients get nothing.
Chunks
cl_level_chunk_data_get, cl_level_chunk_data_set, cl_level_chunk_data_get_nbt, cl_level_chunk_data_set_nbt, cl_level_chunk_data_remove, cl_level_chunk_data_keys (level, chunk x, chunk z, …; Lua level:chunk(cx, cz) or level:chunk_at(pos) with :data, :set_data, :keys, or level:chunk_data / level:set_chunk_data). Loaded chunks only (CL_E_NOT_LOADED); saved in the chunk under clight:data.
Saved data
cl_level_saved_data_get, cl_level_saved_data_set, cl_level_saved_data_get_nbt, cl_level_saved_data_set_nbt, cl_level_saved_data_remove (Lua level:saved_data(key): a live table written at every save, level:set_saved_data(key, value)). One value per key and level in the world’s data/<namespace>/<path>.dat, at most 16 MiB, written when the world saves.
Typed attachments (API 1.20)
cl_attachment_register(key, &desc) (Lua cl.attachment(key, { default = value, sync = true, copy_on_death = true })) gives a key a default and rules, for every scope (entities, players, chunks, saved data). Call it on both sides at setup; the same mod may register a key again (a hot reload), another mod gets CL_E_ALREADY_EXISTS.
cl_attachment_desc |
|
|---|---|
default_snbt |
What the get functions return while no value is set. On the server the default is stored by the first get (like NeoForge’s getData), so the binary get works too; a client returns the default text for its copy. "": no default (CL_E_NOT_FOUND). |
flags CL_ATTACH_SYNC |
Every set of the key syncs, as if CL_DATA_SYNC were passed (entities and players). |
flags CL_ATTACH_COPY_ON_DEATH |
A player keeps the value through death and respawn. Without it the value is removed when the player respawns after dying, and the next get gives the default again. Coming back from the End keeps everything, as in vanilla. |
cl.attachment("mana", { default = { value = 20, max = 20 }, sync = true })
cl.attachment("souls", { default = 0, copy_on_death = true })
cl.on("player.join", function(e)
local mana = e.player:data("mana") -- { value = 20, max = 20 } the first time
e.player:send_message("Mana: " .. mana.value)
end)
cl_attachment_desc d = CL_ATTACHMENT_DESC_INIT;
d.default_snbt = CL_STR("{value:20,max:20}");
d.flags = CL_ATTACH_SYNC;
cl_attachment_register(CL_STR("mana"), &d);
Safety
Vanilla ignores every key and file above. Celestial keeps the data of mods that are not installed as it is, so removing a mod loses nothing.
Also
- Config for settings: Configuration. Files in
mods/<id>/data/for C and C++ mods: Filesystem and HTTP. - Small synced render values (bool / number / string):
cl_entity_set_synced_numberand friends (Entities).