Arcane Wasteland Character Creator
Website for creating characters for the Arcane Wasteland TTRPG, with a searchable rulebook and export to PDF or Word.
- Frontend: React (Vite), 8-step wizard, searchable rules page
- Backend: FastAPI, SQLite,
python-docxandreportlabfor the export - Everything runs in one container
Run it on the server
docker compose up -d --build
Then open http://<server>:8080. Characters are stored in ./db/aw.db. For HTTPS and a domain, put the container behind a reverse proxy (nginx, Caddy, Traefik).
Edit the rules
All rule data lives in backend/data/rules.json: attributes, derived-stat formulas, skills, professions, classes, talents, mutations, implants, conditions, equipment and the texts of the rules page. Edit the file and reload the page; no rebuild is needed because the folder is mounted into the container.
Entries with "placeholder": true are placeholders and show a badge in the app. To remove the badge, fill in the entry and delete that line.
Note: Derived-stat formulas are in rules.json (derived[].formula = list of attributes whose mods are summed). Special rules that cannot be expressed there (profession attribute bonus, skill maximum, higher-of-two-attributes for skills, carry capacity) are mirrored in frontend/src/calc.js and backend/app/derive.py. When changing them, change both files.
Rules presets
Presets are named sets of creation numbers (attribute points, skill pool, talents, proficiency picks, unlock cost, caps ...). They are defined in rules.json under presets: each has an id, name, desc and a creation object that overrides keys of the global creation block (an empty object = the standard values). default_preset is the one new characters start with. The list of values that can be edited per character is tunables.
In the creator, the Concept page only has a "Rules preset" selector. Presets are created, edited, duplicated and deleted on the Presets tab. Built-in presets (from rules.json) are read-only; user presets are stored in the database (/api/presets) and visible to everyone, but only the browser that created one holds the key to change or delete it. The chosen numbers are copied into the character, so shared links and exports use the same numbers even if the preset is changed or deleted later. "Start over" keeps the chosen preset.
Skills, proficiency and expertise
creation.advanced_unlock_cost: pool points needed to unlock an advanced skill (free if a profession or proficiency covers it).creation.free_proficiencies: free proficiency picks every character gets. Talents can add more with"proficiency_picks": N(see "Versatile Training").- Proficiency is +
proficiency_bonus; two picks on one skill (a profession proficiency counts as one) give Expertise, +expertise_bonus.
Equipment
equipment lists every item with id, name, cat (category), stat (damage / armor / type), kg and note. The starting-kit rules are in creation.kit (allowed weapon categories, armor tiers, number of resources). Weights are approximate; for ranges in the source document the upper value is used.
Development
# Backend
cd backend && pip install -r requirements.txt
uvicorn app.main:app --reload --port 8000
# Frontend (second terminal, proxies /api to port 8000)
cd frontend && npm install && npm run dev
Saving and sharing
There are no user accounts. When saved, a character gets an ID and a secret write key that stays in the browser ("My characters" page). The link /#creator/<ID> lets others view the character; only the holder of the key can change it. To move to another browser use the JSON backup (Summary page: "JSON backup" and "Import JSON").
If the site is reachable from the internet, protect it with Basic Auth at the reverse proxy.
While creating, the full character sheet stays visible next to the wizard. Edits are shown as a difference (old → new, added / removed items) until you press Apply (or Apply & next); Discard drops them.
Each wizard page has a Reset this page button that clears only that page's data, plus Start over for the whole character.
API
| Method | Path | Purpose |
|---|---|---|
| GET | /api/rules |
Rule data |
| POST | /api/characters |
Create a character, returns id and token |
| GET | /api/characters/{id} |
Read a character |
| PUT / DELETE | /api/characters/{id} |
Change / delete, header X-Edit-Token |
| POST | /api/presets |
Create a preset, returns id and token |
| PUT / DELETE | /api/presets/{id} |
Change / delete, header X-Edit-Token |
| POST | /api/export/pdf or /docx |
Character JSON in the body, file in the response |