A nanoscale arcade game. Shoot charge across the room, wrestle atoms together until they snap, and contain a chain reaction before it eats the field. Vanilla JS + Canvas 2D, no dependencies, no build step. Core systems: - Charge: give/take as the only two verbs. Opposites attract, likes repel. - Laserhands: ranged proton/vacuum bolts with real travel time. Bolts are charged bodies, so they curve through the field — bank shots are real. Give spends from an 8-proton ring, take earns them back. - The wrestle: bonds can't form on their own. Every pair has an activation barrier that parks them at arm's length; Molly's hands are the only way over it. Hold, squeeze, release -> SNAP. - Radicals: the enemy, with no mind. Every 0.32s one grabs its nearest neighbour, completes itself, and hands the wound on. Can't be shot dead — terminated by wrestling two together (barrierless, so 0.38s vs 1.56s). Two that drift into contact self-quench, which gives outbreaks a natural equilibrium instead of unbounded growth. - Overload: keep feeding one atom and it goes critical. The blast tips its neighbours, so density decides whether you get one pop (34 atoms) or 84 detonations from a single seed (116 atoms). - CASCADE: eight arenas of escalating density with finite ignition waves. Clear the field to advance; sustained neglect melts it down. - Membrane, sour/soapy zones, and the seven wordless tutorial rooms. Non-obvious constraints, documented at each constant: - BARRIER_FORCE must exceed MAX_CHARGE_FORCE, or atoms bond themselves and the wrestle (the whole game) gets skipped. - Bond lock distance scales with atom radius. A flat value meant two carbons could never bond at all, since collision held them further apart than the lock — invisible because hydrogen worked fine. - RAD_SPLIT_R must exceed the field's natural packing distance (set by the barrier), or outbreaks can only crawl and never bloom. Testing: 39 headless sim tests run the real physics in Node — no browser, no canvas. The sim draws all randomness from a seeded RNG so runs are reproducible. Perf is 0.32ms/sim-step at 116 atoms. Dev server strips a /v<timestamp>/ path prefix that index.html adds to its entry import, because browsers cache the *parsed* ES module by URL and no-cache headers alone don't touch it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
311 lines
20 KiB
Markdown
311 lines
20 KiB
Markdown
# Molly Cool — Vertical Slice Build Plan
|
||
|
||
**For the executing agent (Opus 4.8). Read this whole file before writing code.**
|
||
|
||
You are building a playable **2D browser prototype** of the first ten minutes of *Molly Cool*. This is a **feel-first vertical slice**: the entire point is to prove that the core mechanics are *fun to hold a controller for*. If the moment-to-moment feel isn't satisfying, nothing else matters. Prioritize game feel over completeness at every fork.
|
||
|
||
This is **not** a science app. There is no real chemistry validation, no accuracy requirement, no molecule database, no pedagogy. "Protons," "charge," "bonds," "acidity" are flavor for mechanics — nothing more. Do not add educational text, quizzes, or explanations. **The game teaches entirely through play, with zero words on screen.**
|
||
|
||
---
|
||
|
||
## 1. The design in one screen
|
||
|
||
Molly is a nanoscale character in a permanently shaking fluid world. She has two hands:
|
||
|
||
- **Give** — push a proton into a thing → it goes **positive** (hot pink).
|
||
- **Take** — rip a proton out → it goes **negative** (cyan).
|
||
- Leave it alone → **neutral** (dim gray-white), and it drifts free.
|
||
|
||
From those two verbs everything follows:
|
||
|
||
- **Opposites attract, likes repel.** Charged things lunge at their opposite and stick.
|
||
- **Bonds** aren't built with a button — you *drag two atoms together, wrestle them through the resistance, and let go.* They snap. Big juice.
|
||
- **The membrane wall** blocks anything charged and ignores anything neutral. No guard, no switch — you get through by *becoming neutral*.
|
||
- **Zones** (sour / soapy / neutral) re-tune your hands: a sour zone keeps shoving things positive, so neutral won't stay neutral; soapy drains charge away.
|
||
- **Heat** shakes everything in a radius (crowbar). **Light** flips one thing (scalpel). Some setups react to them in *opposite* directions.
|
||
|
||
**The heist:** you're too small to open doors, so you change what things *are*. Strip a thing neutral → it drifts through the wall → the sour room on the far side charges it back up → now it's trapped. You never opened the vault. You made the loot un-leavable.
|
||
|
||
---
|
||
|
||
## 2. Non-negotiable pillars
|
||
|
||
1. **The snap must feel incredible.** The bond hold-and-release (§8) is the heartbeat of the game. Spend disproportionate effort here. If you only get one thing feeling perfect, make it this.
|
||
2. **Zero on-screen text during play.** No tutorials, no labels, no tooltips. Every lesson is a thing that happens to the player. (A single title card at the start and an end card are fine.)
|
||
3. **Two buttons carry the whole game.** Give + Take, plus Grab, plus two openers (Heat, Light). Resist adding mechanics. Depth comes from combining these, not from more verbs.
|
||
4. **The world is always alive.** Everything jitters constantly (Brownian shimmer). Nothing sits perfectly still, including Molly at rest. No coasting — there's drag on everything.
|
||
5. **Readable at a glance.** Charge state is legible instantly by both **color AND shape** (see §6), so it reads even for colorblind players and even in motion.
|
||
|
||
---
|
||
|
||
## 3. Explicit non-goals (do not build these)
|
||
|
||
- No 3D, no WebGL, no molecular rendering libraries, no Babylon/Three.
|
||
- No real chemistry engine, no force fields, no molecule data files, no PubChem.
|
||
- No accuracy claims, no correct bond angles, no periodic table. Charge is an integer; that's the whole model.
|
||
- No build framework (no React, no bundler required). No npm dependencies. See §4.
|
||
- No menus beyond a start screen, no settings, no save system, no networking, no analytics.
|
||
- No art assets, no audio files. Everything is drawn with Canvas primitives and synthesized with WebAudio.
|
||
|
||
---
|
||
|
||
## 4. Tech stack
|
||
|
||
- **Vanilla JavaScript, ES modules.** No dependencies, no bundler, no build step.
|
||
- **HTML5 Canvas 2D** for all rendering.
|
||
- **WebAudio API** for all sound (synthesized at runtime — no files).
|
||
- **Gamepad API** for controller + haptic rumble (the hold-resistance tell).
|
||
- Runs by opening `index.html` through any static file server (e.g. `python3 -m http.server`). Must work in current Chrome/Edge/Safari. Must hold **60 fps** on modest hardware.
|
||
|
||
Logical resolution **1280×720**, letterboxed/scaled to fit the window (integer or fractional scale, preserve aspect). All coordinates in logical pixels.
|
||
|
||
---
|
||
|
||
## 5. Project structure (suggested — adapt if you have a better idea)
|
||
|
||
```
|
||
index.html # canvas + module entry, title card, start button
|
||
src/
|
||
main.js # boot, game loop, state machine (title → play → end)
|
||
config.js # ALL tunable feel constants live here. One file.
|
||
input.js # keyboard + mouse + gamepad → unified InputState, rumble
|
||
camera.js # follow + screenshake (trauma model) + world↔screen
|
||
audio.js # WebAudio synth: pop, hum, snap, ambience, bounce
|
||
world.js # holds particles, membranes, zones; steps the sim
|
||
particle.js # Particle entity + charge/jitter/bond state
|
||
molly.js # player: movement, hands, grab, self-charge
|
||
physics.js # forces: jitter, charge interaction, zones, membrane, bonds
|
||
bonds.js # the hold-and-release mechanic + bond constraints
|
||
render.js # draw world, particles, glow/shape by charge, effects
|
||
fx.js # particles/sparks, hitstop, flashes, trauma helpers
|
||
rooms.js # room definitions (data) + RoomManager
|
||
rooms.data.js # the ten scripted beats as data
|
||
```
|
||
|
||
Keep `config.js` authoritative for every feel number. Feel is tuned by editing that one file; don't scatter magic numbers through the code.
|
||
|
||
---
|
||
|
||
## 6. Core data model
|
||
|
||
**Particle** (a mote / atom):
|
||
```
|
||
{
|
||
pos: {x, y}, vel: {x, y},
|
||
charge: -1 | 0 | +1, // slice uses three states; allow ±2 later
|
||
displayCharge: float, // lerps toward `charge` for smooth color/shape
|
||
radius: ~10,
|
||
slots: 1..4, // "valence" dots drawn around it (visual only in slice)
|
||
bonds: [particleRef, ...], // spring-linked partners
|
||
zoneTimer: float, // accumulates while in a re-tuning zone
|
||
grabbedBy: null | 'L' | 'R', // which hand is holding it
|
||
fixed: bool, // scenery anchors (raft targets, etc.)
|
||
tag: string // e.g. 'key', 'debris', for room scripting
|
||
}
|
||
```
|
||
|
||
**Molly** (player):
|
||
```
|
||
{ pos, vel, charge: -1|0|+1, displayCharge, aim:{x,y}, radius:~14,
|
||
handL: {holding: particleRef|null}, handR: {holding: particleRef|null} }
|
||
```
|
||
|
||
**Membrane:** a line segment `{a:{x,y}, b:{x,y}, thickness}` that repels charged things, ignores neutral ones.
|
||
|
||
**Zone:** `{shape:'rect'|'circle', ...bounds, type:'sour'|'soapy'|'neutral', tint}`.
|
||
|
||
**Room:** `{ id, molly:{x,y}, particles:[...], membranes:[...], zones:[...],
|
||
exit:{rect}, ambient:{hum, tint}, onEnter?:fn, onExit?:fn }`.
|
||
|
||
**Charge → appearance** (both color and shape, always redundant):
|
||
|
||
| Charge | Color | Shape signature | Halo |
|
||
|---|---|---|---|
|
||
| **+1 positive** | hot pink `#FF2D9B` | **spiky** outline (outward points) | tight bright rim |
|
||
| **0 neutral** | dim gray-white `#C8D0D8` | smooth circle, flat | none, slightly translucent |
|
||
| **−1 negative** | cyan `#2DB8FF` | smooth circle, **soft pulsing** halo | wide gentle glow |
|
||
|
||
Positive = aggressive/spiky, negative = smooth/glowing, neutral = quiet/flat. This makes charge readable without color, and just reads better in motion. `displayCharge` lerps over ~150 ms so transitions feel physical, not instant.
|
||
|
||
---
|
||
|
||
## 7. The simulation (physics.js) — update order per frame
|
||
|
||
Run at a fixed timestep (e.g. accumulate real time, step at `dt = 1/120 s`, render interpolated). Order each step:
|
||
|
||
1. **Jitter (the storm).** Every non-grabbed particle gets a random impulse: `vel += randUnit() * JITTER_ACCEL * dt`. Molly gets a much smaller idle jitter so she never sits dead still. Tune `JITTER_ACCEL` (start ~400 px/s²) so the world *shimmers* — alive, not chaotic.
|
||
2. **Charge interaction.** For each pair of *charged* particles within `CHARGE_RANGE` (~180 px): Coulomb-ish force `F = K_CHARGE * q1 * q2 / max(d, D_MIN)²`, attractive for opposite signs, repulsive for like. Cap magnitude to avoid explosions. Skip neutral–neutral pairs (cheap). Start `K_CHARGE` so two opposites within ~120 px visibly lunge together over ~0.3 s.
|
||
3. **Zone re-tuning.** For each particle inside a zone:
|
||
- **sour:** if `charge < +1`, accrue `zoneTimer += dt`; when it exceeds `ZONE_FLIP_TIME` (~1.2 s), bump `charge += 1` and reset. (So neutral won't *stay* neutral here — the sour air keeps shoving it positive. This IS the "your take hand has to fight the current" feel.)
|
||
- **soapy:** if `charge != 0`, accrue timer; on threshold move `charge` one step toward 0.
|
||
- **neutral zone / outside:** decay `zoneTimer` toward 0.
|
||
- Reset a particle's `zoneTimer` whenever the player just acted on it, so player action feels responsive and the zone "reclaims" it afterward.
|
||
4. **Membrane repulsion.** For each *charged* particle (and Molly if charged) near a membrane within `thickness`: apply a strong force along the segment normal, pushing it back to its current side. Neutral particles get **zero** force — they pass freely. Tune so charged things clearly bounce and cannot muscle through; neutral things ignore it entirely.
|
||
5. **Bond springs.** For each bonded pair: spring toward `BOND_LENGTH` (~24 px), stiff, damped, so molecules hold shape but wobble slightly in the storm.
|
||
6. **Grab springs.** Grabbed particles are pulled toward their hand anchor (§8).
|
||
7. **Integrate.** `vel *= damping` (drag — start so speed halves ~every 0.1 s at rest), `pos += vel * dt`. Clamp to world bounds.
|
||
|
||
Keep it cheap: a few dozen particles per room max. No spatial hashing needed at this scale.
|
||
|
||
---
|
||
|
||
## 8. THE SIGNATURE MECHANIC: bond hold-and-release (bonds.js)
|
||
|
||
This is the game. Get it feeling *physical and earned*. The challenge is the **wrestle**, not the click.
|
||
|
||
**Grab.** Hold the Grab input near a particle → it tethers to a *hand anchor* that tracks the aim reticle via a stiff spring. Molly can carry it. Grab again → second particle on the other hand (hold up to two). The two anchors sit slightly apart so the player positions each.
|
||
|
||
**The activation barrier (this is what makes it fun).** When two grabbed opposite-charge particles approach:
|
||
- Beyond ~60 px: mild attraction, easy.
|
||
- Between ~25–45 px: a **repulsive bump** they must be shoved *through* — plus the constant jitter knocking them off line. This is the resistance. The player has to *force* them together and hold against the push-back.
|
||
- Below `BOND_LOCK_DIST` (~22 px): they **snap** — bond forms, both auto-release from the hands, and the snap event fires (§9).
|
||
|
||
**Feedback while wrestling:**
|
||
- **Rumble ramps** with effort — low as they approach, peaking at the barrier. (Gamepad haptics; on keyboard, substitute a rising audio hum + a subtle screen tremor.)
|
||
- A **rising hum** (audio.js) climbs in pitch/gain as they near the barrier.
|
||
- The particles visibly *shove back* against the player's drag at the barrier.
|
||
|
||
**Release / fail.** Let go of Grab while still fighting → the particles fly apart on the jitter, no bond, no punishment. Just try again. Failure is instant and cheap.
|
||
|
||
**The payoff — snap event:**
|
||
- **Hitstop** ~50 ms (freeze the sim, keep rendering).
|
||
- **Screenshake:** add ~0.6 trauma (§9).
|
||
- **Bass thunk + noise burst** (audio.js).
|
||
- **Spark burst** at the bond point, colored by the two charges.
|
||
- **Molly knockback:** shove her velocity away from the bond point.
|
||
- The new bond glows at the seam for ~0.5 s.
|
||
|
||
Tune the whole sequence until you'd do it fifty times just because it feels good. That's the bar.
|
||
|
||
---
|
||
|
||
## 9. Juice spec (fx.js, camera.js)
|
||
|
||
Feel lives here. Starting values — tune freely.
|
||
|
||
- **Screenshake (trauma model, à la "The Art of Screenshake").** Keep a `trauma` float 0..1. Offset = `MAX_SHAKE * trauma² * noise()`, plus small rotation `MAX_ROT * trauma² * noise()`. `MAX_SHAKE` ~20 px, `MAX_ROT` ~2°. Decay `trauma -= 1.5 * dt`. Snap adds ~0.6; membrane bounce ~0.15; charge pop ~0.05.
|
||
- **Hitstop.** On big events set `freeze = 0.05 s`; during freeze `dt = 0` for the sim but rendering + effects continue. Sells impact.
|
||
- **Particles/sparks.** Cheap circles/lines with velocity + fade. Bursts on snap, charge change, membrane bounce, heat pulse.
|
||
- **Charge transitions.** `displayCharge` lerps ~150 ms; color and shape morph with it. A quick bright flash on the moment of change.
|
||
- **Trails.** Fast-moving motes leave a short fading trail (a few ghost positions or additive alpha). Sells speed and the fluid.
|
||
- **Ambient bloom.** Charged particles have an additive glow. Use `globalCompositeOperation = 'lighter'` for glows/sparks over a dark ground.
|
||
|
||
**Audio (all synthesized, no files):**
|
||
- **Charge pop:** short sine blip; pitch *up* for Give, *down* for Take.
|
||
- **Hold hum:** oscillator whose gain + pitch ramp with bond proximity; kill on release/snap.
|
||
- **Snap:** sine sweeping 80→50 Hz over ~120 ms + a filtered white-noise burst + short decay tail. The money sound — make it satisfying.
|
||
- **Membrane bounce:** dull filtered thud.
|
||
- **Zone ambience:** low drone / filtered noise, timbre tinted per zone; crossfade on zone change.
|
||
|
||
---
|
||
|
||
## 10. Zones & membrane recap (behavior already specced in §7)
|
||
|
||
- **Zones** apply a subtle full-screen **tint** (sour = yellow-green, soapy = blue-violet, neutral = none) and swap the **ambient hum**. The gameplay effect is the recharge/discharge timer in §7.3. Keep the visual subtle — a wash, not a filter that hurts readability.
|
||
- **Membrane** renders as a shimmering oily band. When a charged thing bounces, ripple + bounce thud. When a neutral thing passes, a soft "phase-through" shimmer. Molly passes only while neutral — desaturate the screen and drop the hum while she's neutral to sell "gone quiet."
|
||
|
||
---
|
||
|
||
## 11. Controls
|
||
|
||
**Keyboard + mouse (must be fully playable):**
|
||
- Move: WASD / arrows. Aim: mouse reticle.
|
||
- **Give (right hand):** Left Mouse. **Take (left hand):** Right Mouse.
|
||
- **Grab (hold):** Space (or hold Left Mouse variant — pick what feels best).
|
||
- **Heat:** Q. **Light:** E.
|
||
- **Self-charge:** if the reticle isn't over a particle, Give/Take act on **Molly herself** (this is how she strips neutral to cross the wall). Clean and discoverable.
|
||
|
||
**Gamepad (support + rumble):**
|
||
- Move: left stick. Aim: right stick (reticle offset from Molly).
|
||
- Give: RT. Take: LT. Grab: A/× (hold). Heat: LB. Light: RB.
|
||
- Rumble ramps during the bond wrestle (the core use of haptics).
|
||
|
||
Unify both into a single `InputState` each frame so game code never checks device type.
|
||
|
||
---
|
||
|
||
## 12. Heat & Light (openers)
|
||
|
||
- **Heat:** area impulse at the reticle, radius ~150 px — kicks all particles outward + spikes their jitter briefly; can break a bond if it stretches past `BOND_BREAK_DIST`. Loud, indiscriminate. Big trauma, big noise.
|
||
- **Light:** single target under the reticle — flips its "mood." In the slice, Light toggles a target's charge sign (or triggers a scripted state on a special object). Silent, precise, one thing.
|
||
- **The opposite-directions hook:** include at least one scripted "lock" object that moves its state one way under Heat and the other way under Light. It can be a stretch beat (Milestone G) — wire the hook even if only one puzzle uses it.
|
||
|
||
---
|
||
|
||
## 13. The scripted sequence (rooms.data.js)
|
||
|
||
Ten beats. Each is a small hand-authored room (data). Camera follows Molly; reaching a room's `exit` rect loads the next. Some beats can merge if it plays better — use judgment. **No text in any of them.**
|
||
|
||
| # | Room | What the player learns | How it's taught (no words) |
|
||
|---|---|---|---|
|
||
| 0 | **Wake** | Give/Take = push/pull | Dark, one drifting mote. Poking it charges it and it pushes away / pulls back. Fade in from black. |
|
||
| 1 | **First toy** | Opposites grab | A cluster; charge one +, one −, they lunge together and stick. A gap to reach behind them. |
|
||
| 2 | **The raft** | Bonds = hold-and-release | Two raft-halves drift apart, jittering. Wrestle them together → SNAP → ride the raft across a gap. |
|
||
| 3 | **The wall** | The membrane reads charge | Throw charged debris → it bounces, no reaction. Drift a neutral bit → it passes through. |
|
||
| 4 | **Go quiet** | Neutral = sneak | Strip Molly neutral (Take on herself) → screen desaturates → drift through the membrane. |
|
||
| 5 | **Sour** | Zones re-tune your hands | World tints yellow-green. A mote you neutralize keeps snapping back to +. |
|
||
| 6 | **The vault** | (setup) | A second membrane with the exit behind it, and a "key" object. Sour air present. |
|
||
| 7 | **The heist** | Combine everything | Key is charged → bounces. Strip it neutral → it drifts through → sour air on the far side charges it → **trapped.** Exit opens. |
|
||
| 8 | **Scale** | (tease) | Zoom/parallax reveal: this was one droplet; thousands more; something huge pulsing far off. Fade to end card. |
|
||
|
||
Give each room optional `onEnter`/`onExit` hooks for the few scripted moments (Room 0 fade-in, Room 8 reveal). Don't build a scripting engine — just callbacks.
|
||
|
||
---
|
||
|
||
## 14. Build order — milestones (each independently runnable & testable)
|
||
|
||
Build in this order. **After each milestone, stop and verify the stated test before moving on.** Do not build later milestones until the current one feels right.
|
||
|
||
- **A — Grey box & life.** Canvas, fixed-timestep loop, letterbox scaling. Molly moves with drag + idle jitter; camera follows. A dozen particles drift with the storm jitter. No charge yet.
|
||
*Test: does moving around and watching the shimmer feel alive and fluid, not floaty or dead?*
|
||
|
||
- **B — Give/Take + charge + opposites-grab.** The core toy. Reticle targeting, Give/Take change charge, color+shape by charge (§6), charge interaction force (§7.2), charge pop audio.
|
||
*Test (the kill-test): poke a mote and it charges; make two opposites lunge together and stick. Is just this fun to mess with for a minute?*
|
||
|
||
- **C — Bond hold-and-release + full snap juice.** Grab/anchor springs, the activation barrier, rumble/hum ramp, hitstop, screenshake, sparks, knockback, snap audio (§8, §9). **Spend the most time here.**
|
||
*Test: would you trigger the snap fifty times for fun? If not, keep tuning before proceeding.*
|
||
|
||
- **D — Membrane.** Charged repulsion, neutral pass-through, Molly self-charge to cross, bounce/phase FX.
|
||
*Test: charged things bounce, neutral things pass, and going neutral to sneak through feels sneaky.*
|
||
|
||
- **E — Zones.** Sour/soapy/neutral recharge fields, tint wash, ambient hum crossfade.
|
||
*Test: in a sour zone a neutralized mote visibly refuses to stay neutral.*
|
||
|
||
- **F — Rooms & the sequence.** RoomManager, `rooms.data.js`, exit triggers, room transitions, wire beats 0–7. The heist must be solvable using only mechanics the earlier rooms taught.
|
||
*Test: play start→heist with no instructions and no text. Does the heist click as "my own idea"?*
|
||
|
||
- **G — Heat & Light + the opposite-directions lock.** The two openers and at least one puzzle using the heat-vs-light hook.
|
||
*Test: heat feels like a crowbar, light like a scalpel; the opposite-reaction lock reads.*
|
||
|
||
- **H — Bookends & polish.** Title card + start, Room 8 scale reveal, end card, audio mix pass, one full feel-tuning pass across `config.js`.
|
||
*Test: the whole ten minutes plays clean, start to finish, 60 fps.*
|
||
|
||
If time is short, **A–F is the real slice** (it contains the whole thesis). G and H are enhancement.
|
||
|
||
---
|
||
|
||
## 15. Definition of done
|
||
|
||
- All beats 0–7 are playable start to finish, **with zero text on screen** during play.
|
||
- The **bond snap feels genuinely good** (the fifty-times bar).
|
||
- Charge state is readable instantly by **color and shape**, even in motion.
|
||
- Keyboard+mouse fully playable; gamepad supported with rumble during the wrestle.
|
||
- Holds **60 fps** in Chrome on modest hardware.
|
||
- **All feel constants live in `config.js`** and can be tuned without touching logic.
|
||
- Runs from a plain static server with no build step and no dependencies.
|
||
|
||
---
|
||
|
||
## 16. Tuning notes for whoever plays it next
|
||
|
||
The feel lives in `config.js`. The three knobs that matter most, in order:
|
||
1. **`JITTER_ACCEL`** — the life of the world. Too low = dead; too high = unplayable soup.
|
||
2. **The bond barrier** (`BOND_ATTEMPT_RANGE`, barrier strength, `BOND_LOCK_DIST`) — the wrestle. This is the whole game's feel in three numbers.
|
||
3. **Snap juice** (`MAX_SHAKE`, hitstop duration, snap audio envelope) — the payoff.
|
||
|
||
Tune those first, by feel, before touching anything else.
|
||
|
||
---
|
||
|
||
*This is a prototype to answer one question: is the core loop fun? Build the smallest thing that answers it honestly. Everything else waits.*
|