No description
  • Zig 46.8%
  • JavaScript 28.2%
  • CSS 18.9%
  • HTML 5.5%
  • Shell 0.6%
Find a file
2026-10-27 06:11:30 +00:00
assets version 0.1.2 2026-10-27 06:11:30 +00:00
data version 0.1.0 2026-10-27 03:23:19 +00:00
linux version 0.1.2 2026-10-27 06:11:30 +00:00
scripts version 0.1.2 2026-10-27 06:11:30 +00:00
src version 0.1.2 2026-10-27 06:11:30 +00:00
web version 0.1.2 2026-10-27 06:11:30 +00:00
windows version 0.1.2 2026-10-27 06:11:30 +00:00
.gitignore version 0.1.2 2026-10-27 06:11:30 +00:00
build.zig version 0.1.2 2026-10-27 06:11:30 +00:00
build.zig.zon version 0.1.2 2026-10-27 06:11:30 +00:00
LICENSE init commit 2026-10-26 23:17:39 -04:00
README.md version 0.1.2 2026-10-27 06:11:30 +00:00

Field Guide · Time Stranger Tools

License

Custom badge

My own build of many Digimon Story: Time Stranger tools (Shortest Route, Stats, Team Builder, Collection, Speedrun), styled to match my Impmon Alter‑X Field Guide, with all data in plain TOML and the tooling written in Zig.

zig build            # validate data/ and build the site into zig-out/site
zig build serve      # same, then serve it at http://127.0.0.1:8080
zig build serve -- 9000   # ...on another port
zig build windows    # zig-out/windows: TimeStrangerTools.exe + portable zip
zig build linux      # zig-out/linux: TimeStrangerTools-linux-{x86_64,aarch64}.tar.gz
zig build check      # validate data/ only
zig build test       # parser unit tests

Builds with Zig 0.15.2 through 0.17.0 (pip install ziglang==0.17.0 works if you don't want a system install; then use python -m ziglang build). First build compiles everything (~20 s); after that, editing a TOML file and rebuilding takes well under a second.

Deploy: upload the contents of zig-out/site/ to any static host (Netlify, GitHub Pages, your fg.mootube.fans box). It's plain HTML/CSS/JS plus the data and a 12 KB WASM engine. zig-out/site/index.html also works opened straight from disk.

Stats: ranking by several columns

Tap any number header (or its chip in the Rank by bar) to rank by it. Tap more to combine them. Each tap cycles higher is better → lower is better → off (SP cost starts at "lower"). With two or more columns a Score column appears:

  • Raw sum: the values added together (low-is-better columns subtract). Good for Digimon stats, which share a scale.
  • Balanced: each column scaled 0–100 against the whole dataset, then averaged, so Hits (1–10) counts as much as Power (5–140).

Skills also have Total Pow = Power × Hits. Tapping a text header (name, type, ...) clears the ranking and sorts alphabetically. Your ranking is remembered per tab.

Sharing with Windows users

zig build windows (works from Linux, macOS or Windows; Zig cross-compiles) produces two things in zig-out/windows/:

File What the user does
TimeStrangerTools.exe (~7 MB) Double-click. A small window opens and the tools appear in their default browser. Everything is inside the one file. Close the window to stop.
TimeStrangerTools-portable.zip Unzip, double-click index.html. No program runs at all. The same folder can also be uploaded to any web host.

Notes:

  • The .exe isn't code-signed, so the first launch shows Windows SmartScreen's "Windows protected your PC". Click More info → Run anyway. Signing it needs a paid certificate; the portable zip never triggers this.
  • The .exe serves on http://127.0.0.1:47615, reachable from that PC only. Launching it again while it's running just reopens the page. If another program owns that port, pass a different one: TimeStrangerTools.exe 47616.
  • Saved progress lives in the browser and is tied to the address, so the .exe and the portable folder each keep their own Collection/Speedrun progress. The backup code moves it between them.
  • zig build app runs the same single-file app on your own machine, for testing.

How it works: the build packs the finished site into one archive (src/pack.zig) and @embedFiles it into a tiny web server (src/app.zig). windows/app.rc adds the icon and the version info shown in Explorer. The icon's master copy is assets/icon.svg (also the site's browser-tab icon); windows/app.ico and linux/icon.png are rendered from the same design. The portable mode works because the build also writes data/dsts.js, which carries the data and the engine as a script; browsers allow that from file://, but not fetch().

