@bitmagic/world-forger 0.1.24-dev.1 → 0.1.24-dev.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/artifact-types.d.ts +6 -0
  2. package/dist/artifact-types.d.ts.map +1 -1
  3. package/dist/generated/game-data-schema.d.ts +11 -1
  4. package/dist/generated/game-data-schema.d.ts.map +1 -1
  5. package/dist/generated/game-data-schema.js +15 -1
  6. package/dist/generated/game-data-schema.js.map +1 -1
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +1 -0
  10. package/dist/index.js.map +1 -1
  11. package/dist/physics-mode.d.ts +97 -0
  12. package/dist/physics-mode.d.ts.map +1 -0
  13. package/dist/physics-mode.js +101 -0
  14. package/dist/physics-mode.js.map +1 -0
  15. package/dist/pipeline/index.d.ts +4 -0
  16. package/dist/pipeline/index.d.ts.map +1 -1
  17. package/dist/pipeline/index.js +4 -0
  18. package/dist/pipeline/index.js.map +1 -1
  19. package/dist/pipeline/job-types.d.ts +40 -2
  20. package/dist/pipeline/job-types.d.ts.map +1 -1
  21. package/dist/pipeline/persist-sideon.d.ts +83 -0
  22. package/dist/pipeline/persist-sideon.d.ts.map +1 -0
  23. package/dist/pipeline/persist-sideon.js +196 -0
  24. package/dist/pipeline/persist-sideon.js.map +1 -0
  25. package/dist/pipeline/place-and-persist-level.d.ts +14 -1
  26. package/dist/pipeline/place-and-persist-level.d.ts.map +1 -1
  27. package/dist/pipeline/place-and-persist-level.js +59 -5
  28. package/dist/pipeline/place-and-persist-level.js.map +1 -1
  29. package/dist/pipeline/place-and-persist-sideon.d.ts +43 -0
  30. package/dist/pipeline/place-and-persist-sideon.d.ts.map +1 -0
  31. package/dist/pipeline/place-and-persist-sideon.js +352 -0
  32. package/dist/pipeline/place-and-persist-sideon.js.map +1 -0
  33. package/dist/pipeline/progress-types.d.ts +15 -0
  34. package/dist/pipeline/progress-types.d.ts.map +1 -1
  35. package/dist/pipeline/progress-types.js +6 -0
  36. package/dist/pipeline/progress-types.js.map +1 -1
  37. package/dist/pipeline/sideon-layout-map.d.ts +27 -0
  38. package/dist/pipeline/sideon-layout-map.d.ts.map +1 -0
  39. package/dist/pipeline/sideon-layout-map.js +96 -0
  40. package/dist/pipeline/sideon-layout-map.js.map +1 -0
  41. package/dist/pipeline/sideon-types.d.ts +146 -0
  42. package/dist/pipeline/sideon-types.d.ts.map +1 -0
  43. package/dist/pipeline/sideon-types.js +7 -0
  44. package/dist/pipeline/sideon-types.js.map +1 -0
  45. package/dist/pipeline/voxelize-level.d.ts.map +1 -1
  46. package/dist/pipeline/voxelize-level.js +9 -0
  47. package/dist/pipeline/voxelize-level.js.map +1 -1
  48. package/package.json +1 -1
