Small, simple tools and projects, live at spibane.com
A static site with no build step, framework or server. Each tool is a folder with its own index.html, and every page loads the shared stylesheet and script from shared/.
browser ──► index.html (hub) ──► tool/index.html
│ │
└──── shared/ ◄───────┘ base.css, site.js (theme, footer, helpers, backups)
│
▼
localStorage all saved progress and settings
- No accounts or tracking. Everything a tool saves stays in the browser's
localStorage. - Shared helpers.
shared/site.jshas the small pieces tools reuse (shuffle,uid,slug,plural,splitLines,toggleIn,lockButton,fullScreen,PALETTE, and for colorscolorField,pickColor,colorVars,hexColor,inkOn), andshared/base.cssstyles form fields, dialogs, color choices, result rows, locks and played lists. Check there before writing one into a page. - Backups.
backups()inshared/site.jsgives each tool Save, Load and Clear buttons for its own keys, plus Import when the tool passesmerge. The hub's backup holds every tool's data in one file, and a tool can load its part out of that file. - Settings. Put a tool's settings fieldsets right under the intro, wrapped in
<details class="settings"><summary><h2>Settings</h2></summary>…</details>.shared/site.jsstarts it closed and remembers how it was left on each page. Keep main inputs (entries, players, lists) and the toggles beside the roll button outside it. - Game data lives in plain JS files under each game's
data/folder.
| Category | Tool | What it does |
|---|---|---|
| Everyday | Tasks and Events | Checklists that reset, and events that end |
| General | Randomizer | Picks at random from your own lists |
| General | Drop Odds | The chance a drop has dropped by now |
| General | Bingo Cards | Bingo cards from your own list |
| General | Dice Roller | Dice like 2d6+3, and coin flips |
| General | Turn Tracker | Turn order with skips, holds and notes |
| General | Score Pad | Scores with a turn clock or timer |
| General | Brackets | Elimination brackets and round robins |
| General | Character Names | Names that fit a game's races and clans (beta) |
| Games | Aniimo | Collection boxes and checklists |
| Games | Dead by Daylight | Loadout randomizer |
| Games | Final Fantasy XIV | Relic checklists and roulette job picker |
| Games | Marvel Rivals | Hero randomizer |
| Games | The Outlast Trials | Trial and loadout randomizers |
.
├── index.html # Hub page: tool list and site-wide backup
├── 404.html
├── shared/ # base.css, site.js, logo and link preview image
├── tasks/ # Each general tool: index.html + style.css
├── randomizer/
├── odds/
├── bingo/
├── dice/
├── turns/
├── score/
├── brackets/
├── names/ # engine.js (the generator) + data/ (one file per game, plus harvested name lists)
└── games/
├── aniimo/ # collection/, checklist/, data/ (forms, spawns, categories)
├── dbd/ # loadout/, data/ (loadout.js + update.py)
├── ffxiv/ # relics/, roulette/, data/relics/
├── marvel-rivals/
└── outlast-trials/ # randomizer/, loadout/, data/ (trials, rigs and amps)
Any static file server works:
python3 -m http.server # then open http://localhost:8000- Dead by Daylight:
python3 games/dbd/data/update.pyrebuildsloadout.jsfrom the dbd.tricky.lol API. Check the diff before committing, since the API can list things from test builds early. - Aniimo: edited by hand from the official wiki and in-game checks. The wiki leaves some things out on purpose, so don't drop entries just because it's missing them.
- Character Names:
python3 names/data/update.py [skyrim|wow]rebuildsskyrim.names.jsandwow.names.js, the harvested lists of names, from UESP and Warcraft Wiki. Check the diff before committing: both wikis gain and lose pages, and the script guesses at what is a name, so a bad run shows as a race suddenly losing half its list. It only writes those two files; the race definitions beside them are hand-written and never touched. FFXIV has no race-tagged source and is hand-written throughout, to Square Enix's own naming conventions; no convention was ever published for the Viera or the Hrothgar, so those four clans are shaped on the few canon names there are. Forty-six races and clans in all.names/data/*.jsholds one file per game. Names that are a sound (Elezen, Nord) are a list the generator learns from; names that are built to a shape (Roegadyn compounds, Nord surnames, Argonian deed names, the apostrophe in Miqo'te) are patterns and word lists, which a list of finished names can never reproduce. A race is plain data and the engine has no game knowledge, so a new race or game is a data change only. Name lists want roughly 150–300 entries each to generate well; much under thirty and the generator mostly hands back names already in the list.
- Make a folder (games go in
games/) with anindex.htmlthat loadsshared/base.cssandshared/site.jsin<head>. - Call
backups({...})with the tool's storage keys. - Add an
<li>for it under the right category in the hub'sindex.html, and the same entry toTOOLSinshared/site.jsso it appears in the breadcrumb bar's tool switcher. A third item on theTOOLSentry, and a<span class="tag">, marks a tool as beta in the switcher, on its tile and beside its heading. - Add a line to CHANGELOG.md.
| Branch | Deploys to |
|---|---|
dev |
Cloudflare Pages preview, for testing |
main |
GitHub Pages at spibane.com (CNAME) |
Push to dev, test on the preview, then open a PR from dev into main. Never push to main directly. The live site caches files for about 10 minutes.