|
|
||
|---|---|---|
| crates | ||
| docs | ||
| scripts | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CHANGELOG.md | ||
| implementation-plan.md | ||
| LICENSE | ||
| plan.md | ||
| README.md | ||
Simple Taiko
A simple, stable, low-latency Taiko rhythm game that plays songs from an existing OpenTaiko library, in place and unmodified.
Status: v0.8.0 — playable. Browse a library, pick a chart, play it, see your score. Scoring matches OpenTaiko exactly, scores persist, and it plays on keyboard or pad with latency calibration. Song select is a wheel of coloured bars that auditions whatever the cursor rests on. Not yet done: rebinding from inside the game, and the modes listed in docs/v1-scope.md.
See CHANGELOG.md for what each release contains, and implementation-plan.md for where it is going.
Docs
| plan.md | The idea and the feature list |
| implementation-plan.md | Phases, gates, decisions |
| docs/format-notes.md | TJA / box.def / library layout, measured from a real 506-chart corpus; skin and hit-sound investigation |
| docs/shapeshifter-jist.md | One chart's gimmicks explained by the person who wrote them — the source for how branching really behaves |
| docs/timing-notes.md | Toolchain, audio clock measurements, latency budget |
| docs/reference-constants.md | Judge windows, score formula, OFFSET semantics, read from OpenTaiko source |
| docs/v1-scope.md | What v1 does and, more importantly, does not do |
| CHANGELOG.md | What changed in each release |
The format itself is documented outside this repository, and better than we could:
IepIweidieng's tja.md
gives each command's scope and effect time and records where the simulators disagree. It is
the first thing to read before changing the parser.
Layout
crates/tja/ TJA parsing — pure, no raylib
crates/library/ song tree scanning — pure, no raylib
crates/timing/ the master clock — pure, no raylib
crates/play/ judgement and scoring — pure, no raylib
crates/taiko/ the game — the only crate that may touch graphics/audio/input
The split is deliberate: it makes the compiler enforce that the parser stays headless and testable against the whole chart corpus without opening a window.
Getting songs
Simple Taiko needs two things: charts, and a pair of drum samples. Neither is bundled — they belong to other people — but both are a download away, and you do not need to install OpenTaiko unless you want its hit sounds.
Songs
The OpenTaiko community soundtrack is a plain git repository of chart folders, which is exactly the layout the scanner expects:
git clone --depth 1 https://github.com/OpenTaiko/OpenTaiko-Soundtrack Songs
That is around 500 songs. --depth 1 matters: the full history is roughly 3.4 GB on top of
a 1.2 GB working tree, and none of it is any use for playing.
Hit sounds
The drum samples are not in either OpenTaiko repository — they ship inside the release
archive, under publish/Global/HitSounds/. Either take them from a copy of that archive, or
supply your own: any directory holding dong.wav and ka.wav works, and the game runs
(silently) without them.
The layout
Put both next to the binary and it runs with no arguments:
simple-taiko/
├── taiko
├── Songs/
│ ├── 01 OpenTaiko Chapter I/
│ │ ├── box.def category name, colours, description
│ │ ├── 001 - CITYSCAPE/
│ │ │ ├── CITYSCAPE.tja the chart
│ │ │ ├── CITYSCAPE.ogg the audio, named by the chart's WAVE: header
│ │ │ ├── cityscape.png jacket, named by its PREIMAGE: header
│ │ │ └── uniqueID.json stable song id — what your scores are keyed on
│ │ └── 002 - .../
│ └── 02 OpenTaiko Chapter II/
└── Global/
└── HitSounds/
└── Taiko/
├── dong.wav
└── ka.wav
Categories may nest as deeply as you like, and a flat folder of song folders works too.
If OpenTaiko is already installed you need not lay any of this out: its
publish/directory is this layout, withSongs/andGlobal/HitSounds/both in place. Point at it with--base /path/to/OpenTaiko/publish, as below, or drop thetaikobinary intopublish/and run it with no arguments — a binary's own directory is one of the places it looks for content. Either way you get the hit sounds too, which--songson its own does not. Dropping the binary in is the only thing that puts a file in OpenTaiko's folder; the game itself still writes nothing there.
Or point at what you already have
If OpenTaiko is already installed, use it in place — nothing is copied and nothing is written to it:
taiko --base ~/Applications/OpenTaiko/publish
Or mix sources, which is the point of --songs being repeatable:
taiko --songs ~/OpenTaiko-Soundtrack --songs ~/my-charts \
--hitsounds ~/Applications/OpenTaiko/publish/Global/HitSounds/Taiko
Skins are not used. OpenTaiko's skin repository is another 1.4 GB and Simple Taiko draws its own playfield, so there is no reason to clone it — see docs/format-notes.md for why that format was turned down.
Play
cargo run --bin taiko -- --base ~/Applications/OpenTaiko/publish
cargo run --bin taiko -- --songs "<songs folder>" # one or more libraries
cargo run --bin taiko -- "<song folder>" oni # jump straight into one chart
The main menu offers Play, Settings and Quit. Settings holds calibration, audio, video, bindings and an input test.
In song select: Up/Down move, Enter open, Backspace back, C calibrate, Esc back. Playing: F/J hit the drum centre (don), D/K the rim (ka), Esc returns to the list.
The drum works the menus too, as it does on the cabinet: the rim moves — D up, K down — and either don key, F or J, chooses. That matters most to anyone playing on a real drum, where those four inputs are the whole interface. It is why D no longer moves the cursor right: one key cannot both move and adjust on a screen that reads them together.
On a controller the arcade layout applies: every face button is the drum — d-pad for the left hand, A/B/X/Y for the right — and the shoulders are the rim, L1/L2 left and R1/R2 right. The pad drives the menus too.
A library can be nested in categories or a flat folder of song folders; both work.
Settings
~/.config/taiko/config.toml is written on first run, with comments. It holds key and gamepad
bindings, the latency offset, colours, volumes and video settings. --list-keys prints every name
it accepts.
Calibrate before playing seriously: press C in song select and tap along with the metronome. Every audio setup is late by some constant amount, and that is what the offset removes.
Every control is an action with a list of inputs bound to it, under [input.bindings].
Actions are don_left, don_right, ka_left, ka_right, menu_up, menu_down,
menu_page_up, menu_page_down, confirm and back. Inputs are written F,
pad:RIGHT_FACE_DOWN, pad2:MIDDLE for one specific device, or axis:LEFT_Y+. Anything you
omit keeps its default. --save-config rewrites the file with every binding spelled out, and
--list-keys prints everything accepted.
input.gamepad defaults to "all", which listens to every device the system offers. That is
deliberate: a controller shows up as several devices — an 8BitDo Ultimate 2C presents its
keyboard interface first and the actual joystick second — and the indices shift as things are
plugged in and out. Set it to "none", an index, or part of a device name if you need to pin it.
If input is not doing what you expect, run --test-input: it lists every device being listened to
and names each key and button as it arrives.
Fonts
Japanese titles need a font that has Japanese in it, and no such font is shipped: they are several megabytes with their own licences, and every desktop already has one. On startup the game asks fontconfig what is installed and picks two — the sans the rest of your desktop uses for the alphabet, and whichever installed font covers the most of your song titles for everything else. Each is checked after loading, so a font that turns out not to have the characters it advertises is dropped rather than drawn as boxes. The startup line names what was chosen:
font NotoSans-Regular.ttf + HanaMinA.ttf (461 glyphs)
To choose yourself, set path under [font] in the config. It must be a single font file —
.ttf or .otf, not a .ttc collection, which cannot be read. Anything it lacks still falls
back to the automatic choice.
Steam Deck
scripts/build-deck.sh produces a binary that runs there. Built on a current distribution
it will not: Arch's glibc gives the binary a requirement of 2.43 and the Deck has 2.41, so
it refuses to start with a message about a version not found. The script builds inside
Valve's Steam Runtime "sniper" SDK instead, which targets glibc 2.31, and refuses to finish
if the result ever asks for more than the Deck provides.
Confirmed running on a Deck as of 0.5.0. It needs Docker, and downloads about 1.4 GB of SDK the first time. docs/steam-deck-build.md covers how the container is put together and how to check a binary yourself.
scripts/build-deck.sh # build, and report the glibc it needs
scripts/build-deck.sh --package # tarball in dist/, ready to copy across
Steam is not required to run the result. Old glibc is a link-time floor rather than a runtime dependency, and X11 and GL are loaded by name rather than linked, so the binary needs nothing on the Deck but libc, libm and libgcc_s. Copy it across with a song library and run it.
Where it looks for things
Content — songs, hit sounds — comes from a content root, the first of these that exists
and contains Songs/ or Global/HitSounds/:
--base <dir>$TAIKO_BASE- the directory holding the executable — so a copied folder is a self-contained install
~/.local/share/taiko
--songs <dir> (repeatable) and --hitsounds <dir> override individual pieces, and pointing
--base at an existing OpenTaiko installation works without copying anything.
Scores and config are always written to ~/.local/share/taiko and ~/.config/taiko, never
into the content root — which may be read-only, or somebody else's game folder. The game prints
every resolved path at startup.
During development, set TAIKO_BASE once rather than passing --base each time; cargo clean
deletes target/, so assets next to the debug binary would not survive.
Development flags: --auto plays it back automatically (a correct parse → clock → judge chain
scores every note GOOD), --screenshot <file> captures a frame, --seconds <n> exits after a
while, --pick opens the difficulty picker at startup. --help lists everything.
The song-reachability test needs a real library:
TAIKO_BASE=~/Applications/OpenTaiko/publish cargo test --bin taiko
Releasing
scripts/release.sh <version> builds, packages, tags and publishes. Two binaries go out:
one built here, and one built against glibc 2.31 in the Steam Runtime SDK for the Steam
Deck and older systems. Add --dry to stop before tagging, or --no-deck to skip the
second (it needs Docker).
When SteamOS has had a major update, check the Deck's glibc with pacman -Q glibc on the
device and update DECK_GLIBC in scripts/build-deck.sh — that number is what the Deck
build is checked against. See docs/steam-deck-build.md.
Build
cargo build
cargo test
raylib-sys builds raylib from vendored source, so the first build is slow and needs cmake and a C
toolchain.
Tools
# Measure the raw audio clock's resolution and drift.
cargo run --bin clockprobe -- <file.ogg> [seconds] [poll_hz] [buffer_frames]
# Check the smoothed master clock against real hardware (Step 2's gate).
cargo run --bin clocktest -- <file.ogg> [seconds] [poll_hz]
# Parse every chart in a library and report failures (Step 1's gate).
cargo run -p tja --example corpus -- <songs_dir>
# Scan a library into categories and songs.
cargo run -p library --example scan -- <songs_dir> [--tree]
Licence
MIT. No OpenTaiko assets are redistributed here — hit sounds and any skin art are read from the user's own installation at runtime.