@@ -0,0 +1,352 @@
1
+ import { isSideonForgeArtifact } from './sideon-types.js';
2
+ import { requireArtifact } from './artifact-store.js';
3
+ import { isSkippedArchetype, skipNote, structuralSkipNote } from './archetype-skips.js';
4
+ import { placeInstances, reconcileInstancesToAssets } from './place-and-persist-level.js';
5
+ import { buildSideonPersistModifications, SIDEON_FORGED_TAG } from './persist-sideon.js';
6
+ import { planStarterScatterRemoval } from './starter-scatter.js';
7
+ import { emitForgeProgress } from './progress-types.js';
8
+ import { SPAWN_CLEARANCE_M } from '../forge-constants.js';
9
+ /**
10
+ * How far past a surface's ends something may sit and still count as supported
11
+ * by it, when checking that a skipped bake did not leave it stranded. Matches
12
+ * the audit's own coin grab radius: a flag or door placed at `x1 - 1.5` is on
13
+ * its surface, and a coin may hang just off the edge.
14
+ */
15
+ const SUPPORT_SLACK_X_M = 1.6;
16
+ /** Coins hang above their surface rather than resting on it — the jump envelope
17
+ * plus arc headroom, generous on purpose: this test exists to catch a pickup
18
+ * left over a VOID, not to second-guess the expander's placement height. */
19
+ const COIN_SUPPORT_SLACK_Y_M = 6;
20
+ /**
21
+ * Multiplayer spread for a side-on level: extra starts spaced ALONG X on the
22
+ * first surface, never the 3D lane's XZ ring — the gameplay plane is locked to
23
+ * Z=0, and a ring would seat half the players 2 m off it. Same entry shape as
24
+ * `buildSpawnPointEntries`; side-on plans carry no path/playerSpawns/npcSpawns
25
+ * features, so this small builder replaces it rather than parameterizing it.
26
+ */
27
+ export function buildSideonSpawnPoints(options) {
28
+ const yaw = options.playerStartYaw ?? 0;
29
+ const lift = (x) => ({ x, y: options.playerStart.y + options.clearanceM, z: options.playerStart.z });
30
+ const entries = [
31
+ { id: 'player_0', type: 'player', name: 'Player start', position: lift(options.playerStart.x), rotationY: yaw },
32
+ ];
33
+ const maxX = options.firstSurface ? options.firstSurface.x1 - 1 : options.playerStart.x + 7.5;
34
+ for (let i = 1; i <= 3; i++) {
35
+ entries.push({
36
+ id: `player_${i}`,
37
+ type: 'player',
38
+ position: lift(Math.min(options.playerStart.x + i * 2.5, maxX)),
39
+ rotationY: yaw,
40
+ });
41
+ }
42
+ return entries;
43
+ }
44
+ export async function placeAndPersistSideonLevel(store, deps) {
45
+ const input = await requireArtifact(store, 'input');
46
+ const forge = await requireArtifact(store, 'forge');
47
+ if (!isSideonForgeArtifact(forge)) {
48
+ // A 3D `forge` artifact under a side-on resume: the lane frozen on the job
49
+ // input is checked at every entry point, so reaching this means a host bug
50
+ // — fail with the cause rather than a TypeError deep in the persist plan.
51
+ throw new Error(`Job ${store.jobId}'s forge artifact is a 3D level, not a side-on one — the game's dimension `
52
+ + 'changed after the job started. Start a fresh forge instead of resuming this job.');
53
+ }
54
+ const archetypeAssets = await requireArtifact(store, 'archetype-assets');
55
+ const skippedNames = new Set(archetypeAssets.filter(isSkippedArchetype).map((s) => s.name));
56
+ const placements = skippedNames.size === 0
57
+ ? forge.placements
58
+ : forge.placements.filter((p) => !skippedNames.has(p.archetype));
59
+ // A skipped archetype removes its PLACEMENTS — so the layout, the features and
60
+ // the summary must stop describing them too. Left uncorrected, a level whose
61
+ // collectible archetype failed to bake still tells the mandatory coding pass
62
+ // "N coins are ALREADY PLACED … do not re-place them", so scoring is wired to
63
+ // nothing and the pass deliberately declines to create them; and a level whose
64
+ // BUILDING archetype failed still reports a verified rooftop route over ground
65
+ // that has no geometry at all. The 3D sibling is skip-aware for the same
66
+ // reason; this lane must be too, because here the placed objects ARE the level.
67
+ const survives = (archetype) => !skippedNames.has(archetype);
68
+ // Every named thing that really reached the world. Computed BEFORE the layout
69
+ // narrowing because the layout's checkpoints/goal/coins are identified by the
70
+ // same names, and a view built from anything else would describe geometry the
71
+ // bake dropped.
72
+ const placedNames = new Set(placements.filter((p) => p.name !== undefined).map((p) => String(p.name)));
73
+ const sideon = skippedNames.size === 0 ? forge.sideon : (() => {
74
+ const surfaces = forge.sideon.surfaces.filter((sf) => sf.archetype === '' || survives(sf.archetype));
75
+ /**
76
+ * Narrowing by NAME alone is not enough. A skipped archetype removes its
77
+ * SURFACES, but the things standing on those surfaces belong to other
78
+ * archetypes that baked perfectly — the checkpoint flag, the goal door, the
79
+ * coins. They keep their names, pass the name filter, and ship as a success
80
+ * on a level where the goal floats past the end of the route and a fall
81
+ * respawns the player onto a checkpoint standing on nothing: an infinite
82
+ * respawn loop. So anything the player has to REACH must also still have
83
+ * ground under it.
84
+ */
85
+ const standsOnSurvivingGround = (x, y, slackY) => surfaces.some((sf) => x >= sf.x0 - SUPPORT_SLACK_X_M && x <= sf.x1 + SUPPORT_SLACK_X_M && y >= sf.topY - 0.01 && y - sf.topY <= slackY);
86
+ return {
87
+ ...forge.sideon,
88
+ surfaces,
89
+ // These are what the coding pass wires scoring, respawn and the win
90
+ // condition to. Narrowing only `surfaces` left the carrier promising
91
+ // coins and a goal that no instance exists for.
92
+ checkpoints: forge.sideon.checkpoints.filter((c) => placedNames.has(c.id) && standsOnSurvivingGround(c.x, c.y, 0.01)),
93
+ goal: forge.sideon.goal && placedNames.has('goal') && standsOnSurvivingGround(forge.sideon.goal.x, forge.sideon.goal.y, 0.01)
94
+ ? forge.sideon.goal
95
+ : null,
96
+ // Coins hang above their surface (or over a gap at arc height), so they
97
+ // get the jump envelope as slack rather than a hard footing test.
98
+ collectibleCandidates: forge.sideon.collectibleCandidates.filter((c) => c.optional || (placedNames.has(c.id) && standsOnSurvivingGround(c.x, c.y, COIN_SUPPORT_SLACK_Y_M))),
99
+ };
100
+ })();
101
+ const skipNotes = [];
102
+ if (skippedNames.size > 0) {
103
+ const lostSurfaces = forge.sideon.surfaces.length - sideon.surfaces.length;
104
+ if (lostSurfaces > 0) {
105
+ skipNotes.push(`${lostSurfaces} walkable surface(s) are missing because their archetype could not be baked — `
106
+ + 'the route is shorter than designed.');
107
+ }
108
+ const lostCoins = forge.sideon.collectibleCandidates.filter((c) => !c.optional).length
109
+ - sideon.collectibleCandidates.filter((c) => !c.optional).length;
110
+ if (lostCoins > 0)
111
+ skipNotes.push(`${lostCoins} collectible(s) could not be baked and are not in the level.`);
112
+ if (forge.sideon.checkpoints.length > sideon.checkpoints.length) {
113
+ skipNotes.push('The checkpoint archetype could not be baked, so respawn falls back to the player start.');
114
+ }
115
+ if (forge.sideon.goal !== null && sideon.goal === null) {
116
+ skipNotes.push('The goal archetype could not be baked, so the level has no goal marker to win at.');
117
+ }
118
+ }
119
+ // Nothing walkable left is not a degraded level, it is no level: the player
120
+ // would spawn over empty flat ground with the summary claiming a route. This
121
+ // is checked OUTSIDE the skip branch on purpose — an artifact that simply
122
+ // carries no surfaces, or a plan whose every placement was dropped upstream,
123
+ // reaches the same worthless outcome through a door a skip-only guard leaves
124
+ // wide open, and reports success.
125
+ if (sideon.surfaces.length === 0) {
126
+ throw new Error(skippedNames.size > 0
127
+ ? 'Every walkable surface in this side-on level came from an archetype that failed to bake, so the '
128
+ + 'level would be bare flat ground with nothing to stand on. Resume this job once the bake problem '
129
+ + 'is addressed — the design and geometry are saved and are not re-billed.'
130
+ : 'This side-on level has no walkable surfaces at all, so it would be bare flat ground with nothing '
131
+ + 'to stand on. This is a forge bug rather than a content problem — re-run without resuming.');
132
+ }
133
+ if (placements.length === 0 && forge.placements.length > 0) {
134
+ throw new Error('Every object in this side-on level was dropped before placement, so the world would gain nothing at '
135
+ + 'all. Resume this job once the bake problem is addressed — the design and geometry are saved.');
136
+ }
137
+ // Features that hand the coding pass positions must not survive their geometry.
138
+ const gameplayFeatures = skippedNames.size === 0 ? forge.gameplayFeatures : forge.gameplayFeatures.flatMap((f) => {
139
+ if (f.kind === 'collectibleSpawns')
140
+ return placements.some((p) => p.collectible === true) ? [f] : [];
141
+ if (f.kind === 'checkpoints')
142
+ return sideon.checkpoints.length > 0 ? [f] : [];
143
+ if (f.kind === 'goal')
144
+ return sideon.goal !== null ? [f] : [];
145
+ // The hazard survives — the fall is still real — but a respawn rule bound to
146
+ // checkpoints that no longer exist would reset the player to nothing.
147
+ if (f.kind === 'hazard' && sideon.checkpoints.length === 0 && f.params?.respawnRule === 'lastCheckpoint') {
148
+ return [{ ...f, params: { ...f.params, respawnRule: 'playerStart' } }];
149
+ }
150
+ return [f];
151
+ });
152
+ if (skippedNames.size > 0) {
153
+ deps.logger.warn({ jobId: store.jobId, skipped: [...skippedNames], droppedPlacements: forge.placements.length - placements.length }, 'Archetypes skipped at bake time — their instances are dropped, the level keeps everything else');
154
+ }
155
+ emitForgeProgress(deps, {
156
+ step: 'persist',
157
+ phase: 'start',
158
+ message: `Placing ${placements.length} object${placements.length === 1 ? '' : 's'} and saving the level`,
159
+ completed: 0,
160
+ total: placements.length,
161
+ });
162
+ // 'fatal': on this lane the placed objects ARE the level — an empty batch
163
+ // means the world gains nothing, which must never be reported as a success.
164
+ const placedInstances = await placeInstances(deps, placements, 'fatal');
165
+ const validArchetypeAssets = archetypeAssets
166
+ .filter((a) => !!a && !isSkippedArchetype(a));
167
+ const writableAssetIds = new Set(validArchetypeAssets.map((a) => String(a.id)));
168
+ const assetIdByName = new Map(validArchetypeAssets.map((a) => [String(a.name ?? ''), String(a.id)]));
169
+ const { instances: reconciledInstances, remapped, dropped } = reconcileInstancesToAssets(placedInstances, writableAssetIds, assetIdByName);
170
+ if (remapped || dropped) {
171
+ deps.logger.warn({ jobId: store.jobId, remappedInstances: remapped, droppedInstances: dropped, placed: placedInstances.length }, 'Reconciled side-on instances against written assets — dangling assetId refs would fail validation and discard the level');
172
+ }
173
+ // The re-forge replacement key: the next side-on forge replaces exactly this set.
174
+ const taggedInstances = reconciledInstances.map((instance) => ({ ...instance, [SIDEON_FORGED_TAG]: true }));
175
+ // The strip replaces the template's procedural scene, so the starter scatter
176
+ // is orphaned here exactly as in a 3D forge.
177
+ const starterScatter = planStarterScatterRemoval(await deps.worldJson.readForStarterScatterPlan());
178
+ const removedObjectIds = new Set(starterScatter.objectIds);
179
+ // NEVER delete an asset this forge's own instances reference. A starter asset
180
+ // the designer chose to REUSE (`reuseAssetId`) is written back as a reuse stub
181
+ // — which the asset upsert deliberately skips — while its original scatter
182
+ // instances are being removed, so the starter-scatter plan, computed against
183
+ // the OLD world.json alone, still lists it as unreferenced and emits a
184
+ // removal. The result is a live instance pointing at a deleted asset:
185
+ // invisible props in the CLI lane, and a dropped object in the web lane.
186
+ const removedAssetIds = new Set(starterScatter.assetIds.filter((id) => !writableAssetIds.has(String(id))));
187
+ const starterScatterRemovals = [
188
+ ...(removedObjectIds.size > 0
189
+ ? [{
190
+ type: 'removeRoot',
191
+ path: ['environmentObjects'],
192
+ predicate: (o) => removedObjectIds.has(String(o.id ?? '')),
193
+ }]
194
+ : []),
195
+ ...(removedAssetIds.size > 0
196
+ ? [{
197
+ type: 'removeRoot',
198
+ path: ['assets'],
199
+ predicate: (a) => removedAssetIds.has(String(a.id ?? '')),
200
+ }]
201
+ : []),
202
+ ];
203
+ // Baseline `prepareStartingPlate()` preserves the configured Y verbatim, so
204
+ // an elevated rooftop start survives on every template; the clearance drops
205
+ // the capsule onto the surface exactly as outdoors 3D spawns do.
206
+ // `playerStart` was placed on the DESIGNED first surface. When that surface's
207
+ // archetype failed to bake it no longer exists, and spawning on it drops the
208
+ // player through the air on frame one — so re-anchor onto the first surface
209
+ // that actually survived. Identical objects when nothing was skipped.
210
+ const designedFirst = forge.sideon.surfaces[0] ?? null;
211
+ const survivingFirst = sideon.surfaces[0] ?? null;
212
+ const rebasedStart = designedFirst !== null && survivingFirst !== null && survivingFirst !== designedFirst
213
+ ? { x: survivingFirst.x0 + 1.5, y: survivingFirst.topY, z: forge.playerStart.world.z }
214
+ : forge.playerStart.world;
215
+ if (rebasedStart !== forge.playerStart.world) {
216
+ skipNotes.push('The level started on an archetype that could not be baked, so the player start moved to the first surface that survived.');
217
+ }
218
+ // The markers ride into the carrier AND the tool summary, and the coding pass
219
+ // reads them — so they must not outlive their geometry either. The expander
220
+ // names them 'PlayerStart', 'Checkpoint_<n>' (from `checkpoint_<n>`) and
221
+ // 'Goal', which is what ties each one back to the narrowed view.
222
+ const survivingCheckpointSuffixes = new Set(sideon.checkpoints.map((c) => c.id.split('_')[1]));
223
+ const placedMarkers = forge.markers
224
+ .filter((m) => {
225
+ if (m.name === 'Goal')
226
+ return sideon.goal !== null;
227
+ if (m.name.startsWith('Checkpoint_'))
228
+ return survivingCheckpointSuffixes.has(m.name.slice('Checkpoint_'.length));
229
+ return true;
230
+ })
231
+ .map((m) => (m.name === 'PlayerStart' && rebasedStart !== forge.playerStart.world
232
+ ? { ...m, glb: { ...rebasedStart }, world: { ...rebasedStart } }
233
+ : m));
234
+ const spawn = {
235
+ x: rebasedStart.x,
236
+ y: rebasedStart.y + SPAWN_CLEARANCE_M,
237
+ z: rebasedStart.z,
238
+ };
239
+ const spawnPoints = buildSideonSpawnPoints({
240
+ playerStart: rebasedStart,
241
+ clearanceM: SPAWN_CLEARANCE_M,
242
+ playerStartYaw: forge.playerStartYaw,
243
+ // The narrowed view, never the designed one: if the archetype that made the
244
+ // first surface failed to bake, spawning on it drops the player through the
245
+ // air on frame one — over a hazard span, with no checkpoint to land back on.
246
+ firstSurface: sideon.surfaces[0] ?? null,
247
+ });
248
+ const persistPlan = buildSideonPersistModifications({
249
+ existingWorldJson: await deps.worldJson.readForPersistPlan(),
250
+ archetypeAssets: validArchetypeAssets,
251
+ instances: taggedInstances,
252
+ removedInstanceIds: removedObjectIds,
253
+ spawn,
254
+ spawnPoints: spawnPoints,
255
+ playerSpawnRotationY: forge.playerStartYaw,
256
+ groundWorldSizeX: forge.sideon.groundWorldSizeX,
257
+ groundWorldSizeZ: forge.sideon.groundWorldSizeZ,
258
+ // The plan's chosen ground block, when it chose one (rides the layout view).
259
+ groundBlockType: forge.sideon.groundBlockType ?? null,
260
+ carrier: {
261
+ jobId: store.jobId,
262
+ name: input.name,
263
+ prompt: input.prompt,
264
+ ...(input.originalUserPrompt ? { originalUserPrompt: input.originalUserPrompt } : {}),
265
+ spec: forge.spec,
266
+ layout: sideon,
267
+ features: gameplayFeatures,
268
+ markers: placedMarkers.map((m) => ({ name: m.name, ...m.world })),
269
+ },
270
+ activeHqAssetIds: deps.hqAssetIds ? await deps.hqAssetIds() : new Set(),
271
+ });
272
+ deps.logger.info({
273
+ jobId: store.jobId, spawn,
274
+ archetypes: validArchetypeAssets.length, archetypesSkipped: skippedNames.size,
275
+ instances: taggedInstances.length,
276
+ surfaces: forge.sideon.surfaces.length,
277
+ collectibles: forge.sideon.collectibleCandidates.filter((c) => !c.optional).length,
278
+ purgedAssets: persistPlan.purgedAssetIds, persistNotes: persistPlan.notes,
279
+ }, 'Side-on level, library assets, instances and spawn planned for world.json');
280
+ emitForgeProgress(deps, {
281
+ step: 'persist',
282
+ phase: 'done',
283
+ message: `Placed ${taggedInstances.length} object${taggedInstances.length === 1 ? '' : 's'}`,
284
+ completed: placements.length,
285
+ total: placements.length,
286
+ });
287
+ // Level-registry intents don't apply here, and silently honoring the flag's
288
+ // absence-of-effect would read as success — say so instead.
289
+ const ignoredIntentNotes = input.makeStartLevel !== undefined || input.assetId !== undefined
290
+ ? ['A side-on level has no levels registry, so makeStartLevel/assetId do not apply and were ignored.']
291
+ : [];
292
+ return {
293
+ summary: buildSideonSummary(forge, input, archetypeAssets, [...persistPlan.notes, ...ignoredIntentNotes, ...skipNotes], sideon, gameplayFeatures, rebasedStart, placedMarkers),
294
+ modifications: [...starterScatterRemovals, ...persistPlan.modifications],
295
+ };
296
+ }
297
+ /** The rich tool summary for a side-on forge — no vwld asset, so the asset/url
298
+ * fields are empty strings the host omits from its output. */
299
+ function buildSideonSummary(forge, input, archetypeAssets, persistNotes,
300
+ /** The AS-PLACED layout and features — never the designed ones, which may
301
+ * describe geometry a failed bake removed. */
302
+ sideon, gameplayFeatures,
303
+ /** Where the player really spawns — re-anchored if the designed first surface
304
+ * was never baked. */
305
+ playerStart,
306
+ /** The markers whose geometry survived the bake. */
307
+ markers) {
308
+ const skipped = archetypeAssets.filter(isSkippedArchetype);
309
+ const libraryAssets = forge.archetypes.flatMap((a, i) => (isSkippedArchetype(archetypeAssets[i])
310
+ ? []
311
+ : [{ name: a.name, asset_id: String(archetypeAssets[i]?.id ?? ''), instances: a.instanceCount }]));
312
+ const view = sideon;
313
+ const coins = view.collectibleCandidates.filter((c) => !c.optional).length;
314
+ const allNotes = [
315
+ ...forge.notes,
316
+ ...skipped.map((s) => (s.structural ? structuralSkipNote(s) : skipNote(s))),
317
+ ...persistNotes,
318
+ ];
319
+ const message = [
320
+ `Side-on level "${input.name}" is in the world: a ${Math.round(view.lengthM)}m ${view.rooftopMode ? 'rooftop' : 'ground'} route `
321
+ + `across ${view.surfaces.length} surfaces, ${coins} collectible${coins === 1 ? '' : 's'}, `
322
+ + `${view.checkpoints.length} checkpoint${view.checkpoints.length === 1 ? '' : 's'}${view.goal ? ' and a goal' : ''}. `
323
+ + 'No vwld level asset exists for a side-on level — the flat terrain plus the placed objects ARE the level.',
324
+ 'IMPLEMENT IN CODE (the level only places geometry): collectible scoring via the engine collect events, '
325
+ + 'the hazard fall/respawn rule, checkpoint respawn and the goal win condition — the contract is in '
326
+ + 'worldProfileData.worldForgerSideon (layout, movement envelope, features).',
327
+ 'ASSET QUALITY: every placed asset is a coarse voxel PLACEHOLDER carrying its regeneration brief in its '
328
+ + '`description`. To reach the final look, regenerate the 3-5 archetypes the player sees most (the route '
329
+ + 'buildings/platforms, the goal) with the asset generation tool, passing each EXISTING assetId — the new '
330
+ + 'model is fitted into the placeholder\'s box, so the laid-out level does not move. Do not regenerate '
331
+ + 'everything unprompted; pick the visible few, or ask the creator which.',
332
+ ...(allNotes.length > 0 ? [`Notes:\n - ${allNotes.join('\n - ')}`] : []),
333
+ ].join('\n');
334
+ return {
335
+ asset_id: '',
336
+ asset_name: input.name,
337
+ asset_url: '',
338
+ glb_url: '',
339
+ // The AS-PLACED start and markers, never the designed ones. Reporting
340
+ // `forge.playerStart` here while world.json got a re-anchored spawn made the
341
+ // tool's own answer disagree with the level by 20m, and left the carrier
342
+ // advertising a goal marker whose archetype never baked.
343
+ player_start: { x: playerStart.x, y: playerStart.y, z: playerStart.z },
344
+ markers: markers.map((m) => ({ name: m.name, x: m.world.x, y: m.world.y, z: m.world.z })),
345
+ library_assets: libraryAssets,
346
+ gameplay_features: gameplayFeatures,
347
+ terrain_bands: [],
348
+ notes: allNotes,
349
+ message,
350
+ };
351
+ }
352
+ //# sourceMappingURL=place-and-persist-sideon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"place-and-persist-sideon.js","sourceRoot":"","sources":["../../src/pipeline/place-and-persist-sideon.ts"],"names":[],"mappings":"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"}
@@ -35,6 +35,21 @@ export declare const FORGE_STEPS: ReadonlyArray<{
35
35
  readonly key: ForgeStepKey;
36
36
  readonly label: string;
37
37
  }>;
