Enhanced experience
Browse files
app.py
CHANGED
|
@@ -32,6 +32,39 @@ ZONE_PROFILES = [
|
|
| 32 |
"hotel corridors with patterned wallpaper and no visible stairs",
|
| 33 |
]
|
| 34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
DIRECTIONS = {
|
| 36 |
"north": (0, 1),
|
| 37 |
"n": (0, 1),
|
|
@@ -187,6 +220,7 @@ def apply_turn(state: dict[str, Any], user_input: str) -> dict[str, Any]:
|
|
| 187 |
|
| 188 |
encounter_chance = min(0.45, max(0.03, (100 - state["sanity"]) / 260))
|
| 189 |
entity_present = rng.random() < encounter_chance
|
|
|
|
| 190 |
if entity_present:
|
| 191 |
base_loss += rng.choice([2, 3, 4])
|
| 192 |
|
|
@@ -201,17 +235,9 @@ def apply_turn(state: dict[str, Any], user_input: str) -> dict[str, Any]:
|
|
| 201 |
"action": action,
|
| 202 |
"moved": delta != (0, 0),
|
| 203 |
"entity_present": entity_present,
|
| 204 |
-
"encounter_hint":
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
"a soft impact behind the wall",
|
| 208 |
-
"footsteps that stop when you stop",
|
| 209 |
-
"a shape glimpsed through a doorway",
|
| 210 |
-
"breathing from an unlit corridor",
|
| 211 |
-
]
|
| 212 |
-
)
|
| 213 |
-
if entity_present
|
| 214 |
-
else "none",
|
| 215 |
"sanity_loss": base_loss,
|
| 216 |
"zone": zone_profile(state["x"], state["y"]),
|
| 217 |
}
|
|
@@ -238,13 +264,16 @@ Hidden state:
|
|
| 238 |
- Player action: {user_input!r}
|
| 239 |
- Action classification: {turn["action"]}
|
| 240 |
- Entity encounter: {turn["encounter_hint"]}
|
|
|
|
|
|
|
| 241 |
- Sanity erosion this turn: {turn["sanity_loss"]}
|
| 242 |
- Prior event: {state["last_event"]}
|
| 243 |
|
| 244 |
Narration task:
|
| 245 |
Write 2-5 sentences in second person.
|
| 246 |
Describe the immediate result of the action and the environment.
|
| 247 |
-
If an entity encounter is not "none", imply danger
|
|
|
|
| 248 |
If sanity is low, make perception less reliable without naming sanity.
|
| 249 |
Do not invent inventory, explicit exits, UI commands, or system facts.
|
| 250 |
End with a subtle opening for the next action.
|
|
|
|
| 32 |
"hotel corridors with patterned wallpaper and no visible stairs",
|
| 33 |
]
|
| 34 |
|
| 35 |
+
ENTITY_PRESSURES = [
|
| 36 |
+
{
|
| 37 |
+
"name": "acoustic mismatch",
|
| 38 |
+
"hint": "the room tone drops out for half a second, then returns too loud",
|
| 39 |
+
"instruction": "Use a subtle change in sound or silence; avoid saying anything is watching.",
|
| 40 |
+
},
|
| 41 |
+
{
|
| 42 |
+
"name": "impossible maintenance",
|
| 43 |
+
"hint": "a fresh wet-floor sign stands where the floor is bone dry",
|
| 44 |
+
"instruction": "Use a mundane object that is newly wrong; do not make the threat visible.",
|
| 45 |
+
},
|
| 46 |
+
{
|
| 47 |
+
"name": "light lag",
|
| 48 |
+
"hint": "the fluorescent panels brighten one corridor behind the player",
|
| 49 |
+
"instruction": "Use delayed light or shadow behavior; keep it ambiguous.",
|
| 50 |
+
},
|
| 51 |
+
{
|
| 52 |
+
"name": "spatial edit",
|
| 53 |
+
"hint": "a doorway seems to have been moved a few inches while no one looked",
|
| 54 |
+
"instruction": "Use architecture changing by a small amount; avoid direct pursuit language.",
|
| 55 |
+
},
|
| 56 |
+
{
|
| 57 |
+
"name": "borrowed voice",
|
| 58 |
+
"hint": "a voice repeats the last word the player thought, not the last one spoken",
|
| 59 |
+
"instruction": "Use a brief auditory intrusion; do not identify a speaker.",
|
| 60 |
+
},
|
| 61 |
+
{
|
| 62 |
+
"name": "texture error",
|
| 63 |
+
"hint": "the wallpaper pattern misaligns like a copied image pasted over itself",
|
| 64 |
+
"instruction": "Use a visual flaw in the environment; make it quietly disturbing.",
|
| 65 |
+
},
|
| 66 |
+
]
|
| 67 |
+
|
| 68 |
DIRECTIONS = {
|
| 69 |
"north": (0, 1),
|
| 70 |
"n": (0, 1),
|
|
|
|
| 220 |
|
| 221 |
encounter_chance = min(0.45, max(0.03, (100 - state["sanity"]) / 260))
|
| 222 |
entity_present = rng.random() < encounter_chance
|
| 223 |
+
pressure = rng.choice(ENTITY_PRESSURES) if entity_present else None
|
| 224 |
if entity_present:
|
| 225 |
base_loss += rng.choice([2, 3, 4])
|
| 226 |
|
|
|
|
| 235 |
"action": action,
|
| 236 |
"moved": delta != (0, 0),
|
| 237 |
"entity_present": entity_present,
|
| 238 |
+
"encounter_hint": pressure["hint"] if pressure else "none",
|
| 239 |
+
"encounter_mode": pressure["name"] if pressure else "none",
|
| 240 |
+
"encounter_instruction": pressure["instruction"] if pressure else "none",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 241 |
"sanity_loss": base_loss,
|
| 242 |
"zone": zone_profile(state["x"], state["y"]),
|
| 243 |
}
|
|
|
|
| 264 |
- Player action: {user_input!r}
|
| 265 |
- Action classification: {turn["action"]}
|
| 266 |
- Entity encounter: {turn["encounter_hint"]}
|
| 267 |
+
- Encounter mode: {turn["encounter_mode"]}
|
| 268 |
+
- Encounter narration note: {turn["encounter_instruction"]}
|
| 269 |
- Sanity erosion this turn: {turn["sanity_loss"]}
|
| 270 |
- Prior event: {state["last_event"]}
|
| 271 |
|
| 272 |
Narration task:
|
| 273 |
Write 2-5 sentences in second person.
|
| 274 |
Describe the immediate result of the action and the environment.
|
| 275 |
+
If an entity encounter is not "none", imply danger using the encounter narration
|
| 276 |
+
note. Do not repeat stock phrases like "it is watching" or "you are getting closer."
|
| 277 |
If sanity is low, make perception less reliable without naming sanity.
|
| 278 |
Do not invent inventory, explicit exits, UI commands, or system facts.
|
| 279 |
End with a subtle opening for the next action.
|