• v0.5.1 4ca9a1b246

    v0.5.1 Stable

    joe released this 2026-08-16 14:55:06 +01:00 | 143 commits to main since this release

    No change to the game itself. This release adds a Steam Deck build, confirmed running
    on the device.

    Added

    • A binary for the Steam Deck, and for any distribution too old for the main one. Built
      here, the binary asks for glibc 2.43 and the Deck has 2.41 — so it does not start there
      at all, failing with a message about a version not found in a file that plainly exists.
      The gap was two symbols: acosf and atan2f, from raylib's maths.
    • scripts/build-deck.sh builds inside Valve's Steam Runtime "sniper" SDK, targeting glibc
      2.31, and refuses to finish if the result asks for more than the Deck can give. Steam is
      not needed to run the result: an old glibc is a link-time floor, not a runtime
      dependency, so the binary runs on the Deck whether Steam launches it or not.
    • Both binaries now go out with every release.

    Documentation

    • docs/steam-deck-build.md — how the container is put together,
      what was rejected and why, and how to check a binary yourself. Including the trap:
      run-in-sniper will happily run a binary the Deck cannot, because pressure-vessel
      imports the host's newer libc into the container.
    • Releasing is written down, with the one piece of upkeep it needs: when SteamOS has a
      major update, check the Deck's glibc and update DECK_GLIBC.
    Downloads
  • v0.5.0 88748a071a

    v0.5.0 Stable

    joe released this 2026-08-16 14:11:52 +01:00 | 147 commits to main since this release

    0.5.0 — 2026-08-16

    Charts that play tricks with the format now play correctly. All of this came from one
    song — SHAPESHIFTER — which turned out to be wrong in four separate ways.

    Added

    • Branch switching. Charts change between the normal, expert and master paths mid-song,
      and the change is visible: the notes already on screen are replaced. Every path is now
      kept and the chart plays whichever it chooses, decided one bar ahead as the reference
      does. Charts use this as an effect rather than as difficulty — SHAPESHIFTER asks for 101%
      accuracy to leave the normal path, which cannot happen, and 0% to reach master, which
      always does — so playing only the normal path showed the wrong notes rather than a
      reduced chart. #SECTION and #LEVELHOLD come with it.
    • The path is named on screen, at a fixed place in the lane, with the branched section
      tinted from where it begins.
    • #JPOSSCROLL moves the judge position. Charts pair it with a reversed #SCROLL to
      mirror the lane, so honouring the scroll while ignoring the move sent notes in backwards
      past a hit zone that never moved.
    • Complex #SCROLL values. The real part is the horizontal speed as before; the
      imaginary part moves the note vertically, so 0+1i sends notes straight up.

    Fixed

    • Negative #MEASURE walks the time cursor backwards, which charts use deliberately —
      SHAPESHIFTER rewinds 35 beats, and elsewhere it appears as -1/64 nudges. Treating them
      as nonsense left the cursor moving forwards instead, running one difficulty ten seconds
      past the other four of the same song.
    • The button that opens calibration is no longer counted as the first tap. A gamepad's
      A button is both Confirm and don, so calibration was measuring a keypress made on a
      different screen.
    • Balloon counts are per path, so a balloon on a path not being played no longer consumes a
      count meant for the path that is.
    • A balloon the chart never sized needs five hits rather than being unpoppable.

    Changed

    • main.rs is 662 lines rather than 910, with startup and chart loading in their own
      modules and the audio, video and bindings screens sharing one implementation.
    • New autoplay gate: every chart in a library is played perfectly and anything that says
      it cannot — a note that will not resolve, or one a perfect player still missed — is a
      failure. 1907 courses and 1.3 million notes pass. It was written for a bug it now catches,
      where a branched chart could hang the game at 100% CPU.
    Downloads
  • v0.4.0 095ee7d315

    v0.4.0 Stable

    joe released this 2026-08-16 00:10:37 +01:00 | 164 commits to main since this release

    Added

    • Japanese titles render. Song titles were drawn in raylib's built-in font, which has no
      Japanese, so a large part of the library appeared as rows of ?. The game now picks fonts
      from what is installed: the desktop's own sans for the alphabet, plus whichever installed
      font covers the most of your particular song titles, each character drawn by the first font
      that has it. No font is shipped, and the startup line names what was chosen.
    • Left and right are told apart on the drum. Hitting the left side colours the left half of
      the target circle and the right side the right half; a rim hit colours that side's rim rather
      than the face. Autoplay alternates hands, so the feedback looks the way real play does.
    • Big notes reward both hands. A big note struck with one hand scores as a normal note;
      landing both within 50 ms doubles it, as on the arcade cabinet. Previously either hand alone
      took the full doubled value, which made the two-handed notes pointless.
    • --screen select opens the song list directly, alongside the existing settings screens.

    Fixed

    • Colour markup in titles (<c.#cd7f32>玄人</c>, used by the dan ranks) was drawn literally,
      tags and all. It is now stripped to the plain title. The colour is not reproduced.
    • Text is filtered when scaled. Glyphs are rasterised once at 48px and drawn between 13 and 34,
      which with raylib's default point sampling dropped pixels at small sizes.
    Downloads
  • v0.3.1 b509169361

    v0.3.1 Stable

    joe released this 2026-08-15 20:30:40 +01:00 | 168 commits to main since this release

    No changes to the game itself: release tooling and documentation only.

    Fixed

    • scripts/release.sh left the debug binary behind. The version is baked in at compile
      time and the script only built --release, so ./target/debug/taiko kept reporting the
      previous version after a release. It now refreshes the debug build too.
    • Cargo.lock was not synced to the manifest before the clean-tree check, so a version bump
      left the lock naming the previous version at the tag. The v0.3.0 tag has this; nothing
      is broken by it, since cargo regenerates the lock, but the tag did not describe its own
      build. The lock is now synced first, and a stale one blocks the release with a note.
    • --dry pushed the branch to the remote — precisely the side effect a dry run promises not
      to have. It also refused to run against an already-released version, though rebuilding one
      to inspect what went out is a reasonable thing to want.

    Documentation

    • How to get songs and hit sounds, with the expected directory tree. The soundtrack
      repository can be cloned and played directly with no OpenTaiko install. The drum samples
      are in neither OpenTaiko repository — they ship in the release archive — which is the
      step anyone following the repos alone would get stuck on. Skins are not used at all.
    Downloads
  • v0.3.0 cd38b55eb1

    v0.3.0 Stable

    joe released this 2026-08-15 20:11:31 +01:00 | 173 commits to main since this release

    Added

    • A main menu — Play, Settings, Quit — and a settings menu behind it: calibration,
      audio, video, bindings and an input test.
    • Audio and video settings screens. Latency offset, volumes and the effects bypass;
      fullscreen, V-Sync and the frame limit. Fullscreen and the frame limit apply immediately;
      V-Sync says on the row that it needs a restart rather than appearing to do nothing.
    • A bindings screen listing every action and what is bound to it. Read-only for now —
      editing it needs a mode, not a rewrite, since capture already exists.
    • The input test now returns to settings after 10 seconds with nothing pressed, and says so
      on screen. It consumes every input while open, so a player diagnosing a broken Back
      binding could otherwise have had no way out.

    Fixed

    • Opening a screen immediately acted on the keypress that opened it — choosing Settings
      landed straight in Calibration. raylib refreshes input at the end of a frame, and
      switching screens skipped the draw, so the same press was still down when the new screen
      read it. Every transition now absorbs the input that caused it.

    • Leaving a song shared a button with the drum. The arcade layout puts every face
      button on the drum while Back conventionally sits on one of them, so hitting the drum
      could quit the song. Leaving a song is now its own action, defaulting to Start/Select on
      a pad, and conflicting bindings are reported at startup.

    • Controllers were not detected. The game listened to gamepad index 0, which is rarely
      the controller: an 8BitDo Ultimate 2C presents its keyboard interface at index 0 and the
      actual joystick at index 1, and the indices shift as devices come and go. input.gamepad
      now defaults to "all" and listens to every device, so a controller works with no
      configuration. "none", an index, or part of a device name still pin it.

    • Configs written by 0.2.0 still load: the old input.gamepad_index is accepted, ignored,
      and reported once, rather than being rejected and silently taking the player's calibration
      with it.

    Changed

    • Bindings are now actions, and every control is bindable. Previously drum hits came
      from config while menu keys were hardcoded in Rust, and "back" during a song was a
      keyboard-only check in the main loop — so there was no way to leave a song on a gamepad,
      and nothing a settings menu could have enumerated. Now [input.bindings] maps ten actions
      to any number of inputs: keys, pad buttons (pad:NAME, or pad2:NAME for one device),
      and pad axes (axis:LEFT_Y+), with back bound on both keyboard and pad everywhere.
    • Drum actions carry a side (don_left / don_right), which nothing uses yet but big notes
      needing both hands eventually will.
    • Configs from earlier versions are migrated, not discarded: custom don/ka keys move
      into the new bindings and the change is reported.

    Added

    • --save-config writes the config with every binding spelled out.
    • --test-input, which lists the devices being listened to and names every key and button as
      it arrives. Written because "my controller does nothing" is almost always the wrong device
      being polled, and that is invisible without it.
    Downloads
  • v0.2.0 b765f5e894

    v0.2.0 Stable

    joe released this 2026-08-15 19:29:47 +01:00 | 177 commits to main since this release

    Added

    • Controller support, in the arcade layout: 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 as well as the drumming.

    • A calibration screen (press C in song select). Tap along with a metronome and it
      takes the median of your errors rather than asking you to guess a number in milliseconds.
      It shows the spread and warns when the reading was too inconsistent to trust.

    • A config file at ~/.config/taiko/config.toml, written on first run with comments:
      key and gamepad bindings, latency offset, note colours, volumes, and video settings.
      --list-keys prints every accepted name.

    • --calibrate to go straight to calibration, and --list-keys.

    • Scores are saved. Best score and clear grade per chart and difficulty, kept in
      ~/.local/share/taiko/scores.json and shown in the difficulty picker and on the results
      screen. Records are keyed on the song's uniqueID.json id rather than its path, so
      reorganising a library does not lose your history.

    • The results screen says when a run set a new best, and what the previous bar was.

    Notes

    • Gamepad devices are listed at startup, and input.gamepad_index chooses between them.
      Many devices enumerate as gamepads without being one — a keyboard's HID control device and
      a headset both showed up during development — so the right index is rarely obvious and
      never guessable.
    • Calibration accepts at most one tap per beat, ignores input for the first moments after the
      screen opens, and rate-limits taps. A calibration that completes itself from spurious input
      and silently saves a nonsense offset is far worse than one that refuses to finish.
    • The save file is written to a temporary file and renamed over the target, so an
      interrupted save cannot destroy an existing history.
    • A corrupt save file is reported and skipped rather than refusing to start the game.
    • Nothing is ever written into a song library — verified, not merely intended.
    Downloads
  • v0.1.0 13064613c2

    v0.1.0 Stable

    joe released this 2026-08-15 17:20:24 +01:00 | 182 commits to main since this release

    First release. Browsable, playable, and scored the same way OpenTaiko scores it.

    Plays charts

    • Reads .tja charts and their audio in place, without converting or modifying anything.
      Parses 506 of 506 charts in the reference library — every one, including the awkward
      cases: fractional levels, #BRANCHSTART branches, #DELAY running time backwards, and
      courses holding a Single chart plus a Double pair.
    • Don, ka, big notes, rolls, balloons, mines and ADLIBs. Unsupported features are skipped
      rather than failing a load, and what was skipped is recorded rather than swallowed.
    • Judgement at the reference windows: GOOD/OK/BAD at ±25/75/108 ms on Hard and above,
      ±42/108/125 ms on Easy and Normal.
    • Score matches OpenTaiko exactly — verified against four of its own recorded best plays,
      to the point, across three difficulties and two songs.
    • Soul gauge, combo counter, and a results screen.

    Song select

    • Browse a library by category with box art, per-difficulty levels, and song metadata.
    • Nested category trees and flat folders of song folders both work.
    • Several libraries at once via repeated --songs, so an existing collection and your own
      charts sit side by side without copying either.

    Timing

    • The audio clock is smoothed against a monotonic clock, because raylib's music position
      advances in 10.66 ms steps — coarser than a single frame at 144 Hz. Measured on real
      hardware: 0.076 ms p99 per-frame error against 3.739 ms raw, and 0.010 ms of drift
      over three minutes.
    • Frame rate defaults to the monitor's refresh with V-Sync off.
    • Requests a small audio buffer at startup.

    Paths

    • Content is found from a content root: --base, $TAIKO_BASE, the directory holding the
      executable, then ~/.local/share/taiko. A copied folder is a self-contained install.
    • Scores and config always go to ~/.local/share/taiko and ~/.config/taiko, never into
      the content root, which may be read-only or belong to another game.
    • Every resolved path is printed at startup.

    Known limits

    • No calibration screen, so a constant early/late offset is expected and varies with
      audio hardware. Coming in the timing work.
    • Scores are not saved between runs yet.
    • No song preview audio in the menu.
    • Branching charts play their normal branch only; Dan-i Dojo, Taiko Towers, double play,
      background video and lyrics are out of scope for now.
    • Japanese titles render as ? — the built-in font has no CJK coverage.
    • Input is polled per frame, quantising hit times to roughly 7 ms at 144 Hz.
    • Linux x86_64 only.
    Downloads