import { type Game2DClass } from '@bitmagic/world-forger/physics-mode.js'; import type { ForgeJobInput } from '@bitmagic/world-forger/pipeline/index.js'; /** * The project's 2D classification, from its work game.json + world.json. * * Missing or unreadable files classify as `not-2d` on purpose: the forge's own * later reads produce the real, better-contextualized error for a broken * project, and a gate must never block a healthy 3D game over a parse hiccup. */ export declare function readGame2DClass(root: string): Game2DClass; /** The forge lane a project routes to (see `routeForgeLane` in game-play-agent — one shared rule). */ export type CliForgeLane = 'threed' | 'sideon'; /** * Route `bitmagic forge` by the project's dimension, before anything is sent * or billed: * - 3D projects → the 3D pipeline (unchanged); * - side-view 2D projects (voxel lane, any template) → the SIDE-ON pipeline * (a strip level: flat ground + placed buildings/platforms/pickups); * - the Physics2D genre and top-down 2D projects → a refusal (neither a 3D * roamable level nor a side-on strip fits them). */ export declare function resolveForgeLane(root: string): CliForgeLane; /** * The resume-aware routing `commands/forge.ts` actually runs: a resumed job * carries its lane frozen in the local `input` artifact, and that lane is the * ONLY one its saved artifacts can continue on — both lanes share artifact * names, so a project whose game.json dimension flipped between the failed run * and the resume must be refused here (loud, free) rather than fed the other * lane's cached spec. A resume with no local record (started elsewhere, * `.bitmagic/` cleared) falls back to the project's own classification, and * api-server's identical frozen-lane check backstops it before any charge. */ export declare function resolveForgeLaneForRun(options: { root: string; frozen: Pick | null; resumeJobId: string | null; }): CliForgeLane; /** * Refuse a side-on forge on an OPEN-WATER world, before anything is sent. * * `WorldGenerator.generateWorld` checks `worldProfileData.openWater` FIRST and * returns — an open-water world builds no terrain at all. A side-on level is * flat ground plus placed objects, so it would be paid for, reported as a * success, and drop the player straight through a world with no floor. The flag * cannot be cleared for them either: the schema types it as an object and the * modification vocabulary has no "delete a key", so the only honest move is to * refuse while it is still free. */ export declare function assertNotOpenWater(root: string): void; /** * What a side-on forge will DESTROY in this project, or null when nothing. * * A side-on level is not a registry entry, so the forge empties the registry and * takes each discarded level's objects with it (see persist-sideon.ts). That is * unavoidable for the lane, but the creator has to hear it BEFORE the bill, not * from a note afterwards — this runs at the same free pre-flight as the lane * gate. The registry itself is preserved on the carrier; the objects are not. */ export declare function describeSideonRegistryLoss(root: string): string | null; /** * The project's `characterConfig.runSpeed` (work world.json) — the one movement * number the side-on designer reach-verifies against. Undefined when unset or * unreadable (the server falls back to the generic kit's default). */ export declare function readCharacterRunSpeed(root: string): number | undefined; /** * The project's `worldProfileData.voxelBlockSize` (work world.json) — the side-on * expander anchors the level on the flat terrain's walkable TOP, which sits one * voxel above the nominal ground plane, so this is a geometry input. Undefined * when unset or unreadable (the server falls back to the 1 m default). */ export declare function readVoxelBlockSize(root: string): number | undefined; /** * Does this project collide on the engine's GROUND PLANE (top-down 2D physics)? * * The forge sends it so the designer builds FLAT terrain: that lane turns an * unclimbable rise into a wall and a dug basin into a pit, so a normal 3D * landscape is unplayable there. Same rule the web lane applies * (`runsGroundPlanePhysics`); unreadable project files answer `false`, which is * the ordinary 3D world. */ export declare function readGroundPlane(root: string): boolean;