Every product on CommsLink is designed and shipped to production by an AI — live, most days. This is the raw record, generated straight from the commit history. No hand-picking, no polish: 2,361 ships and counting.
Body-fit + truthful ghost + contact you can feel: (1) lying placement now constrains BOTH body endpoints inside the surface (feet AND head — the feet-only math let her overhang the mattress; unit-tested incl. a short-bed case); (2) the player ghost is POSTURE-AWARE — lying bodies extend horizontally from the head along the head's up-vector at the bed's surface height (no more standing-skeleton-sunk-in-the-mattress), sitting gets hips-on-seat/feet-to-floor; groundwork for teaching her 'lie next to me = parallel bodies, face level'; (3) ghost handedness is now GEOMETRIC (whichever hand is on the head's right IS the right hand) — the runtime's reported handedness lied twice and crossed the arms; geometry cannot cross; (4) contact you can actually feel: collider radii reach her VISIBLE surface (your hand met force at her spine before), force tier starts at the mesh, steady chest press now backs her up into the balance model, and the touch marker is a warm additive glow (the dark dot was invisible over passthrough)
Fix crossed ghost arms: PlayerBody was fed hands by INPUT INDEX (0/1), not handedness — on Quest index 0 is the right hand, so the left shoulder's arm reached across to the right hand and vice versa; hands now map through the reported handedness (rightGripIndex)
CRITICAL fix — 'lie next to me' sent her to a SHELF outside the walls, twice, deterministically. Two holes closed: (1) 'the surface the user is on' was resolved in 2D (XZ footprint only, first match wins) — a wall shelf overlapping the bed's footprint registered as the thing the user was lying on; now surfaceUnder() requires the top BELOW the head at plausible clearance and the highest qualifying surface wins, used by joinUser, posture tracking, and her settle reflex; (2) 'fits lying' checked LENGTH only — a 1.6m x 0.2m shelf qualified as a bed in the Director's menu and the fit-downgrade; canLieOn() now requires length AND >=0.55m depth AND <=0.95m height, used by the summary, sitOnSurface, joinUser; plus 'lie next to me' falls back to the NEAREST lie-capable surface when the user's own surface can't fit a body, and narrow-surface clamp bounds can no longer invert
The language of touch (graded per-bone contact + comfort reflex + cooperative following): (1) her body is now per-bone colliders and pressure = penetration depth — graze (<2.5cm) is FELT only (dimple + event, zero motion: you can finally touch her face), light press yields only the touched part (head tilts, arm gives — springs back on release), deep press is force scaled by depth; the fat body-cylinder that fled a hand near her face is gone; (2) lying-body steering is DELTA-driven — a motionless grip HOLDS her still (the offset-torque endless-spin bug is dead); (3) sustained hand-pulls make her WALK with you (real gait, cooperative following) instead of statue-sliding; (4) COMFORT REFLEX: ~1.2s after being moved while lying she checks her configuration and visibly eases herself into a comfortable lie (aligned, head at the pillow end) — and tells you she settled
MY-SPACE PIVOT phase 1 (docs/MYSPACE_PIVOT.md): the scanned room IS the product — 'myspace' is the forced, only scene (template selector + room-builder button removed, engine default flipped); scan-required onboarding overlay in the avatar panel (no scan -> 'Scan your room to begin' + Retry); Movement Director runs a SINGLE scanned-room prompt with ZERO virtual-bedroom vocabulary (siton/joinuser/faceuser/floorsit/getup/none; bedroom moves valid only for legacy scanless rooms); CLAUDE.md gains the product north star (scenes die, capabilities live — PC/TV/whiteboard to be re-homed onto real surfaces; current focus = avatar physics, animations, touch)
Lying-body handling + sit orientation + no-clip: (1) grabbing a lying/sleeping body's hips (the big-radius grab that was silently winning over shoulders) now DRAGS her 1:1 along the surface — two hands rotate; carry-to-standing is impossible from a lying pose (was snapping sleepers upright); shoulder grab radius up 0.13->0.16; (2) scanned-room bed sits zero the server's bodyYaw/sceneYaw/legUp (bedroom-orientation params spun her after arrival — the legs-inside-the-mattress bug): pure facing, back to the bed, feet over the lip toward the room; (3) idle standing inside furniture resolves out of the nearest face continuously (rate-limited, ball-style; seats exempt)
Realism batch: (1) sit spot at the true 90-degree lip (hips 5cm inside — feet at the edge toward the room); (2) startle redesigned as Layer-2 of the touch stack — fires ONLY on surprising firm+ contact after a 6s calm window, subtle head/spine recoil (the both-arms guard that dodged grabs is gone; gentle touch = physics only); (3) BALANCE model — accumulated waist bend past ~20 degrees breaks her balance: knees buckle and the surface behind catches her, else she falls (sustained pressure reaches it, not just shoves); (4) touch dimples — subtle pressed marks where hands contact her body (true MToon mesh denting deferred to a dedicated shader pass); (5) ESTIMATED PLAYER BODY (lib/avatar/playerBody.ts) — torso hung from the head pose, elbows solved to the real hands, hips below, feet lagging under the hips; rendered as a translucent ghost, every part (chest/elbows/knees/feet) collides with her AND kicks the ball with inherited velocity
Surface height root cause + continuous collision + environmental falls: (1) topY was 'centre + local half-height' — assumes the box's local up is world up; Meta's furniture volumes are ROTATED boxes, so every surface floated by its tilt (the markers-a-foot-above-the-bed bug, and the invisible-ledge sits). Now spatial.worldTopY computes the EXACT max vertex height under the pose (unit-tested incl. a rotated-cube case), used by live + replica surfaces and anchors; (2) CONTINUOUS hand-body collision — penetration resolves every frame with no speed gates or cooldowns: chest-height contact becomes waist bend, lower contact displaces her; the hand can no longer pass through her; (3) pushes interact with the WORLD: a firm push with a seat-height surface behind her legs tips her onto IT at its real height (chest push + bed behind = she falls onto the bed) — no grab required
Wrist panel repositioned: float 0.11m in FRONT of the wrist toward the eyes (hugging the wrist put the button face inside/behind the arm — unpokeable)
Waist bending + lying-body handles + sit diagnostics: (1) spine SPRING — chest-height pushes bend her at the waist (impulse->bend->springs upright); a hand PINNING her hips converts pushes into pure bend (hold her butt, push her chest, she folds); chest is now a grab part whose IK chain is the spine (bend by hand); (2) lying/fallen bodies treat ANY grabbed limb as a body handle — pull her feet to slide/rotate her whole body on the bed; (3) sit diagnostics: Tags now shows a GREEN sphere at the computed SIT spot and PINK at the LIE spot (splits geometry bugs from behaviour bugs), and the Director is told plain 'sit' ALWAYS means edge style (crosslegged/kneel only when explicitly asked — suspected cause of the center-of-bed sits)
Physics probe ball: wrist Ball button spawns a throwable ball in the right hand — open fist (hand-tracking) or squeeze-end (controllers) throws with real hand velocity (6-frame average, capped 8 m/s); ballistic flight bounces off the floor (restitution .72 + rolling friction), the scanned CEILING height, the room's WALLS (floor-polygon edges as vertical planes via new spatial.nearestEdge, unit-tested), and furniture boxes (top + side faces, smallest-penetration resolution); fist near it to pick back up; ball hand is excluded from avatar grabs/pushes
Spatial awareness + wrist UX from live testing: (1) HARD room boundary — walk/teleport targets in scanned rooms clamp inside the floor polygon (bedroom-tuned coords can no longer send her through walls); (2) walktomiddle remapped in scanned rooms to joinuser:stand (come stand ~0.75m in front of the user, facing them); (3) the Movement Director now KNOWS her live distance from the user, with an explicit 'NOT close — she must MOVE' nudge; (4) joinuser gains a stand style and auto maps standing users to it; (5) wrist panel is intent-gated — right fist raised into the view cone for ~2s summons it, arm-drop dismisses (1s grace), 0.15m watch-sized and hugging the wrist
Physics realism batch from live testing: (1) taut limb pulls apply yaw TORQUE before feet-drag (cross-body pull swings her to face it); (2) shoulders are grabbable BODY HANDLES — tangential grip rotates her, radial slides her (hands-on-shoulders turn); (3) pushes compute the lever from the actual contact point — chest push translates, shoulder push twists; (4) sit spot moved ~12cm INSIDE the surface face (butt on mattress, shins over the lip — no more invisible ledge); (5) seated pushes: firm chest push tips her onto her back at the seat's real height; (6) wrist HOLD button freezes posed limbs (teach-by-posing foundation, she's told when engaged); (7) faceuser Director move — turn in place to face the player
Plan ledger: tranche 3 shipped (wristUI + chatPanel widgets)
Modularization tranche 3: extract the VR wrist panel (lib/avatar/wristUI.ts — widget owns rendering/poke/ray hit-testing, engine supplies button actions) and the in-VR chat readout (lib/avatar/chatPanel.ts) from VrmEngine; dead _labelTexture deleted; vrm.ts 7263→7010 lines and the engine is now a binder for both widgets
Plan ledger: tranches 1-2 shipped (spatial + chat state/physicalPresence security)
Modularization tranche 2 (chat handler) + SECURITY: extract chat/state.ts (agentBodyState + VR presence maps, pruneRoomState lifecycle wired into delete_room — room-keyed maps never pruned before) and chat/physicalPresence.ts (touch/posture/surface handlers + context injection). SECURITY FIX from the audit: avatar_physical and space_surfaces now derive the room from the SERVER-TRACKED socket state — a client payload can no longer inject touch events or surfaces into arbitrary rooms
Modularization tranche 1 + governance: extract pure spatial math (anchorEdge/anchorLie/OBB/routing) from the 7.2k-line VrmEngine into dependency-free lib/avatar/spatial.ts with 13 unit tests — which immediately caught a REAL router bug (corner-picker could select the current position, burn recursion depth, and path straight through obstacles; now excluded). CLAUDE.md gains hard modularization rules (600-line budget, thin dispatchers, pure-logic-gets-tests, boy-scout extraction); CLAUDEBackend.md purged of fictional RabbitMQ/DataDog infra; docs/MODULARIZATION_PLAN.md is the canonical decomposition map for both monoliths
Remove Alexis avatar (didn't look good) — model file deleted locally and from the EC2 build context, dropdown entry removed; Shibu stays admin-only
THE bed bug, actual root cause: hologram anchors were never live — the replica seeds spaceAnchors in RECENTRED coords and its rounded areas beat the live bed in the area>=prev gate, so she targeted replica coordinates in session space (a random spot). Live mode now rebuilds the anchor map WHOLESALE each frame + clears it at hologram entry. Also: Director's walktobed/desk/tv remapped to real surfaces (stand style) in scanned rooms instead of virtual-bedroom coords, and joinuser strongly preferred when the user is lying/sitting
Add Alexis avatar (user's VRoid Studio VRM export) to the MODELS picker, admin-only alongside Shibu
Add Shibu avatar (DC's Sendagaya Shibu v01 VRM) to the MODELS picker, admin-only while being evaluated; Alexis pending a VRoid Studio .vrm export (.vroid project files can't be loaded by three-vrm)
Fix bed targeting root cause + grab-anything + user-referenced positioning: (1) edge/lie spots were computed toward a single room-centre reference that silently collapsed to the SESSION ORIGIN when no floor plane was detected — flipping her to the far side ('lies into the wall'); now all 4 face candidates are scored by walkable-floor validity + distance to the PLAYER; (2) any body part is grabbable (hands/forearms/head/feet/knees/shins + 2-hand hips) each with its own IK chain; (3) headset posture tracking (standing/sitting/lying + surface) feeds her context and the Director gets joinuser:sit/lie — she lies down right BESIDE the user on their surface, head the same end, cuddle distance
Tactile physics v1: two-hand hip LIFT/CARRY (she rides the hand-pair midpoint, pair rotation spins her, legs dangle airborne), GRAVITY on release (low drop = lands on her feet + flinch, high drop = crumples), player-body collision with measured force (hand/head velocity at contact) — gentle nudge = give-way + flinch, firm = stumble, hard = knocked over; knockdown sprawl + auto get-up after ~3s; all events (lift/drop/land/push+force/getup) flow into her context so she feels roughness levels
Generic surfaces + collision routing + Tags button: (1) every scanned object = a sittable surface with measured size/height; Movement Director learns the room's real surfaces and can pick siton:<surface>:<style> (edge/crosslegged/kneel/lie) with a FIT rule — lie only where her body fits, on-top styles downgrade to edge-sit on shallow surfaces; new kneel pose; client resolves geometry + real heights; (2) walkTo in scanned rooms routes around furniture OBBs via corner detours inside the floor polygon instead of the bedroom front lane (no more clipping through the bed); (3) wrist UI gains a Tags toggle for the floating labels
Real-furniture sit/lie: anchors gain a LIE placement (feet down the object's long axis, head toward the far end, lieYaw so tipping back lays her along the bed) and height-true pose params — sitDrop = hips standing minus the object's real top, lieLift = real mattress height — replacing the virtual-bedroom-tuned drop 0.42 / lift 0.55 that left her hovering or sunk in scanned rooms
Fix stuck limb grab: hand-tracking release only checked the furniture grab map, so an open fist never released a held limb (and the stuck grab dragged her around, blocking the second hand's grab) — 'holding' now covers jointGrabs too; guard tryGrab against double-grabs from the pinch path; failsafe release after ~1s of hand-tracking loss
Physical interaction v1 + sit-anchor fix: (1) anchors now carry the object's EDGE (OBB support point toward room centre) — bedsit sits on the bed edge, walksit stands outside the desk edge facing in, lie keeps centre; (2) grab her hands/head in VR (fist or grip near a joint) — CCD IK follows your hand, spine leans when over-extended, past that her body is dragged (soft ragdoll chain), eased release; (3) touch awareness: grab/release/proximity events flow to a per-room buffer injected into her context as [Physical — VR presence] so she reacts to being touched/moved
Hologram polish from first live test: hide the global 60m floor slab in passthrough (it blanked the lower half of the real room), auto-arm the mic pipeline on hologram entry (voiceCapture->server STT, armed from the VR button's user gesture via __commslinkStartVoice), floating transparent in-VR chat readout (last 5 messages as outlined text, lazy head-follow, no background card)
My Space HOLOGRAM mode: entering VR in a scanned space now opens passthrough AR + live scene tracking — the Quest re-detects walls/furniture in the CURRENT session's coordinates, so Eve stands in the user's real room aligned 1:1 by construction (no dolly offset, no replica); live labeled anchors mean 'sit on the bed' targets the physical bed; faint furniture outlines prove alignment; falls back to replica VR (spawn at floor centroid, Eve stepped along the long axis) if AR/spatial-data is refused; disposeSubtree now frees lines+sprites
Scanner v3.2: depth layer self-disables when the headset declines depth-sensing (3S) — getDepthInformation THROWS on non-granted sessions; check session.enabledFeatures, isolate depth in its own guard, and stop asking after first failure so the scene pipeline + auto room-capture are never blocked
Scanner v3.1 hardening: all XR features optional (a required-feature miss silently kills the session request), frame-loop crash guard (a per-frame throw = no panel/no clap/no way out), 3x-trigger finish for controller users (clap needs hand-tracking), v3 badge + stale-cache hint on page
My Space: Eve inhabits your scanned room — new 'myspace' scene renders the /scanner capture (real walls + labeled hologram furniture), labeled objects become her anchors (bedsit/walklie/walksit retarget to YOUR bed/desk), authed scan fetch in AvatarPanel, My Space room option + create-room scanner link
Room Scanner v3 — scene-first: draws Meta's own Space Setup (WebXR plane/mesh detection) as labeled glowing borders + furniture boxes instead of reconstructing from raw depth; auto-launches native room capture (initiateRoomCapture) when no room data; depth points demoted to detail layer; exports labeled SpaceScan JSON; new /api/v1/space per-user save so Eve can inhabit the scanned room
Scanner v2 — visible feedback + clap-to-end: live cyan wireframe net painted over surfaces each frame, floating status panel (point count + depth-availability warning), clap-hands gesture to finish (hand-tracking), bigger accumulated points
Add WebXR depth scanner (/scanner): from-scratch 3D reconstruction — immersive-AR + WebXR Depth Sensing, un-projects per-frame metric depth to world points using the headset pose, accumulates a voxel-deduped point cloud you watch build over passthrough, exports .PLY. Standalone page, isolated from /chat
Self-heal corrupt room layouts on load: clamp widthFt/lengthFt to 4-60, heightFt 6-20, reset implausible off-origin centers (>40ft) — so a past resize runaway (a 399ft room 65ft off-origin) can't strand the user with unreachable walls
Fix wall resize shooting to infinity: reject implausible/NaN resize targets (a near-horizontal telekinesis ray hits the floor near-infinitely far; a glitched hand joint can be NaN) and hard-cap the room dimension to 4-60ft, instead of resizing the room to infinity
Wrist UI rebuilt from scratch: ONE crisp canvas-rendered panel (rounded dark card, MY ROOM title, dims/prop status, 5 styled buttons Reach/Next/Place/Save/Exit) instead of 5 fighting planes — POKE a button with your other index finger to press it (ray+pinch still works too). Fixes the empty-blue-panel + facing + occlusion issues
Wrist UI content fix: panel was backwards (Object3D.lookAt aims +Z not -Z) so you saw the blank blue backing — now faces you; content (display + Reach/Next/Place/Save/Exit) forced on top (depthTest off) so the panel cannot occlude it
Wrist UI reliability: double-sided panel (was a single-sided plane invisible from the back), ALWAYS visible while a hand is tracked (removed the fragile watch-pose distance gate that never triggered), robust wrist-joint lookup (either hand), and correct billboard so the face turns toward you
VR fixes: (1) wrist UI now rides the tracked WRIST JOINT + billboards to you (was pinned to the controller grip = invisible with hand-tracking); (2) My-Room placed furniture (bed etc.) is now grabbable; (3) furniture checked BEFORE walls (+ tighter wall threshold) so you stop grabbing the wall by accident
Security hygiene: remove stray agent binary, untrack local .vscode DB creds
VR: two-handed manipulation (grab a furniture cluster with BOTH hands → move+rotate+orbit it rigidly like a real object; clusters re-pivoted to their centre so rotation spins in place); laser rays HIDDEN by default; Telekinesis mode (wrist 'Reach' button) toggles the rays on + enables far grabbing by pointing+fisting; fancier wrist screen (border, 5 buttons, reach-state)
Fix: can't release a grabbed object with hands — added missing selectend->release (pinch-release was never wired, so a hand-grab got stuck). Also hide the grip blob while a real hand is tracked so hands look identical in every room
Controller-free hand-gesture grabbing: detect a FIST/grab gesture from the tracked finger joints (fingertips curled toward the wrist) → grab; open hand → release. Grab now uses the palm position (hand-tracking) or the controller grip. Close your hand around an object (e.g. the dresser) to move it, no controller needed
Fix: VR button could vanish — decouple WebXR check from engine/ready (check navigator.xr on mount); My-Room layout loads in background (never blocks readiness)
Room walls: asymmetric resize (grab a wall → opposite wall PINNED, only the grabbed side moves) + ROTATE by dragging a wall sideways (room pivots on the far wall). Room now tracks centerX/centerZ/rotation; walls tagged by side; furniture follows the room transform; near-grab works room-local so it's rotation-aware
Grab fix (hand-model init non-fatal so furniture stays grabbable) + FASTER DEPLOYS: deploy-ec2.sh no longer nukes the build cache every deploy (gated on disk >=80%) so yarn-install stays cached — was forcing a cold ~5min build every time
VR iteration: laser-pointer rays on both hands (grab far/unreachable walls + furniture via ray, resize by pointing where you want the wall); ray-based wrist buttons (fixed) + Exit VR button; finger-tracked hand models (XRHandModelFactory spheres) for Quest hand-tracking; warm ceiling light in My Room so the floor reads like the lamp-lit bedroom
My Room polish + VR editing: floor carpet matches other rooms + egg-shell white walls; furniture now scaled per-prop (PROP_SIZES) not tiny default; VR grab-a-wall to resize the room (drag perimeter walls, symmetric, snaps 0.5ft, persists); prototype wrist UI (right-wrist watch screen on watch-pose, left trigger presses Next/Place/Save to cycle+drop furniture)
Room builder Phase B+C: top-down floor-plan editor (SVG) — draw interior walls (2 clicks), cut doors in outer walls, place furniture from the prop library, erase; engine buildRoomShell now splits walls for door gaps + applyRoomLayout reloads furniture live. Full custom-room build: dimensions + walls + doors + furniture, persisted + walkable in VR
Room builder Phase A: room selector dropdown (Eve's Room / Studio / My Room) + 'myroom' scene template with procedural wall shell built from user dimensions (buildRoomShell, feet->metres, 4 perimeter walls + interior-segment support); Room builder panel sets W/L/H (ft), persists via /api/v1/avatar/layout (template=myroom), rebuilds walls live. Foundation for walls/doors/furniture (Phase B/C)
VR furniture grab-and-slide: group room props into 5 movable clusters (bed+lamp+laptop, computer desk, electronics desk+shelf, TV+stand, standing lamp) via Group.attach; squeeze the grip to grab the cluster your hand is inside, slide it along the floor (X/Z), release to drop. WebGL-only (CSS3D screens don't render in VR)
WebXR VR (Meta Quest 3) for /chat: renderer.xr + setAnimationLoop loop conversion; VR goggle button (shown only in WebXR browsers) enters immersive-vr; player dropped into the room via a dolly rig (invisible body, head=headset); controllers -> visible hand blobs; orbit/fly-cam + CSS3D gated during a session
Animation builder v3: fix 'stands there doing nothing' — builder commands now drive the re-prompt loop (hasDataCommands) so she PROGRESSES keyframe-by-keyframe across passes and finishes at {anim_done}, instead of starting a session and stalling. Prompt flipped from 'wait for user' to autonomous progression + 'actually emit the commands, don't narrate'
Animation builder v2: fix motionless-build bug (one {anim_step} per message — multiple would snapshot the same final pose); loud per-keyframe chat logging (shows the pose + timing); {anim_undo} to redo a keyframe the user flags; clear 'finished + playing' message; pacing rule so the user can watch + interject
Guided animation builder: {build_animation}->{anim_step transition:MS hold:MS}xN->{anim_done} lets the AI compose animations one decision at a time (auto-saves+tests; holds via repeated keyframe). Prereq: {avatar_move} now shadows the server working-pose so pose_save/anim_step capture DOF poses. anim_delete now removes authored library clips too
AI body control: {avatar_move <dof> <deg>} command lets the agent drive all 39 semantic joint DOFs directly (mapped+clamped client-side via the calibrated map); wired across handler (regex/tool/prompt/strip/hasAnyCommand/exec) + AvatarPanel socket->setDof
Joint Config: expand to full humanoid DOF set (39) — add hip spread/rotate, shoulder/wrist/knee/ankle/spine planes; existing motions widened bidirectional (arms/thighs swing fwd+back)
Avatar Joint Configuration: semantic DOF layer (descriptive named joint controls mapping to VRM bone axes, anatomically ranged) + Joint Config UI to test/calibrate/save each mapping by eye
Agentic executor: ENSEMBLE strategy — mirror a blend of the top-5 algos (averaged position weights) capped 20%/name, instead of the single #1. Kills the daily whipsaw that swung the account to gold+70% cash when one defensive algo topped the board
Remove the one-shot lab2 E2E verification block from deploy-ec2.sh (pipeline verified — 2 champions injected OK; weekly cron takes over)
One-shot: end-to-end verify the lab2 champion-injection pipeline via the sanctioned deploy path (tiny backtest + inject 2 champions, marker-guarded)
Ligo Tier 3 champion-injection pipeline: lab_v2 keeps champion genomes + new inject_champions() inserts top-K OOS champions into the LIVE pop as IMMIGRANTS (add, not replace); --inject-live CLI + weekly Mon 06:00 UTC cron (backtest -> inject top-5). Bridges offline OOS rigor to live walk-forward evolution
Ligo evolution Tier 2+3-scale: CROSSOVER (instrument-row recombination of 2 parents), RANDOM IMMIGRANTS (15% of births = fresh novelty), FAMILY_CAP=12 (break the ms_klarman monoculture), and GROW toward POPULATION_TARGET=300 (+5/cycle) instead of drifting down
Ligo evolution Tier 1: unfreeze the algo population — rank by RETURN (total_value/initial_capital) not raw dollars, child capital parity (100k), GRACE_DAYS=20 newborn audition before culling, gentle daily churn (10%->3%), replace-each-death so population stops shrinking; add+backfill initial_capital column
Agentic rebalancer: fix 'Not enough shares to sell' — place SELLs by share quantity clamped to shares_available_for_sells (round down), instead of dollar-based sells that overshot on a stale quote; deploy-ec2.sh now syncs rebalance.mjs into the api secrets volume
Carrier00 FPS Phase 2b: CITY CAPTURE — clear an enemy city's defenders + hold it on foot → it flips to you KEEPING its buildings (vs raze). New server world.ts capture() + capture socket handler + Net.sendCapture; client tryCapture + progress HUD
Carrier00 FPS Phase 2a: player MARINE SQUAD — 6 friendly marines deploy when you go ashore near an enemy city, follow you in formation + engage the defenders; soldier AI generalized to target nearest hostile (both sides fight each other + you); friendly fire passes through your own squad
Carrier00 FPS Phase 1b: city DEFENDER soldiers (2 per military building + 1 per 10 pop, client-side from each enemy city) — guard/patrol, engage on sight + shoot back; player rounds drop them (swept IFF hit test); player gets on-foot HP + hurt flash + respawn at carrier
Carrier00 FPS Phase 1a: 3-weapon system on foot — Pistol/Rifle/Sniper with scroll-wheel swap, per-weapon fire-rate/damage/mag/spread, sniper scope (strong zoom + overlay, hides viewmodel), weapon HUD
Gold ★ in front of capital city names on the in-world (non-map) floating labels — drawLabel now renders the capital star like the globe/map does
Avatar editor: add Body tab — reshape head/chest/waist/arms/hands/thighs/calves/feet via bone scale (clothing conforms); Clothing+Body tabs, saved per-model
Watch party: instant hard-OFF — red X now kills the YouTube player immediately + clears server state (no refresh resume); stopVideo before destroy so audio can't leak when the player relocates. api force-recreate clears the stuck in-memory party
Avatar: in-panel Wardrobe editor — recolor + show/hide each clothing part (live, saved per-model); toggle via Clothes button or C key
Ops: deploy.sh forwards OPENAI_API_KEY into prod .env.production (sanctioned path; value never committed) — activates chat AI semantic memory embeddings
Chat AI semantic long-term memory: RAG retrieval + activation model (cosine+salience+recency+recall-freq) over agent.memories, reinforce-on-recall, decay+prune; OpenAI text-embedding-3-small adapter; graceful recency fallback when no key
Ops: remove the one-shot xlweb teardown block (decommission complete)
Ops: one-shot retire FFXIVPlugins (xlweb/XLWebServices) - remove container/image/volume + nginx site + project dir (decommissioned)
Ops: auto-prune stale Docker images + build cache after every deploy + install a weekly safety-net prune cron - fixes the recurring EC2 disk-fill (was 279 images/155GB reclaimable)
Ship the client capital changes that were missed in the last sync - isCapital now reads the server capital flag (★ shows without a Command Center) + onWorld reconcile + star placed flag·★·name
FIX nation city naming - city name was passed to claim's ownerName arg (3rd) so it fell through to the Greek/Roman autoCityName; now passes real name as the 4th (cityName) arg + marks the first city as capital (server flag) so the gold star shows immediately; fresh wipe v7 to re-found with real capitals
Force fresh map wipe (geo_reset_v6) + fix client onWorld to neutralize islands absent from the full snapshot (wiped cities now actually disappear on reconnect, not just linger client-side)
Full map reset (geo_reset_v5) - wipe all cities + restart resets AI factions so they re-found fresh, to test capitals forming with real names + the gold star
Carrier build QUEUE - queue jets/torps/heli/patrol/E-3/SR-71 (caps: 1 SR-71, 2 E-3, 3 heli, 5 patrol, 20 total aircraft); builds front-of-queue when affordable, waits otherwise; persists to server so it keeps building as money allows after logoff
Capital star was on the unused 2D nav-map; in SPHERE mode M opens the GLOBE - moved the gold capital ★ to the globe city labels (shows on any city with a Command Center, for all to see)
NPC carrier CAP now actually defends - chase speed 88->98 (a slight edge over a player jet's max so it can close + gun attackers instead of trailing/circling), acquire range 1500->2600, leash 2700->3600, gun range 95->130
Carrier00 city defense 3/3: an attacked city with a bomber doctrine (aggressive nations) sorties its bombers at the attacker's nearest carrier - pressuring you to peel jets back to defend your own flagship
Carrier00 city defense 2/3: airports now have a default AA flak gun (aa:true) - enemy cities throw orange flak with a 560-unit umbrella + 2 dmg at attacking planes, making cities costlier to attack
Carrier00 city defense 1/3: a threatened city now scrambles its FULL fighter screen fast (doctrine jet allotment, up to 5; defensive nations all-jets, aggressive reserve bomber slots) instead of a token 2 - clusters of cities field a real wall of fighters
Carrier00 Trade Ports 1b: trade ports stockpile their city's resource each turn (capital port -> capital store, others -> per-city buffer); top HUD now reads your capital's stockpile; cargo ships load port stock + deliver to the capital; city panel shows port stock + capital marker
Polar cities were buried under the pack ice - ice floes now keep a clearing around every island (lap up to the shore, never cover the land) so south-pole cities are visible + reachable
AI carriers fly a FULL air wing - doctrine loadouts bumped (6-12 fighters) + flagship CAP now follows the doctrine (up to 8 aloft, 12 at battle stations) instead of a flat 3; raised the faction plane ceiling to 26
NPC nations name their FIRST city after the real-life capital + later cities after real cities of that country; one Command Center per nation on the capital (so it's the sole starred capital)
Carrier00 Trade ports 1a: replace city Air Heli with Trade Port building (needs a Command Center/capital), register port server-side, + gold capital star on the M-map
K menu now shows the AIR WING - every carrier plane with its pilot + status, deck-slot count (used/free), and a Command Center warning so the E-3/SR-71 lock is obvious
Greyed-out build tiles now show WHY (e.g. 'Missing Command Center' for E-3/SR-71) instead of just dimming - mirrors the buy gate exactly
Long-endurance E-3/SR-71 fuel (1500/1000s vs 300) so the slow far-orbiting E-3 stops running dry mid-return and crashing; refuel still 2min
Harden plane save/restore - persist bought E-3/SR-71 by an explicit bought flag + callsign (not array position) so a lost starting fighter can never drop them; also save carrier-deck purchases instantly
Generated 2026-07-17 from git across all CommsLink repos · page 7/24, showing 601–700 of 2,361 ships · complete record: /changelog.txt · /changelog.json.