Skip to content

WIP: Sequencing rework#295

Closed
OmniTroid wants to merge 26 commits intomasterfrom
sequencing-rework
Closed

WIP: Sequencing rework#295
OmniTroid wants to merge 26 commits intomasterfrom
sequencing-rework

Conversation

@OmniTroid
Copy link
Contributor

@OmniTroid OmniTroid commented Feb 11, 2026

Supersedes #291

OmniTroid and others added 21 commits February 1, 2026 23:17
Implements preloading of all assets before IC message rendering begins,
eliminating visual glitches from sprites popping in late. Adds caching
to avoid repeated HEAD requests for previously loaded assets.

New cache system (webAO/cache/):
- AssetCache: Cache API wrapper with in-memory metadata (LRU, 1000 entries)
- UrlResolver: Extension probing with request deduplication
- AssetPreloader: Parallel resolution of all URLs for a ChatMsg

Modified render flow:
- handleMS now preloads all assets before calling handle_ic_speaking
- handleICSpeaking and chat_tick use pre-resolved manifest URLs
- Graceful fallback to original setEmote() when manifest unavailable

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Only set image src if the URL has changed, preventing the idle
animation from restarting when paired characters receive new messages.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move appendICLog and checkCallword to handleMS before preloading
  to ensure messages are logged in arrival order
- Add message sequence counter to track current message
- Skip rendering if a newer message arrived during preload
- Prevents out-of-order IC log entries when messages arrive rapidly

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Introduces a comprehensive, well-typed RenderSequence interface that
formally represents all 32 MS packet fields (indices 0-31), character
INI data, and mutable runtime state, replacing the loosely-typed ChatMsg
interface with proper enums, literal unions, and three-layer separation
of immutable packet data, immutable INI data, and mutable render state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the mutable packet/INI/runtime three-layer design with a fully
pre-computed, self-contained render plan. The renderer becomes a dumb
executor that follows the plan mechanically.

- Remove PreloadManifest import, RenderRuntimeState, INITIAL_RUNTIME_STATE
- Add pre-parsed text types (TextRun, InlineEffect, TextDisplay)
- Add resolved sprite types (CharacterDisplay, PairDisplay)
- Add phase configs (ShoutPhase, PreanimPhase)
- Add sound/effects types (SfxConfig, EvidenceDisplay, ParsedFrameEffects, OverlayEffect)
- Add layout/chatbox types (PositionLayout, ChatboxDisplay)
- All fields readonly, JSON-serializable, no DOM types

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the hard-coded main+pair character model with an N-character
array of independent timelines. Each CharacterTimeline holds a flat
sequence of RenderSteps where the last step (durationMs: null) is the
terminal emote. This removes the intro/resting distinction entirely.

- Remove CharacterDisplay, PairDisplay, PreanimPhase,
  MainCharacterData, PairCharacterData
- Add RenderStep (uniform step with sprite, talking, duration, sfx)
  and CharacterTimeline (steps + flip/offset/frameEffects/slide)
- Unify MSPacketData.character + .pair into .characters array
- Move blipSound into TextDisplay, sfx/frameEffects/slide into
  CharacterTimeline
- Add global.d.ts for window.* function declarations
- Fix remaining tsc errors (SHOUTS type, handleMS chatmsg properties)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Generalize PreloadManifest to use a characters[] array of
CharacterSpriteUrls instead of hard-coded mainChar*/pairChar* fields.
Preloader methods now operate on CharacterSpriteUrls directly, and
consumers index into the array by position.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Parse the slide flag (MS field 32) from the wire, build a SlidePhase in
the render sequence builder when conditions are met (different panoramic
sides, not a zoom emote), and execute it as a timed CSS transition on
client_fullview with 300ms bookend delays and 500ms pan animation.

Also wires up buildRenderSequence/executeRenderSequence into handleMS
and exposes getRenderContext from the viewport, completing the render
pipeline integration. Removes the misplaced per-character slide field
from CharacterTimeline in favor of the viewport-level SlidePhase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace getResources.js and untyped Testimony interface with typed
Shout/Testimony/TextColor modules following the Position pattern
(union type + config Record). Deduplicate TextColor enum and color
name array into a single enum with derived lookup. Inline RT packet
parser into handleRT. Use enum members throughout the render pipeline
instead of raw numeric literals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce CharIni as the typed shape for client.chars[] entries,
with raw ini sections (options/emotions/soundn/soundt) stored
directly on the object instead of a separate inifile field.
Replace the hand-rolled iniParse.ts with the ini npm package
and a thin case-normalizing wrapper in CharIni.ts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The render pipeline now accepts CharIni directly instead of a
3-field projection. handleMS constructs a per-message CharIni
copy with packet-level overrides (blips, blank-post chat).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The render sequence now fully owns the viewport display — background,
desk, and speed-lines URLs are resolved by AssetPreloader and included
in PositionLayout, eliminating executeRenderSequence's dependency on
global viewport state (getBackgroundName/getBackgroundFolder).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pressing Enter or picking an emote before emotes are loaded would crash
with "Cannot read properties of undefined (reading 'zoom')". Add early
guards so these are no-ops when client.emote is undefined.

Also adds temporary RenderSequence debug logging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The default values (blips: "male", side: "def", etc.) were repeated
inline in setupCharacterBasic, ensureCharIni, and handleMS. Centralise
them in a single defaultCharIni() factory in CharIni.ts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The ini package treats # as an inline comment delimiter, which truncates
emotion entries like "normal#-#normal#0#1" to just "normal". Pre-escape
# in values before parsing so they are preserved as data.

Adds charIni.test.ts covering emotion parsing, showname case preservation,
comment handling, and empty values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@OmniTroid
Copy link
Contributor Author

Generally works but there are still some bugs left (eg. chatbox does not render sometimes). I also want to add some more MS->RenderSequence tests for better coverage and make some tweaks to the RenderSequence data structure itself.

OmniTroid and others added 5 commits February 24, 2026 18:09
Servers send -1 for otherCharId to indicate no pair, but leave garbage
in the otherName/otherEmote fields (e.g. "0<and>0"). The parser now
clears those fields when otherCharId < 0, preventing
buildCharacterTimelines from creating a phantom second character.

Also adds MSPacket debug logging and the CharacterOffset type cleanup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Provides a machine-readable contract for the RenderSequence shape,
useful for debugging, external tooling, and catching drift between
the TypeScript types and builder output. The schema uses
additionalProperties: false and required fields at every level so
any field addition or removal is caught.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…Exists negative cache

Separate the Cache API-based asset system (AssetCache, UrlResolver, AssetPreloader)
onto its own branch so sequencing-rework uses a simpler approach: a negative cache
in fileExists.ts and a resolveManifest() function that probes extensions with HEAD
requests instead of the full cache machinery.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@OmniTroid
Copy link
Contributor Author

The idea is sound (compile MS+char.ini+more to RenderSequence then render it out), but this implementation is overengineered (a separate PreloadManifest type should not be necessary) and the RenderSequence type doesn't cover the whole viewport rendering completely and needs more conceptual work.

@OmniTroid OmniTroid closed this Feb 26, 2026
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