Unit Cards
A random wargame unit card generator for hex-based strategy games. Generates stats, names, and icons for infantry, armour, artillery, mechs, and APCs. Built entirely client-side. Visit /playground/unit-cards.
Architecture
The entire tool is client-side JavaScript in a single file (static/js/unit-cards.js). The server provides:
- The template (
templates/unit-cards.html) — page layout, toolbar, card grid, and styles. - The script (
static/js/unit-cards.js) — card generation, stat bars, grouping logic, and all interactive controls. - The route (
src/routers/unit_cards.py) —GET /playground/unit-cardsserves the template.
Cards
Stats
Each card displays six stats shown as labelled progress bars:
| Stat | Range | Meaning |
|---|---|---|
| ATK | 3–24 | Attack strength |
| RNG | 3–32 | Weapon range |
| DEF | 3–24 | Defence rating |
| MOV | 3–12 | Movement speed |
| LOS | 3–14 | Line of sight |
| Steps | 1–6 | Action points (shown as dots) |
The card also shows a cost value (top-right), calculated as (ATK + DEF + MOV + LOS) × costPerStat where costPerStat varies by unit type (1 for infantry, 2 for armour/artillery, 3 for mechs).
Generation
Cards are generated with random stats within the type's range. The Random button picks a weighted type (infantry most common, heavy mechs rarest). Category buttons generate only that type.
Armoured Property
Cards generated from armour (MBT, Light Tank), APC, and mech types have an armoured: true property. Infantry and artillery units are armoured: false. This property is stored directly on the card object and can be used for rule logic (e.g. armour-piercing weapons, targeting priority).
Unit Types
| Category | Types | Icon | Carry | costPerStat | Armoured |
|---|---|---|---|---|---|
| Infantry | Infantry Squad, Heavy Weapons Squad, Scout Squad | ● ✚ ◇ | 0 | 1 | No |
| Armour | Main Battle Tank, Light Tank | ⏤ ◊ | 0 | 2 | Yes |
| APC | APC | □ | 1 | 2 | Yes |
| Artillery | Field Gun, Mortar | ★ ⊙ | 0 | 2 | No |
| Mech | Light Mech, Heavy Mech, Artillery Mech | ⛊ ⛉ ⚙ | 0 | 3 | Yes |
Controls
Toolbar
| Button | What it does |
|---|---|
| Random | Generates a random unit (weighted toward infantry) |
| Infantry | Generates a random infantry squad |
| Armour | Generates a random tank (MBT or Light Tank; excludes APC) |
| APC | Generates an APC |
| Artillery | Generates a random artillery piece |
| Mech | Generates a random mech |
| Clear All | Removes all cards from the grid |
| Side: Blue / Red | Toggles the side colour for all cards |
| Group (appears when 2+ cards selected) | Groups selected cards into a combined unit |
| Delete (appears when any card selected) | Removes selected cards from the grid |
| Clear (appears when any card selected) | Clears the selection |
Selection
Click any card to select/deselect it. Selected cards show a coloured outline matching their side. The selection counter appears in the toolbar.
Groups
Select two or more cards and click Group to combine them into a single group card. The group inherits the highest ATK, RNG, DEF, and LOS from its members, sum of steps and cost, and the lowest MOV (with infantry riding in APCs ignored for MOV purposes).
Each group container shows an inline action row:
| Button | What it does |
|---|---|
| Rename | Prompts for a new group name |
| + Add | Moves all currently selected non-group cards into this group |
| Ungroup | Breaks the group apart; all member cards return to the grid |
Each member card inside a group has a remove button (bottom, full-width) — clicking it extracts that unit back to the main grid.
If removing the last member from a group, the group card is automatically removed.
Files
| File | Role |
|---|---|
templates/unit-cards.html |
Page template (toolbar, grid, styles) |
static/js/unit-cards.js |
Game logic (generation, stats, grouping, controls) |
src/routers/unit_cards.py |
GET /playground/unit-cards |
templates/playground.html |
Playground index with Unit Cards card |
src/main.py |
Router registration |