Packing a Full 3D Character Outfit into a Single 27-Bit Integer
3D Engineering · October 14, 2026 · 5 min read
How `encodeSpec` and `specOf` serialize 11 customization channels and 9 boolean accessories into a single safe JavaScript number.
Compact Presence Payloads for Real-Time Rooms
In a multiplayer room powered by realtime presence heartbeats, every byte in a participant’s metadata object is broadcast to all peers whenever status or seat assignments update. Sending a verbose JSON object with ten string properties for every avatar would bloat presence payloads and complicate caching.
By indexing our palettes and style arrays in `src/lib/avatars.ts`, we mapped every customization choice—hair style, hair colour, skin tone, outfit type, outfit colour, trousers colour, hat type, hat colour, shoe style, shoe colour, and a 9-bit bitmask for accessories—into fixed-stride integer radices.
Deterministic Caching and Instant Thumbnail Rendering
Because any character configuration maps bijectively to a single integer (`specId`), our 3D thumbnail renderer (`optionThumbs.ts`) and geometry cache (`characterBuild.ts`) can use that integer directly as a lookup key. When you flip between tabs in the Character Creator or when ten students join a room, previously rendered avatar portraits and shared geometries resolve in O(1) time.
For backward compatibility and bot presets, numbers 0 through 9 map to our ten curated signature characters, while any number ≥ 10 unpacks into a full custom spec.