A tool for taking One Page Rule's armies from OPR's Army Forge, and importing them into Table Top Simulator
Used in conjunction with the OPR AF to TTS Importer TTS mod
https://opr-af-to-tts.netlify.app/ <- Use the app right here!
5 min walkthrough of the app
This is a web tool which allows you to take armies from OPR's Army Forge, and assign model loadouts and equipment definitions.
From there, your loadout can be exported and then imported into Tabletop Simulator, providing you with an easy interface to assign stats and rules to your models.
- Node 20 or 22 (repo is known-good on Node 22.14).
-
npm install. -
Copy
.env.exampleto.env. -
(Optional) Add Turso libSQL credentials to
.envif you want saved lists to hit the real database:TURSO_DB_URL=libsql://<your-db>-<org>.<region>.turso.io TURSO_AUTH_STRING=<token>Without these, the app still works end-to-end using an in-memory fallback — see below.
npm run netlify:dev— full local stack onhttp://localhost:8888. Use this for any feature that exercises the/.netlify/functions/*endpoints (Army Forge import,save-list).npm run dev— frontend only via Vite. Calls to/.netlify/functions/*will fail, so this is only useful for pure UI work.npm run build— typechecks withtscand produces a production bundle indist/.
If TURSO_DB_URL / TURSO_AUTH_STRING aren't set, save-list stores generated lists in a module-scoped in-memory map instead of the DB. The share URL you get back (http://localhost:8888/.netlify/functions/save-list?listId=…) is hittable in the browser and returns the same JSON shape the real DB path would return, so you can eyeball the output.
Caveats:
- Entries are lost when
netlify devrestarts. - The URL points at
localhost, so it is not usable from the TTS Lua mod — round-tripping through Tabletop Simulator needs a real Turso database.
The app is translated via react-i18next. Each supported language has its own YAML file under src/locales/:
en.yaml— English. This is the source of truth. New keys are added here first; every other language falls back to English for anything missing.fr.yaml— French.
- Fork the repo.
- Edit the relevant
.yamlfile insrc/locales/. Keep the key structure identical toen.yaml— only change the string values on the right-hand side. - Preserve any
<0>,<1>, … placeholders and{{variable}}interpolations exactly as they appear in English. They are how inline links and dynamic values are rendered. - If you can, run
npm run dev, switch to your language via the picker in the top-right, and eyeball the app. At minimum,npm run buildmust pass. - Open a PR against
maindescribing what you changed. Please cite a source for anything non-obvious (e.g. wargaming terminology).
Please open an issue first before starting work on a new language. This is so we can:
- Agree on the language code (e.g.
de,pt-br,es) and flag icon. - Check that nobody else is already mid-way through the same translation.
- Wire up the language picker on our side — adding a language involves a couple of small code changes beyond just the YAML file, so it's not purely content work.
Once an issue is agreed, the PR itself should:
- Add
src/locales/<code>.yaml, mirroring the full key structure ofen.yaml. - Register the new language in
src/i18n/index.ts(SUPPORTED_LANGUAGES+resources) and insrc/components/LanguagePicker.tsx(LANGUAGES, with its flag icon). - Add the flag icon to
src/components/icons.tsxif one doesn't already exist.
Thanks to Army Forge and its developers for support in making this tool possible, and to users over on the OPR Discord for their valuable feedback.
