proteus
tap = extend  drag up = retract
detached
membrane reserve
engulfed 0

proteus controls

You are inside the amoeba. You don't see it directly; you only see its self-report painted on a map. The map's horizontal axis is the arc length along the membrane perimeter, starting from the south pole (the ventral adhesion centroid). Vertical is nominal latitude: sensors all sit on the equator (middle horizontal band); the top and bottom of the map are virtual dorsal and ventral poles painted from samples at the cell footprint.

Input gesture

tapAnchors the brush at the touch point and starts a mild extend at that arc position (directive +0.5 at the brushed nodes).
holdCortex stays at the extend target while you hold. Pseudopod grows.
drag downStronger extend. Full strength at 60 CSS-px drag.
drag upFlip to retract: directive goes negative at the anchor, pulling that arc region inward. Full retract at 60 CSS-px up.
releaseDirective decays to 0 over ~1 second; the pseudopod relaxes back.

The brush footprint is centered at the anchor, not the current pointer. The drag is a vertical-slider gesture, not a brush trail. A blue ring around the anchor = extending; warm-red ring = retracting; the line from anchor to pointer shows the drag offset.

Sliders

brushBrush radius in CSS pixels (6–80). Wider brush = more nodes inside the footprint Gaussian per gesture.
pushsim.pushStrength (0–6, default 2.0). The signed per-node force coefficient: a brushed node feels basePressure + pushStrength × directive. Higher push = more dramatic response per gesture; too high explodes the cell.
basesim.basePressure (0–0.5, default 0.05). A small constant outward radial force on every node, every tick. Acts as turgor / balloon pressure. Set to 0 for a flaccid cell; turn up to discourage inward folds.
springKsim.springK (1–60, default 6). Uniform cortical spring stiffness. Resists stretch and compression of edges. Higher = tighter / less deformable. Lower = floppier and easier to pseudopod.
γsim.bendK (0–2, default 0.5). Bending / curvature stiffness — pulls each node toward the midpoint of its two neighbors with force proportional to displacement. Discrete Laplace surface tension. Higher γ rounds out sharp features; low γ lets fine curvature accumulate (including stable double-walled involutions).

Buttons

debugToggle the top-down god's-eye view: substrate fields as a tinted bitmap, the cell polyline overlaid, sensor dots colored by their current channel readings, south pole X, chem-gradient arrow, food markers (pulsing = unconsumed, X = digested), and a legend with live winding number + budget.
resetRebuild the cell at the world's suggested start position and re-apply all current slider tunings.
docsThis panel.

Sensor channels (toggles, colored swatches)

adhesionSubstrate grip strength at each sensor. Off by default — currently a rendering artifact; will become real once the ventral surface gets its own sensor sheet.
lightAmbient light at each sensor. Off by default — same caveat: dorsal surface will get real sensors later.
chemistryChemical signal strength sampled at each sensor's world position. On by default. In Level 1 this is a single Gaussian centered on the food, so the gradient leads cleanly to a meal.
tensionCortical stretch magnitude at each sensor (proprioception). On by default. Lights up wherever springs are stretched — extending regions glow, taut bands of the resting cell show a faint hum.

Bottom strip: membrane reserve

The colored bar at the bottom is sim.budget — the cell's internal pool of recyclable membrane material. Sources:

wrinkleThe dorsal-posterior bunching zone accumulates wrinkle. Wrinkled nodes shed material into the budget over time. (Currently this zone is partly conceptual until ventral/dorsal sensors land.)
mergeWhen two adjacent nodes get pushed close together (edge below 45% of rest length), tectonics collapses them; recycled material refunds 0.025 to budget.
engulfEach engulfed food dumps food.value (0.4) into budget AND grows the cell (targetArea × 1.08, perimeter0 × √1.08). The cell now wants to be bigger after a meal.

Sinks:

tensionHigh-tension nodes draw from budget to relax. Their restLenRatio grows so the local spring rest length increases, reducing strain.
splitWhen an edge gets stretched beyond 220% of rest length, tectonics inserts a midpoint node — costs 0.04 from the budget. This is how the cell physically grows after engulfment.

HUD readout (top right)

push base K γLive slider values.
NCurrent node count. Starts at 256; climbs with tectonic splits as the cell grows. Floored at 64, ceiling 1024.
RMean radial distance of nodes from the cell centroid. A rough "cell size" indicator.
vmaxPeak node velocity magnitude across all nodes. Useful for tuning: spikes during deformation, settles low at equilibrium. Hard-clamped at 8.0 in the integrator as a safety net.
dir±Peak |directive| across nodes — measures how strongly your input is registering. ~0.5 on tap, up to ±1.0 on full drag.
fedTotal food engulfments since reset.
DETACHEDAppears if sum of node adhesion drops below the threshold. Input is suppressed in this state — the cell drifts passively until contact is re-established.

Cilia — the second way to move

The cell also carries a compound cilium: four cilia at one point on the membrane that bundle together to swim and unfurl to stop. Crawling is paid for in cortex and needs the substrate; swimming is paid for in beat and does not. They are on the same cell at the same time and they do not cooperate — that is the interesting part.

Every number in it is measured, from Embodied behavioural complexity in a ciliated microorganism, Nat. Commun. 17, 8445 (2026), which filmed 125 Pterosperma cells and 219,368 ciliary waveforms. Details in flagella.js; the selftest re-derives the paper's own reported values from the constants.

StopCilia unfurled, oscillating at about 10 Hz, cell stationary. Mean 58 s in the wild — the cell spends 96.6% of its life here.
SwimCilia bundled, a travelling wave running down the compound cilium at 12–304 Hz. Mean 1.42 s. This is where all the thrust comes from.
ReorientA 41-millisecond tumble that swings the apparatus through 130° ± 30°. Rare: three parts in ten thousand.

The three are wired in a line: Stop and Reorient both hang off Swim, so a stopped cell must swim before it can turn. Nothing you do changes that.

Steering the cilia

Brush the map at the ciliary band (the tinted vertical strip) and the same extend/retract gesture that grows a pseudopod elsewhere does something different here: extend urges the cell to swim, retract urges it to stop. It leans on the transition rates — up to about five-fold — it never sets the state. A tumble in progress ignores you entirely.

ciliaToggle the apparatus off; the cell reverts to a pure crawler.
beat÷Display divisor for the beat. A 95 Hz beat cannot be drawn at 30 fps, so the rendered phase is slowed by this factor. The model frequency — the one that sets the wavelength, the thrust and the µm/s readout — is untouched.

Two departures from the data, stated plainly. The state machine runs 8× faster than measured, because a faithful cell would sit motionless for 58 seconds at a time; that deliberately destroys the four-orders-of-magnitude timescale separation the paper is partly about. And the cilium is drawn at 2.2 cell radii instead of its true ~15, because a faithful one would be a 900-pixel whip in an 800-pixel world.

Notes on emergent behavior

Double walls / stable involutions: at low γ, bending can't blunt sharp curvature fast enough, so a fold can tuck inside and persist. Both shell and fold feel outward pressure but are already separated, so nothing actively unfolds them. Raising γ usually melts them. With arc-length mapU you can also target the inner fold's surface position directly and press extend to push it back out.

Wandering frame: mapU is anchored to the south pole, which is itself the adhesion-weighted centroid. As the cell crawls over the substrate, the south pole shifts and the entire map rotates. This is the cell's actual frame — there's no fixed north star inside an amoeba.