diff --git a/src/core/store/serialize.ts b/src/core/store/serialize.ts index d7738acd..4b1c1edd 100644 --- a/src/core/store/serialize.ts +++ b/src/core/store/serialize.ts @@ -28,7 +28,7 @@ import type { TilemapLayer, } from '../model/Asset'; import { parseCellKey } from '../model/tilemap'; -import { decodeCells, encodeCells, isStoredCells } from './tilemapCells'; +import { decodeCells, encodeCells } from './tilemapCells'; import { isAssetType } from '../model/AssetTypes'; import { isFontFile } from '../model/font'; import { isSoundFile } from '../model/sound'; @@ -80,7 +80,7 @@ import { SHADER_KEY, shaderParamDefs } from '../properties/shaders'; */ export function deserializeProject(raw: unknown, fallbackId = ''): Project { const r = asRecord(raw); - const rawAssets = (Array.isArray(r.assets) ? r.assets : []).map(asRecord).map(migrateAsset); + const rawAssets = (Array.isArray(r.assets) ? r.assets : []).map(asRecord); // Pass 1: asset ids and their effective schemas, needed to coerce overrides in pass 2. const schemas = new Map(); @@ -524,8 +524,7 @@ function normalizeLayers(raw: unknown): TilemapLayer[] { for (const item of Array.isArray(raw) ? raw : []) { const l = asRecord(item); if (typeof l.id !== 'string' || !l.id || layers.some((o) => o.id === l.id)) continue; - // Projects saved before #134 hold the map itself; it is taken over as it is. - const stored = isStoredCells(l) ? decodeCells(l) : asRecord(l.cells); + const stored = decodeCells(l); const cells: Record = {}; for (const [key, value] of Object.entries(stored)) if (parseCellKey(key) && typeof value === 'string' && value !== '') cells[key] = value; @@ -550,17 +549,6 @@ function normalizeBag(raw: unknown, schema: PropertySchema, sparse: boolean): Pr return bag; } -/** - * A tile was called an autotile before it could be a plain one (#131). Such an asset had no kind - * but the autotile blocks, and one written without a kind meant a floor – which it has to stay now - * that a missing kind means a plain tile. - */ -function migrateAsset(a: Record): Record { - if (a.type !== 'autotile') return a; - const props = asRecord(a.props); - return { ...a, type: 'tile', props: { ...props, kind: props.kind ?? 'floor' } }; -} - function asRecord(value: unknown): Record { return value && typeof value === 'object' ? (value as Record) : {}; } diff --git a/src/core/store/tilemapCells.ts b/src/core/store/tilemapCells.ts index 1719723f..3f01e3ae 100644 --- a/src/core/store/tilemapCells.ts +++ b/src/core/store/tilemapCells.ts @@ -113,8 +113,3 @@ export function decodeCells(raw: { }); return cells; } - -/** Whether a stored layer is in this format rather than the map of the first version (#128). */ -export function isStoredCells(raw: Record): boolean { - return Array.isArray(raw.rows); -} diff --git a/tests/core/tile.test.ts b/tests/core/tile.test.ts index a66b2f70..83c27c80 100644 --- a/tests/core/tile.test.ts +++ b/tests/core/tile.test.ts @@ -417,29 +417,17 @@ describe('tile in the document', () => { expect(tilePlayback(read)).toBe('loop'); }); - /** - * #131 renamed the asset and made a plain tile the default. A project saved before that holds - * `autotile` assets, and one of them without a stored kind meant a floor block: it has to open as - * the same floor, not turn into a plain tile. - */ - it('reads an autotile of an older project as the tile it was', () => { + // No migration any more (#137): `autotile`, the name before #131, is an unknown type like any other. + it('drops an asset of the old type autotile', () => { const raw = { id: 'p', assets: [ { id: 's', type: 'scene', name: 'Main', props: {}, objects: [] }, - { id: 'a', type: 'autotile', name: 'Old grass', props: {}, pictures: ['x'] }, - { id: 'b', type: 'autotile', name: 'Old wall', props: { kind: 'wall', fps: 2 }, pictures: [] }, + { id: 'a', type: 'autotile', name: 'Old grass', props: { kind: 'floor' }, pictures: ['x'] }, { id: 'c', type: 'tile', name: 'New', props: {}, pictures: [] }, ], }; - const project = deserializeProject(raw); - const byId = (id: string) => project.assets.find((a): a is TileAsset => a.id === id && a.type === 'tile'); - expect(byId('a')?.pictures).toEqual(['x']); - expect(tileKind(byId('a')!)).toBe('floor'); - expect(tileKind(byId('b')!)).toBe('wall'); - expect(byId('b')?.props.fps).toBe(2); - expect(tileKind(byId('c')!)).toBe('none'); - expect(project.assets.some((a) => (a.type as string) === 'autotile')).toBe(false); + expect(deserializeProject(raw).assets.map((a) => a.id)).toEqual(['s', 'c']); }); }); diff --git a/tests/core/tilemap-cells.test.ts b/tests/core/tilemap-cells.test.ts index 5316d765..1dae7192 100644 --- a/tests/core/tilemap-cells.test.ts +++ b/tests/core/tilemap-cells.test.ts @@ -108,19 +108,14 @@ describe('the cells of a tilemap in the file', () => { expect((findAsset(project, id) as TilemapAsset).layers[0]!.cells).toEqual(cells); }); - it('take a project saved before #134 over as it is, and write it in the new form', () => { + // No migration any more (#137): the map of the first version (#128) is not read. + it('read a layer holding the map itself as empty', () => { const { project, id } = projectWith({}); const raw = serializeProject(project) as { assets: Record[] }; - const old = raw.assets.find((a) => a.id === id)!; - old.layers = [ - { id: 'L1', name: 'Ground', cells: { '1,2': 'grass', '2,2': 'grass', nonsense: 'x', '3,3': '' } }, - ]; - const loaded = deserializeProject(raw); - expect((findAsset(loaded, id) as TilemapAsset).layers[0]!.cells).toEqual({ - '1,2': 'grass', - '2,2': 'grass', - }); - expect(storedLayer(serializeProject(loaded), id)).toMatchObject({ tiles: ['grass'], rows: ['1*2'] }); + raw.assets.find((a) => a.id === id)!.layers = [{ id: 'L1', name: 'Ground', cells: { '1,2': 'grass' } }]; + const layer = (findAsset(deserializeProject(raw), id) as TilemapAsset).layers[0]!; + expect(layer).toMatchObject({ id: 'L1', name: 'Ground' }); + expect(layer.cells).toEqual({}); }); it('shrink a full map of 100 × 100 with two layers to a small part of the old size', () => {