# Agent Handoff Notes This file is for future coding agents continuing work on the Forge Master Strategy Optimizer. Do not duplicate game rules, formulas, stat caps, or gameplay assumptions here. Use [GAME.md](GAME.md) as the source of truth for those details. Use [README.md](README.md) for the player-facing overview. ## Project shape This is a dependency-free static web app: - `index.html`: page markup and templates. - `styles.css`: responsive styling. - `app.js`: all state, rendering, calculations, import/export, save slots, and comparison logic. - `README.md`: concise player guide. - `GAME.md`: game mechanics and formulas. There is no build system, package manager, or test runner currently configured. ## Development workflow 1. Read `GAME.md` before changing calculations. 2. Keep `README.md` player-facing. Avoid implementation or formula detail there unless linking to `GAME.md`. 3. Keep `AGENTS.md` implementation-focused. Avoid repeating game mechanics from `GAME.md`. 4. Prefer small, self-contained commits. 5. Validate with headless Firefox after UI changes: ```bash firefox --headless --screenshot /tmp/forge-master-check.png file://$PWD/index.html ``` 6. Also grep for accidental debug markers: ```bash grep -R "TO[D]O\|FIX[M]E\|console[.]log" -n . --exclude-dir=.git ``` ## State and persistence The app stores state in browser `localStorage`: - named save slots use `forgeMasterOptimizer.v1`, - the autosaved current draft uses `forgeMasterOptimizer.draft.v1`. Import/export uses a wrapped JSON payload with `app`, `version`, `exportedAt`, and `build`. Raw build objects are also accepted. Keep import normalization backward-compatible when changing state shape. Important state paths in `app.js`: - `createDefaultState()` defines new blank state. - `normalizeState()` handles imported/draft/saved state migration. - `createDefaultPiece()` defines normal equipment entries. - `createDefaultNewItem()` defines the New item comparison entry. ## Rendering structure Rendering is manual DOM construction, not a framework. Important functions: - `render()` orchestrates full rendering. - `renderControls()` updates strategy and combat-style controls. - `renderGear()` renders current equipment cards. - `renderNewItemComparison()` renders the replacement comparison card. - `renderEffectTotals()` renders the total effect tags and marginal max-roll values. - `renderSacrifices()` renders sacrifice candidates. Event binding is centralized in `bindEvents()`. Current equipment edits go through `handleGearInput()`. New item edits go through `handleNewItemInput()`. ## Calculation entry points Use the function names below rather than adding duplicate calculation logic: - `calculateTotals()` sums base stats and effects. - `calculateDamageDetails()` returns single hit, crit hit, and DPS. - `calculateDps()` returns DPS only. - `calculateRegenDetails()` returns health-regen healing, lifesteal healing, and total Regen. - `calculateSurvivability()` is used for defensive marginal effect comparison. - `replacePieceInTotals()` creates totals after replacing one piece. - `renderReplacementComparison()` displays New item DPS/Regen deltas. If a calculation changes, update `GAME.md` first or in the same commit. ## Replacement comparison behavior The New item panel compares one hypothetical roll against a selected current target. Target behavior is implemented by: - `getReplacementOptions()` - `getFixedReplacementTarget()` - `getReplacementTargetPiece()` - `createNewItemCandidate()` When the target is `Pet`, `getReplacementTargetPiece()` chooses the lowest-scoring current pet. ## Validation expectations Before reporting completion: - load the page with headless Firefox, - confirm no obvious render errors in stderr, - run the debug-marker grep from the workflow section, - check `git diff --stat`, - commit changes unless explicitly asked not to. ## Style constraints - Keep the app dependency-free unless the user explicitly approves adding tooling. - Keep controls usable in narrow cards and small screens. - Prefer readable helper functions over inline formula duplication. - Preserve backward compatibility for saved/imported JSON whenever practical.