# Development Plan

Working document for Naked Desire implementation. Tracks current state vs. the GDD (README.md) and the phased roadmap. Update this file as state changes — code is the source of truth, this file is the navigation chart.

When the GDD changes, update README.md first, then revisit this plan. When this plan changes, keep phase exit criteria concrete so we know when to move on.

---

## 1. Implementation status snapshot

State of the C++ module as of the latest pass. File references use `Source/NakedDesire/...` paths.

### 1.1 Implemented

- **Modular character w/ per-slot meshes** — `Player/NakedDesireCharacter.cpp:40-67` creates 14 skeletal mesh components, one per clothing slot. Aligns with GDD §17.6.
- **Equip / unequip / drop event** — `Clothing/ClothingManager.cpp:88-172` (slot-based, broadcasts `OnClothingEquip / Unequip / Dropped`).
- **Basic perception** — `Player/NakedDesireCharacter.cpp:167-203` implements `IAISightTargetInterface::CanBeSeenFrom` against `boobs_root` and `pelvis` bones with line-of-sight checks. Foundation for GDD §7.1.
- **AI sight + behavior tree** — `NPC/NPCAIController.cpp` runs a BT with `Player` / `TargetLocation` blackboard. `NPC/NPCSpawner.cpp` does proximity-gated spawning with day / night caps.
- **Mission framework** — `Mission` → `MissionGoal` → `GoalRestriction` composition (`MissionBuilder/`). Two goals (`FlashGoal`, `MinTimeGoal`), three restrictions (`EquipClothing`, `ExposeBodyPart`, `Location`).
- **Location triggers** — `Locations/LocationTrigger`, `Locations/LocationData` via gameplay tags (GDD §10.4 area foundation).
- **Censorship toggle** — compliance feature on `NakedDesireCharacter` (BoobL/R, Front/BackBottom static meshes), driven by user settings.
- **Movement** — `EnhancedInput`, walk / run / crouch (`NakedDesireCharacter.cpp:115-127`), stamina-gated run (`Tick` lines 91-113).
- **Wardrobe interactable** — `Interactables/Wardrobe.h` holds `ClothingItems[]`; `NakedDesireGameMode::BuyItem` charges money and pushes into wardrobe.

### 1.2 Partially implemented (deviates from GDD)

- **Item identity (§6.1)** — `Clothing/ClothingItemData.h:14-27` exists as an "instance" UObject but has no unique ID and no per-instance state (no condition, color, coverage float, isUnderwear, canExpose, isRestrictive, containerSlots). `SaveGame/ClothingItemSaveData.h` only stores a `TSoftObjectPtr<UClothingItem>` — it saves the *template*, not the instance. Directly violates the "every item is a unique physical instance" rule.
- **Save system (§16)** — `SaveGame/GlobalSaveGameData.h` only persists `HaveSeenTutorial`, `Money`, and two clothing lists. No world items, NPCs, time, mission state, recognition / reputation / followers, or wanted flag. Save fires only on explicit Blueprint call; load only happens in `ANakedDesireCharacter::BeginPlay`.
- **Attributes (§7)** — `Stats/StatsManager.h:17-31` has only Embarrassment, Energy, Stamina. Missing Lust, Recognition, Reputation, Followers, Wanted. No GAS. `TickComponent` (`StatsManager.cpp:23-28`) unconditionally drains energy and decays embarrassment — observation-driven gain is not wired in C++.
- **Coverage (§6.3.1)** — `ClothingManager::IsBodyTypeExposed` (`ClothingManager.cpp:14-25`) is binary. No coverage float, no underwear halving, no max-of-covering-garments math.
- **Body parts (§6.3)** — only `FrontTop / FrontBottom / BackBottom` exist (`Player/PrivateBodyPartType.h:14-20`). GDD references boobs, ass, genitals as distinct parts.
- **Mission system** — composable goals work but lacks the typed objective steps from §13.4 (`BeFullyNakedNearNPCs`, `WalkNakedDistance`, `MoveDistanceFromClothing`, `BeObservedByNPCType`, `TakePhotoAtLocation`, `DeliverItemTo`). Missions are hand-authored in `MissionsConfig`.
- **Day / night** — affects spawn caps (`NPCSpawner.cpp:40-41`) but not embarrassment rate, NPC type weights, or police spawning.

### 1.3 Missing

