Skip to content

feat(ui): expand the lobster pet's random universe#112073

Merged
steipete merged 7 commits into
mainfrom
steipete/lobster-randomization-ideas-afa370
Jul 21, 2026
Merged

feat(ui): expand the lobster pet's random universe#112073
steipete merged 7 commits into
mainfrom
steipete/lobster-randomization-ideas-afa370

Conversation

@steipete

@steipete steipete commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

The sidebar lobster pet's random universe was small enough to exhaust quickly: 12 palettes, one visitor species besides strangers (the crab), a single walk-up entrance, and a Lobsterdex that only ever collects palettes and never gives anything back. Regular users see the whole variety space within days, and the collection has no long game.

Why This Change Was Made

Maintainer request: more random lobsters for the bottom-left lobster, built from a reviewed idea list (shinies as a multiplier, real-genetics palettes, an ecosystem of ledge visitors, and making the Lobsterdex feel alive instead of write-only).

User Impact

All decorative, all client-side, all behind the existing "Lobster visits" toggle; reduced motion keeps its guarantees.

  • Shiny lobsters (~1 in 512): sparkle overlay + saturated sheen on any palette, in the name tooltip, tracked per palette in the Lobsterdex (gold star on the mini).
  • Two new palettes: cottoncandy (pastel pink/blue with a slow iridescent drift, after the famous Maine catches, ~0.8%) and lumen (bioluminescent photophores that only really glow in the dark theme, ~2%). Rare names: Taffy and Glimmer.
  • Old friends return (~8% of loads): a palette the Lobsterdex already remembers comes back wearing its recorded first-visitor name, waves hello on arrival, and the title reads <name> · an old friend.
  • The Elder (~1.5% of loads): scale-3, barnacled, sleepy, mighty-clawed "Methuselah · old as the tides". Never molts.
  • Crusher/pincer claw asymmetry (~15%): real lobsters have a crusher and a pincer; one claw renders mighty, the other dainty.
  • Freckles (~12%) and seeded eye-glint tints (~30%) for common palettes (rare palettes keep their signature glints; offline grey still wins the cascade).
  • New ledge traffic inside the unchanged 9.5% passer gate: a snail (90-second crossing — glance away, glance back, still crossing), a rubber duck, and a jellyfish drifting above the ledge, joining the stranger and the crab. Per-kind crossing durations; the resident reacts mid-cross (friends wave, shy pets peek).
  • Entrance variants: rare arrivals descend under a balloon (6%) or pop out of a bubble (7%) instead of walking up.
  • Message in a bottle (~3% of loads): washes up on its own clock, pet or no pet; clicking it swaps the tooltip to one of 14 fortunes, then the tide reclaims it.
  • National Lobster Day (Sept 25): monocles join the seasonal accessory pool. We do not cook friends.
  • Completed-Lobsterdex reward: once all 14 palettes have visited, a quiet golden trim appears along the ledge.

Determinism is preserved: every new feature rolls on its own XOR-salted seeded stream, new look traits append after the existing roll sequence, and all legacy probe seeds (0/2/7/21/42/70/91) keep their exact roles.

Also includes a structural refactor to stay under the max-lines cap: static SVG art moved to lobster-pet-sprites.ts, passer/bottle scheduling into a LobsterLedgeTraffic ReactiveController (lobster-pet-traffic.ts), and rare-load identity resolution into lobster-pet-plans.ts.

Evidence

New variants (live components, probed seeds, dark theme):

variants

Ledge traffic + bottle (crossings mid-ledge; snail + opened bottle in the second shot):

traffic

snail and open bottle

Lobsterdex before / after (12 → 14 palettes, shiny stars):

before

after

Real sidebar with a visiting pet and the golden completed-dex trim:

sidebar

