/** * Repoints the platform's OWN default voxel assets from their legacy JSON `.vxl` files to the * VXL3 re-encodings under `default-assets/voxel/v2/`. * * Every project scaffolded before engine 3.1056 got a `src/work/world.json` whose default trees * and rocks (six generated variants plus three converted rocks) pointed at the pre-VXL3 files. * Those files are still served, deliberately — games in the wild reference them by URL — but * they are the legacy JSON layout: the engine converts each one in memory on EVERY load, logs a * warning per asset per load, and the file carries no LOD trailer for mobile to drop. Nothing * else ever rewrote the URLs: `bitmagic upgrade` replaces `engine/` and leaves the creator's * `world.json` alone by contract, so an upgraded project kept warning forever. * * This is the one exception to that contract, and it is a narrow one. Only the nine URLs the * platform itself put into `world.json` at scaffold time are touched — matched by their exact * path under `worlds/v3/`, host preserved — and each is swapped for the same asset in the new * encoding: the three rocks are literal re-encodings of those files, the six variants are the * regenerated defaults every current template ships. Ids, names and every other field stay as * they are, except `size`, which follows the bytes (the Assets tab shows it, and the old values * overstate the new files by 10-20x). Assets the creator added, generated or forged are never * looked at: their legacy files, if any, are unknown to this table and need a real re-save. * * The table is a snapshot of `templates/standard-3d/source/world.json` before and after the move * (repo commit a9618f3c), so it is a fixed migration rather than a live lookup — a project must * get the same result from every CLI that carries it. `legacy-default-assets.test.ts` holds each * entry's `to` side to the template the repo ships, so a regenerated default cannot drift away * from this table unnoticed. See docs/voxel-default-assets.md. */ /** The URL path under `worlds/v3/` before the move, and the record fields it becomes. */ export interface LegacyDefaultAssetTarget { /** Path under `worlds/v3/` of the VXL3 file. */ path: string; /** Byte size of that file — `size` on the asset record follows it. */ size: number; } /** * Keyed by the legacy path under `worlds/v3/`. Six generated variants keep their file name one * directory down; the three converted rocks were per-game uploads and now live beside them. */ export declare const LEGACY_DEFAULT_ASSET_TARGETS: Readonly>; /** The marker every asset URL on the CDN carries; the table's keys are the paths after it. */ export declare const WORLDS_ROOT = "/worlds/v3/"; /** One asset record that was repointed, for the upgrade report. Absent id/name are left absent. */ export interface RepointedAsset { id?: string; name?: string; from: string; to: string; } /** What the repoint did to the project, for the upgrade report. */ export interface RepointOutcome { /** The records rewritten, in file order. Empty when there was nothing to rewrite. */ repointed: RepointedAsset[]; /** * Why `world.json` was left alone when it could not even be inspected — missing, unreadable, * not JSON, not a world object. Absent when the file was read; "read and nothing matched" is * an empty `repointed`, not a skip. Reported so the creator knows the migration did not run * rather than concluding their assets are already current. */ skipped?: string; } /** * The VXL3 URL a legacy default-asset URL maps to, or null when the URL is not one of the nine. * The host is kept — the table matches on the path only, so a project pointed at another * environment's CDN keeps pointing at it. Exported for the tests; the migration is the function * below. */ export declare function repointLegacyDefaultAssetUrl(url: string): { url: string; size: number; } | null; /** * Rewrite the project's `src/work/world.json` in place and report what moved. Never throws for a * file it cannot read: upgrading the engine must not be blocked by a world.json the creator is * mid-edit on, so an unreadable or unparseable file is left exactly as it was and named in * `skipped`. A write that fails DOES throw — by then the file was fine and the failure is the * disk's, which the creator has to hear about — but `writeWorldJsonAtomic` leaves no partial * file or stray temp behind. */ export declare function repointLegacyDefaultAssets(root: string): RepointOutcome;