Sharing with Linux users

zig build linux produces, in zig-out/linux/ (separate from the Windows files):

File For
TimeStrangerTools-linux-x86_64.tar.gz Regular PCs and the Steam Deck
TimeStrangerTools-linux-aarch64.tar.gz ARM: Raspberry Pi 4/5, ARM laptops

Each unpacks to a TimeStrangerTools/ folder with the app, a README, an icon and install-desktop-entry.sh (adds it to the app menu; it opens in a terminal window so it's clear when it's running). It behaves exactly like the .exe: ./TimeStrangerTools serves on 127.0.0.1:47615 and opens the browser.

The binaries are statically linked (musl), so there's nothing to install and they run on any distro. The archive is a standard .tar.gz, but stored without compression: Zig 0.15's compressor is unfinished, and the contents (images and machine code) barely compress anyway.

This is a personal-use app, not a public web server: it has no HTTPS, compression or connection timeouts. To host the site publicly, serve zig-out/site with Caddy or nginx.

Collection

Tap a Digimon to mark it converted; + / − count extra copies (tapping + on an unconverted one converts it first). The progress bar and per-generation strip show what's left; tap a generation to filter to it. Custom entries are left out of the totals unless you tick "Include custom entries". The same toggle lives in every Digimon's detail sheet, and Stats has "Converted / Not converted" filters. Progress is stored in your browser, so use Copy backup code to move it between devices (format: C1:21,60x2,... = id, optional x extras).

Speedrun checklists

