feat(scripting): load base game blocks from data files into worldgen #13
No reviewers
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
scope/assets
scope/client
scope/networking
scope/renderer
scope/scripting
scope/server
scope/shared
scope/workspace
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Synvael/synvael!13
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/data-loader-worldgen"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What does this PR do?
Content is now registered only from data files, per the new ADR-0017, which supersedes the registration path of ADR-0007. I removed
synvael.blocks.registerandsynvael.items.registerfrom the Lua API, so scripts refer to content bynamespace:idand never define it.I added a data-pack loader in
crates/scripting/src/data.rs.load_datareads every<pack_root>/data/blocks/*.jsonanddata/items/*.jsonfile in file-name order and deserialises each one straight intoBlockDeforItemDef, with no Lua involved.crates/scripting/src/content.rsthen registers it after checking the load phase and that the ID uses the loading pack's namespace. A file that fails to parse or register returns the newScriptError::Datanaming the file, with aDataErrorsaying why. A client VM skipsdata/since content is authoritative. The mluaserializefeature is no longer needed and is dropped.load_packnow sets the loading-pack scope once and loadsdata/beforescripts/init.lua, so a script can refer to blocks its pack declared as data. I addedscripting::load_base_game(side, assets_root), which creates a VM, loadsassets/as packsyn, ends the load phase, and returns the unboundContent.The base game's blocks now live in
assets/data/blocks/dirt.json,grass.jsonandstone.json.In
shared,WorldGenConfignames its three blocks byContentIdinstead of rawBlockId.VoxelGenerator::newtakes the block registry and resolves the IDs to handles once, returningGeneratorError::UnregisteredBlockfor an ID the registry does not hold.assets/data/worldgen/default/0.jsonnow says"syn:grass","syn:dirt"and"syn:stone". Because the worldgen params stored inlevel.datchanged shape, I bumpedWORLD_FORMAT_VERSIONfrom 3 to 4.In
server/src/main.rsI removed the hardcodedBLOCK_IDSlist andregister_blocks. The server now gets its blocks fromscripting::load_base_game, andbuild_generatorsbuilds one generator per worldgen history entry against the bound registry.inspect_savelogs the params field by field so the IDs print readably.Why is this change necessary?
The server registered blocks from a Rust constant, and worldgen referred to them by raw handles 1 to 3 that only matched because the constant happened to register them in that order. That bypassed the scripting layer, and ADR-0007 requires content to be declared through the modding API. Content could also have been written either as JSON or through the Lua
registerfunctions from PR #12, which gave each content kind two authoring formats to keep in sync. ADR-0017 keeps one: data files, with datagen (not part of this PR) as the only way to generate them programmatically. Naming blocks by content ID in the worldgen params also means a history entry keeps its meaning whatever handles a world's ID table assigns.Scope of Changes
server, shared, scripting, workspace, assets
Testing
Automated, all passing:
cargo check -p scripting -p server -p sharedcargo test -p scripting -p server -p sharedcargo clippy --all-targets --all-features -- -D warningscargo fmt --all -- --checkNew tests cover block and item data files registering in file-name order, malformed and rejected files erroring with the file name, each kind of refused registration (missing or foreign-namespace ID, unknown field, registration after load), Lua having no registration functions, the base game registering its blocks at the handles worldgen expects, a generator refusing a config that names an unregistered block, a block the base game no longer registers staying an orphan in the ID table, and a version 3
level.datbeing refused.Manual: I ran both the client and the server with
--releaseon my machine.Additional Context
This breaks the save format.
WORLD_FORMAT_VERSIONis now 4 and a version 3level.datis refused withUnsupportedVersionper ADR-0015, so existing dev worlds have to be deleted. The worldgen config schema also changed: block fields are now content ID strings, not integers.docs/save_format.mdanddocs/scripting.mddescribe both.This also removes
synvael.blocks.registerandsynvael.items.register. They were added in PR #12 and never shipped, and no script inassets/ormods/calls them.docs/scripting.md,docs/packs.mdandDEVELOPMENT.mdare updated.Checklist
dev(or a feature branch offdev) and my PR targetsdev.///doc comments for Rust) where necessary.feat(scripting): load base game blocks from data files into worldgento WIP: feat(scripting): load base game blocks from data files into worldgenWIP: feat(scripting): load base game blocks from data files into worldgento feat(scripting): load base game blocks from data files into worldgen