init
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
# 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_
|
||||
Reference in New Issue
Block a user