- Zig 46.8%
- JavaScript 28.2%
- CSS 18.9%
- HTML 5.5%
- Shell 0.6%
|
|
||
|---|---|---|
| assets | ||
| data | ||
| linux | ||
| scripts | ||
| src | ||
| web | ||
| windows | ||
| .gitignore | ||
| build.zig | ||
| build.zig.zon | ||
| LICENSE | ||
| README.md | ||
Field Guide · Time Stranger Tools
License
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 appruns 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 ofstd.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 asNAME=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.