Updated readme and plan

This commit is contained in:
2026-05-23 11:04:42 +03:00
parent 4c9a2df9f0
commit a6eb1d4083
2 changed files with 334 additions and 134 deletions
+159 -82
View File
@@ -18,7 +18,7 @@ State of the C++ module as of the latest pass. File references use `Source/Naked
- **Body-part enum (GDD §6.3)** — `Clothing/BodyPart.h` defines `EBodyPart { None, Boobs, Ass, Genitals }`. Used on `UClothingItem::CanExpose`.
- **Save scaffolding (GDD §16)** — `SaveGame/SaveSubsystem.h/.cpp` (`UGameInstanceSubsystem`), `SaveGame/ItemSaveRecord.h` (generic `{ InstanceId, Definition, Condition, ParentId }`). `Global/Constants.h` now uses `DefaultSaveSlotName` instead of a single `SLOT_NAME` macro.
- **Observation-driven embarrassment (GDD §7.1)** — `NPC/NPCAIController.cpp:56-69` listens to `OnTargetPerceptionUpdated` and forwards bSensed transitions to `Stats/StatsManager::SetObserved`. `Stats/StatsManager::TickComponent` (`StatsManager.cpp:23-38`) now gates gain vs. decay on `ObserverCount` instead of unconditional decay. Foundation for Phase 4.
- **Modular character w/ per-slot meshes** — `Player/NakedDesireCharacter.cpp:40-67` creates 14 skeletal mesh components, one per `EClothingSlotType`. Aligns with GDD §17.6.
- **Modular character w/ per-slot meshes** — `Player/NakedDesireCharacter.cpp:40-67` creates 14 skeletal mesh components, one per current `EClothingSlotType` value. Aligns with GDD §17.6 in spirit; the specific slot list needs reshaping per §1.4 (locked 18-slot list now lives in GDD §6.5).
- **Equip / unequip / drop event** — `Clothing/ClothingManager.cpp:88-163` (slot-based, broadcasts `OnClothingEquip / Unequip / Dropped` with `UClothingItemInstance*`).
- **Censorship toggle** — compliance feature on `NakedDesireCharacter` (`BoobL/R`, `Front/BackBottom` static meshes), driven by `UNakedDesireUserSettings`.
- **AI sight + behavior tree** — `NPC/NPCAIController.cpp` runs a BT with `Player` / `TargetLocation` / `SpawnLocation` blackboard keys. `NPC/NPCSpawner.cpp` proximity-gated spawn with day / night caps.
@@ -32,18 +32,23 @@ State of the C++ module as of the latest pass. File references use `Source/Naked
- **Save subsystem (GDD §16)** — scaffolded but **not actually wired through gameplay**. `USaveSubsystem::SaveGame` (`SaveSubsystem.cpp:10-13`) delegates to `UGlobalSaveGameData::SaveGame`, which creates a *fresh empty* `UGlobalSaveGameData` (`GlobalSaveGameData.cpp:45-53`) and writes it — i.e., it does not capture the live player / wardrobe / world state at all. `USaveSubsystem::LoadGame` calls the static loader but discards the result without applying it (`SaveSubsystem.cpp:5-8`). `ClothingManager::HydrateClothing` (`ClothingManager.cpp:66-73`) is an empty stub with the previous logic commented out. Exit criterion of Phase 1 (round-trip an item with modified condition) is not met yet.
- **Item identity → world (§6.1)** — `UItemInstance` GUIDs exist, but no item has been promoted to a world `AActor`. `ClothingManager::DropClothing` (`ClothingManager.cpp:156-163`) still only broadcasts `OnClothingDropped` — no spawn, no parent reassignment in any registry.
- **Attributes (§7)** — `StatsManager` covers Embarrassment, Energy, Stamina with observation-driven gain now correctly tied to NPC perception. Missing: Lust, Pulse (new, §7.5), Recognition, Reputation, Followers, Wanted. Coverage weighting in the gain formula is stubbed at `0.0f` with a TODO marker (`StatsManager.cpp:30-32`).
- **Attributes (§7)** — `StatsManager` covers Embarrassment, Energy, Stamina with observation-driven gain now correctly tied to NPC perception. Missing: Lust, Pulse (§7.5), Recognition, Reputation, Followers, Wanted. Coverage weighting in the gain formula is stubbed at `0.0f` with a TODO marker (`StatsManager.cpp:30-32`). Food-buff hookpoints (per-rate multipliers for stamina regen, embarrassment-gain resistance, lust-gain resistance — see GDD §6.7) are not in place; future Phase 10 work depends on the attribute simulation accepting external multipliers cleanly.
- **Coverage (§6.3.2)** — `UClothingItem::Coverage` and `IsUnderwear` exist on the definition, but `ClothingManager::IsBodyTypeExposed` (`ClothingManager.cpp:14-25`) is still binary. No `GetEffectiveCoverage(EBodyPart)` function, no underwear-halving, no sum-of-garments math.
- **Body-part enums — duplicated** — both `Player/PrivateBodyPartType.h` (`EPrivateBodyPartType { FrontBottom, BackBottom, FrontTop }`) and `Clothing/BodyPart.h` (`EBodyPart { Boobs, Ass, Genitals }`) exist. `UClothingItem::CoveredBodyParts` uses the **old** enum; `UClothingItem::CanExpose` uses the **new** one. Half-migrated.
- **Mission system** — composable goals work but lacks the typed objective steps from §13.4 (`BeFullyNaked`, `BeFullyNakedNearNPCs`, `WalkNakedDistance`, `MoveDistanceFromClothing`, `BeObservedByNPCType`, `TakePhotoAtLocation`, `DeliverItemTo`). Missions still hand-authored in `MissionsConfig::DailyMissions` keyed by day index — no procedural generation.
- **Mission system** — composable goals work but lacks the typed objective steps from §13.4 (`BeFullyNaked`, `BeFullyNakedNearNPCs`, `WalkNakedDistance`, `MoveDistanceFromClothing`, `BeObservedByNPCType`, `TakePhotoAtLocation`, `DeliverItemTo`). Missions still hand-authored in `MissionsConfig::DailyMissions` keyed by day index — no procedural generation, no Accept lifecycle (§13.1 / §13.2), no path-filtering on the generator (§13.4).
- **Day / night** — `NPCSpawner.cpp:38-41` reads `GetCurrentTime().Hours` and gates spawn cap, but does not affect embarrassment gain, NPC type weighting, or police spawning (see §1.3).
### 1.3 Missing
- **Session system (GDD §4)** — no `USessionManager`, no session start / end events, no `USessionLossResolver`. Game-over on embarrassment is a single `EndGameEmbarrassed` BP event in `NakedDesireGameMode`; none of §4.4's behavior (energy-zero cutscene to home, bag-placed-in-world loss, sleep-deterministic clothing loss) is implemented.
- **Three progression paths runtime (§5)** — enum exists; no path XP, no per-path level, no path-gated unlocks at runtime, no level-up flow.
- **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.
- **Session system (GDD §4)** — no `USessionManager`, no session start / end events, no `USessionLossResolver`. Game-over on embarrassment is a single `EndGameEmbarrassed` BP event in `NakedDesireGameMode`; none of §4.4's behavior (energy-zero cutscene to home, bag-placed-in-world loss, sleep-deterministic clothing loss, embarrassment-max → apartment with no extras) is implemented.
- **Three progression paths runtime (§5)** — enum exists; no XP pool, no per-path level derived from investment, no path-gated unlocks at runtime, no level-up flow. **XP is a single shared pool, not per-path** (GDD §5, §7.10).
- **Phone (§9)** — entire system absent: camera, gallery, livestream, bank, Feetex, maps, health tracker. Includes the new sub-systems:
- **Battery (§9.8)** — passive base + per-app multiplier drain; apartment charger; portable powerbank consumable (Convenience Store); hard shutdown at 0%; mid-livestream cutoff with earnings-to-date deposited; sleep always charges to 100%.
- **Livestream tip requests (§9.1.1)** — viewer-driven action requests with phone popup (Accept / Decline + countdown); fail = viewer count drops, no rep hit.
- **Livestream follower trickle (§9.1.1)** — `streamQualityScore` ticks through `FollowerGainCalculator` per tick.
- **Bank app income breakdown (§9.4)** — line items by source incl. the weekly follower auto-deposit at week boundary.
- **`PhoneSubsystem` (§17.1)** — tickable subsystem owning phone state (battery %, active app, livestream session lifecycle, charger interaction). Does not yet exist.
- **Forum (§13)** — no `UCommissionTemplate`, no procedural generation, no weekly missions distinct from daily, no profile (incl. weekly follower-income summary), no posting photos. Forum scope is locked minimal (board + own profile only, no threads / no other-users feed) — that's a non-build, but worth recording.
- **Photo & livestream** — absent.
- **NPC types (§10.2)** — only one generic `ANPC` class. No Walker / Stalker / Blogger / Snitch / Harasser, 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, no apartment bed interaction.
@@ -53,35 +58,78 @@ State of the C++ module as of the latest pass. File references use `Source/Naked
- **Rip & tear (§6.3.5)** — absent. `UClothingItemInstance::Condition` is read-only in code; no decrement source.
- **Expose action (§6.3.6)** — `CanExpose` data exists on the definition; runtime action absent.
- **Restrictive clothing (§6.3.7 / §10.4.1)** — `IsRestrictive` field exists; no enforcement of hand-action locks, no Key-based unlock flow.
- **Adult shop, gym, beauty salon, cafe, convenience store** — none.
- **Food / consumables (§6.7)** — absent.
- **Recognition, wanted state, news (§7.6–§7.7, §11.1)** — absent.
- **Underwear selling (§15.1)** — absent.
- **Bodysuit exclusion rule (§6.5)** — when implementing the new slot enum, `ClothingManager` must auto-unequip `Top`/`Bottom`/`UnderwearTop`/`UnderwearBottom` on bodysuit equip, and vice versa.
- **Toy slots (§6.5)** — `Nipples`, `Anal`, `Vagina` are now **toy slots** (not body-clothing slots, not body-parts conflict). Independent; all three can be active. Items in these slots are sex toys from the Adult Shop (§10.4), follow standard item-identity rules, do **not** contribute to coverage, and may modify lust / embarrassment / pulse plus add audible vibration NPCs may detect.
- **Adult shop, gym, beauty salon, café, convenience store** — none.
- **Food / consumables (§6.7)** — absent. Vocabulary now locked: 2 instant effects (energy restore, lust decrease), 4 timed buffs (stamina regen +, max stamina +, embarrassment-gain resistance, lust-gain resistance). Stacking: different types parallel; same type additive up to per-type cap. Cooking minigames (slice / stir / cook) modulate buff strength; never poison.
- **Recognition, wanted state, news (§7.6–§7.7, §11.1)** — absent. Face-cover bypass via `Face` and `Eyes` slots is part of this work.
- **Underwear selling (§15.1)** — absent. Backed by the `DeliverItemTo` typed objective (player-owned source only, §13.4).
- **Endless mode flag (§3.3)** — absent.
- **Pulse attribute (§7.5)** — absent (new in the updated GDD).
- **GAS adoption (§17.2)** — `StatsManager` is still a bespoke `UActorComponent`; no `UAttributeSet`, no `GameplayEffect`-driven modifiers.
### 1.4 Conflicts to resolve
- **`SaveGame` UPROPERTY typo** — `GlobalSaveGameData.h:35` declares `UPROPERTY(SaceGame)` instead of `SaveGame` on `DaysPassed`. The field will not serialize. (Likely also blocks Unreal Header Tool warnings; needs a clean rebuild after the fix.)
- **`EClothingSlotType`** (`Clothing/ClothingSlotType.h`) still includes `Nipples`, `Anal`, `Vagina` as equipment slots — those are body parts per the GDD. Slot list also lacks `Outerwear`, `Accessory`, `Restraint` (GDD §6.3 / §21 Q1). The character builds 14 skeletal mesh components against these values (`NakedDesireCharacter.cpp:40-67`), so the cleanup needs a matching content / BP pass.
- **`SaveGame` UPROPERTY typo** — `GlobalSaveGameData.h:35` declares `UPROPERTY(SaceGame)` instead of `SaveGame` on `DaysPassed`. The field will not serialize.
- **`USaveSubsystem::SaveGame` writes an empty save** — does not pull state from the live world before writing (`SaveSubsystem.cpp:10-13`, `GlobalSaveGameData.cpp:45-53`). Any "save" call at present destroys progress. Highest-priority correctness bug.
- **`USaveSubsystem::LoadGame` ignores the loaded object** — static returns a populated `UGlobalSaveGameData`; subsystem stores / applies nothing.
- **`EClothingSlotType` — concrete reshape to the locked 18-slot list (GDD §6.5)**
Current enum (`Clothing/ClothingSlotType.h`, 14 values): `Nipples, Anal, Vagina, Head, Neck, Face, Eyes, Body, Top, Bottom, Bra, Panties, Socks, Shoes`.
Target (18 slots, 4 groups): see GDD §6.5. Migration table:
| Current | Target | Action |
|--------------|-------------------|---------------------------------------------------------------------|
| `Top` | `Top` | Keep |
| `Bottom` | `Bottom` | Keep |
| `Bra` | `UnderwearTop` | Rename |
| `Panties` | `UnderwearBottom` | Rename |
| `Body` | `Bodysuit` | Rename + enforce exclusion with `Top`/`Bottom`/`UnderwearTop`/`UnderwearBottom` |
| `Socks` | `Socks` | Keep |
| `Shoes` | `Footwear` | Rename |
| — | `Outerwear` | **Add** |
| `Head` | `Head` | Keep |
| `Face` | `Face` | Keep (now a face-cover slot per §7.6) |
| `Eyes` | `Eyes` | Keep (now a face-cover slot per §7.6) |
| `Neck` | `Neck` | Keep |
| — | `WristRestraint` | **Add** |
| — | `AnkleRestraint` | **Add** |
| — | `NeckRestraint` | **Add** (distinct from cosmetic `Neck`; auto-exclusion is *not* enforced — content authoring handles visual collision) |
| `Nipples` | `Nipples` | Keep — **now a toy slot, not a body-clothing slot** |
| `Anal` | `Anal` | Keep — **now a toy slot** |
| `Vagina` | `Vagina` | Keep — **now a toy slot** |
Net: 14 → 18 (4 renames, 4 additions, 3 semantic repurposes). `NakedDesireCharacter::SetupClothingSlots` (`NakedDesireCharacter.cpp:357-433`) needs four new mesh components added and four existing components renamed in lockstep with BP references in `Content/Blueprints/Player`.
Bodysuit exclusion is a runtime rule on `ClothingManager::PutOnClothing` — equipping a bodysuit must un-equip the four body slots; equipping any of those four must un-equip a present bodysuit.
Toy slots are independent and stackable; their items are sex toys (not clothing) but use the same `UItemInstance` model. The `UClothingItem` data class is named for clothing — a `USexToyItem` (or similar) `UItemInstance` subclass may be cleaner than reusing `UClothingItem` for toys, since the toy effects (lust modifier, embarrassment modifier, pulse modifier, NPC-audible vibration) don't map onto clothing's coverage / `CanExpose` / `IsRestrictive` model.
- **Two competing body-part enums** — `EPrivateBodyPartType` vs. `EBodyPart`. `ClothingItem::CoveredBodyParts` uses one, `ClothingItem::CanExpose` uses the other. The censorship / observation code paths in `NakedDesireCharacter` and `ClothingManager` are still on `EPrivateBodyPartType`. Pick one (recommend `EBodyPart`) and migrate.
- **`USaveSubsystem::SaveGame` writes an empty save** — it does not pull state from the live world before writing (`SaveSubsystem.cpp:10-13`, `GlobalSaveGameData.cpp:45-53`). Any "save" call at present destroys progress rather than persisting it. Highest-priority correctness bug.
- **`USaveSubsystem::LoadGame` ignores the loaded object** — the static returns a populated `UGlobalSaveGameData`, the subsystem stores nothing and applies nothing.
- **`UClothingList`** forward-declared in `GlobalSaveGameData.h:11` and `Wardrobe` / save records no longer use it. Dead reference; remove.
- **`Money` representation** — `ANakedDesireCharacter::Money` is `int` (`NakedDesireCharacter.h:132`), `UGlobalSaveGameData::Money` is `float` (`GlobalSaveGameData.h:27`). The earlier "Resolve Money duplication" commit consolidated the field locations but the type mismatch and the routing-through-save story are unfinished — verify which is authoritative before adding economy systems on top.
- **`STARTING_MONEY`** macro added to `Constants.h:8` but no code references it. Either wire it into the player / save init, or remove.
- **`ClothingItemInstance` has no public constructor / factory** — `ClothingItem` pointer is `protected` with no `Init(UClothingItem*)`. Wardrobe / BuyItem flows currently `EditAnywhere Instanced` populate the array at design-time, which works for the existing test level but won't support runtime purchase or save-driven hydration.
- **`StatsManager::TickComponent` energy drain** — drains energy at a flat `0.9f` per tick (`StatsManager.cpp:26`) regardless of activity, indoor / outdoor, or modifiers. GDD §7.3 specifies per-activity modifiers (`energyDrainRunModifier`, etc.).
- **`NPCSpawner` day window** — uses `Hours >= 9 && < 21` for "day" (`NPCSpawner.cpp:40`), GDD §10.1 says the day phase is `08:00 → 20:00`. Off-by-one and an hour offset.
- **`UClothingList`** forward-declared in `GlobalSaveGameData.h:11`; `Wardrobe` and save records no longer use it. Dead reference; remove.
- **`Money` representation** — `ANakedDesireCharacter::Money` is `int` (`NakedDesireCharacter.h:132`); `UGlobalSaveGameData::Money` is `float` (`GlobalSaveGameData.h:27`). Pick one authoritative location and one type.
- **`STARTING_MONEY`** macro defined in `Constants.h:8` but unreferenced. Either wire it into save / character init or remove.
- **`ClothingItemInstance` has no public constructor / factory** — `ClothingItem` pointer is `protected` with no `Init(UClothingItem*)`. Wardrobe / BuyItem flows rely on `EditAnywhere Instanced` design-time population, which won't support runtime purchase or save-driven hydration.
- **`StatsManager::TickComponent` energy drain** — drains energy at a flat `0.9f` per tick (`StatsManager.cpp:26`) regardless of activity. GDD §7.3 specifies per-activity modifiers.
- **`NPCSpawner` day window** — uses `Hours >= 9 && < 21` for "day" (`NPCSpawner.cpp:40`); GDD §10.1 says `08:0020:00`. Off by one hour on each end.
- **GDD shifts not yet reflected in code:**
- Phase 4-era loss resolver work must avoid stripping equipped clothing — GDD §4.4 now says equipped items are **never** force-removed on loss.
- Energy = 0 must trigger a "cutscene to apartment + sleep" flow, not a teleport (GDD §4.4).
- Theft is now a chance-based model with grace periods (`T_grace`, `T_grace_bag`) and flat per-tick `P_theft`, not a ramping curve (GDD §6.3.4).
- Sleep is the deterministic side of clothing loss — guaranteed loss of every item left outside the apartment (GDD §4.4).
- No Helper NPC, no adult-shop unlock; restraint removal is Key + timed unlock only (GDD §10.4.1).
- Masturbation gating is Slut-path only (GDD §5.1 / §7.2 / §14.1).
- Police spawn day **and** night while `wanted` (GDD §7.7 / §10.3) — current spawner has no police path at all, but record this when it's built.
- **Loss resolver** must not strip equipped clothing (§4.4).
- **Energy = 0** must trigger a "cutscene apartment sleep" flow, not a teleport (§4.4).
- **Embarrassment = max** must fade to apartment with **no extra cost** (no time skip, no money penalty, no rep hit) — GDD §4.4.
- **Theft** is a chance-based model with grace periods and flat per-tick `P_theft`, not a ramping curve (§6.3.4).
- **Sleep** is the deterministic side of clothing loss — guaranteed loss of every clothing item left outside the apartment (§4.4).
- **No Helper NPC**; restraint removal is **Key + timed unlock only** (§10.4.1).
- **Masturbation** is **Slut-path gated** — generator must filter `PerformAction(masturbate)` for non-Slut players; quick-action entry must hide until unlocked (§5.1 / §7.2 / §14.1).
- **Police** spawn day **and** night while `wanted` (§7.7 / §10.3).
- **XP is a single shared pool, not per-path** — Phase 9 implementation must use a shared XP counter; a path's level is derived from how many upgrades the player has bought from that path's attribute pool (§5, §7.10).
- **Commission lifecycle:** explicit Accept required for daily *and* weekly; un-accepted commissions carry no penalty; weekly rewards now include followers (§13.1 / §13.2).
- **Commission generator** must respect `pathRequirement` (incl. `None` = path-neutral) and filter templates whose steps reference path-locked actions (§13.4). `failurePenalty` field is canonical; generator supplies tier-scaled default when empty.
- **`DeliverItemTo`** must source from player inventory only; commission does not auto-issue items. Worn-underwear sales (§15.1) are the canonical use case (§13.4).
- **Livestream → follower trickle** via `FollowerGainCalculator` per tick; signed by reputation. Tip requests give an additional bonus on completion (§9.1.1 / §13.5).
- **Locations locked for launch:** Beach + Train Station are in; School exterior and Hot springs were cut. Vertical slice is the basic shop set only (§10.4, §18.1).
- **Food vocabulary locked:** 2 instant effects + 4 timed buffs; same-type stacks additively up to a cap; never poison (§6.7).
---
@@ -89,9 +137,9 @@ State of the C++ module as of the latest pass. File references use `Source/Naked
The item-identity rule (§6.1) and the save contract (§16.3) are still load-bearing. With the definition / instance split in place, the next bottleneck is **wiring serialization through gameplay**: condition mutation, world drops, container parent links, hydration on load. Until that round-trip works, content on top of the current system has no durable home.
The session-system + loss resolver (Phase 3) is the second pin. Several GDD shifts (equipped-never-dropped, energy-zero cutscene, sleep-deterministic clothing loss) move complexity from §4.4 prose into a single deterministic resolver. Build it once, well.
The session-system + loss resolver (Phase 3) is the second pin. Several GDD shifts (equipped-never-dropped, energy-zero cutscene, embarrassment-max no-extras, sleep-deterministic clothing loss) move complexity from §4.4 prose into a single deterministic resolver. Build it once, well.
GAS adoption (§17.2) remains deferred until Phase 4. Adding new attributes to the bespoke `StatsManager` in the meantime is fine — keep them additive and easy to migrate.
GAS adoption (§17.2) remains deferred until Phase 4. Adding new attributes to the bespoke `StatsManager` in the meantime is fine — keep them additive and easy to migrate. Food buffs (§6.7) are external multipliers on attribute rates, so design the per-rate interface with that in mind even before GAS lands.
---
@@ -99,34 +147,34 @@ GAS adoption (§17.2) remains deferred until Phase 4. Adding new attributes to t
Phase estimates are rough and assume one engineer. Adjust as we go.
### Phase 1 — Finish item identity + save round-trip (1 week)
Most of the structural work is done. What remains is connecting the pieces so an item modified at runtime survives a save / load cycle.
### Phase 1 — Finish item identity + save round-trip; reshape slot enum (12 weeks)
- Fix the `SaceGame` UPROPERTY typo on `DaysPassed` (`GlobalSaveGameData.h:35`).
- Add `UClothingItemInstance::Init(UClothingItem* Definition)` (or a static factory) so instances can be constructed at runtime — not just `Instanced` at design-time.
- Make `USaveSubsystem::SaveGame` actually pull live state into a `UGlobalSaveGameData`: player money, equipped items, wardrobe items, calendar, observation-attribute snapshot. Cover `WardrobeItems` and `EquippedItems` arrays via `FItemSaveRecord` populated from current `UClothingItemInstance`s (Guid, definition soft pointer, condition, parent guid).
- Make `USaveSubsystem::LoadGame` actually apply the loaded data: rebuild `UClothingItemInstance`s from records, push into the wardrobe array and `ClothingManager` slots. Replace the commented-out `ClothingManager::HydrateClothing` with the real hydration.
- Unify `EPrivateBodyPartType` and `EBodyPart` (recommend keeping `EBodyPart`, retiring the legacy enum). Update `ClothingItem::CoveredBodyParts`, `ClothingManager::IsBodyTypeExposed`, censorship checks in `NakedDesireCharacter`, and the BT / observation paths.
- Slot vocabulary pass: drop `Nipples` / `Anal` / `Vagina` from `EClothingSlotType`, add `Outerwear` / `Accessory` / `Restraint`. Update the character's mesh component layout and any BP references in lockstep.
- Money: pick one authoritative location (`UGlobalSaveGameData` is the natural choice; `ANakedDesireCharacter::Money` becomes a cached read-through). Apply `STARTING_MONEY` at new-save creation. Convert character field to match save type.
- Remove the dead `UClothingList` forward declarations.
- Add `UClothingItemInstance::Init(UClothingItem* Definition)` (or static factory) so instances can be constructed at runtime.
- Make `USaveSubsystem::SaveGame` actually capture live state into `UGlobalSaveGameData`: player money, equipped items, wardrobe items, calendar, observation-attribute snapshot. Populate `FItemSaveRecord` from current instances.
- Make `USaveSubsystem::LoadGame` actually apply the loaded data: rebuild instances from records, push into wardrobe + `ClothingManager` slots. Replace the commented-out `ClothingManager::HydrateClothing` with real hydration.
- Unify `EPrivateBodyPartType` and `EBodyPart` on `EBodyPart`. Migrate `ClothingItem::CoveredBodyParts`, `ClothingManager::IsBodyTypeExposed`, censorship paths in `NakedDesireCharacter`, BT / observation paths.
- **Reshape `EClothingSlotType` to the locked 18-slot list (§1.4 table).** Add `Outerwear`, `WristRestraint`, `AnkleRestraint`, `NeckRestraint`. Rename `Bra → UnderwearTop`, `Panties → UnderwearBottom`, `Body → Bodysuit`, `Shoes → Footwear`. Add four new `USkeletalMeshComponent`s in `NakedDesireCharacter` for the new slots. Update BP references in lockstep.
- **Implement Bodysuit exclusion** in `ClothingManager::PutOnClothing` (auto-unequip `Top`/`Bottom`/`UnderwearTop`/`UnderwearBottom`; vice versa).
- **Define toy items**: either a new `USexToyItem : UItemInstance` (recommended) or extend `UClothingItem` with a toy variant. Toy items target `Nipples` / `Anal` / `Vagina` slots, carry lust / embarrassment / pulse modifier fields, and an optional NPC-audible-vibration flag. Do not contribute to coverage.
- Money: pick one authoritative location (`UGlobalSaveGameData`), make `ANakedDesireCharacter::Money` a read-through. Apply `STARTING_MONEY` at new-save creation. Reconcile int vs. float.
- Remove dead `UClothingList` forward declarations.
**Exit criteria:**
1. Item dropped at runtime, condition modified, save → quit → load reproduces the same `FGuid`, condition value, and slot / wardrobe membership.
2. `EBodyPart` is the only body-part enum in use.
3. Slot list matches GDD §6.3 / §21 Q1 decision.
3. `EClothingSlotType` matches the §6.5 18-slot list. Bodysuit exclusion is enforced at runtime. Toy slots work with at least one placeholder toy item.
4. A new game starts with `STARTING_MONEY` and rent / purchase flows debit the canonical money field.
### Phase 2 — World item actors + drop / pickup (1 week)
- `AItemActor` base wrapping a `UItemInstance*` (in `Items/`). Spawn transform, owning instance pointer, SaveGame-tagged.
- `AClothingPickup : AItemActor` with a visual representation (use `UClothingItem::StaticMesh` when set, fallback to skeletal mesh impostor).
- `AClothingPickup : AItemActor` with a visual representation (`UClothingItem::StaticMesh` when set, fallback to skeletal mesh impostor).
- Hook `ClothingManager::DropClothing` to spawn `AClothingPickup` at the player location with the actual instance reference — *not* a template copy. Reparent the instance from "equipped slot" to "world".
- Pickup interaction via existing `UInteractionManager` + `IInteractionTarget`. Pickup re-parents the instance into wardrobe or directly into the matching slot.
- `USaveSubsystem` extension: serialize `AClothingPickup`s as `FItemSaveRecord`s with world transform.
**Exit criteria:** unequip → world pickup actor appears → save / reload → pickup is still there at the same transform with the same instance ID → pick up restores the same instance to the slot.
**Exit criteria:** unequip → world pickup actor appears → save / reload → pickup still there at the same transform with the same instance ID → pick up restores the same instance to the slot.
### Phase 3 — Session system + loss resolver (1 week)
@@ -134,94 +182,120 @@ Most of the structural work is done. What remains is connecting the pieces so an
- `USessionLossResolver` — single class, one method `ResolveLoss(ESessionLossCause Cause)`. Implements GDD §4.4:
- Equipped clothing **stays** equipped (do not strip).
- Bag placed in world: mark its world record for deletion.
- Loose clothing on ground: leave as-is (theft chance has been running through Phase ?-7 logic; sleep step is what finalizes).
- Energy=0 path: trigger a cutscene → apartment → sleep cycle → guaranteed loss of every world clothing outside the apartment safe zone.
- Embarrassment-max / police-capture path: fade to apartment, no sleep cycle, no forced clothing loss.
- Police-capture: deduct money penalty, queue skipped days for the unpaid remainder, clear `wanted`.
- Loose clothing on ground: leave as-is at this stage; sleep step finalizes any guaranteed loss.
- **Energy = 0**: trigger a cutscene → apartment → sleep cycle → guaranteed loss of every world clothing outside the apartment.
- **Embarrassment = max**: fade to apartment. **No extra cost** (no time skip, no money, no rep).
- **Police capture**: fade to apartment, deduct money penalty, queue skipped days for the unpaid remainder, clear `wanted`.
- Wire `StatsManager::IncreaseEmbarrassment` max-hit and energy-zero into `USessionLossResolver`. Replace `EndGameEmbarrassed` BP-event with the C++ path.
- Add a debug overlay that shows the current loss state and what would be lost if a given cause fired.
- Add a debug overlay showing the current loss state and what would be lost if a given cause fired.
**Exit criteria:** all four code paths (safe end, embarrassment max, energy zero, police capture) produce the §4.4 outcomes deterministically. Inventory state after each loss matches the §6.6 summary table 1:1.
### Phase 4 — Attributes refactor (12 weeks)
- Decision: GAS vs. extended `StatsManager`. Recommend GAS — the embarrassment formula now has Pulse, Recognition, Coverage, Day/Night, and per-NPC-type weights as modifiers (§7.1), which is exactly what `UGameplayEffect` is shaped for.
- Add Lust (§7.2), Pulse (§7.5, **new**), Recognition (§7.6), Wanted (§7.7), Reputation (§7.8), Followers (§7.9). Money should be the only attribute that also lives in the save schema directly (since it has non-attribute side effects).
- Implement `GetEffectiveCoverage(EBodyPart)` on `ClothingManager` per §6.3.2 (sum of garments covering the part, underwear halved, clamped to 1.0). Replace the `CoverageWeight = 0.0f` stub in `StatsManager::TickComponent`.
- Lust → masturbate action (Slut-path gated, §7.2). Block the action in BP / quick-action when the player's Slut path level is 0.
- Pulse simulation: rises with running, masturbation, exposure events; decays toward baseline at rest. Modifies embarrassment / lust gain (§7.5).
- Recognition rise from Blogger photo events; face-cover bypass; reduce via news-site reporting (§11.1).
- Decision: GAS vs. extended `StatsManager`. Recommend GAS — the embarrassment formula has Pulse, Recognition, Coverage, Day/Night, per-NPC-type weights, and food-buff multipliers (§7.1, §6.7), which is exactly what `UGameplayEffect` is shaped for.
- Add Lust (§7.2), **Pulse (§7.5)**, Recognition (§7.6), Wanted (§7.7), Reputation (§7.8), Followers (§7.9). Money remains in the save schema directly (non-attribute side effects).
- Implement `GetEffectiveCoverage(EBodyPart)` on `ClothingManager` per §6.3.2 (sum of garments covering the part, underwear halved, clamped to 1.0). Replace the `0.0f` stub in `StatsManager::TickComponent`.
- Lust → masturbate action (Slut-path gated, §7.2). Block the action in BP / quick-action when the player has no Slut investment.
- **Pulse simulation:** rises with running, masturbation, exposure events; decays toward baseline at rest. Modifies embarrassment and lust gain rates (§7.5).
- Recognition rise from Blogger photo events; **face-cover bypass via `Face` + `Eyes` slots** (§7.6); reduction via news-site reporting (§11.1).
- Define the per-rate multiplier interface that food buffs (§6.7) and toy effects (§6.5) will hook into. Don't ship the buffs here; just leave the seams.
- Debug overlay extension: live values + active modifier sources for every attribute.
**Exit criteria:**
1. Observed-while-exposed embarrassment gain reads coverage and modifiers from the attribute system (no more `0.0f` stub).
2. Lust + Pulse simulate correctly and visibly influence embarrassment in a playtest scenario.
3. Recognition increases after a (mocked) photo event and decreases after a news-report action.
3. Recognition increases after a (mocked) photo event and decreases after a news-report action. Face-cover slot occupancy reduces recognition gain.
### Phase 5 — Time + calendar + rent + sleep (34 days)
- `UTimeOfDaySubsystem` replacing the BP-implementable time on `NakedDesireGameMode`. 90-day calendar, week boundary, day phase `08:0020:00` (fix the 0921 mismatch in `NPCSpawner.cpp:40`).
- `UTimeOfDaySubsystem` replacing the BP-implementable time on `NakedDesireGameMode`. 90-day calendar, week boundary, day phase `08:0020:00` (fix the `0921` mismatch in `NPCSpawner.cpp:40`).
- Sleep action on apartment bed: triggers the same path as energy-zero (§4.4) for the "items left outside" cleanup, restores energy, autosaves, advances calendar.
- Weekly rent transaction at week boundary; eviction if money insufficient (`game over (run)`, §3.3).
- Weekly rent transaction at week boundary; eviction if money insufficient (game over (run), §3.3).
- **Weekly follower-income auto-deposit** to the bank at week boundary (§7.9, §9.4).
- Endless-mode flag on `UGlobalSaveGameData`; rent-eviction branch checks it.
**Exit criteria:** play through 7 in-game days, get charged rent at the week boundary, eviction triggers on insufficient funds, endless-mode disables eviction.
**Exit criteria:** play through 7 in-game days, get charged rent at the week boundary, eviction triggers on insufficient funds, endless-mode disables eviction, weekly follower income lands in the bank.
### Phase 6 — NPC types + recognition pipeline (12 weeks)
- `ENPCType` enum, type-specific BT branches or per-type controller subclasses: Walker / Stalker / Blogger / Snitch / Harasser. **No Helper** (cuff removal is Key-only per §10.4.1).
- Police as a separate AI controller / spawn pipeline. Patrols spawn day and night while `wanted` (§7.7 / §10.3). Detection logic (`face hidden?` + coverage threshold) → chase → break-LOS timer.
- `ENPCType` enum, type-specific BT branches or per-type controller subclasses: Walker / Stalker / Blogger / Snitch / Harasser. **No Helper.**
- Police as a separate AI controller / spawn pipeline. Patrols spawn day **and** night while `wanted` (§7.7 / §10.3). Detection logic (face hidden? + coverage threshold) → chase → break-LOS timer.
- Wanted-poster mechanic: spawn posters in the city; tearing all down clears `wanted` (§10.3).
- Recognition flow: Blogger sight + photo event → article → news-site article state → "report" reduces recognition.
- Wire Snitch's "report to police" → immediate police spawn this session + sets `wanted` (§7.7).
**Exit criteria:** every listed NPC type observably distinct; recognition rises after a Blogger event and can be reduced via news report; Snitch report triggers police spawn and the `wanted` tag that persists across sessions until posters torn down or capture.
### Phase 7 — Commission template system (12 weeks)
### Phase 7 — Commission template system + accept lifecycle (12 weeks)
- Replace `MissionsConfig`'s hand-authored daily list with `UCommissionTemplate` + procedural generation per §13.4.
- Add typed objective steps as new `UMissionGoal` subclasses:
- `BeFullyNaked(duration)` (new in §13.4)
- `BeFullyNaked(duration)`
- `BeFullyNakedNearNPCs(count, duration)`
- `WalkNakedDistance(meters)`
- `MoveDistanceFromClothing(meters)`
- `BeObservedByNPCType(type, durationOrCount)`
- `TakePhotoAtLocation(locationTag)` (requires phone work from Phase 8 — gate this objective until then)
- `DeliverItemTo(npcOrLocation)`
- Path-tagged XP (§5). Generation weights against player path progression.
- Weekly-vs-daily generation pass.
- `TakePhotoAtLocation(locationTag)` (gated by Phase 8 phone work)
- `DeliverItemTo(npcOrLocation)`**player-owned inventory only** (§13.4); the commission does not auto-issue items.
- `PerformAction(actionId)`**generator filters path-locked actions** (e.g., `masturbate` is Slut-only).
- **Accept lifecycle (§13.1 / §13.2):**
- Both daily and weekly require explicit Accept on the forum.
- Un-accepted commissions carry no penalty; accepted-but-failed apply the template's `failurePenalty`.
- Weekly rewards include followers; weekly `failurePenalty` is heavier than daily.
- **Generator rules:** respect `pathRequirement` (incl. `None`); filter path-locked-action templates by player path investment; substitute a tier-scaled default penalty when `failurePenalty` is empty.
**Exit criteria:** daily commissions regenerate from templates each in-game day; weekly arc is distinct; failed commissions deduct reputation.
**Exit criteria:** daily commissions regenerate from templates each in-game day; weekly arc is distinct; explicit Accept committed flow works end-to-end; failed accepts deduct the template penalty; un-accepted commissions never penalize the player.
### Phase 8 — Phone + forum UI (23 weeks)
### Phase 8 — Phone + forum UI + battery + livestream (34 weeks)
- Phone as an `AItemActor` (Phase 2 base) with hand / pocket / bag location semantics (§9).
- Apps: Camera + Gallery, Livestream (`UStreamSession` tickable UObject — works while phone is held *or* placed, §9.1.1 exception), Bank, Feetex, Maps, Health Tracker, Forum.
- Photo system: render-to-texture (§17.6 / §21 Q6 — recommended).
- `PhoneSubsystem` (§17.1): tickable; owns battery %, active app, livestream session lifecycle, charger interaction.
- **Battery (§9.8):**
- Passive base drain + per-app multiplier (Forum/Bank/Maps/Health Tracker/Gallery ~1×, back-camera ~3×, livestream ~5×). Livestream stacks on top of foreground app.
- Apartment charger interactable: place phone on it, recharges at a fixed rate.
- **Portable powerbank**: consumable `UItemInstance` purchasable at Convenience Store (§10.4). Single-use, restores fixed % when consumed. S-size container slot.
- **Hard shutdown at 0%**: all apps lock; livestream ends and deposits earnings-to-date; future tips forfeit. Phone wakes from a consumed powerbank.
- **Sleep auto-charges to 100%** (voluntary or energy-zero cutscene).
- Battery % is part of the phone's `UItemInstance` state; persists across saves.
- Apps: Camera + Gallery, Livestream, Bank, Feetex, Maps, Health Tracker, Forum.
- **Bank app income breakdown (§9.4):** line items by source — commissions, livestream donations, in-stream tip-request completions, underwear sales, weekly follower auto-deposit.
- **Livestream (§9.1.1):**
- `UStreamSession` tickable UObject — works while phone is held OR placed.
- Per-tick `streamQualityScore``FollowerGainCalculator` for the follower trickle (signed by reputation; shrinks at negative rep).
- End-of-stream deposits both money and accumulated follower delta.
- **Tip requests:** phone popup with Accept / Decline + countdown. Accept = spawn live objective tracker (reuse Phase 7 primitives). Complete = tip lands + small follower bonus. Fail = viewer count drops (less passive income for the remainder); no rep hit. Decline / timeout = no effect.
- Photo system: render-to-texture (§17.6 / §21 Q5 — recommended).
- Wire `TakePhotoAtLocation` commission step to actual photo events.
**Exit criteria:** end-to-end photo loop — equip phone, capture photo, view in gallery, post to forum, follower count updates. Livestream can be started, run while the phone is set down, and ended with payout deposited.
**Exit criteria:** end-to-end photo loop (capture → gallery post follower count updates). Livestream can be started, run while the phone is placed, generate trickle followers + donations, accept and complete a tip request for a bonus, end with payout. Battery drain visibly different per app; charger and powerbank both restore charge; 0% hard-shutdown behaves correctly.
### 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 GDD §18.1 (15-20 clothing items, 3 bag variants, 8 food items, 20 commission templates, 1 functional district).
- Masturbation gating (§5.1, §7.2) — actually hide the quick-action entry until Slut path level 1.
- **Single shared XP pool** — not per-path. Add `XP` to the save schema. Player invests XP via the forum profile (§13.3) into any path's attribute pool.
- A path's level is derived from how many upgrades the player has purchased from that path's pool (§5.4 / §7.10) — there is no per-path XP counter.
- Level-gating on clothing (§5.15.3) and on path-tagged commission templates (§7).
- Author the vertical-slice content set from GDD §18.1 (1520 clothing items, 3 bag variants, 8 food items, 20 commission templates, 1 functional district).
- Masturbation gating (§5.1, §7.2) — hide the quick-action entry until the player has at least one Slut-path upgrade.
**Exit criteria:** all three paths have at least 5 unlockable items and 3 path-specific commission templates. Slut-path-locked actions are correctly hidden / gated.
**Exit criteria:** all three paths have at least 5 unlockable items and 3 path-specific commission templates. Slut-path-locked actions correctly hidden until the player invests. XP spent into one path raises *that* path's level without consuming XP that could go to another path.
### Phase 10 — Remaining systems & polish
- Bag inventory (§6.4) — uses Phase 2's `AItemActor` for world placement.
- Food / cooking (§6.7) — three minigames per the GDD (slice, stir, cook).
- Gym / beauty salon / adult shop / cafe / convenience store (§10.4).
- **Food (§6.7):**
- Implement the locked vocabulary: 2 instant effects (energy restore, lust decrease) + 4 timed buffs (stamina regen +, max stamina +, embarrassment-gain resistance, lust-gain resistance).
- Stacking: different types parallel; same type additive to a per-type cap.
- Three cooking minigames (slice / stir / cook); scoring modulates buff strength; never poison.
- Gym / beauty salon / adult shop / café / convenience store (§10.4). Convenience Store stocks powerbanks (Phase 8 dep). Adult Shop stocks toy items for the three toy slots (Phase 1 dep).
- Rip & tear (§6.3.5).
- Theft model (§6.3.4) — implement `T_grace` / `T_grace_bag` grace timers and per-tick `P_theft` chance roll. No ramp.
- **Theft model (§6.3.4)** — implement `T_grace` / `T_grace_bag` grace timers and per-tick `P_theft` chance roll. No ramp.
- Expose action (§6.3.6) — read `CanExpose` per garment, blocked by overlapping coverage.
- Restrictive-clothing flow (§6.3.7 / §10.4.1) — Key + timed unlock action. Lock hand-dependent actions while restrained.
- Underwear selling (§15.1) — Feetex drop-box or location drop-off variant.
- Underwear selling (§15.1) — Feetex drop-box or location drop-off variant. Backed by `DeliverItemTo(npcOrLocation)` from Phase 7.
- Wanted-poster takedown (§10.3) — interaction + spawn placement pass.
- Final tuning: `T_grace`, `T_grace_bag`, `P_theft`, embarrassment / lust / energy / pulse rates (§21).
- Beach + Train Station locations (§10.4) for full-launch scope.
- Final tuning of all §21 numbers (theft, food caps, battery, tip-request distribution, embarrassment / lust / energy / pulse rates, face-cover magnitudes, etc.).
---
@@ -231,5 +305,8 @@ Use this section for in-flight decisions, blockers, and open questions that emer
- **Phase 1 critical path:** the save-write-without-state bug is the most damaging current issue — any "save" call destroys progress. Fix the SaveSubsystem before anything else builds on save behaviour.
- **Body-part enum migration:** the existing censorship code in `NakedDesireCharacter::OnClothingEquip` / `OnClothingUnequip` reads `EPrivateBodyPartType`. Migration to `EBodyPart` must update that path or the censorship visibility will silently desync.
- **Slot-vocabulary cleanup will break BP references** — coordinate before deleting `Nipples` / `Anal` / `Vagina` from `EClothingSlotType`. The character constructor creates skeletal-mesh components keyed to those names; expect BPs in `Content/Blueprints/Player` to need a touch.
- _empty beyond this point_
- **Slot-vocabulary reshape will break BP references** — coordinate before renaming/adding values in `EClothingSlotType`. The character constructor creates skeletal-mesh components keyed to those names; expect BPs in `Content/Blueprints/Player` to need a touch.
- **Toy items vs. clothing items:** the `UClothingItem` schema (coverage, `CanExpose`, `IsRestrictive`) doesn't fit sex toys cleanly. Strongly recommend a separate `USexToyItem : UItemInstance` (with `LustModifier`, `EmbarrassmentModifier`, `PulseModifier`, `VibrationAudible` fields) rather than overloading `UClothingItem`. Decide before Phase 1 toy work begins.
- **XP is a single shared pool** (GDD §5, §7.10). Do not introduce per-path XP counters in Phase 9 or earlier — a path's level is derived from how much the player has invested into that path's attribute pool.
- **Food buff hookpoints belong in Phase 4** (attribute multiplier interface), even though the food items themselves ship in Phase 10. Leave the seams; don't retrofit later.
- _empty beyond this point_
+175 -52
View File
@@ -37,7 +37,7 @@ A sandbox exhibitionist life-sim where the player accepts fetish commissions fro
Yumi, while browsing the internet after a rent increase, discovers a hidden fetish forum that pays for exposure-themed commissions. After completing her first task she realizes she enjoys it. She begins taking commissions to cover rent and explore the new feelings.
### 2.2 Setting
A modern Japanese-style city. Currency is Yen. The city is the entire playable map: residential, commercial, parks, alleys, a beach (TBD), a gym, a beauty salon, multiple shop types, the player's apartment.
A modern Japanese-style city. Currency is Yen. The city is the entire playable map: residential, commercial, parks, alleys, a beach, a train station, a gym, a beauty salon, multiple shop types, the player's apartment. See §10.4 for the locked location list.
### 2.3 Tone
Sexual, playful, transgressive. The player character is a willing participant, not a victim. The "stalker" NPC is the only non-consensual antagonist and exists as a session-loss threat, not a narrative one.
@@ -94,7 +94,7 @@ Player returns home. All carried items persist. Rewards from completed commissio
Triggered by any session-loss condition (§3.3). On loss:
- **The player returns to the apartment.** The route home depends on the cause:
- **Energy = 0** — a cutscene plays of the player trudging home, exhausted, and going to bed. The player never sleeps outside; the apartment bed is the only sleep location. Time advances by one sleep cycle.
- **Embarrassment = max** — fade to apartment (or a dedicated fail-state location — TBD).
- **Embarrassment = max** — fade to apartment. No extra cost beyond the session loss itself (no time skip, no money penalty, no reputation hit).
- **Police capture** — the player is processed (money penalty below) and returned home.
- **Equipped clothing is never forcibly removed by loss.** Whatever the player was wearing at the moment of failure stays equipped on arrival home.
- **A bag placed in the world** (not carried) is lost along with its contents — the player did not retrieve it before the failure.
@@ -109,7 +109,7 @@ Triggered by any session-loss condition (§3.3). On loss:
## 5. The Three Progression Paths
The player chooses how they level up but is not locked into one path. XP earned from commissions is path-tagged.
The player chooses how they level up but is not locked into one path. **XP is a single shared pool** — every commission, mission, and stream feeds the same number. The player decides which path's attribute pool to spend it on. Given enough XP, every attribute on every path can be upgraded; there is no requirement to earn "Slut XP" before buying a Slut-path upgrade.
### 5.1 Slut
- **Unlocks:** revealing clothing (mini skirts, high heels, lingerie variants), masturbation action, masturbation-related missions.
@@ -127,7 +127,7 @@ The player chooses how they level up but is not locked into one path. XP earned
- **Playstyle:** physically demanding, restriction-based puzzles (cuffs require NPC help to remove).
### 5.4 Path level
Each path has a level (e.g., 110). Level gates clothing, missions, and attribute upgrades. XP per path is independent.
Each path has a level (e.g., 110). Level gates clothing, missions, and attribute upgrades within that path's pool. **A path's level is derived from how much the player has invested into that path's attribute upgrades** (§7.10), not from any per-path XP counter — XP itself is a single shared pool.
---
@@ -147,11 +147,13 @@ Each path has a level (e.g., 110). Level gates clothing, missions, and attrib
- **Bags** (§6.4)
- **Phone** (one — special, §9)
- **Consumables** (food, §6.7)
- **Gadgets** (TBD beyond phone)
- **Toys** — sex toys for the toy slots (§6.5). Bought at the Adult Shop (§10.4).
There are no other gadget categories. The phone is the only electronic device the player carries.
### 6.3 Clothing
Attributes per clothing instance:
- `type` — equipment slot (top, bottom, underwear-top, underwear-bottom, outerwear, footwear, accessory, restraint, etc. — final slot list TBD).
- `type` — equipment slot. See **§6.5 Equipment slots** for the canonical 18-slot list (body clothing, accessories, restraints, toys), exclusion rules, and which slots drive the face-cover bypass.
- `covers` — set of body parts: `{ boobs, ass, genitals, ... }`.
- `progressionPath` — Slut / Exhibitionist / Slave / None.
- `color` — primary color enum.
@@ -212,10 +214,61 @@ Theft applies to lose clothing on the ground and to bags placed in the world (se
- Bags follow the same theft rules as clothing (§6.3.4) and the same session-loss rules as other items (§4.4 / §6.6).
### 6.5 Inventory & Equipment
- **Clothing slots** — one per equipment slot type (see §6.3 `type` field for the slot vocabulary; final list is TBD per §21 Q1).
The player has 18 equipment slots in four groups, plus a bag slot, a hand slot, and container slots exposed by what's currently equipped.
#### Equipment slots
**Body-clothing slots (layering, with one exclusion rule):**
| # | Slot | Examples |
|--:|--------------------|-----------------------------------------|
| 1 | `Outerwear` | Coat, jacket, hoodie |
| 2 | `Top` | T-shirt, blouse, crop top |
| 3 | `Bottom` | Skirt, pants, shorts |
| 4 | `UnderwearTop` | Bra, sports bra, bikini top |
| 5 | `UnderwearBottom` | Panties, thong, bikini bottom |
| 6 | `Bodysuit` | Latex catsuit, leotard |
| 7 | `Socks` | Stockings, tights, socks |
| 8 | `Footwear` | Shoes, heels, boots, sandals |
`Bodysuit` is **mutually exclusive** with `Top`, `Bottom`, `UnderwearTop`, and `UnderwearBottom`. Equipping a bodysuit auto-unequips all four of those slots; equipping any of those four while a bodysuit is on auto-unequips the bodysuit. `Outerwear`, `Socks`, `Footwear`, and the accessory / restraint slots are unaffected by bodysuit equipping.
**Accessory slots (cosmetic unless noted):**
| # | Slot | Examples | Notes |
|--:|--------|---------------------------------------|--------------------------------------------------------|
| 9 | `Head` | Hat, hood, headband | Cosmetic only. |
| 10 | `Face` | Mask, face shield | **Face-cover for recognition bypass (§7.6).** |
| 11 | `Eyes` | Glasses, sunglasses, blindfold | **Face-cover for recognition bypass (§7.6).** |
| 12 | `Neck` | Necklace, choker, scarf | Cosmetic. |
**Restraint slots (independent — all three can be active simultaneously):**
| # | Slot | Examples |
|--:|-------------------|-----------------------------------|
| 13 | `WristRestraint` | Wrist cuffs, rope bindings |
| 14 | `AnkleRestraint` | Ankle cuffs, spreader bar |
| 15 | `NeckRestraint` | Collar (restraint variant), gag |
Restraint slots are governed by §6.3.7 (effects) and §10.4.1 (removal). `NeckRestraint` is distinct from cosmetic `Neck`; a restraint collar and a necklace do not auto-exclude — content authoring is responsible for ensuring they don't visually collide (e.g., hide the necklace mesh when a collar is present).
**Toy slots (independent — all three can be active simultaneously):**
| # | Slot | Examples |
|--:|-----------|-------------------------------------------------------|
| 16 | `Nipples` | Nipple clamps, nipple suckers, pasties with vibrators |
| 17 | `Anal` | Butt plug, anal beads |
| 18 | `Vagina` | Vibrator, dildo, internal egg |
Sex toys are bought from the Adult Shop (§10.4) and follow the standard item-identity rules (§6.1). Toys do **not** contribute to coverage (§6.3.2); a butt plug under panties leaves `UnderwearBottom`'s coverage value unchanged and the ass remains "covered" by panties for embarrassment math. Toys can be hidden beneath clothing or worn while otherwise nude — the slot is orthogonal to the body-clothing layering rules. Effects (lust modifier, embarrassment modifier, pulse modifier, audible vibration that NPCs may detect) are per-toy and authored on the toy's `UItemInstance`.
#### Other equipment
- **Bag slot** — 1 (see §6.4).
- **Hand slot** — 1. Holds one carriable item at a time (phone, food, key, etc.). Restrictive clothing (§6.3.7) disables all hand-dependent actions while equipped.
- **Container slots** — additional storage exposed by equipped clothing (e.g., pants pocket) and by the equipped bag. Each container slot has a size class (S / M / L, §6.3.1) that constrains what fits.
- **Hand slot** — 1. Holds one carriable item at a time (phone, food, key, etc.). Any item in `WristRestraint` disables all hand-dependent actions (§6.3.7).
#### Container slots
- Each equipped clothing item may expose container slots (e.g., pants pocket). The equipped bag exposes container slots as well. Each container slot has a size class (S / M / L, §6.3.1) that constrains what fits.
- There is no abstract "backpack" inventory. Total carry capacity = sum of container slots provided by currently equipped items.
### 6.6 Item loss summary table
@@ -229,14 +282,30 @@ Theft applies to lose clothing on the ground and to bags placed in the world (se
| Sleep with clothing left outside the apartment (voluntary or forced energy-zero cutscene) | **Guaranteed** loss of every clothing item left outside, regardless of grace / chance state. |
### 6.7 Consumables — Food
- Restores energy.
- May grant timed buffs (e.g., ramen: +stamina regen for 3h in-game).
- Buffs are typed and stackable per design (specifics TBD).
- Some foods require cooking (ingredients from convenience store), some are pre-made (from café).
- Food is cooked via mini-games
- Slice ingredients via fruit ninja
- Stir ingredients via clicker(Mortal Kombat - Test your strength)
- Cook ingredients via Genshin Impact cooking minigame(DBD generator fix minigame)
Food items live in the `UItemInstance` system (§6.1). They come from two sources: **ingredients** at the Convenience Store (require cooking) and **pre-made** food at the Café (eat immediately). Eating consumes the item and applies any combination of the effects below.
**Instant effects** (one-shot on consumption, no timer):
- **Energy restore** — adds a fixed amount of energy (§7.3).
- **Lust decrease** — subtracts a fixed amount of lust. Particularly relevant for non-Slut players who cannot masturbate to reset lust (§7.2).
**Timed buffs** (run for a per-item duration):
- **Stamina regen +** — raises `staminaRecoveryRate` above baseline (§7.4). The original ramen example.
- **Max stamina +** — additive bonus to base max stamina before the energy multiplier in §7.4 applies.
- **Embarrassment-gain resistance** — multiplier < 1 on the embarrassment-gain rate (§7.1).
- **Lust-gain resistance** — multiplier < 1 on the lust-gain rate (§7.2).
The effect list above is locked. No pulse-specific buffs, no caffeine "energy trickle," no other categories at launch.
**Stacking:**
- **Different effect types always stack** and run in parallel.
- **Same effect type stacks additively up to a per-type cap.** Two ramens (each +X stamina regen for 3h) compose to `min(2X, cap)` for 3h, with timers tracked independently.
- Per-type caps and the instant-effect amounts are TBD per §21.
**Cooking:**
- Ingredients from the Convenience Store must be cooked at the apartment before they become edible.
- Cooking runs through three minigames: **slice** (fruit-ninja-style), **stir** (rhythm / timing-mash), and **cook** (timing-stop). Performance on each minigame modulates the buff strength of the resulting dish; failing badly produces a weaker variant of the intended effect, never poison or negative buffs.
- Pre-made Café food has no cooking step — eat directly.
---
@@ -303,7 +372,7 @@ All attributes update in real time. Indoor and outdoor behavior is identical —
- Each photo taken by a Blogger NPC and published increases recognition.
- Higher recognition → faster embarrassment gain (NPCs recognize the player).
- Reducible by reporting articles on the city news site (PC, §11.1).
- Can be **bypassed** by hiding the face (mask, hat-and-glasses combo — TBD specifics).
- Can be **bypassed** by hiding the face. Each of the face-cover slots — `Face` (mask) and `Eyes` (glasses / sunglasses / blindfold) — applies an additive recognition-resistance modifier when occupied. Either one alone provides a partial bypass; both equipped stacks toward a full bypass. The `Head` slot (hat / hood) is cosmetic only and does not contribute. Per-slot resistance magnitudes are TBD per §21.
### 7.7 Wanted
- Boolean. Set when a Snitch (§10.2) successfully reports the player to police during a session. The tag persists even if the session ends safely afterward (§4.3).
@@ -324,7 +393,7 @@ All attributes update in real time. Indoor and outdoor behavior is identical —
- **Money (Yen)** — earned from commissions, livestream donations, selling worn underwear. Spent on rent, clothing, food, gym, beauty salon.
### 7.10 Attribute leveling
Path XP unlocks the *ability* to upgrade attributes within that path's pool. Money or a separate currency may be required per level-up (TBD — recommend keeping it tied to XP only for clarity, but flag for playtest).
Each attribute upgrade in a path's pool costs only **XP** — no money, no separate currency. **XP is a single shared pool, not per-path** (§5): every commission, mission, and stream credits the same number, and the player decides which path's attribute pool to spend it on. With enough XP a player can max all three paths. Per-level XP costs (flat, escalating, or stepwise) are tuning numbers, not design decisions; they live in the per-path attribute table and are calibrated in playtest.
---
@@ -342,10 +411,10 @@ Movement should be implemented as a state machine on the character with clear tr
## 9. Phone
TODO: Add battery charge
The phone is the player's diegetic UI hub. It can be used if it is in: hand, pocket (pants with phone-sized container slot), or equipped bag. **Exception:** the livestream app (§9.1.1) continues to operate while the phone is placed in the world, so the player can keep streaming after setting the phone down for a back-camera shot.
The phone is battery-powered (§9.8). A dead phone is unusable until charged — no forum, no camera, no maps. Plan accordingly.
### 9.1 Camera
- **Front camera** — held in hand, framed selfie shot.
- **Back camera** — phone is placed in the world via `place camera` action. A floating window shows the camera's view. Photos are triggered via hotkey while the camera is placed.
@@ -355,9 +424,15 @@ The phone is the player's diegetic UI hub. It can be used if it is in: hand, poc
- Available at any time via the phone, regardless of whether the player is holding it or it is placed in the world.
- Same dual-mode setup as the camera: front-facing while held, back-facing when placed.
- Generates donation income in real time. Income rate scales with exposure visible in the stream (similar logic to photo follower-gain math, but continuous).
- Also grows **followers** in a continuous trickle. The live `streamQualityScore` is fed into `FollowerGainCalculator` (§13.5) per tick at a tunable rate; gains accumulate over the stream. Reputation sign applies — streaming with negative reputation shrinks the audience instead of growing it.
- Recommended implementation: livestream is a `StreamSession` object owned by the phone, tickable, with `viewerCount`, `tipRate`, and `streamQualityScore` (a function of what the camera sees and player attributes).
- Ending the stream returns earnings to the bank.
- TODO: Stream requests for huge donations
- Ending the stream returns earnings to the bank and finalizes the accumulated follower delta.
- **Tip requests.** During an active stream, viewers post named action requests with a fixed yen reward attached. Each request is a small commission expressed in the §13.4 typed objective vocabulary — e.g. `ExposeBodyPart(boobs, 8s)` for a small tip, `BeFullyNaked(15s)` for a medium tip, `TakePhotoAtLocation(fountain)` for a large tip. The full tip-size range is wide; occasional high-roller requests pay several times a normal commission for correspondingly demanding objectives.
- Requests appear as a phone popup with **Accept** / **Decline** hotkeys and a short countdown. Ignoring the popup until it times out is treated as a decline.
- **Decline** has no penalty — viewers keep watching and baseline tip rate is unaffected. Players who don't want to engage with the request system can ignore it indefinitely and still earn passive donation income.
- **Accept** spawns a live objective tracker for the duration of the request. Completing it in time deposits the tip into the bank along with the rest of the stream earnings.
- **Failing an accepted request** drops the viewer count slightly (less passive income for the remainder of the stream) but does **not** damage reputation (§7.8). A failed accept is a missed opportunity, not a breach of contract.
- Request frequency, tip-size distribution, acceptance countdown, and the viewer-count-drop magnitude on failure are TBD per §21. Higher viewer count generally → more frequent and higher-value requests.
### 9.2 Gallery
- Lists all captured photos with metadata (time, location, equipped state, exposed parts).
@@ -368,6 +443,7 @@ The phone is the primary access point for the forum. See §13.
### 9.4 Bank app
- Track balance, income, spending. Pay rent (or auto-pay).
- Income line items break down by source: commissions, livestream donations, in-stream tip-request completions, underwear sales (§15.1), and the **weekly follower-income auto-deposit** (§7.9) that lands at each week boundary.
### 9.5 Feetex (deliveries)
- Track pending online orders (clothing, food). Items arrive at the apartment door one in-game day after purchase.
@@ -378,6 +454,25 @@ The phone is the primary access point for the forum. See §13.
### 9.7 Health Tracker
- Displays the player's attribute readouts (energy, stamina, lust, embarrassment, recognition).
### 9.8 Battery
The phone has a finite battery that drains while powered on and recharges at the apartment.
- **Drain.** Two layers, multiplied together:
- **Passive base** — slow tick whenever the phone is powered on (idle in pocket, hand, or bag).
- **Per-app multiplier** — foreground app raises the drain rate above baseline. Indicative ranking (concrete numbers TBD per §21):
- Forum / Bank / Feetex / Maps / Gallery / Health Tracker: ~1× (baseline + minor UI cost).
- Camera placed in the world (back-camera mode): ~3×.
- Livestream: ~5× — heaviest drain. Livestream is the only app that ticks in the background and stacks its drain on top of whatever app is in the foreground.
- **Charging.**
- **Apartment charger** — primary source. A charger spot in the apartment recharges the phone at a fixed rate (TBD) while the phone is placed on it.
- **Portable powerbank** — purchasable consumable (Convenience Store, §10.4). Single-use; consuming one restores a fixed percentage of charge (TBD). Occupies one container slot (size S, §6.3.1) in the player's inventory and follows normal item-identity / theft rules.
- **Dead battery (0%).** Hard shutdown:
- All apps lock. Opening the phone shows a "dead battery" overlay; no input passes through.
- An active livestream **ends immediately**. Earnings accrued up to the cut-off are deposited; further viewers / tips that would have arrived are forfeit.
- The phone can still accept a powerbank charge from the player's inventory — consuming a powerbank wakes the phone at the powerbank's restore percentage. Without a powerbank, the phone stays dead until the player reaches an apartment charger.
- **Sleep.** Sleeping at the apartment always charges the phone to 100%, whether or not the player explicitly docked it on the charger. This applies equally to voluntary sleep and to the energy-zero cutscene (§4.4) — that cutscene's sleep cycle includes the charge-to-full step.
- **Persistence.** Current battery percentage is part of the phone's `UItemInstance` state and persists across saves.
---
## 10. The City
@@ -412,14 +507,17 @@ Sleeping at home fast-forwards 8 hours.
### 10.4 Locations
- **Apartment** — safe zone. Wardrobe, bed, PC, kitchen.
- **Convenience store** — cooking ingredients.
- **Convenience store** — cooking ingredients; portable phone powerbanks (§9.8).
- **Café** — pre-made food.
- **Clothing shops** — various types, each with a different inventory mix.
- **Gym** — increase max energy. Costs energy in the process. Costs money.
- **Beauty salon** — boobs size, ass size, makeup, hairstyle, hair color.
- **Adult shop** — Buy adult toys.
- **Adult shop** — Buy sex toys for the `Nipples`, `Anal`, and `Vagina` toy slots (§6.5).
- **Streets / parks / alleys** — commission space.
- **(TBD)** beach, train station, school exterior, hot springs, etc. — design pass needed for variety.
- **Beach** — open sand, daytime crowds, nighttime privacy. Strong fit for exhibitionist / swimwear content.
- **Train station** — platforms, concourses. Dense voyeur space; an indoor-transit setting distinct from streets.
The location set above is **locked for launch**. School exterior and hot springs (onsen) were considered and explicitly cut.
#### 10.4.1 Cuff / restraint removal
Restrictive clothing (§6.3.7) is removed by **Key + timed unlock action**:
@@ -459,49 +557,59 @@ Restrictive clothing (§6.3.7) is removed by **Key + timed unlock action**:
The forum is accessed via phone or PC. It is both diegetic and the primary mission UI.
TODO: Review
### 13.1 Weekly missions
- Generated at week start, semi-random, weighted by player path progression.
- Rewards: money, XP.
- If the player doesn't meet entry requirements (level, path level), missions are visible but not marked failed — they serve as goals.
- Must be completed by end of week or marked failed.
- Rewards: money, XP, followers. Money / XP scale larger than daily commissions (week-long commitment); follower payouts are correspondingly larger.
- The player must **accept** a weekly mission from the forum before it counts as committed (same accept lifecycle as daily commissions in §13.2). Un-accepted weekly missions stay visible as goals and carry no penalty.
- An accepted weekly mission that the player fails to complete by the end of the week is marked failed and applies the template's `failurePenalty` (§13.4), which is heavier than the daily equivalent.
- A mission visible on the board that requires a path level the player hasn't reached is shown for context but cannot be accepted yet.
### 13.2 Daily commissions
- Generated at day start, semi-random, weighted by path progression.
- Rewards: money, XP, followers.
- Failing or not completing within the day → followers/reputation loss.
- A commission is "started" when the player accepts it; remaining un-started commissions are simply offered.
- The player must **accept** a daily commission from the forum to commit to it. Accepted commissions that aren't completed by day end trigger the template's `failurePenalty` (§13.4) — typically a reputation / followers loss. Un-accepted commissions sitting on the board carry no penalty; they are offers, not obligations.
- Multiple commissions can be accepted simultaneously; there is no built-in cap. The day timer is the natural limit on workload.
### 13.3 Profile
- View stats, progression, path levels, posted photos.
- Post photos → follower gain (calculated from exposed body parts + visible coverage in photo).
- Post photos → follower gain (calculated from exposed body parts + visible coverage in the photo via the `FollowerGainCalculator`, §13.5).
- Livestream is initiated from the phone at any time (see §9.1.1), not from the forum profile. The profile displays livestream history and lifetime earnings.
- Level up attributes (gated by path XP).
- Level up attributes — paid for from the shared XP pool (§5, §7.10). The profile is the UI surface for choosing which path's attribute to upgrade.
- Displays weekly follower-income summary: current follower count, next weekly payout estimate, lifetime earnings from followers (the underlying auto-deposit lives in the bank app, §9.4).
> **Forum scope:** The forum surface is intentionally minimal — the **commission board** (§13.1 / §13.2) and the **player's own profile**. There are no other users to browse, no threads, no popular-posts feed. The forum exists to drive the gameplay loop, not to simulate a social network.
### 13.4 Commission generation
Commissions should be procedural with template-driven content. Recommended template structure:
```
CommissionTemplate {
id,
pathRequirement: { path, minLevel },
pathRequirement: { path, minLevel }, // path ∈ { None, Slut, Exhibitionist, Slave }; None = path-neutral
steps: [ list of typed objective steps ],
rewardMoneyRange,
rewardXPRange,
rewardFollowersRange,
failurePenalty,
validLocations: [ ... ],
failurePenalty, // canonical penalty when an accepted commission expires unfinished;
// empty/zero = generator applies a default appropriate to the reward tier
validLocations: [ ... ], // locations where the commission can run; applies to the whole commission
}
```
**Generator rules:**
- The generator never emits a template the player cannot complete: `pathRequirement` (including `path: None` for path-neutral commissions) is respected, and templates whose steps reference path-locked actions (e.g., `PerformAction(masturbate)` for non-Slut players) are filtered out before they reach the board.
- The `failurePenalty` field is authoritative. When empty / zero, the generator substitutes a default penalty scaled to the reward range.
- Weekly templates and daily templates draw from the same pool; the daily/weekly distinction lives on the template tier (longer step chains, higher reward bands).
Typed objective steps (initial set):
- `ExposeBodyPart(part, durationSeconds)`
- `BeFullyNaked(durationSeconds)` — fully unclothed for the duration; no NPC requirement.
- `BeFullyNakedNearNPCs(count, durationSeconds)`
- `WalkNakedDistance(meters)`
- `MoveDistanceFromClothing(meters)`
- `PerformAction(actionId)` (e.g., masturbate)
- `PerformAction(actionId)` (e.g., masturbate) — actions with path gating are only used in templates whose `pathRequirement` matches; generator filter enforces this.
- `BeObservedByNPCType(type, durationOrCount)`
- `TakePhotoAtLocation(locationTag)`
- `DeliverItemTo(npcOrLocation)`
- `DeliverItemTo(npcOrLocation)` — the player must **source the item from their own inventory**. The commission does not auto-issue items on accept. Worn-underwear sales (§15.1) are the canonical use case. "Deliver this pre-issued package to X" is intentionally not supported by this primitive — if that flavor is needed later, add a separate `DeliverIssuedItemTo` step rather than overloading this one.
Steps compose: a single commission step list may chain primitives that must all be satisfied (concurrently or sequentially as specified by the template).
@@ -513,9 +621,15 @@ Example commissions from the brief that should be representable:
### 13.5 Subscriber math (rough)
```
followerGain = base(photoExposureScore) * reputationFactor * (1 / log(followerCount + e))
followerGain = base(exposureScore) * reputationFactor * (1 / log(followerCount + e))
```
Concrete formula to be calibrated in playtest. Keep this isolated in a single `FollowerGainCalculator` for tunability.
- **`exposureScore`** is the input — for a posted photo it is computed from exposed body parts + visible coverage in that photo; for a livestream tick it is the current `streamQualityScore` (§9.1.1).
- **`reputationFactor`** is **signed**. Positive / neutral reputation → positive `followerGain` (followers grow). Negative reputation → negative `followerGain` (followers shrink). This is the §7.8 "positive vs. negative reputation" branch expressed in one number.
- The `1 / log(followerCount + e)` term enforces diminishing returns: at `followerCount = 0` the divisor is `1.0`; growth slows as the audience grows.
Both photo posts and livestreams run through the same `FollowerGainCalculator`. Photos compute once on submission; livestreams call it per tick at a tunable rate and accumulate. Completed in-stream tip requests (§9.1.1) apply an additional follower bonus on top, treated as a mini-commission completion.
Concrete numbers to be calibrated in playtest. Keep this isolated in `FollowerGainCalculator` for tunability.
---
@@ -614,6 +728,7 @@ The unique-instance rule (§6.1) means save must serialize each item by instance
- `NPCManager` — spawning, density, type weighting by location and time.
- `RecognitionSubsystem` — photo-to-news pipeline, article state, reporting.
- `PoliceManager` — patrols, wanted state, line of sight, chase.
- `PhoneSubsystem` — tickable phone state: battery drain (passive base + per-app multiplier, §9.8), active app, livestream session lifecycle, charger interaction at the apartment. Owns the phone's `UItemInstance` extension for battery percentage.
- `SaveSubsystem` — orchestrates serialization across all of the above.
### 17.2 GAS usage
@@ -656,7 +771,7 @@ Clothing, commissions, food, NPC templates all live as `DataAssets` (or DataTabl
### 18.2 Full launch target (TBD)
- 60+ clothing items.
- All NPC types polished, multiple visual variants each.
- Full city, 4+ districts.
- Full city, 4+ districts, including the **Beach** and **Train Station** locations (§10.4) added on top of the vertical-slice shop set.
- 100+ commission templates.
- All 3 paths leveled to cap with distinct content.
@@ -689,21 +804,29 @@ Decisions previously open, now fixed:
8. **Run length:** 90-day campaign. Endless mode unlocked after first completion (rent-eviction disabled, all other systems intact). See §3.3.
9. **Cuff/restraint removal:** Key + timed unlock action only. No Helper NPC, no paid adult-shop service. See §10.4.1.
10. **Voice commands:** Not used. Hotkey-driven only.
11. **Equipment slot list:** 18 slots, locked. Body clothing (8): `Outerwear`, `Top`, `Bottom`, `UnderwearTop`, `UnderwearBottom`, `Bodysuit` (exclusive with the prior four), `Socks`, `Footwear`. Accessories (4): `Head`, `Face`, `Eyes`, `Neck`. Restraints (3, independent): `WristRestraint`, `AnkleRestraint`, `NeckRestraint`. Toys (3, independent): `Nipples`, `Anal`, `Vagina`. Face-cover bypass for recognition is driven by `Face` and `Eyes`. Toys do not contribute to coverage. See §6.5 for the full table.
12. **City location list:** locked for launch. Apartment, Convenience Store, Café, Clothing Shops, Gym, Beauty Salon, Adult Shop, Streets / Parks / Alleys, **Beach**, **Train Station**. School exterior and hot springs (onsen) were considered and cut. Vertical slice (§18.1) covers everything except Beach and Train Station — those are full-launch additions. See §10.4.
13. **Attribute level-up cost:** XP only. XP is a single shared pool (not per-path); the player chooses which path's attribute pool to spend it on, and may eventually max all three. No money, no separate currency. See §7.10.
14. **Food effect vocabulary:** locked. Two instant effects (energy restore, lust decrease) plus four timed buffs (stamina regen +, max stamina +, embarrassment-gain resistance, lust-gain resistance). Stacking: different types parallel; same type additive up to a per-type cap. No pulse buffs, no caffeine trickle. See §6.7.
15. **Carriable categories:** locked. Clothing, Bags, Phone, Consumables (food), Toys. No other gadget categories beyond the phone. See §6.2.
## 21. Open Design Questions
These remain genuinely unresolved and should be addressed during implementation:
1. Final slot list for clothing equipment (top, bottom, underwear-top, underwear-bottom, outerwear, footwear, accessory, restraint — confirm and lock).
2. NPC theft tuning: grace periods (`T_grace`, `T_grace_bag`), per-tick chance (`P_theft`), and check-tick interval — see §6.3.4.
3. Concrete tuning numbers for embarrassment / lust / energy / stamina / pulse rates.
4. Specific ending conditions for the 90-day campaign (path level + follower thresholds).
5. Manual save in apartment: enabled or auto-save only?
6. Photo system implementation: render-to-texture vs. screenshot-with-overlay (§17.6).
7. Crowd density: full pawns vs. instanced extras with awareness-radius promotion (§17.6).
8. Modular character system specifics — base mesh, layering scheme, attachment sockets.
9. Photo-post follower decay curve and per-photo cap.
10. Stamina ↔ energy multiplier curve specifics (linear vs. eased between 0% and 80% energy, §7.4).
1. NPC theft tuning: grace periods (`T_grace`, `T_grace_bag`), per-tick chance (`P_theft`), and check-tick interval — see §6.3.4.
2. Concrete tuning numbers for embarrassment / lust / energy / stamina / pulse rates.
3. Specific ending conditions for the 90-day campaign (path level + follower thresholds).
4. Manual save in apartment: enabled or auto-save only?
5. Photo system implementation: render-to-texture vs. screenshot-with-overlay (§17.6).
6. Crowd density: full pawns vs. instanced extras with awareness-radius promotion (§17.6).
7. Modular character system specifics — base mesh, layering scheme, attachment sockets.
8. Photo-post follower decay curve and per-photo cap.
9. Stamina ↔ energy multiplier curve specifics (linear vs. eased between 0% and 80% energy, §7.4).
10. Phone battery tuning (§9.8): passive base drain rate, per-app multipliers, total capacity (target ~real-time minutes of livestream), apartment-charger recharge rate, powerbank restore percentage, and powerbank price.
11. Livestream tip-request tuning (§9.1.1): request frequency curve vs. viewer count, tip-size distribution (including high-roller frequency), countdown length on the accept popup, and the per-failure viewer-count drop magnitude.
12. Face-cover recognition resistance per slot (§7.6, §6.5): per-slot resistance magnitudes for `Face` and `Eyes` and the stacking curve.
13. Food tuning (§6.7): instant-effect amounts (energy restore, lust decrease), per-buff durations and magnitudes, per-type stacking caps, and the cooking-minigame scoring → buff-strength curve.
---