Files

3.5 KiB

Development and storage tools

This guide documents the storage tools introduced in the first implementation stage. The current workspace also includes a game server, graphical client, and MCP server; see README and STATUS. The local JSON-lines CLI described below is a storage development interface, not MCP.

Build and checks

Requirements: Rust/Cargo 1.96.0, a C compiler for bundled SQLite, Python 3 for crash testing, and Node.js 22+ for JavaScript and network checks. Cargo.lock pins dependency versions. Run these commands from the repository root:

bash scripts/verify.sh

The script checks formatting, runs Clippy and Rust tests, builds the workspace, and runs storage crash checks, JavaScript tests, and HTTP/WebSocket scenarios. check_storage.py creates temporary worlds and forcibly terminates only its own child process.

Storage demonstration

cargo run -p shacraft-tools -- --data data/demo demo
cargo run -p shacraft-tools -- --data data/demo stats

demo requires an empty store. It creates a floor map and two independent instances, edits one, checks isolation, and exercises undo and reset. Running it again in a nonempty directory is rejected. Use a new directory name for another run.

Measurement

cargo build --release -p shacraft-tools
target/release/shacraft-tools --data data/bench-001 --cache 8 benchmark --sections 256 --worlds 100

benchmark also requires an empty store. It creates 256 distinct sections and 100 instances, traverses more data than the cache can hold, and edits/resets each instance. Its JSON output separates whole-process RSS/peak measurements on Linux, storage metrics, durations, and file sizes. This is synthetic test data: no players, network ticks, or background simulation. These numbers do not establish an advantage over Paper.

JSON-lines session

target/debug/shacraft-tools --data data/manual --cache 8 session

Send one JSON command per line:

{"op":"register","state":"shacraft:stone"}
{"op":"create","name":"world"}
{"op":"registry"}
{"op":"revision","world":"world"}
{"op":"get","world":"world","pos":[-1,0,0]}
{"op":"stats"}

First obtain the actual block ID and current revision, then pass them to edit:

{"op":"edit","world":"world","expected_revision":0,"operation_id":"first-stone","changes":[{"pos":[-1,0,0],"block":1}]}
{"op":"undo","world":"world","expected_revision":1,"operation_id":"undo-first","target_operation":"first-stone"}
{"op":"reset","world":"world","expected_revision":2,"operation_id":"reset-world"}

ID 1 is valid in this example only if registration actually returned 1. Each response contains ok and either result or error. A successful write response is sent after the durable API returns. The maximum input line is 8 MiB; block-count and region-volume limits also apply.

Further development

Read STATUS and PLAN. Add workspace components together with their implementation and verification commands. Do not add empty executables that merely print a success message. Current API boundaries are documented in CONTRACT and the component-specific documents; completing the storage stage alone does not establish completion of subsequent stages.

Copying only worlds.sqlite3 from a live SQLite store is not a complete backup: current data may still be in the WAL. Stop the owning process before manually copying it, or use a future coordinated backup API. Source archives intentionally exclude runtime worlds.