- **Session system (§4)** — no `USessionManager`, no session start / end events, no `SessionLossResolver`. Game-over on embarrassment is a single `EndGameEmbarrassed` Blueprint event in `NakedDesireGameMode`; none of §4.4's item-drop logic is implemented.
- **Three progression paths (§5)** — no path enum on `UClothingItem`, no Path XP, no path levels, no path-gated content.
- **Phone (§9)** — entire system absent: camera, gallery, livestream, bank, Feetex, maps, health tracker.
- **Forum (§13)** — no `UCommissionTemplate`, no procedural generation, no weekly missions distinct from daily, no profile / followers, no posting photos.
- **Photo & livestream** — absent.
- **NPC types (§10.2)** — only one generic `ANPC` class. No Walker / Stalker / Paparazzi / Snitch / Harasser / Helper, no Police, no Wanted-poster mechanic.
- **Calendar, rent, sleep (§2.4, §15.2)** — `DaysPassed` increments in `NakedDesireGameMode::OnHourChanged(4)`, but no week, no rent, no eviction, no sleep action.
- **Item-world AActor (§6.1)** — clothing drops broadcast a delegate but no `AItemActor` exists.
- **Bag inventory (§6.4)** — absent.
- **Rip & tear, theft (§6.3.3-4)** — absent.
- **Expose action (§6.3.5)** — absent.
- **Restrictive clothing (§6.3.6)** — absent.
- **Adult shop, gym, beauty salon, cafe, convenience store** — none.
- **Food / consumables (§6.6)** — absent.
- **Recognition, wanted state, news (§7.5–7.6, §11.1)** — absent.
- **Underwear selling (§15.1)** — absent.
- **Endless mode flag (§3.3)** — absent.

### 1.4 Conflicts to resolve

- **`EClothingSlotType` (`Clothing/ClothingSlotType.h`)** treats `Nipples / Anal / Vagina` as equipment slots; GDD treats those as body parts. Slot list also lacks `Outerwear`, `Accessory`, `Restraint`. Slot vocabulary needs a cleanup pass.
- **`Money` lives on `ANakedDesireCharacter`** (`NakedDesireCharacter.h:139`) as `int Money = 300000`, and also as a field on `UGlobalSaveGameData`. Duplicate state. Default 300k vs. ~20k weekly rent (§15.3) — test value.
- **`MissionsManager::RefreshDailyMissions`** (`MissionBuilder/MissionsManager.cpp:53-68`) has a remove-while-iterating bug; `OnComplete.RemoveAll(this)` is called on the *mission*, not on the manager handle.
- **`NakedDesireGameMode::RefreshDailyMissions`** indexes `MissionsConfig->DailyMissions[DaysPassed]` — crashes past the authored array and contradicts §13.4 procedural generation.
- **`StatsManager::TickComponent` unconditionally decays embarrassment** (`StatsManager.cpp:27`). §7.1 says decay should happen only when not observed; today no observation-driven gain offsets it.
- **Save constant `SLOT_NAME "Slot2"`** (`Global/Constants.h:5`) — magic single-slot save, no multi-save support.
- **`UClothingItemData` is `EditInlineNew`** and stored inline in `UClothingList::ClothingItems`. Instances live inside the list asset, not as standalone objects with stable identity. Direct conflict with §6.1.

---

## 2. Architectural premise

The item-identity rule (§6.1) and the save contract (§16.3) are load-bearing. Clothing condition, world drops, session loss, theft, the bag, and the forum's "post a photo of *this* specific worn item" all depend on stable per-instance state.

Until Phase 1 lands, content authored on top of the current system needs migration. Do not build the higher phases first.

---

## 3. Phased roadmap

Phase estimates are rough and assume one engineer. Adjust as we go.

### Phase 1 — Item identity + save foundation (1–2 weeks)

- Split `UClothingItem` (immutable definition, `UPrimaryDataAsset`) from a new `UItemInstance` UObject with `FGuid InstanceId` and mutable state (`Condition`, `Color`, container parent, world transform). Make `UClothingItemInstance : UItemInstance`.
- Add to the definition: `Coverage` float, `IsUnderwear`, `CanExpose` list, `IsRestrictive`, `ContainerSlots`, `ProgressionPath` enum.
- Enumerate slots cleanly — split slot vs. body-part vocabulary (resolves §1.4 conflict).
- Replace `FClothingItemSaveData` with a generic `FItemSaveRecord { Guid, DefinitionPath, InstanceState, Location, ParentRef }`.
- Introduce `USaveSubsystem` (GameInstance subsystem) that orchestrates serialization across player, world items, time, missions, attributes, recognition.
- Convert single-slot `SLOT_NAME` to a slot-name argument.