38
+ /**
39
+ * The SIDE-ON 2D pipeline's steps: the 3D list minus the level bake — a
40
+ * side-on level is flat baseline ground plus placed voxel objects, so there is
41
+ * no terrain GLB to voxelize into a vwld.
42
+ *
43
+ * Reuses the same {@link ForgeStepKey} values on purpose: artifact names,
44
+ * resume/skip logic and every host's data-driven step rendering work unchanged;
45
+ * only a host that BAKED the five-step list in (the CLI's own progress tracker)
46
+ * needs the list as a parameter.
47
+ */
48
+ export type SideonForgeStepKey = Exclude<ForgeStepKey, 'voxelize'>;
49
+ export declare const SIDEON_FORGE_STEPS: ReadonlyArray<{
50
+ readonly key: SideonForgeStepKey;
51
+ readonly label: string;
52
+ }>;
38
53
  /**
39
54
  * How the designer chose to build this level.
40
55
  *
@@ -1 +1 @@
1
- {"version":3,"file":"progress-types.d.ts","sourceRoot":"","sources":["../../src/pipeline/progress-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,yCAAyC;AACzC,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,YAAY,GAAG,UAAU,GAAG,SAAS,CAAC;AAEtF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC;IAAE,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAMpF,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,MAAM,GAAG,YAAY,GAAG,SAAS,GAAG,UAAU,CAAC;AAE7F;iGACiG;AACjG,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACvE,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;qGACiG;IACjG,cAAc,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1D;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACnC,8EAA8E;IAC9E,OAAO,EAAE,MAAM,CAAC;IAChB;kGAC8F;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qFAAqF;IACrF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAOlF;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,aAAa,GAAG,oBAAoB,CAwBpF"}
1
+ {"version":3,"file":"progress-types.d.ts","sourceRoot":"","sources":["../../src/pipeline/progress-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,yCAAyC;AACzC,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,YAAY,GAAG,UAAU,GAAG,SAAS,CAAC;AAEtF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC;IAAE,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAMpF,CAAC;AAEX;;;;;;;;;GASG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;AAEnE,eAAO,MAAM,kBAAkB,EAAE,aAAa,CAAC;IAAE,QAAQ,CAAC,GAAG,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAKjG,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,MAAM,GAAG,YAAY,GAAG,SAAS,GAAG,UAAU,CAAC;AAE7F;iGACiG;AACjG,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACvE,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;qGACiG;IACjG,cAAc,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1D;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACnC,8EAA8E;IAC9E,OAAO,EAAE,MAAM,CAAC;IAChB;kGAC8F;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qFAAqF;IACrF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAOlF;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,aAAa,GAAG,oBAAoB,CAwBpF"}
@@ -11,6 +11,12 @@ export const FORGE_STEPS = [
11
11
  { key: 'voxelize', label: 'Baking level' },
12
12
  { key: 'persist', label: 'Placing & saving' },
13
13
  ];
14
+ export const SIDEON_FORGE_STEPS = [
15
+ { key: 'design', label: 'Designing level' },
16
+ { key: 'forge', label: 'Building the level' },
17
+ { key: 'archetypes', label: 'Creating objects' },
18
+ { key: 'persist', label: 'Placing & saving' },
19
+ ];
14
20
  /** Cap on {@link ForgeProgressSummary.objects} — this rides on every host's progress frame, and a
15
21
  * city forge can produce hundreds of archetypes. The biggest kinds are the informative ones. */
