# AGENTS.md — Vermine2047 FoundryVTT system ## Project FoundryVTT v14 game system for the French post-apocalyptic TTRPG "Vermine 2047". Bilingual FR/EN. - **Entrypoint**: `module/vermine2047.mjs` (declared in `system.json` esmodules) - **CSS**: `css/vermine2047.min.css` (compiled from LESS, **not** SCSS) - **System ID**: `vermine2047` ## Architecture | Layer | Location | Notes | |-------|----------|-------| | Entry/init | `module/vermine2047.mjs` | `Hooks.once('init',...)` — register DataModels before Document classes | | DataModels | `module/models/*.mjs` | FoundryV2 `TypeDataModel` — 4 Actor types, 12 Item types | | Documents | `module/documents/*.mjs` | `VermineActor`, `VermineItem` (thin wrappers) | | Sheets (AppV2) | `module/applications/sheets/*.mjs` | ApplicationV2 sheets per type | | System | `module/system/*.mjs` | config, roll, fight, dialogs, hooks, settings, dice3d, group-link | | Templates (HBS) | `templates/actor/appv2/*.hbs` | ApplicationV2 templates | | Legacy templates | `templates/actor/*.hbs`, `templates/actor/{character,group,npc,creature}/*.hbs` | Coexisting legacy templates | ### Actor types: character, npc, group, creature ### Item types: item, weapon, defense, vehicle, ability, specialty, background, trauma, evolution, rumor, target, rite Key objects at runtime: - `game.vermine2047` → `{ VermineUtils, VermineCombat, GroupLink }` - `CONFIG.VERMINE` → game configuration (totems, traits, skills, etc.) - `CONFIG.ui.combat` → custom `VermineCombatTracker` Dice system: d10-based, success-counting (`Xd10cs>=N`). Totems give domain bonuses. Initiative formula: `(@abilities.reflexes.value + @skills.alertness.value)d10cs>=@combatStatus.difficulty` ## Commands ```sh npm run build:less # LESS → vermine2047.min.css npm run build:less:dev # LESS → vermine2047.dev.css (unminified) npm run build:all-css # both npm run watch # gulp watch + browser-sync proxy to localhost:30000 npm run lint:less # lesshint npm run pushLDBtoYAML # extract Foundry packs → src/packs/*.yml npm run pullYAMLtoLDB # compile src/packs/*.yml → packs/ LevelDB make build / watch / lint # Makefile wrappers for above ``` - Node version required: `v16.15.1` (per `.nvmrc`) ## Gotchas - **DataModels before Document classes**: In `init` hook, register `CONFIG.Actor.dataModels.*` and `CONFIG.Item.dataModels.*` **before** setting `CONFIG.Actor.documentClass` / `CONFIG.Item.documentClass`. - **`no-console: 'error'`**: ESLint blocks `console.log/warn/info`. Use `console.error` sparingly or disable the rule inline. - **ESLint is very verbose**: ~350 rules. Common failures: missing semicolons, trailing commas, single quotes, 2-space indent, `max-len: 120`. Run `npx eslint module/` before committing. - **Two template systems**: Both legacy (`templates/actor/*.hbs`) and ApplicationV2 (`templates/actor/appv2/*.hbs`) are preloaded. Don't confuse them. - **Packs in two places**: `src/packs/*.yml` (YAML source, tracked) ↔ `packs/*` (LevelDB binary, gitignored). Edit YAML source, then run `pullYAMLtoLDB` to compile. - **CSS auto-loaded**: `system.json` declares styles; **do not** inject `` manually (causes MIME type errors). - **`game-mode` setting**: Default in code is `'e'` (likely a typo for `'1'`). Values: `1`=Survie, `2`=Cauchemar, `3`=Apocalypse. - **editMode flag disabled**: No auto-set on actor creation (causes ActiveEffect errors). Enable manually via sheet checkbox. - **GroupLink auto-syncs**: `GroupLink.registerHooks()` runs on init. Actor updates propagate to groups and vice versa. - **Custom dice**: Dice So Nice integration uses user color (regular/human/adapted color sets) with custom d10 face images. - **No tests**: `npm test` is a stub (exits 1). No test framework installed. - **No CI**: `.github/` is gitignored; no workflows configured. - **HotReload**: `system.json` flags hotReload for css, scss, hbs, json extensions.