fix designed-room iso character rendering

This commit is contained in:
jwinterm
2026-07-06 07:04:26 -04:00
parent f505a4fb8a
commit 49ea01606e
88 changed files with 389 additions and 45 deletions
+19
View File
@@ -0,0 +1,19 @@
const Appearance = require('../src/multiplayer/appearance');
describe('appearance normalization for 3D avatars', () => {
test('preserves base colors for model avatars', () => {
const ap = Appearance.normalizeAppearance({
avatar: 'kenney-survivor-male',
tint: 'gold',
colors: { base: 'teal', skin: 'umber', hair: 'silver' },
equipment: { body: 'mail', head: 'helm' }
});
expect(ap).toMatchObject({
avatar: 'kenney-survivor-male',
tint: 'teal',
equipment: { body: 'none', head: 'none', shield: 'none', weapon: 'none' },
colors: expect.objectContaining({ base: 'teal', skin: 'umber', hair: 'silver' })
});
});
});
+10 -1
View File
@@ -82,7 +82,7 @@ describe('render pack visual resolver', () => {
RK.setEntitlementSnapshot({ totalCreditsPurchased: 1 });
const iso = RK.avatarVisuals.resolve({ avatar: 'char-ranger' }, { projection: 'iso' });
expect(iso).toMatchObject({ projection: 'iso', kind: 'iso', pack: 'iso-dungeon', allowed: true });
expect(iso.character.idle).toContain('Male_0_Idle0.png');
expect(iso.character.idle).toContain('Male_4_Idle0.png');
const compat = RK.resolveAppearance(
{ appearance: { avatar: 'kenney-survivor-female' } },
@@ -95,6 +95,15 @@ describe('render pack visual resolver', () => {
const RK = loadRenderKit();
expect(RK.isoAssets.tiles.floor).toContain('planks_S.png');
expect(RK.isoAssets.tiles.floor).not.toContain('stone_S.png');
expect(RK.isoAssets.tiles.wall).toContain('stoneWallHalf_S.png');
});
test('iso pack exposes only real imported character variants', () => {
const RK = loadRenderKit();
expect(RK.isoAssets.characters['char-villager'].idle).toContain('Male_0_Idle0.png');
expect(RK.isoAssets.characters['char-merchant'].idle).toContain('Male_7_Idle0.png');
expect(RK.isoAssets.characters['char-wizard']).toBeUndefined();
expect(RK.isoAssets.characters['char-goblin']).toBeUndefined();
});
test('projection visuals expose the saved base tint as a render color', () => {
+17
View File
@@ -35,4 +35,21 @@ describe('sceneFromTavern (render kit adapter)', () => {
const s = scene.sceneFromTavern({ cols: 2, rows: 1, layout: ['?~'], occupants: [] });
expect(s.grid[0]).toEqual(['wall', 'wall']);
});
test('uses walkability when a designed room has no ASCII layout', () => {
const s = scene.sceneFromTavern({
cols: 3,
rows: 2,
layout: null,
walkable: [
[true, false, true],
[false, true, true]
],
occupants: []
});
expect(s.grid).toEqual([
['floor', 'wall', 'floor'],
['wall', 'floor', 'floor']
]);
});
});
+14
View File
@@ -23,6 +23,20 @@ describe('Room — shared real-time engine (Tavern instance)', () => {
expect(ids).toEqual(['alice', 'bob']);
});
test('full state includes walkability for designed rooms without ASCII layout', () => {
const room = new Room({
id: 'designed',
roomData: {
cols: 2,
rows: 2,
walkable: [[true, false], [false, true]]
}
});
const state = room.fullState();
expect(state.layout).toBeNull();
expect(state.walkable).toEqual([[true, false], [false, true]]);
});
test('server-authoritative movement: a valid step moves and sets facing', () => {
const room = new Room({ id: 'r' });
const occ = room.addOccupant('alice');