Conversation
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>
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. |
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>
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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Supersedes #291