Four sites where Pixi v8's stricter typing tripped tsgo:
- AvatarImage: container.filters is typed as 'readonly Filter[] | null'
in v8 (no longer a single-Filter union). The old fallback branch
'else container.filters = [container.filters, …]' tried to treat a
readonly array as a single Filter; collapsed to the array-spread
path which now covers both undefined and non-empty cases. Added
Filter to the pixi.js import.
- FurnitureBadgeDisplayVisualization.updateSprite() had a 4-arg
override (sprite, asset, scale, layerId) of the parent's 2-arg
signature (scale, layerId). The sprite/asset were never used from
the parameters — the body only mutated 'sprite'. Refactored to
fetch the sprite via this.getSprite(layerId) inside the override
body so the signature matches the base.
- ExtendedSprite: 'renderer.gl' / 'glRenderTarget.resolveTargetFramebuffer'
exist only on WebGLRenderer / GlRenderTarget (not the WebGPU
variants). The runtime check 'renderer.type === RendererType.WEBGL'
guarantees this; cast at the boundary to satisfy the typechecker.
- TextureUtils.generateImage: Pixi v8's Extractor.image() returns the
union ImageLike (HTMLCanvasElement | HTMLImageElement); the public
signature promises HTMLImageElement. Cast at return — the Pixi
default backend returns HTMLImageElement here.
Display Container
├── Furniture Container (renders 1st - back)
│ └── All furniture sprites sorted by z-depth
├── Avatar Container (renders 2nd - middle)
│ └── All avatar sprites sorted by z-depth
└── Badge Container (renders 3rd - front)
└── All badge sprites sorted by z-depth
✅ Badges render on top of their furniture
✅ Avatars respect proper 3D depth (in front when in front, behind when behind)
✅ Animated GIFs work beautifully
✅ Clean, maintainable code with just a tiny z-offset