Tutorial: Teeworlds end-to-end¶
This tutorial walks the full reference workload — the one Myelin treats as the canonical pressure test. By the end you'll have run xxuejie's CKB replayer binary through Myelin's VM, chunked the game tape, projected each chunk to CKB, and produced a court bundle ready for the future dispute verifier.
What we're exercising¶
%%{init: {
"theme": "base",
"themeVariables": {
"primaryColor": "#A5B4FC",
"primaryTextColor": "#1E293B",
"primaryBorderColor": "#4F46E5",
"lineColor": "#6366F1",
"secondaryColor": "#C7D2FE",
"tertiaryColor": "#C7D2FE"
}
}}%%
flowchart TB
A["Scripted tape<br/>(generated by teeworlds-cli)"]:::off
B["xxuejie's fixture builder<br/>(teeworlds-cli utils build-test-tx)"]:::off
C["CKB mock transaction<br/>(4-witness shape)"]:::off
D["Myelin teeworlds build-fixture"]:::l2
E["CKB replayer<br/>(RISC-V ELF)"]:::off
F["Myelin VM probe<br/>(CKB-strict)"]:::l2
G["Per-chunk projection report"]:::l2
H["Court bundle<br/>(chunk 0)"]:::l2
I["Court bundle verification<br/>(16 assertions)"]:::l2
J["Settlement intent"]:::l2
A --> B --> C --> D
E --> F --> G
C --> F
D --> G
D --> H --> I
H --> J
classDef off fill:#CBD5E1,stroke:#334155,color:#1E293B;
classDef l2 fill:#A5B4FC,stroke:#4F46E5,color:#1E293B;
Every box is a real step. Every arrow is a real CLI invocation.
Prerequisites¶
- The Myelin workspace installed per Install the toolchain.
- The Teeworlds checkout parented at
$HOME/RustroverProjects/teeworlds(see the parentMYELIN_ARCHITECTURE.mdfor the structure). - A built
ckb/build/replayer_strippedRISC-V ELF in the Teeworlds checkout.
If anything is missing, myelin-cli teeworlds doctor will tell you
exactly what's not ready:
cargo run -p myelin-cli -- teeworlds doctor \
--teeworlds-root $HOME/RustroverProjects/teeworlds \
--out reports/teeworlds-doctor.json
Step 1 — Generate a scripted tape¶
The replayer doesn't need a live game session — a deterministic scripted tape with the right shape (connect, enter, input, tick, replay) is enough to exercise the witness wiring, the map/config loading, and the replay loop.
cargo run --bin teeworlds-cli -- utils build-scripted-tape \
--ticks 300 \
--clients 1 \
--input-every 5 \
--seed 1 \
--output /tmp/myelin-teeworlds-scripted-tape.bin
The tape is a deterministic sequence of game events. Replaying it twice produces the same final state CRC, because the replayer is deterministic.
Step 2 — Build the CKB mock transaction¶
xxuejie's fixture builder takes the tape + map + config and emits a CKB mock transaction with the four-witness shape Myelin expects:
cargo run --bin teeworlds-cli -- utils build-test-tx \
--replayer $HOME/RustroverProjects/teeworlds/ckb/build/replayer_stripped \
--tape /tmp/myelin-teeworlds-scripted-tape.bin \
--map $HOME/RustroverProjects/teeworlds/build/data/maps/dm1.map \
--config $HOME/RustroverProjects/teeworlds/build/myelin_replay_40265.cfg \
--output /tmp/myelin-teeworlds-scripted-mock-tx.json
The mock transaction has:
witness[0] -> signature witness (placeholder)
witness[1] -> tape (game events)
witness[2] -> map (game world geometry)
witness[3] -> config (game rules)
The slot numbers are part of the contract; the replayer reads them at fixed positions.
Step 3 — Build the Myelin fixture¶
The teeworlds build-fixture command ingests the mock
transaction, chunks the tape, emits per-chunk CellTx reports with
projection status, benchmarks the run, and finalises a
static-committee benchmark block:
cargo run -p myelin-cli -- teeworlds build-fixture \
--teeworlds-root $HOME/RustroverProjects/teeworlds \
--replayer $HOME/RustroverProjects/teeworlds/ckb/build/replayer_stripped \
--tape /tmp/myelin-teeworlds-scripted-tape.bin \
--map $HOME/RustroverProjects/teeworlds/build/data/maps/dm1.map \
--config $HOME/RustroverProjects/teeworlds/build/myelin_replay_40265.cfg \
--mock-tx-output /tmp/myelin-teeworlds-scripted-mock-tx.json \
--runs 3 \
--out reports/teeworlds-build-fixture.json
What's inside the JSON:
workload : "teeworlds"
source_repo : "$HOME/RustroverProjects/teeworlds"
mode : "ckb-style-fixture"
tape_size_bytes : 4096
chunk_size_bytes : 262144
vm_cycles : measured for each run
execution_latency_ms : measured
scheduler_overhead_ms : measured
committee_finalisation_latency_ms : measured
semantic_profile : "ckb-compatible"
ckb_projection_possible : true
No expected numbers are hard-coded. The benchmark records what was measured, and the report says whether each chunk projects.
Step 4 — Run the VM probe¶
The VM probe constructs the witness layout and runs the replayer binary as a type-script group through Myelin's CKB-VM verifier:
cargo run -p myelin-cli -- teeworlds vm-probe \
--replayer $HOME/RustroverProjects/teeworlds/ckb/build/replayer_stripped \
--tape /tmp/myelin-teeworlds-scripted-tape.bin \
--map $HOME/RustroverProjects/teeworlds/build/data/maps/dm1.map \
--config $HOME/RustroverProjects/teeworlds/build/myelin_replay_40265.cfg \
--max-cycles 70000000 \
--out reports/teeworlds-vm-probe.json
The probe models the replayer's CKB witness contract with input
witness slots 1 = tape, 2 = map, 3 = config, exactly as the
replayer expects.
If the probe runs cleanly, the JSON reports:
vm_exit_code : 0
cycles : <measured>
semantic_profile : "ckb-compatible"
vm_profile : "ckb-strict-basic"
ckb_spawn_ipc_required : false
court_verifiable : true
projection_possible : true
A live gameplay tape (vs the scripted one we're using here) would produce the same shape, just with more cycles and longer execution_latency_ms.
Step 5 — Build a court bundle¶
Take chunk 0 of the fixture and package it for the future court:
cargo run -p myelin-cli -- teeworlds court-bundle \
--mock-tx /tmp/myelin-teeworlds-scripted-mock-tx.json \
--chunk-bytes 262144 \
--chunk-index 0 \
--out reports/teeworlds-court-bundle.json
cargo run -p myelin-cli -- teeworlds verify-court-bundle \
--bundle reports/teeworlds-court-bundle.json \
--out reports/teeworlds-court-bundle-verify.json
The verify command runs 16 distinct assertions against the bundle.
If it reports valid: true with all 16 passing, you've reached
Tier 2 of the claim ladder: "executable disputed-chunk input
shape."
Step 6 — Run the acceptance gate¶
If you want to do all of this in one shot:
The script:
- Regenerates the scripted tape.
- Invokes xxuejie's fixture builder.
- Runs Myelin build-fixture, VM probe, court-bundle, and court-bundle verification.
- Asserts every JSON output is
ckb-compatible,projection_possible: true,vm_profile: ckb-strict-basic,court_verifiable: true, and finalised by the static committee.
A passing acceptance gate means:
- ✅ A real CKB binary ran through Myelin's CKB-strict VM.
- ✅ Per-chunk projection reports all say
ckb-compatible. - ✅ A court bundle exists, with all 16 assertions passing.
- ⚠ Live gameplay tape and CKB mainnet court verifier remain next-step work.
What this proves¶
The end-to-end Teeworlds path is the most comprehensive evidence Myelin has today. It exercises:
- CellScript source → typed-cell metadata → CellTx.
- CKB-VM-style verifier with a real RISC-V binary.
- Molecule encoding throughout.
- Per-chunk projection reports.
- Court bundle construction and verification.
- Static-committee finality.
It does not exercise (yet):
- A live gameplay tape (network + GUI + sequencer dump).
- Permissionless validator entry.
- The on-chain court verifier (which is not yet implemented).
Where to go next¶
- Production gate — the broader gate that includes this path.
- Local CKB devnet smoke — the live chain path.
- Court path — the deeper walk-through of the bundle shape.