Routes live in data/speedrun/*.toml, one file per route (each shows up in a dropdown once there's more than one). any-hard.toml is your Any% Hard notes: 16 sections, 249 steps. Format:

name = "Any% Hard"

[[section]]
title = "Kuwagamon"
steps = [
  "[menu] Evo Koro > Agu, Puni x2 > Tsuno x2, Kura > Pagu",
  "[fight] Kuwaga: Auto, X-Art on turn 2",
  "- a detail line shown under the step above",
]

Tags: [fight] [menu] [shop] [warn]; no tag = a route/pickup step. Checkmarks are tied to each step's text, so fixing a typo only un-checks that one step. In the tab: Done · Next (or Space) ticks the current step and scrolls to the next, U undoes, J jumps back to where you are. The progress bar stays pinned while you scroll.

Layout

data/
  site.toml              title, icon paths, team size, allowed generations/attributes/elements
  digimon/<slug>.toml    one file per Digimon (476 + your custom ones)
  skills/special.toml    special skills
  skills/attachment.toml attachment skills
  skills/custom.toml     your own skills
src/
  toml.zig     TOML parser (with line numbers for error messages)
  gen.zig      validator + generator -> site/data/dsts.json + graph_data.zig
  wasm.zig     shortest-route BFS + random team chains, compiled to WebAssembly
  compat.zig   everything that differs between Zig 0.15 / 0.16 / 0.17
  httpd.zig    small HTTP server shared by serve.zig and app.zig
  serve.zig    local dev server (zig build serve)
  app.zig      the single-file Windows/Linux app (site built in)
  pack.zig     builds dsts.js, the app's built-in archive, .zip and .tar.gz
  import.zig   upstream JSON -> TOML (re-import)
scripts/check-zig-versions.sh   build every step with several Zig versions
web/           index.html, css/style.css (your Field Guide sheet, unchanged), css/tools.css, js/tools.js
assets/        portraits (images/digimon) and icons (images/icons/{element,attribute})

Zig versions (0.15.2 → 0.17.0)

Zig 0.16 rebuilt the standard library around a new std.Io interface: files, networking, sleeping, child processes and even main's signature changed, and 0.17 changed a few build-system calls. All of that is handled in one place, src/compat.zig; the rest of the code calls it and doesn't care which Zig it's on. Each version-specific branch is chosen at compile time, so the other branch is never even compiled.

To confirm a set of Zig versions after you change something:

scripts/check-zig-versions.sh zig-0.15.2 zig-0.16.0 zig-0.17.0

(pass whatever your Zig executables are called). It runs every build step on each, from a clean cache.

What was verified on all three versions: identical dsts.json; identical routing results (20,000 test routes plus a seeded random team, compared result by result); serve, the Linux app, the Windows .exe (under Wine), import (byte-identical TOML) and the validator's error messages.

Two notes on the Windows .exe:

  • On Zig 0.16+, it uses Winsock (ws2_32.dll) directly instead of std.Io.net. Zig 0.16 moved Windows networking to the AFD kernel driver, which Wine can't run at all. Winsock is the long-standing public API: it works on every Windows version and under Wine, which is also how the .exe gets tested from Linux.
  • Under Wine with a very large Linux environment, any program built with Zig 0.16/0.17 crashes at startup ("start index ... is larger than end index"). That's a Zig standard-library bug: its Windows startup code assumes every environment entry contains =, and Wine can pass one that doesn't. Real Windows always stores entries as NAME=value, so Windows users aren't affected. When testing under Wine, start it with a trimmed environment: env -i PATH=/usr/bin:/bin HOME=$HOME wine TimeStrangerTools.exe.

Editing digivolution

Open the Digimon's file and change evolves_to:

# data/digimon/impmon.toml
evolves_to = ["bakemon", "wizardmon", "clockmon", "sangloupmon", "devimon", "witchmon"]

Only one side of a link is needed. Pre‑evolutions are derived automatically, and a file can also say evolves_from = ["impmon"] instead, so new entries never require touching existing files. Requirements describe how to digivolve into that Digimon:

[requires]
kind = "stats"          # simple | stats | item | jogress  (list lives in site.toml)
agent_rank = 3
SP = 640                # any of HP SP ATK DEF INT SPI SPD = minimum value
SPD = 430
# talent = 30
# valor = 46            # agent skills: valor philanthropy wisdom amicability
# item = "Digi-Egg of Courage"
# jogress = [
#   { with = "ankylomon", personality = "Overprotective" },
#   { with = "angemon", personality = "Enlightened" },
# ]

The Shortest Route tool's Agent Rank filter reads agent_rank.

Adding your own Digimon

Copy data/digimon/impmon-alter-x.toml (it's already in the data as the worked example). custom = true keeps it behind the "Include custom entries" toggle in Shortest Route and tags it CUSTOM everywhere. portrait = "..." points at any image; it's set to /images/face_neutral.png, so it shows your art when deployed on the same domain as the Field Guide, and falls back to initials otherwise.

When something's wrong

The build refuses to write anything and lists every problem with file and line:

error: data/digimon/impmon.toml:4: generation "Rokie" isn't listed in site.toml (did you mean "Rookie"?)
error: data/digimon/impmon.toml:18: unknown key 'SPP' in [requires] (did you mean 'SP'?)
error: data/digimon/impmon.toml:12: evolves_to 'bakemn' doesn't match any data/digimon/*.toml file (did you mean 'bakemon'?)

It also checks unknown skills, duplicate ids, stat rows that aren't 7 numbers, and warns about Digimon with no links at all.

Refreshing from upstream

zig build import -- path/to/digimon.json path/to/skills.json          # only adds new Digimon
zig build import -- path/to/digimon.json path/to/skills.json --force  # overwrite everything

The JSON files live in src/lib/data/digimon-story-ts/ of github.com/diegogliarte/tools.diegogliarte.com. Without --force your edited files are left alone.

Icons

site.toml → icon_base decides where icons load from, using the same layout as the Field Guide (element/fire-icon.png, attribute/no-data-icon.png). The bundled copies come from the upstream project; set icon_base = "/images/icons" to use your site's own set when deployed alongside it.

Credits

Game data and portraits via diegogliarte/tools.diegogliarte.com (originally grindosaur.com); those are third‑party assets and not covered by any license here. Digimon is © Bandai Namco / Toei Animation.