Validation (Blacksmith Testbox, provider blacksmith-testbox):

  • pnpm test ui/src/components/lobster-pet.test.ts ui/src/components/lobster-dex.test.ts — 69/69 pass (58 pet incl. 11 new rare-load/plan tests, 11 dex incl. shiny immutability).
  • pnpm check:changed — full gate green (conflict markers, max-lines ratchet, format, i18n catalog, typecheck core tests, typecheck UI, lint core).
  • oxlint clean on all touched files including the max-lines cap after the module split; oxfmt clean.
  • Screenshots captured with a Playwright harness against the e2e mock gateway using deterministic probe seeds (harness not committed).
  • Codex autoreview (gpt-5.6-sol, high), four rounds: disconnect-lifecycle and dead-export findings accepted and fixed; one accessibility finding consciously rejected (note below).

Review note (consciously rejected finding): Codex autoreview repeatedly flagged that the bottle is aria-hidden, pointer-only, and tooltip-based. This is intentional and consistent with the whole lobster pet surface: every sprite and interaction here (poke, pet, shoo, names, honorifics, moving-day flavor) is decorative, out of the accessibility tree, and rides the native title channel specifically to avoid an i18n surface. A focusable easter-egg button would inject itself into every user's tab order ~3% of loads, and visible fortune text would create a new localized-copy surface — both worse trades. Documented inline at the showBottle scene comment. The reviewer's other findings (traffic-controller disconnect lifecycle, dead exports) were accepted and fixed.

steipete added 3 commits July 20, 2026 20:13
Shiny rolls (1/512) with Lobsterdex tracking, cotton candy and lumen
palettes, crusher/pincer claw asymmetry, freckles, seeded eye glints,
elder and old-friend rare loads, balloon/bubble entrances, snail/duck/
jellyfish ledge traffic with per-kind crossing times, passer reactions,
a message-in-a-bottle event, National Lobster Day monocles, and a golden
ledge trim for a completed Lobsterdex.
lobster-pet-sprites.ts owns the static SVG art, lobster-pet-traffic.ts
owns passer/bottle scheduling as a ReactiveController, and load identity
(elder, old friend, dex completion) moves into lobster-pet-plans.ts;
keeps lobster-pet.ts and lobster-pet-look.ts under the max-lines cap and
fixes the passerBaseStyle consistent-return lint.
@steipete
steipete marked this pull request as ready for review July 21, 2026 04:57
@openclaw-barnacle openclaw-barnacle Bot added the maintainer Maintainer-authored PR label Jul 21, 2026
steipete added 4 commits July 20, 2026 21:59
Review findings: a host reconnect no longer shows a frozen passer or an
unebbing bottle, and the bottle joins the rest of the decorative ledge
sprites behind aria-hidden (fortunes stay on the native-tooltip channel
by design - no i18n surface).
…mers

isLobsterElderLoad and planLobsterOldFriend become module-local (tests
prove them through resolveLobsterLoadIdentity), and the traffic
controller's hook/scene types stay local; fixes the knip production
unused-export gate.
Lit does not re-render on reattach by itself; the queued update makes
sure a detached-then-reattached pet never shows a stale passer/bottle.
@clawsweeper

clawsweeper Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper status: review started.

I am starting a fresh review of this pull request: feat(ui): expand the lobster pet's random universe This is item 1/1 in the current shard. Shard 0/1.

This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking.

Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted.

@steipete

Copy link
Copy Markdown
Contributor Author

Land-ready verification (pre-merge):

  • Head: 569bed716f259db1ed68ff1f0034ce68fd764f3c — hosted CI openclaw/ci-gate pass on this exact head (CI run); zero failing or pending checks.
  • Focused proof (Blacksmith Testbox, blacksmith-testbox, lease tbx_01ky1fsxd5040j7c1p1xdgcpyj): pnpm test ui/src/components/lobster-pet.test.ts ui/src/components/lobster-dex.test.ts → 69/69 pass at this head; oxlint + oxfmt --check clean on all touched files.
  • Autoreview: four Codex rounds (gpt-5.6-sol, high). Accepted and fixed: traffic-controller disconnect lifecycle (incl. requestUpdate on clear), knip dead production exports. Consciously rejected: bottle accessibility rework — see the "Review note" in the PR body and the inline invariant comment at the showBottle scene code.
  • ClawSweeper: two review leases on this PR expired without posting a review (last placeholder lease ended 06:44Z); no Rank-up moves were ever posted, so there is nothing to apply. Landing with this note rather than silently; happy to address moves in a follow-up if a later sweep posts them.
  • Known proof gap: none beyond the consciously rejected finding above. Screenshots in the PR body were captured from live components against the e2e mock gateway with deterministic probe seeds.

