- hooks.mjs: replace static dice-so-nice import with dynamic import
using game.modules.get('dice-so-nice').id (path removed in v14)
- hooks.mjs: fix permission condition (|| -> &&), jQuery -> vanilla JS
- less/base.less: override --color-text-* and --button-text-color
for both .themed.theme-dark (AppV2) and body.theme-dark (legacy apps)
- target #settings-config buttons + labels + hints for dark grays
6.4 KiB
Vermine 2047 — Copilot Instructions
Build & Development
Requires Node.js v16.15.1 (see .nvmrc).
npm run watch # Watch SCSS + templates, proxy Foundry at localhost:30000 (requires Foundry running)
npm run buildStyle # Compile SCSS once to css/vermine2047.css
npm run pullYAMLtoLDB # Build LevelDB compendium packs from src/packs/ YAML → packs/
npm run pushLDBtoYAML # Extract LevelDB packs to editable YAML in src/packs/
npx eslint module/ # Lint JavaScript (ESLint configured in .eslintrc.js)
There are no automated tests. Use npm run watch during development — browser-sync proxies Foundry over HTTPS and live-reloads SCSS, .hbs, and .html templates on change. system.json declares hotReload for .css, .scss, .hbs, and .json extensions, so Foundry auto-refreshes those assets client-side when the dev server is running.
Architecture
This is a FoundryVTT game system (system.json → system ID vermine2047), compatible with Foundry v11–v14. It implements the French post-apocalyptic TTRPG Vermine 2047.
Entry point: module/vermine2047.mjs — loaded as an ES module. On the init hook it registers custom document classes, sheet classes, combat classes, Handlebars helpers, settings, hooks, and preloads templates.
Actor types (4): character, npc, group, creature
Item types (12): item, weapon, defense, vehicle, ability, specialty, background, trauma, evolution, rumor, target, rite
Key source files (module/system/):
| File | Role |
|---|---|
config.mjs |
All game constants (CONFIG.VERMINE) — abilities, skills, totems, threat/role/pattern levels, traits, damage types |
roll.mjs |
VermineUtils class — d10 dice pool system with success counting, totem mechanics, rerolls, Dice So Nice integration |
dice3d.mjs |
Dice So Nice 3D dice configuration (appearance, colors, themes for totem/standard dice) |
fight.mjs |
Confrontation system (VermineFight), plus VermineCombat, VermineCombatant, VermineCombatTracker |
group-link.mjs |
GroupLink — bidirectional sync of members/encounters between group actors and character/NPC actors via Foundry hooks |
hooks.mjs |
All Foundry hook registrations (chat messages, hotbar drop, combat, preCreate, Dice So Nice) |
settings.mjs |
System settings (game mode: survie/cauchemar/apocalypse) |
handlebars-manager.mjs |
Template preloading paths + all Handlebars helpers (level config lookups, math, conditionals) |
effects.mjs |
Active effect management |
dialogs/rollDialog.mjs |
Advanced roll dialog (ability/skill selection, difficulty, totems, specialties, assist/pool bonuses) |
applications.mjs |
TotemPicker and TraitSelector applications (still AppV1) |
applications/sheets/ |
ApplicationV2 sheet classes: base-actor-sheet.mjs, base-item-sheet.mjs + 4 actor + 12 item sheets |
Data model: Defined via Foundry DataModels (module/models/) extending foundry.abstract.TypeDataModel. Type-specific derived data is computed in each DataModel's prepareDerivedData(). The legacy template.json has been removed in favor of system.json → documentTypes.
Sheet inheritance: ApplicationV2 (HandlebarsApplicationMixin(ActorSheetV2)/ItemSheetV2) in module/applications/sheets/. VermineBaseActorSheet → VermineCharacterSheetV2, etc. Sheets expose CONFIG.VERMINE as context.config in template data. Each sheet is split into parts via static PARTS; tab navigation uses Core's templates/generic/tab-navigation.hbs.
Data preparation: VermineActor.prepareDerivedData() delegates to the type-specific DataModel. Each DataModel implements its own prepareDerivedData() with type-specific computation logic.
Global access: On init, game.vermine2047 is populated with { VermineActor, VermineItem, VermineUtils, VermineCombat, GroupLink } for easy access in macros and scripts.
Compendium packs: Stored in packs/ as LevelDB databases. Edit source data in src/packs/ as YAML, then npm run pullYAMLtoLDB to build. The CI release workflow runs this automatically.
Key Conventions
- All
.mjsfiles: ES module syntax only. Foundry globals (game,Hooks,CONFIG,Actor,Item,ChatMessage,Roll,Handlebars,renderTemplate,foundry,ui,Canvas,Dialog) are available but declared as readonly globals in.eslintrc.js. - ESLint conventions: 2-space indent, single quotes, semicolons required,
===equality (except== null). Constants named withVERMINE_prefix are exempt from camelCase. Max 1 class per file, 500 lines per file, 100 lines per function, 5 levels of nesting max. Noconsole.logcalls — useui.notifications. - Code language: Source code and comments are in French. UI strings in
lang/fr.jsonandlang/en.json. Usegame.i18n.localize()for all user-visible text. - Template naming: Actor sheets use ApplicationV2 part templates in
templates/actor/appv2/{type}-{part}.hbs(e.g.character-main.hbs,npc-characteristics.hbs). Item sheets attemplates/item/item-{type}-sheet.html. Chat card templates attemplates/item/chatCards/{type}.hbs. Legacy templates intemplates/actor/subdirectories are preserved for dialog/chat use. - Dice system: d10 pools with success counting (result ≥ difficulty). Totem dice (human/adapted) count double on success. Formula syntax:
{N}d10cs>={threshold}[label]. Totem dice:(1d10cs>={threshold}[totem_label]*2). - CSS: SCSS sources in
scss/compile tocss/vermine2047.css. Entry point:vermine2047.scsswhich imports partials:_app.scss,_flex.scss,dialog.scss,item-sheet.scss,itemCards.scss,roll.scss,special-applications.scss,special-inputs.scss,style.scss,base_work.scss. Add new SCSS partials as_component.scss, import invermine2047.scss. - Data tools: The
pushLDBtoYAML/pullYAMLtoLDBscripts use@foundryvtt/foundryvtt-clito convert between LevelDB packs and editable YAML. When adding pack content, edit YAML insrc/packs/then rebuild. - Actor updates: Use
actor.update({...})with dot-notation paths (e.g.,'system.adaptation.totems.human.value'). TheGroupLinkhooks system automatically syncs group memberships on actor changes. - New template partials: Must be listed in
preloadHandlebarsTemplates()inhandlebars-manager.mjsfor pre-compilation. - Full architecture documentation: See
docs/technical/ARCHITECTURE.md.