**Exit criteria:** an item dropped in the world, with its condition modified, survives save / load with the same GUID and condition value.

### Phase 2 — World item actors + drop / pickup (1 week)

- `AItemActor` base wrapping a `UItemInstance*`. `AClothingPickup : AItemActor`.
- Hook `ClothingManager::DropClothing` to spawn `AClothingPickup` at the player location with the actual instance reference (no template copy).
- Pickup interaction via existing `InteractionManager`.

**Exit criteria:** unequip → world actor appears → re-pick-up restores the same instance to the slot.

### Phase 3 — Session system + loss resolver (1 week)

- `USessionManager` (GameMode component). Apartment `LocationTrigger` flag drives session start / end.
- `USessionLossResolver` — single class, per §4 implementation note. Takes the loss cause and runs §4.4 deterministically over the new world-item registry.
- Wire `StatsManager::IncreaseEmbarrassment` max-hit and energy-zero into the resolver.

**Exit criteria:** lose to embarrassment → equipped clothing spawns as world actors at the loss location, persists through save.

### Phase 4 — Attributes refactor (1 week)

- Decide GAS vs. extended `StatsManager` (recommend GAS per §17.2; embarrassment formula has many modifiers that GAS effects model cleanly).
- Add Lust, Recognition, Reputation, Followers, Wanted.
- Move observation-driven embarrassment gain out of BP into the C++ pipeline (use the existing `CanBeSeenFrom` result + per-NPC type weights).
- Add Lust + masturbate action + blackout vision effect.
- Add Recognition with face-cover bypass + Wanted bool.

**Exit criteria:** observed-while-exposed gains embarrassment from C++; unobserved decays; both rates are inspectable in a debug overlay.

### Phase 5 — Time + calendar + rent + sleep (3–4 days)

- `UTimeOfDaySubsystem` replacing the BP-implementable time on `NakedDesireGameMode`. 90-day calendar, week boundary, rent transaction.
- Sleep action on apartment bed: time-skip + energy restore + autosave.
- Endless-mode flag on the save.

**Exit criteria:** play through 7 in-game days, get charged rent at week boundary, eviction triggers on insufficient funds.

### Phase 6 — NPC types + recognition pipeline (1–2 weeks)

- `ENPCType` enum, type-specific BT branches or per-type controller subclasses.
- Walker / Stalker / Paparazzi / Snitch / Harasser / Helper / Police.
- Recognition flow: Paparazzi photo → article → news site → "report" reduces recognition.

**Exit criteria:** each NPC type observably distinct behavior; recognition rises after paparazzi exposure and can be reduced via news report.

### Phase 7 — Commission template system (1–2 weeks)

- Replace `MissionsConfig`'s hand-authored daily list with `UCommissionTemplate` + procedural generation per §13.4.
- Add typed objective steps as new `UMissionGoal` subclasses (`BeFullyNakedNearNPCs`, `WalkNakedDistance`, `MoveDistanceFromClothing`, `BeObservedByNPCType`, `TakePhotoAtLocation`).
- Weekly vs. daily generation pass.

**Exit criteria:** daily commissions regenerate from templates each in-game day; weekly arc is distinct; failed commissions deduct reputation.

### Phase 8 — Phone + forum UI (2–3 weeks)

- Phone as a holdable / pocketable `AItemActor`.
- Apps: Camera + Gallery, Livestream (`StreamSession` tick object), Bank, Feetex, Maps, Health Tracker, Forum.
- Photo system: pick render-to-texture (§17.6) — recommended for in-fiction photo posts.

**Exit criteria:** end-to-end photo loop — equip phone, capture photo, view in gallery, post to forum, follower count updates.

### Phase 9 — Path progression + content authoring (2 weeks)

- Path XP per path, level gating on clothing / missions / attribute upgrades.
- Author the vertical-slice content set from §18.1.

**Exit criteria:** all three paths have at least 5 unlockable items and 3 path-specific commission templates.

### Phase 10 — Remaining systems & polish

- Bag inventory (§6.4).
- Food / cooking (§6.6).
- Gym / beauty salon / adult shop (§10.4).
- Rip and tear (§6.3.4).
- Theft timer (§6.3.3).
- Expose action (§6.3.5).
- Restrictive-clothing flow (§6.3.6, §10.4.1).
- Underwear selling (§15.1).
- Wanted-poster takedown (§10.3).

---

## 4. Working notes

Use this section for in-flight decisions, blockers, and open questions that emerge during a phase. Move resolved items into the README's §20 "Resolved Design Decisions" or into git history.

- _empty_
