Skip to content

Loom (Alpha) pivot: entity browser + thread chips#296

Merged
CoreyRDean merged 1 commit into
developfrom
coreyrdean/loom-entity-browser
May 27, 2026
Merged

Loom (Alpha) pivot: entity browser + thread chips#296
CoreyRDean merged 1 commit into
developfrom
coreyrdean/loom-entity-browser

Conversation

@CoreyRDean
Copy link
Copy Markdown
Collaborator

Summary

Replaces the zone-only browse model from the closed #293-#295 with the Loom design's actual centerpiece: an everything-browser and thread chips that jump between related entities.

The previous alpha shipped a view of one corner of zone metadata (waypoints / spawns / triggers / portals) and skipped everything that actually makes a project interesting — the actors, items, spells, factions. This pivot surfaces all of it.

Stacks on top of merged #292 (skeleton + Project Manager launcher).

What it does now

Browser — everything-grid with a category tab bar:

[Actors] [Items] [Spells] [Zones] [Factions] [Animation Sets]
                                                              
[Goblin Shaman   ]  [Goblin Scout ]  [Old Cassian ]  [Bandit  ]
[Forest Tribe    ]  [Forest Tribe ]  [Veiled       ]  [Forest  ]
[XP mult: 100    ]  [XP mult: 100 ]  [XP mult: 100 ]  [XP: 100 ]

Each card paints kind-specific summary content. Hover lifts the border to arcane blue. Click focuses the entity.

Composer — right-side property panel for the focused entity, with per-kind layouts:

Kind Thread chips it offers
actor Faction, M anim set, F anim set
zone Per-portal chips to the target zone (broken portals in red)
faction Chip per member actor (computed: actors whose DefaultFaction matches)
animset Chip per actor using this anim set as M or F
item / spell No entity-to-entity refs in rcce2's data model; script bindings render as text

Thread chips — clickable rounded rects with kind icon + target name + arrow. Click pushes current focus onto a back stack and refocuses on the target. Broken references render in danger red.

Back stack — Esc walks back through the navigation chain. Hero flow:

Goblin Shaman -> [Faction: Forest Tribe] -> Forest Tribe ->
[Member: Goblin Scout] -> Goblin Scout -> Esc -> Forest Tribe ->
Esc -> Goblin Shaman -> Esc -> closes composer back to browser

Footer hint shows ""Esc walks back · N in trail"" when the stack is non-empty.

Architecture

File What
src/Loom.bb Data load + main loop. Browser_RenderAndUpdate + Composer_RenderAndUpdate per frame. Esc consumes one of: pop back stack | close composer | exit Loom.
src/Modules/Loom/Threads.bb Focus state + back stack (BBList of LoomFocusEntry) + per-kind name resolution + Threads_RenderChip primitive.
src/Modules/Loom/Browser.bb Category tab bar with brass underline for active tab, paginated card grid auto-fits window width, per-kind card bodies.
src/Modules/Loom/Composer.bb Per-kind detail page renderers, row/chip layout helpers, value formatters, zone-name -> Handle resolver for portal threads.

Read-only in alpha

Every field is read-only. Editing is a beta concern — it needs save / dirty tracking that's its own design surface. The alpha's job is ""I can finally see my whole world through Loom's lens, and follow the threads between things.""

Blast radius

  • New files: Browser.bb, Composer.bb, Threads.bb
  • Rewritten: Loom.bb (was splash skeleton, now data-load + browse loop)
  • No existing GUE module modified
  • All five engine targets compile clean. Loom.exe ~2.4 MB.

Why no 3D zone viewport

ClientAreas.bb's LoadArea is entangled with GUE-specific UI globals (GY_Cam, GY_*, ResolutionType, RandomImages, GetMusicName$, GetTexture, the Gooey lib). Pulling all of that in would lock Loom to GUE's UI substrate, which is exactly what Loom is supposed to decouple. A literal 3D viewport can land as a beta refactor once LoadArea's data path is decoupled from its UI path.

Test plan

  • compile.bat builds clean
  • In Project Manager, click Loom (Alpha)
  • Loading screen flashes, then browser opens to Actors tab
  • Cards visible: every actor in the project, with race [class] + faction + XP mult
  • Click a tab — Items / Spells / Zones / Factions / Animation Sets — grid repopulates
  • Click an actor card — composer appears on right with full actor data
  • Click the actor's Faction chip — composer switches to that faction, shows roster
  • Click a member chip — composer switches to that actor, footer shows ""Esc walks back · 2 in trail""
  • Press Esc — back to faction; Esc again — back to original actor; Esc again — composer closes
  • Press Esc on plain browser — Loom exits
  • Switch to Zones tab, click a zone — composer shows zone metadata + portal links
  • Click a portal chip — composer switches to that destination zone (if target resolves; broken targets render in red)