@steipete
steipete merged commit ae27ee9 into main Jul 21, 2026
104 checks passed
@steipete
steipete deleted the steipete/lobster-randomization-ideas-afa370 branch July 21, 2026 07:18
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

vincentkoc added a commit that referenced this pull request Jul 21, 2026
* origin/main: (24 commits)
  fix(agents): keep compaction on live session model (#95713)
  fix(plugin-sdk): guard provider catalog live URL parsing against malformed responses (#109986)
  chore(cli): drop dead classifiers and single-use wrappers left by fallback removal (#112191)
  feat(ui): expand the lobster pet's random universe (#112073)
  chore(ci): audit dependency fingerprint exports (#112190)
  fix(ui): preserve graphemes in provider icons (#109509)
  fix(ui): align settings search with navigation rows (#112172)
  fix(agents): allow configless gateway rebind to activate standalone owner (#111841)
  fix(secrets): register secret targets for installed-origin plugins (#104347)
  improve(ui): show real machine identity in the place picker (#112162)
  fix: webChat scrollback history is too limited — older assistant replies and tool outputs disappear when scrolling… (#104250)
  test(ui): run DOM-free suites in Node (#112031)
  feat(nodes): make computer.act eligibility capability-based for desktop nodes (#112107)
  fix(apps): harden mobile gateway and watch state
  fix(ci): restore Z.AI API Platform validation (#112171)
  fix(ui): prevent Logs controls from overlapping (#112170)
  fix #95291: message tool fails to deliver files/images on Feishu (400 volc-dcdn / write ECONNRESET) while same Lark SDK upload succeeds standalone (#95514)
  refactor(cli)!: remove automatic gateway→embedded fallback from openclaw agent (#112074)
  refactor: move provider transports into packages/ai behind a typed host port (#111669)
  fix(anthropic): complete transcript reverse-scan windows across short reads (#109431)
  ...
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 22, 2026
* feat(ui): expand lobster pet randomization

Shiny rolls (1/512) with Lobsterdex tracking, cotton candy and lumen
palettes, crusher/pincer claw asymmetry, freckles, seeded eye glints,
elder and old-friend rare loads, balloon/bubble entrances, snail/duck/
jellyfish ledge traffic with per-kind crossing times, passer reactions,
a message-in-a-bottle event, National Lobster Day monocles, and a golden
ledge trim for a completed Lobsterdex.

* style: apply oxfmt formatting to lobster pet files

* refactor(ui): split lobster pet art and ledge traffic into modules

lobster-pet-sprites.ts owns the static SVG art, lobster-pet-traffic.ts
owns passer/bottle scheduling as a ReactiveController, and load identity
(elder, old friend, dex completion) moves into lobster-pet-plans.ts;
keeps lobster-pet.ts and lobster-pet-look.ts under the max-lines cap and
fixes the passerBaseStyle consistent-return lint.

* fix(ui): clear ledge traffic on disconnect, hide bottle from AT

Review findings: a host reconnect no longer shows a frozen passer or an
unebbing bottle, and the bottle joins the rest of the decorative ledge
sprites behind aria-hidden (fortunes stay on the native-tooltip channel
by design - no i18n surface).

* style: oxfmt formatting for lobster plans/sprites/pet

* refactor(ui): narrow lobster plan/traffic exports to production consumers

isLobsterElderLoad and planLobsterOldFriend become module-local (tests
prove them through resolveLobsterLoadIdentity), and the traffic
controller's hook/scene types stay local; fixes the knip production
unused-export gate.

* fix(ui): request host update when disconnect clears ledge traffic

Lit does not re-render on reattach by itself; the queued update makes
sure a detached-then-reattached pet never shows a stale passer/bottle.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui maintainer Maintainer-authored PR size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant