Index
# mmo.rpg — overview for AI code generation `mmo.rpg` (PHP package `mmo.rpg`, namespace `MMO\rpg`) turns real-life objectives — habits, skills, recovery goals — into an RPG-style progression system: pluggable XP/level curves, tiers, streaks and inactivity decay tracked on `Objective` entities, plus simpler daily/mood event logging. It depends on `mmo.core` (entities, routing, repositories) and `mmo.client` (the `` configurator UI is a `.jhs` custom element). Read the other documentation resources this server exposes (`resources/list` under the `mmo.rpg` library) in this order: 1. **xp-system** (`docs/XP system.md`) — the design framework this package implements: the 5 original curve families (linear/polynomial/exponential/logarithmic/logistic), the per-action XP formula, starting-level calibration from a 0–1 skill score, tiers, and a worked example. Two notes added to keep it honest: the shipped code has 13 curve shapes, not 5 (§3), and the "suggested objectives" table (§7) predates the specialized curve types — `src/xp/presets.php` is the authoritative mapping now. 2. **xp-curves** (`docs/XP curves.md`) — "Human Experience Curves": the narrative/psychological background (habit S-curve, skill step-stair, addiction inverted-hyperbolic, sustainability cyclical-wave) that motivated the curve shapes in §1. No code maps to this 1:1 — it's the "why", not a spec. 3. **curves-framework** (`docs/Curves framework.md`) — a much broader mathematical reference catalog (30+ curve families with formulas: Weibull, Gompertz, J-curve, inverted-U, threshold/relapse models, multidimensional feedback loops...). Most of it is **not implemented** — it's a reference catalog to draw from if you're adding a new `iCurve` to `CurveFactory`, not a description of current behavior. 4. **training** (`docs/Training.md`) — heads up: this is a personal workout routine (in French), not documentation of the package. It has nothing to do with the XP system; skip it unless asked about it specifically. ## The things that matter most 1. **A curve is an `iCurve`** (`src/xp/Curves.php`): one method, `xpForLevel(int $n, array $params): float` — the XP cost to go from level `n-1` to level `n`. Get one via `CurveFactory::make($type)`, list all type keys via `CurveFactory::types()`. **`CurveFactory::catalog()` is the single source of truth** for the full list, formulas, param keys and defaults — it drives the configurator UI and is more complete and more current than the design docs. The 13 shipped types: `linear`, `polynomial`, `exponential`, `logarithmic`, `logistic`, `habit`, `learning`, `addiction`, `sustain`, `gompertz`, `saturation`, `weibull`, `regression`. 2. **All the real math routes through `XPCalculator`** (`src/xp/XPCalculator.php`), constructed with `new XPCalculator(['curveType' => ..., 'curveParams' => ..., 'tiers' => ...])`. Key methods: `xpForLevel($n)`, `cumulativeXp($n)`, `levelTable($lMax)` (full level→tier→XP table), `tierForLevel($level, $lMax)`, `startingLevel($skillScore, $lMax)` (`round(S × L_max)`), `levelFromTotalXp($totalXp, $lMax)` (resolve a raw XP total into current level/progress), `actionXp($params)` (per-action XP with streak + diminishing-returns handling), and `applyInactivityDecay($totalXp, $inactiveDays, $graceDays, $halfLifeDays, $floorXp)` (Ebbinghaus-style half-life decay for regression). 3. **`Objective` is the persisted unit** (`src/entities/Objective.php`) — a curve config (`curveType`, `curveParams`, `lMax`, `tiers`) plus running state (`totalXp`, `streakDays`, `lastLogDate`, `sameDayCount`). **Don't drive `XPCalculator` by hand from application code that logs progress** — call `$objective->logAction(float $quantity, ?float $difficultyOverride = null): array`. It folds in any pending inactivity decay first (a lapse costs XP even if you're about to log again right now), updates streak/diminishing-returns bookkeeping, and returns `['xpGained', 'xpDecayed', 'inactiveDays']`. Read current status via the entity's computed properties — `getProgress()` (level/tier/XP into next level), `getPendingDecay()`, `getInactiveDays()` — never trust a stale `totalXp` for display; it isn't corrected for decay until `logAction()` actually persists. 4. **Ready-made objective configs live in `src/xp/presets.php`**, keyed by slug (`quit_drinking`, `exercise`, `guitar`, `reading`, `language`, `meditation`, `running`, `cooking`, `sleep`, `screen_time`, `saving_money`, `cold_showers`, `coding`, `public_speaking`, `leadership_development`, `reduce_bad_habit`). Each entry is `{name, unit, lMax, curveType, curveParams, action: {xpBase, difficultyMultiplier}, regression?, why}` — exactly the shape `Objective`'s ArrayProperty fields expect, so a preset can be spread directly into a new-objective payload. 5. **HTTP surface** (`src/controllers/XPController.php`) adds four routes beyond generic entity CRUD: `GET rpg/xp/curves.json` (the catalog), `GET rpg/xp/presets.json`, `POST rpg/xp/compute.json` (stateless level-table preview for any curve config — no `Objective` needed, used by the live configurator before saving), and `POST rpg/xp/objectives/{id}/log.json` (calls `logAction()` on a saved objective and commits). Saved-objective CRUD itself is **generic** `MMO\core\controllers\RepositoryController` over `data/main/objectives.json` — there is no bespoke create/update/delete route for `Objective`. 6. **``** (`src/customElements/elements/mmo-xp-lab.jhs`) is the reference client for all of the above: a curve configurator with a live preview chart, a preset picker, and a progress-logging panel. If you're building any UI against this package, read it first — it exercises every route above with the exact request/response shapes, including the two-phase bootstrap gotcha (catalog/presets must land in the view before `form.curveType` is set, or the `