16
22
  export const FORGE_SUMMARY_OBJECT_CAP = 20;
@@ -1 +1 @@
1
- {"version":3,"file":"progress-types.js","sourceRoot":"","sources":["../../src/pipeline/progress-types.ts"],"names":[],"mappings":"AA6BA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAA0E;IAChG,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,iBAAiB,EAAE;IAC3C,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE;IAC1C,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,kBAAkB,EAAE;IAChD,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,EAAE;IAC1C,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,kBAAkB,EAAE;CACrC,CAAC;AAYX;iGACiG;AACjG,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAyD3C;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAe,EAAE,KAAyB;IAC1E,IAAI,CAAC,IAAI,CAAC,UAAU;QAAE,OAAO;IAC7B,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,2DAA2D;IAC7D,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAuB;IAC5D,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU;SAChC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACnB,IAAI,EAAE,SAAS,CAAC,IAAI;QACpB,SAAS,EAAE,SAAS,CAAC,aAAa;QAClC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7C,CAAC,CAAC;SACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;IAE7C,MAAM,QAAQ,GAAoC,QAAQ,CAAC,IAAI,CAAC,OAAO;QACrE,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAE5C,OAAO;QACL,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,wBAAwB,CAAC;QACnD,WAAW,EAAE,OAAO,CAAC,MAAM;QAC3B,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,MAAM;QACtC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM;QAChC,YAAY,EAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5D,GAAG,CAAC,QAAQ,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,gBAAgB,EAAE,CAAC;KAC/F,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"progress-types.js","sourceRoot":"","sources":["../../src/pipeline/progress-types.ts"],"names":[],"mappings":"AA6BA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAA0E;IAChG,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,iBAAiB,EAAE;IAC3C,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE;IAC1C,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,kBAAkB,EAAE;IAChD,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,EAAE;IAC1C,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,kBAAkB,EAAE;CACrC,CAAC;AAcX,MAAM,CAAC,MAAM,kBAAkB,GAAgF;IAC7G,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,iBAAiB,EAAE;IAC3C,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE;IAC7C,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,kBAAkB,EAAE;IAChD,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,kBAAkB,EAAE;CACrC,CAAC;AAYX;iGACiG;AACjG,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAyD3C;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAe,EAAE,KAAyB;IAC1E,IAAI,CAAC,IAAI,CAAC,UAAU;QAAE,OAAO;IAC7B,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,2DAA2D;IAC7D,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAuB;IAC5D,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU;SAChC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACnB,IAAI,EAAE,SAAS,CAAC,IAAI;QACpB,SAAS,EAAE,SAAS,CAAC,aAAa;QAClC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7C,CAAC,CAAC;SACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;IAE7C,MAAM,QAAQ,GAAoC,QAAQ,CAAC,IAAI,CAAC,OAAO;QACrE,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAE5C,OAAO;QACL,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,wBAAwB,CAAC;QACnD,WAAW,EAAE,OAAO,CAAC,MAAM;QAC3B,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,MAAM;QACtC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM;QAChC,YAAY,EAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5D,GAAG,CAAC,QAAQ,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,gBAAgB,EAAE,CAAC;KAC/F,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * A SIDE-VIEW map of a side-on level, in the existing {@link ForgeLayoutMap}
3
+ * contract so every renderer (the Creator's canvas, the dev shell's
4
+ * interpolated no-free-identifiers renderer) draws it without changes.
5
+ *
6
+ * The encoding re-purposes the top-down contract deliberately:
7
+ * - the raster is the ELEVATION view — columns are X along the strip, rows are
8
+ * Y from the level's top down (row-major, matching the renderer's loop);
9
+ * - `heights` bytes are occupancy: SOLID (at/below a walkable surface) rides
10
+ * the top of the ramp so it renders as bright ground, SKY rides the bottom;
11
+ * - hazard spans (streets/pits) put their bottom rows AT/below `waterLevel`,
12
+ * so danger renders in the water color — legible without a renderer change;
13
+ * - `objects` dots are the placed collectibles, `markers` are the checkpoints
14
+ * and the goal, `playerStart` is the spawn.
15
+ *
16
+ * Drawn with the terrain palette this reads as relief rather than as a side
17
+ * view — a deliberate v1 trade recorded in the plan (a `kind` field on the map
18
+ * plus side-aware shading is the follow-up). What matters now: the level's
19
+ * shape, its pickups and its route landmarks are visible during the run.
20
+ */
21
+ import type { ForgeLayoutMap } from './layout-map.js';
22
+ import type { SideonForgeArtifact } from './sideon-types.js';
23
+ /**
24
+ * Build the side-view map, or null when the layout has nothing to draw.
25
+ */
26
+ export declare function buildSideonLayoutMap(artifact: SideonForgeArtifact): ForgeLayoutMap | null;
27
+ //# sourceMappingURL=sideon-layout-map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sideon-layout-map.d.ts","sourceRoot":"","sources":["../../src/pipeline/sideon-layout-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAkB7D;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,cAAc,GAAG,IAAI,CAsFzF"}
@@ -0,0 +1,96 @@
1
+ import { FORGE_MAP_MAX_DIM, FORGE_MAP_MAX_OBJECTS } from './layout-map.js';
2
+ /** Byte values for the three cell classes (same 0-255 ramp the renderer blends). */
3
+ const SOLID_SAMPLE = 224;
4
+ const SKY_SAMPLE = 24;
5
+ const HAZARD_SAMPLE = 8;
6
+ /** `waterLevel` sits between hazard and sky so ONLY hazard cells compare at/below it. */
7
+ const HAZARD_WATER_LEVEL = 12;
8
+ /** Vertical headroom above the highest surface, so rooftops never touch the frame. */
9
+ const HEADROOM_M = 4;
10
+ /** How far below ground level the view extends (pit depth read-room). */
11
+ const UNDERGROUND_M = 2;
12
+ function toBase64(bytes) {
13
+ return Buffer.from(bytes).toString('base64');
14
+ }
15
+ /**
16
+ * Build the side-view map, or null when the layout has nothing to draw.
17
+ */
18
+ export function buildSideonLayoutMap(artifact) {
19
+ const view = artifact.sideon;
20
+ if (!view || view.lengthM <= 0 || view.surfaces.length === 0)
21
+ return null;
22
+ const minX = Math.min(...view.surfaces.map((s) => s.x0));
23
+ const maxX = Math.max(...view.surfaces.map((s) => s.x1));
24
+ const spanX = maxX - minX;
25
+ if (!(spanX > 0))
26
+ return null;
27
+ const topY = Math.max(0, ...view.surfaces.map((s) => s.topY)) + HEADROOM_M;
28
+ const bottomY = -UNDERGROUND_M;
29
+ const spanY = topY - bottomY;
30
+ // Longest axis capped exactly like the top-down map; a strip is much wider
31
+ // than tall, so width usually lands at the cap and height stays legible.
32
+ const scale = FORGE_MAP_MAX_DIM / Math.max(spanX, spanY);
33
+ const width = Math.max(2, Math.min(FORGE_MAP_MAX_DIM, Math.round(spanX * Math.min(1, scale))));
34
+ const height = Math.max(2, Math.min(FORGE_MAP_MAX_DIM, Math.round(spanY * Math.min(1, scale))));
35
+ const toCol = (x) => Math.max(0, Math.min(width - 1, Math.round(((x - minX) / spanX) * (width - 1))));
36
+ // Row 0 is the TOP of the view (matches the renderer's row-major draw).
37
+ const toRow = (y) => Math.max(0, Math.min(height - 1, Math.round(((topY - y) / spanY) * (height - 1))));
38
+ // Per-column highest surface top (the strip silhouette). Ground runs and the
39
+ // baseline plane cover Y<=0 everywhere, so every column is at least ground-solid.
40
+ const surfaceTopByCol = new Float64Array(width).fill(0);
41
+ for (const surface of view.surfaces) {
42
+ const c0 = toCol(surface.x0);
43
+ const c1 = toCol(surface.x1);
44
+ for (let c = c0; c <= c1; c++) {
45
+ if (surface.topY > surfaceTopByCol[c])
46
+ surfaceTopByCol[c] = surface.topY;
47
+ }
48
+ }
49
+ const hazardCols = new Set();
50
+ for (const span of view.hazardSpans) {
51
+ const c0 = toCol(span.x0);
52
+ const c1 = toCol(span.x1);
53
+ for (let c = c0; c <= c1; c++)
54
+ hazardCols.add(c);
55
+ }
56
+ const bytes = new Uint8Array(width * height).fill(SKY_SAMPLE);
57
+ for (let c = 0; c < width; c++) {
58
+ const solidFromRow = toRow(surfaceTopByCol[c]);
59
+ for (let r = solidFromRow; r < height; r++) {
60
+ bytes[r * width + c] = SOLID_SAMPLE;
61
+ }
62
+ if (hazardCols.has(c)) {
63
+ // The ground band of a hazard column renders as water (= danger).
64
+ const groundRow = toRow(0);
65
+ for (let r = groundRow; r < height; r++) {
66
+ bytes[r * width + c] = HAZARD_SAMPLE;
67
+ }
68
+ }
69
+ }
70
+ const placed = view.collectibleCandidates.filter((candidate) => !candidate.optional);
71
+ const objects = [];
72
+ for (const coin of placed.slice(0, FORGE_MAP_MAX_OBJECTS)) {
73
+ objects.push(toCol(coin.x), toRow(coin.y));
74
+ }
75
+ const markers = [
76
+ ...view.checkpoints.map((c) => ({ name: c.id, x: toCol(c.x), z: toRow(c.y) })),
77
+ ...(view.goal ? [{ name: 'Goal', x: toCol(view.goal.x), z: toRow(view.goal.y) }] : []),
78
+ ];
79
+ const playerStart = artifact.playerStart
80
+ ? { x: toCol(artifact.playerStart.world.x), z: toRow(artifact.playerStart.world.y) }
81
+ : null;
82
+ return {
83
+ width,
84
+ height,
85
+ heights: toBase64(bytes),
86
+ // The scale labels: X is the strip length, "Z" is the vertical span drawn.
87
+ worldSizeX: Math.round(spanX),
88
+ worldSizeZ: Math.round(spanY),
89
+ waterLevel: hazardCols.size > 0 ? HAZARD_WATER_LEVEL : null,
90
+ objects,
91
+ markers,
92
+ playerStart,
93
+ objectCount: placed.length,
94
+ };
95
+ }
96
+ //# sourceMappingURL=sideon-layout-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sideon-layout-map.js","sourceRoot":"","sources":["../../src/pipeline/sideon-layout-map.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAG3E,oFAAoF;AACpF,MAAM,YAAY,GAAG,GAAG,CAAC;AACzB,MAAM,UAAU,GAAG,EAAE,CAAC;AACtB,MAAM,aAAa,GAAG,CAAC,CAAC;AACxB,yFAAyF;AACzF,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAE9B,sFAAsF;AACtF,MAAM,UAAU,GAAG,CAAC,CAAC;AACrB,yEAAyE;AACzE,MAAM,aAAa,GAAG,CAAC,CAAC;AAExB,SAAS,QAAQ,CAAC,KAAiB;IACjC,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAA6B;IAChE,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC7B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE1E,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAE9B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,UAAU,CAAC;IAC3E,MAAM,OAAO,GAAG,CAAC,aAAa,CAAC;IAC/B,MAAM,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC;IAE7B,2EAA2E;IAC3E,yEAAyE;IACzE,MAAM,KAAK,GAAG,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/F,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAEhG,MAAM,KAAK,GAAG,CAAC,CAAS,EAAU,EAAE,CAClC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnF,wEAAwE;IACxE,MAAM,KAAK,GAAG,CAAC,CAAS,EAAU,EAAE,CAClC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAErF,6EAA6E;IAC7E,kFAAkF;IAClF,MAAM,eAAe,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpC,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC7B,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC7B,KAAK,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9B,IAAI,OAAO,CAAC,IAAI,GAAG,eAAe,CAAC,CAAC,CAAE;gBAAE,eAAe,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1B,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1B,KAAK,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE;YAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,YAAY,GAAG,KAAK,CAAC,eAAe,CAAC,CAAC,CAAE,CAAC,CAAC;QAChD,KAAK,IAAI,CAAC,GAAG,YAAY,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,KAAK,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,YAAY,CAAC;QACtC,CAAC;QACD,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACtB,kEAAkE;YAClE,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC3B,KAAK,IAAI,CAAC,GAAG,SAAS,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACxC,KAAK,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,aAAa,CAAC;YACvC,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACrF,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,qBAAqB,CAAC,EAAE,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,OAAO,GAAG;QACd,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9E,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KACvF,CAAC;IAEF,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW;QACtC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;QACpF,CAAC,CAAC,IAAI,CAAC;IAET,OAAO;QACL,KAAK;QACL,MAAM;QACN,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC;QACxB,2EAA2E;QAC3E,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QAC7B,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QAC7B,UAAU,EAAE,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI;QAC3D,OAAO;QACP,OAAO;QACP,WAAW;QACX,WAAW,EAAE,MAAM,CAAC,MAAM;KAC3B,CAAC;AACJ,CAAC"}