Terminal-first Rust reimplementation scaffold for nine-or-null parity work.
null-or-die is a rewrite of nine-or-null by @telperion.
Why:
- Performance advantages from implementing the sync-analysis pipeline in a lower-level language (Rust).
- Acting as a submodule/integration target for
deadsync, the Rust rewrite of ITGmania/StepMania.
null-or-die analyze <path> [--plot]: scans simfiles, parses chart metadata throughrssp, decodes OGG audio, and computes native bias metrics per chart. With--plot, also writes nine-or-null-style PNGs (bias-freqdomain-*,bias-beatdigest-*,bias-postkernel-*) into the report directory.null-or-die parity <path> --baseline <dir>: validates MD5-sharded fixtures and checks native bias outputs against baseline chart rows (including split#MUSICrows).null-or-die harness <path> --baseline <dir>: runs Pythonnine-or-nullreference analysis and writes canonicaljson.zstfixtures.null-or-die bench <simfile>: runs repeated analyze-style passes on one simfile and reports phase timings (read, parse, decode, bias, total).null-or-die plot <input.json> <out.png>: draws bias markers from JSON (bias_ms,bias_result, orbias).
analyze and parity now share the native bias math path.
For harness, --source-root should point to the Python package root containing nine_or_null/ (for example nine-or-null-0.8.0/nine-or-null). If omitted, null-or-die auto-detects that sibling path from the current working directory.
MD5-sharded baseline lookup matches the existing rssp corpus style:
<baseline>/<md5[0..2]>/<md5>.json or <baseline>/<md5[0..2]>/<md5>.json.zst
MD5 is computed from raw simfile bytes.
Baseline chart rows include a music field (chart #MUSIC if present, else simfile #MUSIC) so split-audio parity can target the correct OGG per chart.
cargo run -- analyze /path/to/Songs --output /tmp/null-or-die-scan.json
cargo run -- analyze /path/to/song.sm --plot --report-path /tmp/null-or-die-plots
# legacy-style invocation is also supported:
cargo run -- --analyze /path/to/song.sm --plot --report-path /tmp/null-or-die-plots
cargo run -- parity /path/to/Songs --baseline /path/to/baseline --fail-on-missing --fail-on-mismatch
cargo run -- harness /path/to/Songs --baseline /path/to/baseline --source-root /path/to/nine-or-null-0.8.0/nine-or-null
cargo run --release -- bench "/path/to/PEMDMonium.sm" --warmup 3 --iterations 20
cargo run -- plot /tmp/null-or-die-scan.json /tmp/bias.png --span-ms 20null-or-die now exposes a direct Rust API for in-engine sync tooling:
null_or_die::api::inspect_simfile(path)-> chart metadata for selection/UInull_or_die::api::analyze_chart(path, chart_index, &cfg)-> full bias estimate + full graph matricesnull_or_die::api::analyze_chart_stream(path, chart_index, &cfg, stream_cfg, on_event)-> incremental events while processing (Init,Beat,Convolution,Done) plus final result
For streamed rendering layout, use stream_cfg.orientation (Vertical or Horizontal) as display intent in your actor/UI layer.