Updated plan

This commit is contained in:
2026-05-24 14:44:13 +03:00
parent d286b9bdb4
commit 45187450ef
2 changed files with 210 additions and 44 deletions
+62 -18
View File
@@ -13,7 +13,7 @@ State of the C++ module as of the latest pass. File references use `Source/Naked
### 1.1 Implemented
- **Item identity scaffold (GDD §6.1)** — `Items/ItemInstance.h` defines `UItemInstance` as an abstract `UObject` with a stable `FGuid InstanceID`, auto-assigned in `PostInitProperties` and refreshed in `PostDuplicate`. `Clothing/ClothingItemInstance.h` inherits from it and holds per-instance `Condition`, a pointer to the immutable `UClothingItem` definition, and a `StoredItems` array for container slots.
- **Definition / instance split (GDD §6.1, §17.4)** — `Clothing/ClothingItem.h` is the immutable `UPrimaryDataAsset` definition with GDD-aligned fields: `Coverage`, `IsUnderwear`, `CanExpose`, `IsRestrictive`, `ContainerSlots` (typed S/M/L via `EGarmentContainerSlotType` + `FGarmentContainerSlot`), `ProgressionPath`, plus rendering data (`SkeletalMesh`, `Materials`, `StaticMesh`).
- **Definition / instance split (GDD §6.1, §17.4)** — `Clothing/ClothingItem.h` is the immutable `UPrimaryDataAsset` definition. Most fields align with the current GDD: `Coverage`, `CanExpose`, `ContainerSlots` (typed S/M/L via `EGarmentContainerSlotType` + `FGarmentContainerSlot`), `ProgressionPath`, plus rendering data (`SkeletalMesh`, `Materials`, `StaticMesh`). The `IsUnderwear` and `IsRestrictive` fields also exist but **no longer match the locked spec** (§20 #20, §20 #21) — see §1.4 for the removal / migration work.
- **Progression path enum (GDD §5)** — `Progression/ProgressionPath.h` defines `EProgressionPath { None, Slut, Exhibitionist, Slave }`. Used on `UClothingItem::ProgressionPath`.
- **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.
@@ -33,7 +33,7 @@ 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 (§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.
- **Coverage (§6.3.2)** — `UClothingItem::Coverage` exists; `ClothingManager::IsBodyTypeExposed` (`ClothingManager.cpp:14-25`) is still binary. No `GetEffectiveCoverage(EBodyPart)` function. **The locked formula is now `max(coverage)` across garments covering a body part** — not sum, and no underwear halving (§20 #20). `UClothingItem::IsUnderwear` is dead spec and should be removed during the Phase 1 cleanup.
- **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, 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).
@@ -57,7 +57,7 @@ State of the C++ module as of the latest pass. File references use `Source/Naked
- **Theft (§6.3.4)** — new chance-based model (per-tick `P_theft` after grace period) not implemented. No theft timer / probability code at all.
- **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.
- **Restrictions system (§6.3.7 / §10.4.1)** — `IsRestrictive` boolean exists on `UClothingItem` but is now stale spec. The locked design is a **per-item `restrictions` list** with granular entries (`BlockRun`, `BlockCrouch`, `BlockPhoneUse`, `BlockItemPickup`, `BlockMasturbate`, `BlockExposeAction`, and parameterized `BlockSlotChange(slot)`). No code enforcement of any restriction flag; no Key-based unlock flow; no DBD-style unlock minigame (§10.4.1).
- **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.
@@ -66,6 +66,14 @@ State of the C++ module as of the latest pass. File references use `Source/Naked
- **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).
- **Hunger / max-energy decay (§7.3)** — absent. The new model has two layers of max energy: **base max** (gym progression) and **effective max** (decays via hunger). Eating any food restores effective max to base max as a universal built-in effect. Sleep does **not** clear hunger. `StatsManager` currently has only `MaxEnergy = 1000.0f` (`StatsManager.h:20`) — no hunger field, no decay tick, no eat-restores-hunger hook.
- **Police chase loss precedence (§4.4)** — when a chase is active and another loss fires, capture wins. No code logic for this yet (no chase exists, no precedence resolution in the loss path).
- **Holding-cell cutscene (§4.4)** — short non-interactive cutscene played when police capture and player can't pay. Time fast-forwards to next morning. Replaces the earlier "skip days proportional to debt" prose. Absent in code (no capture path exists yet).
- **Casino (§10.4.2)** — entire new location. Main floor (slots, blackjack, roulette), VIP room with per-day entrance fee, strip-game variants of blackjack and roulette that bet clothing items, lost-and-found inventory that retains `UItemInstance` identity for lost garments, mixed pacing (slots instant; table games burn in-game minutes), no poker. Significant scope: 3 minigames + VIP gating + strip-bet flow + lost-and-found UI.
- **Phone models + Electronics Shop (§9.9 / §10.4)** — three-tier phone (Starter / Mid / Pro) with three stat axes per tier (`camera quality`, `livestream quality`, `battery capacity`). New Electronics Shop location sells Mid and Pro. **Player can own multiple phones simultaneously**; only the equipped phone is active. Battery is per-phone-instance; hot-swap at the apartment wardrobe. Profile-side state (gallery, followers, history) does not move when swapping phones.
- **Restraint unlock minigame (§10.4.1)** — DBD-style skill checks. Successful hits speed up removal; misses have no penalty; no fail state. Restraint always comes off when the baseline timer expires. Absent (no restraint flow exists).
- **Instant commission rewards (§13.1 / §13.2 / §3.1 / §4.3)** — money / XP / followers credit at the moment of commission completion, not on return home. `UMissionsManager::CollectRewards` (`MissionsManager.cpp:35-51`) currently batches rewards into a manual "collect" call — this needs to be replaced with immediate crediting on `OnMissionCompleted`.
- **Hiding spots for ground items (§6.3.4)** — new bullet in the GDD that adds a hiding-spot concept; collides with the §4.4 "sleep = guaranteed loss" rule. Spec needs clarification before code (see Working notes).
- **GAS adoption (§17.2)** — `StatsManager` is still a bespoke `UActorComponent`; no `UAttributeSet`, no `GameplayEffect`-driven modifiers.
### 1.4 Conflicts to resolve
@@ -111,6 +119,9 @@ State of the C++ module as of the latest pass. File references use `Source/Naked
- **`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.
- **`UClothingItem::IsUnderwear` is dead spec** — `ClothingItem.h:82`. The locked design (§20 #20) drops the field entirely; `coverage` is authored directly to reflect the "just underwear" discount. Remove the field and any references during Phase 1.
- **`UClothingItem::IsRestrictive` is dead spec** — `ClothingItem.h:76`. The locked design (§20 #21) replaces the boolean with a granular `restrictions` list. Remove the boolean and add a `TArray<FClothingRestriction>` (or equivalent) supporting `BlockRun`, `BlockCrouch`, `BlockPhoneUse`, `BlockItemPickup`, `BlockMasturbate`, `BlockExposeAction`, and `BlockSlotChange(slot)`. Restriction evaluation is the union across all equipped items.
- **`UClothingItem` per-body-part coverage TODO is now resolved against** — `ClothingItem.h:61` carries `// TODO: Add coverage per body part`. The locked spec uses a single `coverage` value per item (multi body parts via `covers` set + `max()` formula, §6.3.2). The TODO comment should be removed; per-body-part coverage is intentionally not the model.
- **`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.
@@ -118,18 +129,25 @@ State of the C++ module as of the latest pass. File references use `Source/Naked
- **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.
- **Police chase precedence (§4.4):** if a chase is active when any other loss fires, the loss resolves as police capture — chase wins.
- **Police capture, can't pay (§4.4):** short non-interactive holding-cell cutscene + time skip to next morning. Replaces the earlier "skip days proportional to debt" model.
- **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).
- **Sleep** is the deterministic side of clothing loss — guaranteed loss of every clothing item left outside the apartment (§4.4). Hiding-spots bullet in §6.3.4 currently contradicts this — see Working notes.
- **No Helper NPC**; restraint removal is **Key + timed-unlock action with a DBD-style skill-check minigame** (§10.4.1). Successful checks speed up removal; missed checks have no penalty; restraint always comes off when the baseline timer expires.
- **Per-item `restrictions` list** replaces `IsRestrictive` boolean (§6.3.7). Granular vocabulary: `BlockRun`, `BlockCrouch`, `BlockPhoneUse`, `BlockItemPickup`, `BlockMasturbate`, `BlockExposeAction`, parameterized `BlockSlotChange(slot)`. Restrictions union across equipped items.
- **Coverage math** is `max()` across garments covering a body part — not sum. No underwear halving; the `IsUnderwear` flag is removed entirely (§6.3.2).
- **Hunger / max-energy decay (§7.3):** two-layer max energy — base (gym) and effective (decays via hunger, restored by eating). Eating any food triggers the restoration as a universal built-in effect. Sleep does not clear hunger.
- **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). (Note: the README has a current contradiction about home-masturbation for non-Slut players — see Working notes.)
- **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 lifecycle:** explicit Accept required for daily *and* weekly; un-accepted commissions carry no penalty; weekly rewards now include followers (§13.1 / §13.2). **Rewards land instantly on completion** — money / XP / followers credit at the moment the commission completes; no return-to-home "collect rewards" step. Replace the manual `UMissionsManager::CollectRewards` flow with immediate crediting on `OnMissionCompleted`.
- **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).
- **Phone models (§9.9):** three tiers with three stat axes each (camera quality, livestream quality, battery capacity). Bought at the new Electronics Shop. Player may own multiple phones; gallery / followers / stats live on the profile (not the phone); battery is per-phone-instance.
- **Casino (§10.4 / §10.4.2):** main floor (slots / blackjack / roulette, money only), VIP room (per-day entrance fee), strip-game blackjack and roulette tables in VIP that bet clothing. Lost garments go to a casino lost-and-found inventory that retains `UItemInstance` identity. Mixed pacing.
- **Locations locked for launch:** Beach + Train Station + Casino + Electronics Shop 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 (energy restore, lust decrease) + 4 timed buffs (stamina regen +, max stamina +, embarrassment-gain resistance, lust-gain resistance); same-type stacks additively up to a cap; never poison (§6.7). Plus the universal "eating restores effective max energy" hunger reset.
---
@@ -157,6 +175,8 @@ Phase estimates are rough and assume one engineer. Adjust as we go.
- **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.
- **Drop dead spec from `UClothingItem`**: remove `IsUnderwear` (`ClothingItem.h:82`) and `IsRestrictive` (`ClothingItem.h:76`); remove the `// TODO: Add coverage per body part` comment on line 61 (resolved against — single `coverage` is locked spec).
- **Replace `IsRestrictive` with a `restrictions` list** on `UClothingItem`: `TArray<FClothingRestriction>` (struct with `ERestrictionType` enum + optional `EClothingSlotType` parameter for `BlockSlotChange`). No runtime enforcement yet (Phase 4 / 10 own that) — Phase 1 just needs the data field, the struct, and the enum.
- 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.
@@ -180,12 +200,14 @@ Phase estimates are rough and assume one engineer. Adjust as we go.
- `USessionManager` (subsystem on `UNakedDesireGameInstance` or a `UWorldSubsystem`). Apartment `ALocationTrigger` flag drives session start / end. Emits `OnSessionStart` / `OnSessionEnd` with cause.
- `USessionLossResolver` — single class, one method `ResolveLoss(ESessionLossCause Cause)`. Implements GDD §4.4:
- **Police chase precedence**: if a chase is active (between detection and the disengage timer, §10.3), force `Cause = PoliceCapture` regardless of what triggered the loss. Chase always wins.
- Equipped clothing **stays** equipped (do not strip).
- Bag placed in world: mark its world record for deletion.
- 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`.
- **Police capture (can pay)**: fade to apartment, deduct money penalty, clear `wanted`.
- **Police capture (can't pay)**: short non-interactive holding-cell cutscene; time fast-forwards to next morning; debt settled; clear `wanted`. Already-accepted commissions still expire at day end with their normal `failurePenalty` — the cutscene does not pause the day clock.
- Wire `StatsManager::IncreaseEmbarrassment` max-hit and energy-zero into `USessionLossResolver`. Replace `EndGameEmbarrassed` BP-event with the C++ path.
- Add a debug overlay showing the current loss state and what would be lost if a given cause fired.
@@ -195,7 +217,8 @@ Phase estimates are rough and assume one engineer. Adjust as we go.
- 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`.
- **Hunger / max-energy decay (§7.3):** add a second layer to max energy. `baseMaxEnergy` (gym progression) stays; introduce `effectiveMaxEnergy` (decays at `maxEnergyDecayRate` per in-game hour toward a floor). Eating any food sets `effectiveMaxEnergy` back to `baseMaxEnergy` as a universal hook in the eat-item flow. Sleep does **not** reset hunger. Health Tracker (§9.7) surfaces effective max alongside current energy.
- Implement `GetEffectiveCoverage(EBodyPart)` on `ClothingManager` per §6.3.2 — **`max()` across garments covering the part** (no sum, no underwear halving). 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).
@@ -210,7 +233,7 @@ Phase estimates are rough and assume one engineer. Adjust as we go.
### 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`).
- 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.
- Sleep action on apartment bed: triggers the same path as energy-zero (§4.4) for the "items left outside" cleanup, restores energy (clamped to current effective max), autosaves, advances calendar. **Charges the equipped phone to 100%** (§9.8). **Does NOT reset hunger** (§7.3) — only eating clears effective-max decay.
- 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.
@@ -243,9 +266,10 @@ Phase estimates are rough and assume one engineer. Adjust as we go.
- 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.
- **Instant rewards on completion (§13.1 / §13.2 / §3.1 / §4.3):** money wires to the bank, XP credits to the shared pool, followers update on the profile **at the moment of completion** — not on return home. Replace the current `UMissionsManager::CollectRewards` batched flow with immediate crediting in `OnMissionCompleted`. There is no "collect rewards" step at the apartment.
- **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; explicit Accept committed flow works end-to-end; failed accepts deduct the template penalty; un-accepted commissions never penalize the player.
**Exit criteria:** daily commissions regenerate from templates each in-game day; weekly arc is distinct; explicit Accept committed flow works end-to-end; rewards credit instantly on completion (no return-home gate); failed accepts deduct the template penalty; un-accepted commissions never penalize the player.
### Phase 8 — Phone + forum UI + battery + livestream (34 weeks)
@@ -267,8 +291,15 @@ Phase estimates are rough and assume one engineer. Adjust as we go.
- **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.
- **Phone models + Electronics Shop (§9.9 / §10.4):**
- 3 tiers (Starter / Mid / Pro). Each is a `UClothingItem`-style data asset (or dedicated `UPhoneItem` definition) with `CameraQuality`, `LivestreamQuality`, `BatteryCapacity` multipliers.
- Starter is owned at game start. Mid and Pro are bought in-person at the new **Electronics Shop** location (interactable like Wardrobe / Adult Shop).
- Player can own multiple phones simultaneously — store them in the wardrobe / inventory as regular `UItemInstance`s. Only the equipped phone is active.
- Hot-swap from the apartment wardrobe; battery percentage is per-phone-instance and **does not transfer** on swap.
- Profile state (gallery, follower count, livestream history) lives on the player profile, never on the phone — swapping phones does not move or duplicate this state.
- `CameraQuality` multiplies `exposureScore` for photo posts (§13.5). `LivestreamQuality` multiplies per-tick `streamQualityScore`. `BatteryCapacity` multiplies the total charge budget (drain rates unchanged).
**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.
**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. Buying a Mid / Pro phone at the Electronics Shop adds it to the wardrobe; equipping it visibly improves photo / stream gain rates per the multipliers.
### Phase 9 — Path progression + content authoring (2 weeks)
@@ -285,17 +316,25 @@ Phase estimates are rough and assume one engineer. Adjust as we go.
- Bag inventory (§6.4) — uses Phase 2's `AItemActor` for world placement.
- **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).
- Universal built-in effect: every food restores effective max energy to base max (hunger reset; §7.3 hookpoint from Phase 4).
- 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.
- 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.
- **Theft model (§6.3.4)** — implement `T_grace` / `T_grace_bag` grace timers and per-tick `P_theft` chance roll. No ramp. Hiding-spot mechanic is currently spec-ambiguous (see Working notes) — coordinate before implementing.
- Expose action (§6.3.6) — read `CanExpose` per garment, blocked by overlapping coverage. Also blocked when `BlockExposeAction` is active in the restrictions set.
- **Restrictions enforcement (§6.3.7 / §10.4.1):**
- Wire each `Block*` flag into the relevant subsystem (`BlockRun` into movement, `BlockPhoneUse` into `PhoneSubsystem`, `BlockMasturbate` into the quick action, `BlockSlotChange(slot)` into `ClothingManager::PutOnClothing` / `RemoveClothing`, etc.).
- **Restraint removal:** Key + timed-unlock action with a **DBD-style skill-check minigame** (§10.4.1). Rotating pointer + target zone; hits speed up removal; misses do nothing; no fail state. Restraint always comes off when the baseline timer expires.
- **Casino (§10.4 / §10.4.2):** new location, significant scope.
- Three game UIs: slots (instant single-button), blackjack (vs. dealer NPC, in-game-minute pacing), roulette (multi-bet single spin, in-game-minute pacing). No poker.
- VIP room interactable: pay per-day entrance fee at reception; access flag clears at next day boundary.
- Strip-game blackjack and roulette tables in VIP: bet a clothing item from an equipped slot. Lost garments transfer to a **casino lost-and-found** safe inventory keyed to the player; retains `UItemInstance` identity per §6.1. Reclaim by winning back at the same table or paying a flat buy-back fee at reception.
- Wire casino income/loss into the Bank app income breakdown (§9.4).
- 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.
- 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.).
- Final tuning of all §21 numbers (theft, food caps, battery, tip-request distribution, embarrassment / lust / energy / pulse rates, face-cover magnitudes, casino RTP + VIP fee, phone-tier multipliers, restraint minigame parameters, hunger decay, etc.).
---
@@ -309,4 +348,9 @@ Use this section for in-flight decisions, blockers, and open questions that emer
- **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.
- **Hunger hookpoint also belongs in Phase 4.** Add `effectiveMaxEnergy` + decay tick when adding Lust / Pulse / etc., so Phase 10's food items only need to call an existing reset method.
- **README contradiction — follower income cadence.** §7.9 line 433 says "Followers generate money each day"; §9.4 and §13.3 say weekly auto-deposit at week boundary. Don't pick one in code until the GDD is reconciled. Phase 5 implementation depends on resolution.
- **README contradiction — hiding spots vs sleep loss.** §6.3.4's new "Hiding spots" bullet says items have a *chance* of theft after sleep, but §4.4 says sleep = guaranteed loss of anything outside. Phase 10 theft work must wait until the GDD resolves whether hiding spots are an explicit exception to the sleep rule or only affect in-session theft chance.
- **README contradiction — masturbation gating.** §7.2 says non-Slut players "must accept the max-lust handicaps... until they go home and masturbate in home before sleep" — but §5.1 has masturbation as a Slut-path unlock. Phase 4 masturbate-action work needs the spec reconciled: either home masturbation is universally available (with public masturbation gated by path) or non-Slut players cannot masturbate at all.
- **Stale §5.3 Slave path text** in the README still says "(cuffs require NPC help to remove)" — contradicts the Key + minigame removal flow. Phase 6 / Phase 10 work should not implement an NPC removal path; if encountered, treat it as stale documentation.
- _empty beyond this point_
+148 -26
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, a train station, a gym, a beauty salon, multiple shop types, the player's apartment. See §10.4 for the locked location list.
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 casino, a gym, a beauty salon, an electronics shop, multiple other 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.
@@ -58,8 +58,8 @@ Sexual, playful, transgressive. The player character is a willing participant, n
2. Plan: check commissions, check bank, check pending deliveries, check news/recognition.
3. Equip outfit from wardrobe. Pack bag (optional).
4. Leave the house → **session begins**.
5. Travel to commission locations, complete tasks, manage attributes.
6. Return home → **session ends**, rewards finalized, optional sleep.
5. Travel to commission locations, complete tasks, manage attributes. Each completion immediately wires money to the bank, credits XP, and updates followers — no return-to-home collection step.
6. Return home → **session ends**, optional sleep.
7. Spend earnings (shops, gym, beauty salon), level up attributes, post photos.
8. Repeat. Pay rent at end of week.
@@ -88,10 +88,14 @@ Triggered by leaving the apartment. Snapshots current equipment, attributes, and
- The player can freely re-enter the apartment to safely end the session at any time.
### 4.3 Session end (safe)
Player returns home. All carried items persist. Rewards from completed commissions are finalized. Embarrassment resets toward baseline. If a Snitch reported the player to police during the session (§10.2), the player keeps the `wanted` tag even after a safe return — see §7.7.
Player returns home. All carried items persist. Embarrassment resets toward baseline. Commission rewards (money, XP, followers) are *not* finalized at session end — they were already credited at the moment each commission completed (§13.1 / §13.2). If a Snitch reported the player to police during the session (§10.2), the player keeps the `wanted` tag even after a safe return — see §7.7.
### 4.4 Session end (loss)
Triggered by any session-loss condition (§3.3). On loss:
Triggered by any session-loss condition (§3.3).
**Precedence — police chase wins.** If the player is being actively chased by police (between detection and the disengage timer, §10.3) at the moment another loss condition fires, the loss is **always resolved as police capture**. The cops catch them as they collapse or freeze; the chase outcome supersedes embarrassment-max and energy-zero outcomes (including the energy-zero sleep cutscene). This applies whether or not the player has the `wanted` tag in advance — being mid-chase is the trigger, not the tag.
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. No extra cost beyond the session loss itself (no time skip, no money penalty, no reputation hit).
@@ -101,7 +105,7 @@ Triggered by any session-loss condition (§3.3). On loss:
- **Unequipped clothing left on the ground** can be lost two ways:
1. **In-session theft** — a chance-based roll while the player is away from the item. See §6.3.4 for the model.
2. **Sleep** — any clothing left outside the apartment when the player sleeps is **guaranteed** lost. This fires both for the energy-zero cutscene (forced sleep) and for voluntary sleep at home with items still outside.
- **Police capture** during pursuit applies a money penalty. If the player can't cover it, they skip days until the debt clears; the number of skipped days scales with the unpaid amount. Capture also clears the `wanted` tag (§7.7).
- **Police capture** during pursuit applies a money penalty. If the player can cover it, the debt is paid and they are returned to the apartment. If they **can't cover it**, a short cutscene plays of the player in a **holding cell**, then time fast-forwards to the next in-game morning — the night served settles the penalty, no money is owed afterward. The cutscene is non-interactive; the player does not actually inhabit the cell. Capture clears the `wanted` tag (§7.7) in either case. Already-accepted commissions still expire at day end with their normal `failurePenalty` (§13.4); the cutscene does not pause that clock.
> **Implementation note:** session loss must be a clearly defined transactional state. All "what gets lost" logic should live in a single SessionLossResolver to keep this deterministic and debuggable.
@@ -145,7 +149,7 @@ Each path has a level (e.g., 110). Level gates clothing, missions, and attrib
### 6.2 Carriable item categories
- **Clothing** (§6.3)
- **Bags** (§6.4)
- **Phone** (one — special, §9)
- **Phone** (one active at a time, but the player may own multiple models simultaneously — §9, §9.9)
- **Consumables** (food, §6.7)
- **Toys** — sex toys for the toy slots (§6.5). Bought at the Adult Shop (§10.4).
@@ -157,11 +161,10 @@ Attributes per clothing instance:
- `covers` — set of body parts: `{ boobs, ass, genitals, ... }`.
- `progressionPath` — Slut / Exhibitionist / Slave / None.
- `color` — primary color enum.
- `coverage` — float [0,1].
- `isUnderwear` — bool. If true, effective coverage = `coverage / 2`.
- `coverage` — float [0,1]. Authored per item to reflect how much it conceals — including the psychological "this is just underwear" discount. There is no separate underwear flag; an item in `UnderwearTop` / `UnderwearBottom` is simply authored with a lower `coverage` than a similarly-sized non-underwear garment.
- `condition` — float [0,1]. Starts at 1.0 (new). Decreases via §6.3.4.
- `canExpose` — list of body parts this garment can momentarily reveal without unequipping (e.g., coat → boobs, ass).
- `isRestrictive`bool. If true, restricts hand use; requires NPC to remove.
- `restrictions`list of restriction entries that fire while this item is equipped (e.g., wrist cuffs block phone use and changing top clothing; ankle cuffs block running). Most items have an empty list. See §6.3.7 for the full vocabulary.
- `containerSlots` — optional inventory (e.g., pants pocket for phone).
#### 6.3.1 Container slots
@@ -171,10 +174,12 @@ Container slot allows player to carry items there.
#### 6.3.2 Coverage resolution
For each body part `b`:
- Find the set of equipped garments covering `b`.
- Effective coverage of `b` = `min(max(effectiveCoverage of garments covering b), 100%)` where `effectiveCoverage = isUnderwear ? coverage/2 : coverage`.
- Find the set of equipped garments whose `covers` set includes `b`.
- Effective coverage of `b` = `max(coverage of garments covering b)`. Only the highest-coverage garment per body part counts; layering does not stack.
- Body part is "exposed" if effective coverage = 0.
- Lower total coverage → faster embarrassment gain when observed (§7.1).
- Lower coverage → faster embarrassment gain when observed (§7.1).
Authoring guidance: underwear in `UnderwearTop` / `UnderwearBottom` should be authored with lower `coverage` than equivalently-shaped outerwear in `Top` / `Bottom`, so being seen in just underwear correctly reads as more exposed than being seen in a thin shirt of the same physical coverage. The math itself does not special-case underwear — the value in the editor is the contribution, full stop.
#### 6.3.3 Equipping & unequipping
- Equip/unequip anywhere in the world via the quick action menu.
@@ -203,9 +208,36 @@ Theft applies to lose clothing on the ground and to bags placed in the world (se
- Blocked if another garment covers the same part (e.g., pants block coat's ass-expose).
- While exposed, the body part counts as fully uncovered for embarrassment math.
#### 6.3.7 Restrictive clothing*
- Cuffs, restrain bars and similar items lock hand-dependent actions (using phone, picking up items, masturbating).
- Can be removed by having key and spending some time to remove it.
#### 6.3.7 Restrictions
Each clothing item carries an optional `restrictions` list. Most items have none. Restraint-slot items (§6.5 slots 1315) declare meaningful lists; a few non-restraint items (heels, tight skirts) can declare lighter restrictions too.
Restrictions are the union of all entries on all equipped items — any restraint that declares a given flag activates it for the player, regardless of which equipped item provides it.
Vocabulary:
| Restriction | Effect while at least one equipped item declares it |
|--------------------------|------------------------------------------------------------------------------------------------------------------|
| `BlockRun` | Player cannot run. Movement capped at walk speed. |
| `BlockCrouch` | Player cannot enter the crouch state. |
| `BlockPhoneUse` | The phone (§9) is unusable — no apps, no camera, no livestream, even when in hand / pocket / bag. |
| `BlockItemPickup` | Cannot pick up world items. |
| `BlockMasturbate` | The masturbate quick action (§14.1) is disabled. A commission objective requiring masturbation cannot progress until cleared. |
| `BlockExposeAction` | The per-garment expose action (§6.3.6) is disabled. |
| `BlockSlotChange(slot)` | The named equipment slot cannot be (un)equipped while the declaring item is on. Multiple `BlockSlotChange(...)` entries on one item are allowed and stack. |
Authored examples:
- **Wrist cuffs** (`WristRestraint`): `BlockPhoneUse`, `BlockItemPickup`, `BlockMasturbate`, `BlockExposeAction`, `BlockSlotChange(Top)`, `BlockSlotChange(Outerwear)`, `BlockSlotChange(UnderwearTop)`, `BlockSlotChange(Bodysuit)`.
- **Ankle cuffs** (`AnkleRestraint`): `BlockRun`, `BlockSlotChange(Bottom)`, `BlockSlotChange(Footwear)`, `BlockSlotChange(Socks)`, `BlockSlotChange(UnderwearBottom)`.
- **Spreader bar** (`AnkleRestraint`): same as ankle cuffs, plus `BlockCrouch`.
- **High heels** (`Footwear`, non-restraint): `BlockRun` only.
- **Tight pencil skirt** (`Bottom`, non-restraint): `BlockRun`, `BlockCrouch`.
**Removal:**
- Restraint-slot items typically declare `BlockSlotChange(<their-own-slot>)`, which means the player cannot remove them via normal unequip. These require the Key + timed-unlock action in §10.4.1.
- Non-restraint restrictive items (heels, skirts) remove via normal unequip as long as no other equipped item is blocking the slot change.
**Commission interaction:** an accepted commission whose objective needs a blocked action (e.g., `PerformAction(masturbate)` with `BlockMasturbate` active) does not auto-fail; it simply cannot progress until the restriction is cleared. The commission's day / week deadline still applies normally.
### 6.4 Bags
- Bag is an equippable item with its own inventory.
@@ -265,7 +297,7 @@ Sex toys are bought from the Adult Shop (§10.4) and follow the standard item-id
#### Other equipment
- **Bag slot** — 1 (see §6.4).
- **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).
- **Hand slot** — 1. Holds one carriable item at a time (phone, food, key, etc.). Hand-dependent actions (phone use, item pickup, masturbate, expose action) are disabled when an equipped item declares the corresponding `Block*` restriction (§6.3.7); wrist cuffs are the canonical case.
#### 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.
@@ -285,8 +317,11 @@ Sex toys are bought from the Adult Shop (§10.4) and follow the standard item-id
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).
**Built-in effect** (applies on any eating action, not per-food authored):
- **Effective max energy fully restored** — eating resets the hunger decay (§7.3). Effective max energy returns to the base max. This effect is universal — every food, no matter how small, fully clears hunger.
**Instant effects** (one-shot on consumption, no timer, per-food authored):
- **Energy restore** — adds a fixed amount of current energy (§7.3), clamped to the (just-restored) effective max.
- **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):
@@ -345,8 +380,15 @@ All attributes update in real time. Indoor and outdoor behavior is identical —
- `energyDrainMasturbateModifier` (masturbation)
- Recovered during sleep at `energyRecoveryRate`.
- Hard floor at 0 → session lost.
- Max raised by gym training.
- Low energy reduces effective max stamina (see §7.4).
- Low effective energy reduces effective max stamina (see §7.4).
**Max energy has two layers:**
- **Base max energy** — the player's underlying ceiling. Raised by gym training (the progression lever).
- **Effective max energy** — the *current* ceiling on energy. This is what the player's energy bar can actually reach. Effective max **decays over time** at a hunger rate (`maxEnergyDecayRate`, TBD per §21), down to a floor (TBD, expressed as a fraction of base max) so the player is never fully starved into a forced game-over.
- **Eating any food (§6.7) restores effective max energy fully to base max** — this restoration overrides all other buffs and is the canonical way to reset hunger. It is a built-in effect of the eating action, not a per-food authored flag; every food does it.
- Recovered energy (sleep, instant-restore foods) is always clamped to effective max — sleeping does not also reset hunger; only eating does.
Together these mean a player who never eats slowly loses their available energy headroom each day, even with full sleep. The 90-day campaign forces a steady food cadence rather than allowing pure sleep cycling.
### 7.4 Stamina
- Used for running and other burst physical actions.
@@ -419,12 +461,14 @@ The phone is battery-powered (§9.8). A dead phone is unusable until charged —
- **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.
- All photos saved to **Gallery**.
- Photo follower gain is multiplied by the equipped phone's **camera quality** stat (§9.9). Better phone → more followers per equivalent shot.
### 9.1.1 Livestream
- 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.
- `streamQualityScore` is multiplied by the equipped phone's **livestream quality** stat (§9.9). Better phone → higher donation rate and faster follower trickle from an identical scene.
- 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 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.
@@ -453,6 +497,7 @@ 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).
- Shows **effective max energy** alongside current energy so the player can read hunger state (§7.3) — the gap between base max and effective max is the "how hungry am I" signal.
### 9.8 Battery
The phone has a finite battery that drains while powered on and recharges at the apartment.
@@ -472,6 +517,31 @@ The phone has a finite battery that drains while powered on and recharges at the
- 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.
- **Capacity scales with phone tier** — total charge budget is multiplied by the equipped phone's **battery capacity** stat (§9.9). Per-app drain rates are unchanged; a Pro phone simply has more battery to spend.
### 9.9 Phone models
Three phone models exist. The starter model is owned at game start; the other two are purchased at the **Electronics Shop** (§10.4). The player may **own multiple phones simultaneously** — they are regular `UItemInstance` items (§6.1) that live in the wardrobe / inventory, and only the *equipped* phone is active per the §9 usage rules.
| Tier | Model name | Camera quality | Livestream quality | Battery capacity | Source |
|------|-----------|----------------|--------------------|------------------|-----------------------|
| 1 | Starter | 1.0× | 1.0× | 1.0× | Owned at game start |
| 2 | Mid | > 1.0× (TBD) | > 1.0× (TBD) | > 1.0× (TBD) | Electronics Shop |
| 3 | Pro | highest (TBD) | highest (TBD) | highest (TBD) | Electronics Shop |
Stat axes:
- **Camera quality** — multiplier on the `exposureScore` input to `FollowerGainCalculator` (§13.5) when posting a photo. A better camera turns the same scene into a higher-follower-gain photo.
- **Livestream quality** — multiplier on the per-tick `streamQualityScore` (§9.1.1). Better optics + mic → higher donation rate and faster follower trickle.
- **Battery capacity** — multiplier on total charge budget (§9.8). Per-app drain rates are unchanged; the better phone simply runs longer between charges.
The multipliers apply to **new** photos and stream ticks only. Buying a Pro phone never retroactively improves a tier-1 photo already posted.
**Switching phones:**
- Hot-swap at the apartment wardrobe. Equipping a different phone moves the previously-equipped phone back to the wardrobe.
- **Battery percentage is per-phone-instance.** Swapping does not transfer charge — a Pro phone left uncharged stays uncharged when you swap to it.
- **Gallery, livestream history, and account state live on the player profile**, not the phone. Swapping never loses photos, follower count, or stream stats.
Tier prices and exact stat multipliers are TBD per §21.
---
@@ -513,18 +583,53 @@ Sleeping at home fast-forwards 8 hours.
- **Gym** — increase max energy. Costs energy in the process. Costs money.
- **Beauty salon** — boobs size, ass size, makeup, hairstyle, hair color.
- **Adult shop** — Buy sex toys for the `Nipples`, `Anal`, and `Vagina` toy slots (§6.5).
- **Electronics shop** — Buy upgraded phone models. Sells the Mid and Pro tiers (§9.9). In-person only; no online variant.
- **Streets / parks / alleys** — commission space.
- **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.
- **Casino** — money-and-clothing gambling. Main floor + VIP room. See §10.4.2.
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**:
A restraint that blocks its own slot (i.e., declares `BlockSlotChange(<own-slot>)`, §6.3.7) cannot be removed by normal unequip and requires the **Key + timed unlock action**:
- The player must possess the matching key for the restraint instance.
- Performing the unlock takes time; movement and all other actions are disabled for the duration.
- Performing the unlock takes time; movement and all other actions are disabled for the duration. The restraint always comes off when the timer completes — the only question is *how quickly*.
- **Unlock minigame.** While the unlock action runs, a DBD-style skill-check minigame plays: a rotating pointer sweeps a circular meter that includes a small target zone, and the player presses a hotkey when the pointer crosses the zone. Each **successful hit advances the removal progress faster** than the baseline tick. **Missed checks carry no penalty** — they simply fail to grant the speed bonus, and the baseline timer keeps ticking down. There is no noise alert, no key loss, no fail state. The minigame is a pure accelerator for engaged players; impatient or unskilled players can ignore the checks and wait out the baseline timer.
- Per-restraint baseline timer length, skill-check frequency, target-zone size, and per-hit speed bonus are TBD per §21.
- There is no Helper NPC, no adult-shop unlock service, and no break-out option. If the player loses the key, the restraint stays on until a key is acquired again.
#### 10.4.2 Casino
The casino is a location for spending time and (potentially) earning money. It splits into a **main floor** (always open) and a **VIP room** (gated; see below). The house edge means the expected value per session is intentionally negative — variance is the appeal, not steady income.
**Games (main floor):**
- **Slots** — single-button pull, instant outcome. Small-to-medium bets per pull. Pure RNG; rapid chase loop. Time cost is the player's choice — keep pulling as long as you want.
- **Blackjack** — vs. a dealer NPC. Skill-light card game. Each hand burns a few in-game minutes (dealer + decision pacing).
- **Roulette** — multiple bet types on a single spin. Each round burns a couple of in-game minutes.
The mixed pacing is deliberate: slots are the "fast burn," tables are the "time investment." Spending an afternoon at blackjack visibly eats into the commission window.
**VIP room:**
- Access is **gated by a per-day entrance fee** paid at the reception. One payment grants access for the rest of the in-game day; access expires at the next day boundary and must be paid again. No permanent unlock, no progression-based gating — anyone with enough money in the bank can enter, but every visit-day costs.
- Higher bet limits (higher floor on losses, higher ceiling on wins).
- Lower NPC density and a permissive dress code — nudity is socially accepted inside the VIP room, so the few NPCs present contribute less embarrassment than the main floor would.
- Strip-game tables live exclusively in the VIP room.
- The entrance fee functions as a built-in negative EV floor — even a winning night at the tables has to clear the day's entry cost before it's net profit.
**Strip variants (VIP-only):**
- A separate set of blackjack and roulette tables let the player bet **clothing items** as stakes (in addition to, or instead of, money).
- Losing a hand transfers the bet garment from the player's equipped slot to the **casino lost-and-found** — a safe inventory at the casino reception. The garment retains its `UItemInstance` identity (§6.1); it is not destroyed.
- Reclaiming a lost garment: win it back at the same table, or buy it back at reception for a flat fee (TBD).
- Strip outcomes don't bypass the normal embarrassment model — being stripped at the table and then walking out through the VIP room (low NPC density) or the main floor (higher density) still ticks embarrassment per §7.1.
**Player attributes during casino play:**
- Casino games themselves do not drive embarrassment, lust, energy, or pulse. Only the normal observation-driven model applies based on what other NPCs in the room can see.
- Energy is not consumed by gambling actions; food, sleep, and run-driven drain remain the only energy levers.
**Economy hook:**
- Casino is both an income source and a money sink. Net EV per session is negative on average; spikes are possible.
- Casino income is logged in the Bank app's income breakdown (§9.4) as a distinct line item; net losses appear in the corresponding spending breakdown.
---
## 11. PC (at home)
@@ -563,12 +668,14 @@ The forum is accessed via phone or PC. It is both diegetic and the primary missi
- 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.
- **Rewards land instantly on completion** — money wires to the bank, XP credits to the shared pool (§7.10), and followers update on the profile. There is no return-to-home "collect rewards" step.
### 13.2 Daily commissions
- Generated at day start, semi-random, weighted by path progression.
- Rewards: money, XP, followers.
- 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.
- **Rewards land instantly on completion** — money wires to the bank (visible in §9.4 as a commission-completion line item), XP credits to the shared pool, followers update on the profile. No return-to-home step is required.
### 13.3 Profile
- View stats, progression, path levels, posted photos.
@@ -623,7 +730,7 @@ Example commissions from the brief that should be representable:
```
followerGain = base(exposureScore) * reputationFactor * (1 / log(followerCount + e))
```
- **`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).
- **`exposureScore`** is the input — for a posted photo it is computed from exposed body parts + visible coverage in that photo, then multiplied by the equipped phone's **camera quality** stat (§9.9); for a livestream tick it is the current `streamQualityScore`, which already includes the phone's **livestream quality** multiplier (§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.
@@ -671,6 +778,7 @@ Forum, bank, gallery, shops are all in-fiction screens (phone/PC). Avoid out-of-
- **Feetex shipping** — drop the item in a Feetex shipping box at the post office or convenience store. Payment arrives 1 in-game day later (mirrors Feetex's existing 1-day delivery delay).
- **Drop-off** — travel to a specified location (varies per order) and leave the underwear there. Immediate payment, but the location may be in a high-risk area depending on the order. Tactical trade-off: convenience vs. drop-off-style commission tension.
- Photo posts (indirect) and accumulated followers — drive the weekly **passive follower income** (§7.9). Higher follower count → larger weekly payout and larger commission payouts.
- **Casino winnings (§10.4.2)** — high-variance, negative-EV-on-average. Not a reliable income source; treat as gambling, not as a salary.
### 15.2 Costs
- Weekly rent — **flat across the campaign**. No escalation, no event-driven spikes. The pressure comes from the 90-day timer and other expenses, not from a moving rent target.
@@ -678,6 +786,7 @@ Forum, bank, gallery, shops are all in-fiction screens (phone/PC). Avoid out-of-
- Food / ingredients.
- Gym membership / beauty salon.
- Adult shop.
- **Casino losses (§10.4.2)** — the dominant cost over time, by design. Strip-game losses additionally cost clothing inventory (reclaimable but not free).
### 15.3 Tuning targets (placeholder)
| Tier | Daily income | Weekly rent | Notes |
@@ -771,7 +880,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, including the **Beach** and **Train Station** locations (§10.4) added on top of the vertical-slice shop set.
- Full city, 4+ districts, including the **Beach**, **Train Station**, **Casino** (main floor + VIP room), and **Electronics Shop** locations (§10.4) added on top of the vertical-slice shop set.
- 100+ commission templates.
- All 3 paths leveled to cap with distinct content.
@@ -805,10 +914,19 @@ Decisions previously open, now fixed:
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.
12. **City location list:** locked for launch. Apartment, Convenience Store, Café, Clothing Shops, Gym, Beauty Salon, Adult Shop, Electronics Shop, Streets / Parks / Alleys, **Beach**, **Train Station**, **Casino**. School exterior and hot springs (onsen) were considered and cut. Vertical slice (§18.1) covers the basic shop set; Beach, Train Station, Casino, and Electronics Shop 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.
16. **Casino:** added to the city (§10.4, §10.4.2). Main floor (slots, blackjack, roulette — money only). VIP room — **gated by a per-day entrance fee** (no permanent unlock; pay each day you want in). Permissive dress code; strip-game blackjack and roulette tables that bet clothing. No poker. Mixed pacing: slots instant, table games take in-game minutes. Net EV negative — variance is the appeal.
17. **Police capture, can't pay:** short non-interactive holding-cell cutscene, then time fast-forwards to the next morning. The night served settles the debt; no money owed afterward. Replaces the earlier "skip days proportional to unpaid amount" rule. See §4.4.
18. **Loss precedence during a police chase:** if the player is actively being chased by police (per §10.3) and any other loss condition fires (embarrassment max, energy zero), the loss resolves as **police capture** — the chase wins. The cops catch the player as they collapse. Applies even without a prior `wanted` tag. See §4.4.
19. **Phone models:** 3 tiers (Starter / Mid / Pro). Three stat axes per tier — camera quality (photo follower-gain multiplier), livestream quality (`streamQualityScore` multiplier), and battery capacity (total charge budget multiplier). Bought in-person at the new Electronics Shop (§10.4). Player may own multiple phones simultaneously; gallery / followers live on the profile, battery is per-phone-instance. See §9.9.
20. **No `isUnderwear` flag on clothing.** Coverage math no longer special-cases underwear. Authors set `coverage` directly to reflect concealment (including the psychological "just underwear" discount); the value in the editor is the contribution to coverage math. See §6.3 / §6.3.2.
21. **Per-item restrictions list replaces `isRestrictive` boolean.** Each clothing item carries an optional `restrictions` list with granular entries: `BlockRun`, `BlockCrouch`, `BlockPhoneUse`, `BlockItemPickup`, `BlockMasturbate`, `BlockExposeAction`, and parameterized `BlockSlotChange(slot)`. Restrictions union across equipped items. Restraints typically declare `BlockSlotChange(<own-slot>)` to force the §10.4.1 Key removal flow. Non-restraint items (heels, tight skirts) can declare lighter restrictions. See §6.3.7.
22. **Restraint-removal unlock minigame.** DBD-style skill-check minigame (rotating pointer + target zone). Successful hits **speed up** the removal. Missed checks have **no penalty** — they just don't grant the speed bonus. The restraint always comes off when the baseline timer expires. No noise alerts, no key loss, no fail state. See §10.4.1.
23. **Commission rewards land on completion, not on return home.** Money wires to the bank instantly, XP credits to the shared pool, followers update on the profile. No "collect rewards" step at the apartment. See §13.1 / §13.2 / §4.3 / §3.1.
24. **Hunger via max-energy decay.** Effective max energy decays over time (a hunger rate); eating any food restores effective max to base max as a built-in universal effect (no per-food authoring). Sleep restores current energy but does NOT reset hunger — only eating does. Floors at a TBD fraction of base max so the player can't be starved into a forced game-over. See §7.3 / §6.7.
## 21. Open Design Questions
@@ -827,6 +945,10 @@ These remain genuinely unresolved and should be addressed during implementation:
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.
14. Casino tuning (§10.4.2): RTP per game (slots, blackjack, roulette), bet ranges per tier (main vs. VIP), the **VIP per-day entrance fee**, in-game-minutes burned per table-game round, and the strip-garment buy-back fee.
15. Phone-tier tuning (§9.9): exact multiplier values for Mid and Pro on each of the three stat axes (camera quality, livestream quality, battery capacity), and the Electronics Shop purchase prices for each tier.
16. Restraint unlock-minigame tuning (§10.4.1): per-restraint baseline timer length, skill-check frequency, target-zone size, and per-hit speed bonus.
17. Hunger tuning (§7.3): `maxEnergyDecayRate` (effective max energy lost per in-game hour), the effective-max floor as a fraction of base max, and any per-food bonus on top of the universal full-restore (if we ever want a "big meal heals you faster" lever).
---