What's NOT in (beta concerns)

  • Editing. Every field is read-only.
  • Search. Hub-spoke nav works for known entities; for "find anywhere by name" you walk the tab bar. A Ctrl+F palette would be the obvious next add.
  • Scrolling. Card grids and composer pages are sized for what fits; large projects will exceed both. Browser pagination + composer scroll come with editing.
  • 3D zone view. Deferred for the reason above.
  • Spell/item back-references. The data model doesn't store "which actors cast this spell" — that's determined by scripts. Would need to grep scripts to surface.

🤖 Generated with Claude Code

Replaces the zone-only browse model from #293-#295. The previous alpha
shipped a view of one corner of zone metadata (waypoints / spawns /
triggers / portals) and skipped everything that actually makes a
project interesting -- the actors, items, spells, factions. This
pivot surfaces all of it through the design's actual centerpiece:
"every reference is a clickable thread."

What the alpha now does:

  Browser: everything-grid with a category tab bar at the top.
    Categories: Actors / Items / Spells / Zones / Factions /
    Animation Sets. Each card paints kind-specific summary content:

      actor   : Race [Class] + faction name + XP multiplier
      item    : name + type label + value
      spell   : name + recharge + script binding (if any)
      zone    : name + portal/spawn/trigger counts
      faction : name + computed member count
      animset : name + clip count + computed "used by" count

  Composer: right-side property panel that paints whatever's focused.
    Per-kind detail pages with the entity's full read-only field set.
    Each composer page also includes a "Threads" section with chips
    for every reference the entity makes:

      actor    -> faction, M anim set, F anim set
      zone     -> per-portal chips to the target zone (when the target
                  resolves; broken portals render in danger red)
      faction  -> chip per member actor (computed: every actor whose
                  DefaultFaction matches this index)
      animset  -> chip per actor using this anim set (computed: M or F
                  binding)
      item     -> no entity-to-entity references in rcce2's data model;
                  composer shows the script binding as text
      spell    -> same; script + restriction strings

  Thread chips (Threads.bb): clickable rounded rects with kind icon +
    target name + arrow. Click pushes current focus onto a back stack
    and refocuses on the target. Broken references render with a
    red border and danger-colored "(broken kind #N)" text.

  Back stack: Esc walks back through the navigation chain. Hero flow:

    Goblin Shaman -> [Faction: Forest Tribe] ->
    Forest Tribe -> [Member: Goblin Scout] ->
    Goblin Scout -> Esc -> Forest Tribe -> Esc -> Goblin Shaman ->
    Esc -> closes composer back to browser

    Footer hint shows "Esc walks back -- N in trail" when the stack
    is non-empty; switches to "Esc returns to browser" when empty.

Architecture:

  src/Loom.bb
    Data loading (unchanged from #293). Main loop has a single
    Browser_RenderAndUpdate + Composer_RenderAndUpdate per frame.
    Esc consumes one of: pop back stack | close composer | exit Loom.

  src/Modules/Loom/Threads.bb
    Focus state (Loom_FocusKind$ / Loom_FocusID), back stack
    (Loom_BackStack BBList of LoomFocusEntry), name resolution per
    kind, and Threads_RenderChip primitive that all surfaces use.

  src/Modules/Loom/Browser.bb
    Category tab bar with brass underline for the active tab,
    paginated card grid that auto-fits the window width, per-kind
    card body renderers.

  src/Modules/Loom/Composer.bb
    Per-kind detail page renderers, row+chip layout helpers,
    boolean / enum / float formatters, zone-name -> Handle resolver
    for portal threads.

Read-only throughout. Editing is a beta concern -- it needs save /
dirty tracking that's its own design surface.

All five engine targets compile clean. Loom.exe grew from ~2.0 MB
(skeleton) to ~2.4 MB (with data layer + browser + composer +
threads). About 1,200 lines of Loom-specific code total.

Supersedes the closed #293 (atlas), #294 (zone map), and #295
(zone composer). Branches off develop on top of the merged #292
(skeleton + PM launcher).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@CoreyRDean CoreyRDean requested a review from a team as a code owner May 27, 2026 00:14
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: aba0d594f8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Function Browser_RenderAndUpdate(sw, sh, project$)
Local mx = MouseX()
Local my = MouseY()
Local clicked = MouseHit(1)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve click events for composer chip navigation

Browser_RenderAndUpdate reads MouseHit(1) before Composer_RenderAndUpdate runs in the same frame, and MouseHit is edge-triggered since the last call. That means the browser consumes the click and the composer receives 0, so thread chips cannot be followed reliably (and often never fire at all), which breaks the core Loom navigation flow. Sample the mouse click once per frame (e.g., in Loom.bb) and pass it into both render/update functions.

Useful? React with 👍 / 👎.

@CoreyRDean CoreyRDean merged commit dafbab4 into develop May 27, 2026
1 check passed
@CoreyRDean CoreyRDean deleted the coreyrdean/loom-entity-browser branch May 27, 2026 00:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant