# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with this repository.

## Overview

FoundryVTT v13+ game system for the **Lethal Fantasy RPG**. Entry point: `lethal-fantasy.mjs`.

## Commands

```bash
# Compile LESS styles (styles/ -> css/)
npx gulp css          # one-shot
npx gulp              # compile + watch

# Lint
npx eslint .

# Compendium pack management (LevelDB <-> YAML source)
npm run pushLDBtoYML   # export packs-system/ LevelDB -> source YAML
npm run pullYMLtoLDB   # import source YAML -> packs-system/ LevelDB
```

No test suite exists.

## Architecture

Four layers in `module/`, all wired in `lethal-fantasy.mjs` via the `init` hook:

| Layer | Path | Purpose |
|---|---|---|
| Config | `module/config/` | Game constants. `SYSTEM` is `globalThis.SYSTEM` — always use `SYSTEM.*` for enumerations. |
| Models | `module/models/` | `TypeDataModel` subclasses — data schemas per document type. |
| Documents | `module/documents/` | Actor/Item/Roll/ChatMessage subclasses — game logic, roll processing, hooks. |
| Applications | `module/applications/` | `ApplicationV2` sheets + custom combat tracker. |

**Actor types**: `character`, `monster`
**Item types**: `skill`, `gift`, `vulnerability`, `weapon`, `armor`, `shield`, `spell`, `miracle`, `equipment`

Each layer has an `_module.mjs` barrel file that re-exports all classes from that layer.

Templates (`.hbs`) live in `templates/`. Styles are authored in LESS under `styles/` and compiled to `css/`.

### Key Patterns

- **Sheets**: Extend `HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2)` — imported from `foundry.applications.api`. **Not** the legacy `ActorSheet`. Child sheets (e.g. `character-sheet.mjs`) extend `base-actor-sheet.mjs` and override `static PARTS` and `DEFAULT_OPTIONS.actions`. Template paths are prefixed `systems/fvtt-lethal-fantasy/templates/`. Actor sheets have a play/edit toggle via `_sheetMode` and `SHEET_MODES`.
- **Models**: `static defineSchema()` using `foundry.data.fields.*`. Field definitions derived from SYSTEM config objects.
- **Rolls**: `LethalFantasyRoll` extends `Roll` with rich metadata via `this.options`. `D30Roll` is a separate class for D30 result tables (initialized in the `ready` hook).
- **Socket**: Events use `game.socket.on(\`system.${SYSTEM.id}\`, ...)`. Multi-player attack-defense uses a global `pendingDefenses` Map.
- **i18n**: All user-visible strings are keys in `lang/en.json` as `LETHALFANTASY.Category.Key`. Always use `game.i18n.localize(key)`.

### Compendium Packs

Five LevelDB packs in `packs-system/`: skills, equipment, gifts, vulnerabilities, spells-miracles. Use the `tools/` scripts to export/import editable YAML.

## Code Style

- No semicolons, double quotes, 2-space indent
- JSDoc `/** */` required on all functions/classes
- Max line length 180 (strings/templates exempt)
- Arrow functions: omit parens for single param
- ESLint + Prettier config in `eslint.config.mjs`
