-
Notifications
You must be signed in to change notification settings - Fork 0
The Mirror Ideation
Status: design notes, not a commitment. This page documents
docs/ideation/mirror-and-still-here.mdon branchideation/mirror-and-still-here— not merged intomain, no code exists for it. The source document opens with "Design notes, not a commitment. Exploratory — bias toward volume over polish," and that framing applies to everything on this page. Nothing here is implemented; treat it the same way you'd treat Roadmap / Ideas — tentative, sourced from the project's own words, not from shipped code.
The ideation doc opens from a single reference image: a grimy bathroom mirror whose reflection doesn't match the person in front of it — gaunt, bloodied, scrawled with "I AM STILL HERE." The doc is explicit that this image is a tonal reference only, not a target:
This image is a tonal reference only — not something LULL builds toward literally or reproduces. It is far past LULL's line (see
CLAUDE.md§1: uncanny, not traumatizing). What we take from it: the gap between the person and what the mirror insists is still there.
That distinction — reference vs. target — is the load-bearing idea of the whole document, and it's worth reading The Safety Invariant and Concept & Design's "No genuine harm" principle alongside this page for the constraint it's being designed against.
THE MIRROR is pitched as the same premise as THE EYE — a surface that's
supposed to show you yourself, faithfully, and the horror of it lying — "in
a different costume," reusing THE EYE's actual plumbing (CameraGate,
the EyeSession-shaped phase escalation) rather than inventing new
machinery. It's proposed as a new mechanic in the THE EYE / THE ROOM /
THE REACH naming family from Concept & Design.
An escalation ladder deliberately shaped like EyeSession.Phase
(dormant → seekingConsent → watching → noticing → awake), so it could
reuse the same state-machine pattern:
- Clear — the reflection tracks the player normally; establishes trust.
- Lag — a half-second delay, easy to mistake for a frame hitch.
- Drift — the reflection stops matching exactly (a pose already broken, a hand still raised). Still deniable.
- Independence — the reflection does something the player didn't do. The first true rule break.
- Contact (the ceiling) — the reflection writes on the glass. The doc is explicit LULL does not go further than this.
Proposed player interactions: look away / look back (using
Sensor.motion — already an allowed sensor in LULLKit.Sensor today, just
unused by any mechanic yet — to catch the reflection mid-change);
wipe the mirror (a drag gesture that reveals more, never less, as the
session escalates — flagged as the cheapest interaction to prototype since
it needs no sensor at all); and avoid mirrors entirely, framed as a
fictional-level panic switch alongside the literal one — per the doc,
"the player needs an equivalent of the panic switch within the fiction,
not just the meta-level 'close the eye' button." The doc is explicit that
however it's dressed up, THE MIRROR is still Sensor.camera under the
hood, and the real ConsentLedger/panic-switch contract applies unchanged.
Proposed as a corruption of the existing Poe lines in
Atmosphere.swift's awake phase, rather than a fourth narrative register —
the doc argues a fourth voice "would dilute Kafka/Beckett/Poe's discipline."
Example given: "it knows your face now." degrading over repeat visits
toward "it knows your face now. i am still here." The doc calls for
restraint on the phrase itself — mostly heard or implied, fogged and fading
before fully legible, reserving one full visual scrawl (if it appears at
all) for a single moment near the ceiling of the escalation ladder.
The doc explicitly scopes "recurring" to within one sitting — 3–5 returns
to the same bathroom over a session, matching LULL's existing "short, one
sitting" scope from docs/concept.md §05, not a multi-session rework. It
proposes seeding each return from EyeSession.elapsed /
Atmosphere.beat(forElapsed:) — the same clock LULLKit already has — and
sketches a 5-row config table of small, deterministic deltas per return
(condensation, a scratch mark, light dimming a stage) rather than any real
simulation.
Two ideas for rendering a "reflection" without building a real mirror, both explicitly framed as reuse of existing plumbing:
-
Live-feed distortion through the existing
CameraGateprotocol —CIFilters (desaturate, contrast crush) plus a frame-delay ring buffer for the "lag" beat (display framenow - k,kgrowing with elapsed time). No face tracking or ML proposed. - Canned-asset cut-ins for the "independence"/"contact" beats — crossfade from the live distorted feed to a pre-authored asset at the moment the player looks back, rather than attempting real-time generation of a distorted face.
Lighting, audio, and haptics are all proposed as reuses of existing
LULLKit concepts — Atmosphere.beatSeconds' pacing for flicker cadence,
Sensor.motion stillness detection for a breathing loop that's audibly out
of sync with the player, and THE PULSE's haptic curve rather than a new
one.
- Dread over gore, always — no blood-streaked baseline state; the reference image's "soaked" register is explicitly called out as not LULL's.
- Implication over reveal — glimpsed partially, cut short, never a screen-filling clear shot.
- Escalates on LULL's existing slow clock (the same 9-second
Atmospherebeat, the same 40s/30sEyeSessionpacing), not a jump-scare cadence. - Never actually deceives the player about what's real — the reflection
lies to the character; the game doesn't lie to the player, per
CLAUDE.md§1. - No new sensors and no silent consent —
THE MIRRORisSensor.camera(+ optionallySensor.motion) with an honest in-app rationale, same revocation contract asTHE EYE.
Quoted directly, because the doc itself frames these as unresolved:
- Does
THE MIRRORship as part ofTHE EYE's vertical slice, or as its own slice reusingCameraGate? (The doc's own lean: "own slice — keepsTHE EYE's scope, and its existing tests, untouched.") - Does the one-sitting bathroom loop stay scoped as is, or become the first real use of the future Vapor "haunt" server for cross-session persistence? Only the former is called "small enough to prototype next."
- Should the corrupted-line approach live in
Atmosphere.swiftdirectly (a transform over existingLines) or as a parallel script keyed by loop count? Flagged as worth a spike before committing either way.
Home · Concept & Design · The Safety Invariant · Architecture · Building & Running · Roadmap / Ideas
testtest126/LULL · MIT license
you can close this tab now. it will still be listening.