@bitmagic/world-forger 0.1.0

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 (105) hide show
  1. package/dist/artifact-types.d.ts +295 -0
  2. package/dist/artifact-types.d.ts.map +1 -0
  3. package/dist/artifact-types.js +17 -0
  4. package/dist/artifact-types.js.map +1 -0
  5. package/dist/forge-constants.d.ts +106 -0
  6. package/dist/forge-constants.d.ts.map +1 -0
  7. package/dist/forge-constants.js +111 -0
  8. package/dist/forge-constants.js.map +1 -0
  9. package/dist/index.d.ts +28 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +28 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/log.d.ts +26 -0
  14. package/dist/log.d.ts.map +1 -0
  15. package/dist/log.js +14 -0
  16. package/dist/log.js.map +1 -0
  17. package/dist/pipeline/archetype-skips.d.ts +57 -0
  18. package/dist/pipeline/archetype-skips.d.ts.map +1 -0
  19. package/dist/pipeline/archetype-skips.js +51 -0
  20. package/dist/pipeline/archetype-skips.js.map +1 -0
  21. package/dist/pipeline/artifact-store.d.ts +4 -0
  22. package/dist/pipeline/artifact-store.d.ts.map +1 -0
  23. package/dist/pipeline/artifact-store.js +10 -0
  24. package/dist/pipeline/artifact-store.js.map +1 -0
  25. package/dist/pipeline/asset-catalog.d.ts +27 -0
  26. package/dist/pipeline/asset-catalog.d.ts.map +1 -0
  27. package/dist/pipeline/asset-catalog.js +47 -0
  28. package/dist/pipeline/asset-catalog.js.map +1 -0
  29. package/dist/pipeline/create-level-archetypes.d.ts +45 -0
  30. package/dist/pipeline/create-level-archetypes.d.ts.map +1 -0
  31. package/dist/pipeline/create-level-archetypes.js +197 -0
  32. package/dist/pipeline/create-level-archetypes.js.map +1 -0
  33. package/dist/pipeline/deps.d.ts +72 -0
  34. package/dist/pipeline/deps.d.ts.map +1 -0
  35. package/dist/pipeline/deps.js +2 -0
  36. package/dist/pipeline/deps.js.map +1 -0
  37. package/dist/pipeline/errors.d.ts +10 -0
  38. package/dist/pipeline/errors.d.ts.map +1 -0
  39. package/dist/pipeline/errors.js +13 -0
  40. package/dist/pipeline/errors.js.map +1 -0
  41. package/dist/pipeline/forged-work-store.d.ts +46 -0
  42. package/dist/pipeline/forged-work-store.d.ts.map +1 -0
  43. package/dist/pipeline/forged-work-store.js +69 -0
  44. package/dist/pipeline/forged-work-store.js.map +1 -0
  45. package/dist/pipeline/index.d.ts +36 -0
  46. package/dist/pipeline/index.d.ts.map +1 -0
  47. package/dist/pipeline/index.js +36 -0
  48. package/dist/pipeline/index.js.map +1 -0
  49. package/dist/pipeline/job-types.d.ts +145 -0
  50. package/dist/pipeline/job-types.d.ts.map +1 -0
  51. package/dist/pipeline/job-types.js +2 -0
  52. package/dist/pipeline/job-types.js.map +1 -0
  53. package/dist/pipeline/level-registry.d.ts +57 -0
  54. package/dist/pipeline/level-registry.d.ts.map +1 -0
  55. package/dist/pipeline/level-registry.js +108 -0
  56. package/dist/pipeline/level-registry.js.map +1 -0
  57. package/dist/pipeline/model-types.d.ts +51 -0
  58. package/dist/pipeline/model-types.d.ts.map +1 -0
  59. package/dist/pipeline/model-types.js +2 -0
  60. package/dist/pipeline/model-types.js.map +1 -0
  61. package/dist/pipeline/persist-level.d.ts +82 -0
  62. package/dist/pipeline/persist-level.d.ts.map +1 -0
  63. package/dist/pipeline/persist-level.js +201 -0
  64. package/dist/pipeline/persist-level.js.map +1 -0
  65. package/dist/pipeline/place-and-persist-level.d.ts +83 -0
  66. package/dist/pipeline/place-and-persist-level.d.ts.map +1 -0
  67. package/dist/pipeline/place-and-persist-level.js +405 -0
  68. package/dist/pipeline/place-and-persist-level.js.map +1 -0
  69. package/dist/pipeline/request-id.d.ts +7 -0
  70. package/dist/pipeline/request-id.d.ts.map +1 -0
  71. package/dist/pipeline/request-id.js +10 -0
  72. package/dist/pipeline/request-id.js.map +1 -0
  73. package/dist/pipeline/spawn-points.d.ts +47 -0
  74. package/dist/pipeline/spawn-points.d.ts.map +1 -0
  75. package/dist/pipeline/spawn-points.js +100 -0
  76. package/dist/pipeline/spawn-points.js.map +1 -0
  77. package/dist/pipeline/starter-scatter.d.ts +34 -0
  78. package/dist/pipeline/starter-scatter.d.ts.map +1 -0
  79. package/dist/pipeline/starter-scatter.js +49 -0
  80. package/dist/pipeline/starter-scatter.js.map +1 -0
  81. package/dist/pipeline/storage-types.d.ts +48 -0
  82. package/dist/pipeline/storage-types.d.ts.map +1 -0
  83. package/dist/pipeline/storage-types.js +19 -0
  84. package/dist/pipeline/storage-types.js.map +1 -0
  85. package/dist/pipeline/transport-types.d.ts +35 -0
  86. package/dist/pipeline/transport-types.d.ts.map +1 -0
  87. package/dist/pipeline/transport-types.js +2 -0
  88. package/dist/pipeline/transport-types.js.map +1 -0
  89. package/dist/pipeline/voxelize-level.d.ts +24 -0
  90. package/dist/pipeline/voxelize-level.d.ts.map +1 -0
  91. package/dist/pipeline/voxelize-level.js +63 -0
  92. package/dist/pipeline/voxelize-level.js.map +1 -0
  93. package/dist/pipeline/world-json-source.d.ts +78 -0
  94. package/dist/pipeline/world-json-source.d.ts.map +1 -0
  95. package/dist/pipeline/world-json-source.js +2 -0
  96. package/dist/pipeline/world-json-source.js.map +1 -0
  97. package/dist/pipeline/world-json-types.d.ts +104 -0
  98. package/dist/pipeline/world-json-types.d.ts.map +1 -0
  99. package/dist/pipeline/world-json-types.js +15 -0
  100. package/dist/pipeline/world-json-types.js.map +1 -0
  101. package/dist/terrain-height-grid.d.ts +45 -0
  102. package/dist/terrain-height-grid.d.ts.map +1 -0
  103. package/dist/terrain-height-grid.js +50 -0
  104. package/dist/terrain-height-grid.js.map +1 -0
  105. package/package.json +72 -0
@@ -0,0 +1,295 @@
1
+ /**
2
+ * The forged-artifact SCHEMA — the data shapes that cross from the private
3
+ * design/geometry half of the forger into the publishable half that drives the
4
+ * browser (archetype bakes, the level bake, instance placement and persist).
5
+ *
6
+ * These are declarations, not algorithms: a client that consumes a forge
7
+ * artifact at all has to know its shape, so the schema is public and the code
8
+ * that produces it is not. Each type is DEFINED here and re-exported from the
9
+ * module it used to live in (`forge-world.ts`, `derive-settings.ts`,
10
+ * `dungeon/dressing.ts`, `course.ts`, `dungeon/fixture-parts.ts`), so there is
11
+ * still exactly one definition of each and every historic import site keeps
12
+ * working.
13
+ *
14
+ * This file imports nothing.
15
+ */
16
+ export interface WorldMarker {
17
+ name: string;
18
+ /** Position in GLB/spec space (origin at level center). */
19
+ glb: {
20
+ x: number;
21
+ y: number;
22
+ z: number;
23
+ };
24
+ /** Position in baked world space (world min corner is the origin). */
25
+ world: {
26
+ x: number;
27
+ y: number;
28
+ z: number;
29
+ };
30
+ }
31
+ export interface ForgedPlacement {
32
+ archetype: string;
33
+ /** WORLD-space position (object origin / base on the ground). */
34
+ position: {
35
+ x: number;
36
+ y: number;
37
+ z: number;
38
+ };
39
+ rotationYDeg: number;
40
+ scale: number;
41
+ /** Per-axis scale (overrides uniform `scale` when present); city buildings. */
42
+ scaleXYZ?: {
43
+ x: number;
44
+ y: number;
45
+ z: number;
46
+ };
47
+ collision: boolean;
48
+ /** Loose prop: placed as an individual dynamic rigid body that settles under
49
+ * gravity and sleeps until pushed (wrecks, barrels) — not a static batch. */
50
+ dynamic?: boolean;
51
+ /** Authored mass in kg for `dynamic` placements (omitted → engine estimate). */
52
+ mass?: number;
53
+ }
54
+ /** How an object's geometry collides in the bake. */
55
+ export type ColliderKind = 'trimesh' | 'voxel' | 'none';
56
+ /** One line of the forge's object report (the summary the caller reads). */
57
+ export interface ForgedObjectSummary {
58
+ name: string;
59
+ kind: 'level' | 'asset';
60
+ triangles: number;
61
+ instances?: number;
62
+ smooth: boolean;
63
+ collider: ColliderKind;
64
+ }
65
+ /** A terrain LOD band the forger chose (node name -> lodOffset), for reporting. */
66
+ export interface ForgedTerrainBand {
67
+ name: string;
68
+ lodOffset: number;
69
+ }
70
+ export interface CoursePoint {
71
+ x: number;
72
+ y: number;
73
+ z: number;
74
+ }
75
+ export interface CourseCheckpoint extends CoursePoint {
76
+ /** Arc-length fraction along the course (0 = start, 1 = finish/lap). */
77
+ t: number;
78
+ }
79
+ /**
80
+ * A declared runtime behavior (ski lift, elevator, door) with its anchors
81
+ * resolved to world coordinates — the handoff the game's coding agent
82
+ * implements with engine systems. The level bakes geometry; features carry
83
+ * the intent the geometry alone cannot.
84
+ */
85
+ export interface ResolvedFeature {
86
+ kind: string;
87
+ name: string;
88
+ description: string;
89
+ /** Single-point anchors: props, markers and structures — one entry each. */
90
+ anchors: Array<{
91
+ name: string;
92
+ x: number;
93
+ y: number;
94
+ z: number;
95
+ }>;
96
+ /**
97
+ * Instanced sets this feature is about — a scatter archetype ("CoconutPalms")
98
+ * or a city building type, where the intent is EVERY instance, not one of them.
99
+ *
100
+ * Per-instance positions are deliberately NOT inlined. A real level places up
101
+ * to ~640 instances of a single archetype, and these features are rendered
102
+ * verbatim into the coding agent's prompt AND persisted into world.json — so
103
+ * inlining would make both scale with instance count. The positions are already
104
+ * reachable: resolve `name` → `asset_id` through `library_assets`, then read
105
+ * world.json `environmentObjects`. This payload stays O(archetypes).
106
+ */
107
+ archetypeAnchors?: Array<{
108
+ name: string;
109
+ instances: number;
110
+ centroid: {
111
+ x: number;
112
+ y: number;
113
+ z: number;
114
+ };
115
+ }>;
116
+ points: Array<{
117
+ x: number;
118
+ y: number;
119
+ z: number;
120
+ }>;
121
+ /** Open structured parameters carried verbatim to the game's coding agent (e.g. lock id,
122
+ * timing, spawn-candidate metadata). `points` are world-resolved; `params` is opaque. */
123
+ params?: Record<string, unknown>;
124
+ }
125
+ /**
126
+ * Auto-emitted for every designed path: the level's intended flow as ordered
127
+ * world-space control points (dense through sharp turns, at most ~8 m apart
128
+ * on straights) with start/finish/checkpoints. The designed path is
129
+ * authoritative intent — game code should consume this rather than derive a
130
+ * line from the baked surface (which is lossy and closed-loop-only).
131
+ */
132
+ export interface ResolvedPathFeature extends ResolvedFeature {
133
+ kind: 'path';
134
+ /** Ribbon width in meters (world space). */
135
+ widthM: number;
136
+ /** True for circuits: the last point connects back to the first. */
137
+ closed: boolean;
138
+ /** 3D arc length of the control polyline (m). */
139
+ lengthM: number;
140
+ /** First control point — the intended start of travel. */
141
+ start: CoursePoint;
142
+ /** Last control point (the lap point itself for closed circuits). */
143
+ finish: CoursePoint;
144
+ /** Evenly spaced by arc length, strictly between start and finish. */
145
+ checkpoints: CourseCheckpoint[];
146
+ /** Ribbon node name when its surface is queryable via the named-trimesh API. */
147
+ surfaceObjectName?: string;
148
+ }
149
+ /** Mirror of the engine handler's `options` payload. */
150
+ export interface LevelVoxelizeOptions {
151
+ levelSizeX: number;
152
+ levelSizeZ: number;
153
+ /**
154
+ * NEVER set by the forger. A present `levelSizeY` switches the engine's
155
+ * `applyLevelSizeTransform` to a NON-uniform Y scale, while
156
+ * `marker-transform.ts` — the agent-side mirror every marker, door, key,
157
+ * spawn, water and nav Y is mapped through — assumes the uniform scale. The
158
+ * engine's `worldExtentY` already auto-sizes the level box from geometry,
159
+ * which is what a dungeon hanging under the terrain plate needs.
160
+ */
161
+ levelSizeY?: number;
162
+ chunkSize: number;
163
+ minVoxelSize: number;
164
+ maxVoxelSize: number;
165
+ fillInterior: boolean;
166
+ additionalLods?: Array<{
167
+ minVoxelSize: number;
168
+ maxVoxelSize: number;
169
+ distance?: number;
170
+ }>;
171
+ objectLodOffsets?: Record<string, number>;
172
+ objectLodPins?: Record<string, true>;
173
+ objectTrimeshColliders?: Record<string, true>;
174
+ objectNoColliders?: Record<string, true>;
175
+ objectCollisionOnlyNodes?: Record<string, true>;
176
+ objectDisplacementAxes?: Record<string, 'x' | 'y' | 'z'>;
177
+ /**
178
+ * Objects EXCLUDED from the level bake — they are library-asset instance
179
+ * groups (tagged in the GLB) placed as environment objects instead.
180
+ */
181
+ objectAssetInstances?: Record<string, true>;
182
+ /**
183
+ * Per-object GROUND TYPE names (see the engine's `vxlscene/GroundTypes.ts`
184
+ * registry, mirrored in `city/ground-style.ts`). The bake rasterizes the
185
+ * tagged nodes' triangles into the level's ground mask, which drives the
186
+ * runtime cobble domes and grass ground cover.
187
+ */
188
+ objectGroundTypes?: Record<string, string>;
189
+ /**
190
+ * Authored `#RRGGBB` → emissive strength (16..255). The bake matches these
191
+ * against the palette colors it actually produces and writes the matching
192
+ * cells into the level's emissive block, so glowing runes, lava seams and
193
+ * crystal veins light up at zero light-budget cost. Dungeon palettes are the
194
+ * only producer today.
195
+ */
196
+ emissiveByColor?: Record<string, number>;
197
+ }
198
+ export type DoorAnimation = 'hinge' | 'slide' | 'dissolve';
199
+ export interface DungeonLightConfig {
200
+ color: string;
201
+ intensity: number;
202
+ distance: number;
203
+ flicker: boolean;
204
+ offset?: {
205
+ x: number;
206
+ y: number;
207
+ z: number;
208
+ };
209
+ }
210
+ /**
211
+ * Spec-space mirrors of `DoorDefinition` / `KeyItemDefinition` in
212
+ * `game/src/types/game.ts`, minus the fields the PIPELINE owns: `levelId`
213
+ * (assigned at persist) and `assetId` (assigned once the archetype is baked).
214
+ * Mirrored rather than imported — the agent project does not compile the game
215
+ * project's sources — so any field added there must be added here too.
216
+ */
217
+ export interface DungeonDoorDef {
218
+ id: string;
219
+ /** Closed-pose CENTRE of the leaf. */
220
+ position: {
221
+ x: number;
222
+ y: number;
223
+ z: number;
224
+ };
225
+ /** Yaw in RADIANS. Door-local X is the width, Z the thickness. */
226
+ rotationY: number;
227
+ width: number;
228
+ height: number;
229
+ thickness: number;
230
+ kind: 'plain' | 'locked';
231
+ keyId?: string;
232
+ animation: DoorAnimation;
233
+ /** Explicit for forged hinge doors; the engine retains 100° when omitted. */
234
+ maxOpenAngleDeg?: number;
235
+ /** Fallback box-leaf tint used until an asset is wired. */
236
+ color?: string;
237
+ autoOpenRadius?: number;
238
+ }
239
+ export interface DungeonKeyItemDef {
240
+ id: string;
241
+ keyId: string;
242
+ name: string;
243
+ position: {
244
+ x: number;
245
+ y: number;
246
+ z: number;
247
+ };
248
+ color?: string;
249
+ }
250
+ /**
251
+ * A NARROWED view of the designed scene spec (`scene-spec.ts`'s
252
+ * `WorldSceneSpec`, which stays private): exactly the fields the persist step
253
+ * reads, plus the identity it echoes back in the summary. The full validated
254
+ * spec is what actually travels — it is written verbatim onto the level asset
255
+ * record as `worldForgerSpec` — this type just declares the part any consumer
256
+ * of a forge artifact is entitled to depend on.
257
+ *
258
+ * Narrowing rather than restating is what keeps it honest: the private
259
+ * `WorldSceneSpec` is widened into this view in ONE place, so a field renamed
260
+ * or dropped over there fails to compile rather than drifting. That check only
261
+ * bites for the REQUIRED fields, though — `dungeon` and `city` are optional
262
+ * here, so renaming either away on the private side would still compile and
263
+ * would silently stop a dungeon getting its atmosphere. The producer therefore
264
+ * names both fields explicitly rather than relying on a bare assignment; see
265
+ * `toForgedSpecView` in the private half's `forge-and-upload-level.ts`.
266
+ */
267
+ export interface ForgedSpecMaterialView {
268
+ name: string;
269
+ role: string;
270
+ color: string;
271
+ emissive?: {
272
+ strength: number;
273
+ };
274
+ }
275
+ /** The dungeon plan's palette — all the level atmosphere is derived from. */
276
+ export interface ForgedDungeonView {
277
+ materials: ForgedSpecMaterialView[];
278
+ }
279
+ /** The city plan's zones — the persist step only asks whether any is water. */
280
+ export interface ForgedCityView {
281
+ zones?: Array<{
282
+ kind: string;
283
+ }>;
284
+ }
285
+ export interface ForgedSpecView {
286
+ name: string;
287
+ size: {
288
+ x: number;
289
+ z: number;
290
+ };
291
+ /** Present iff the level is a dungeon (drives spawn clearance + atmosphere). */
292
+ dungeon?: ForgedDungeonView;
293
+ city?: ForgedCityView;
294
+ }
295
+ //# sourceMappingURL=artifact-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-types.d.ts","sourceRoot":"","sources":["../src/artifact-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,GAAG,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,sEAAsE;IACtE,KAAK,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5C;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,QAAQ,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,SAAS,EAAE,OAAO,CAAC;IACnB;kFAC8E;IAC9E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qDAAqD;AACrD,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAExD,4EAA4E;AAC5E,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,YAAY,CAAC;CACxB;AAED,mFAAmF;AACnF,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,MAAM,WAAW,WAAW;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,wEAAwE;IACxE,CAAC,EAAE,MAAM,CAAC;CACX;AAID;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClE;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,KAAK,CAAC;QACvB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC/C,CAAC,CAAC;IACH,MAAM,EAAE,KAAK,CAAC;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD;8FAC0F;IAC1F,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,MAAM,EAAE,OAAO,CAAC;IAChB,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,KAAK,EAAE,WAAW,CAAC;IACnB,qEAAqE;IACrE,MAAM,EAAE,WAAW,CAAC;IACpB,sEAAsE;IACtE,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,gFAAgF;IAChF,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAID,wDAAwD;AACxD,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,KAAK,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1F,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACrC,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC9C,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACzC,wBAAwB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAChD,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;IACzD;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC5C;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAID,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC;AAE3D,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9C;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,sCAAsC;IACtC,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,aAAa,CAAC;IACzB,6EAA6E;IAC7E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CACjC;AAED,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,sBAAsB,EAAE,CAAC;CACrC;AAED,+EAA+E;AAC/E,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/B,gFAAgF;IAChF,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,IAAI,CAAC,EAAE,cAAc,CAAC;CACvB"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * The forged-artifact SCHEMA — the data shapes that cross from the private
3
+ * design/geometry half of the forger into the publishable half that drives the
4
+ * browser (archetype bakes, the level bake, instance placement and persist).
5
+ *
6
+ * These are declarations, not algorithms: a client that consumes a forge
7
+ * artifact at all has to know its shape, so the schema is public and the code
8
+ * that produces it is not. Each type is DEFINED here and re-exported from the
9
+ * module it used to live in (`forge-world.ts`, `derive-settings.ts`,
10
+ * `dungeon/dressing.ts`, `course.ts`, `dungeon/fixture-parts.ts`), so there is
11
+ * still exactly one definition of each and every historic import site keeps
12
+ * working.
13
+ *
14
+ * This file imports nothing.
15
+ */
16
+ export {};
17
+ //# sourceMappingURL=artifact-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-types.js","sourceRoot":"","sources":["../src/artifact-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * The dependency-free leaf: every constant and pure predicate that BOTH halves
3
+ * of the world forger need.
4
+ *
5
+ * The forger splits in two — the private design/geometry half (`forge-world.ts`,
6
+ * `scene-spec.ts`, the geometry tree, the designer and the director) and the
7
+ * publishable half that drives the browser steps (archetype bakes, the level
8
+ * bake, instance placement + persist). A handful of numbers and one predicate
9
+ * are genuinely shared. Left where they were, importing them would drag
10
+ * `forge-world.ts` (700+ lines, and through it `build-scene`, `glb-write`,
11
+ * `dungeon/nav-compile`, `marker-transform` and `heightfield`) or `city/zones.ts`
12
+ * (`geometry`, `street-graph`, `ground-style`) — and therefore three.js — into
13
+ * the publishable half for the sake of three numbers.
14
+ *
15
+ * So this file imports NOTHING, and every previous home re-exports from here so
16
+ * each symbol still has exactly one definition. Add to it only what both halves
17
+ * actually need; it is a boundary, not a junk drawer.
18
+ */
19
+ /**
20
+ * Absolute LOD0 leaf ceiling for one archetype bake — the bake loop re-bakes at
21
+ * doubled voxel sizes until the count fits. Per-archetype TARGETS below are what
22
+ * actually size the bake; this is only the runaway backstop.
23
+ */
24
+ export declare const ASSET_LOD0_VOXEL_BUDGET = 500000;
25
+ /**
26
+ * The LOD0 leaf TARGET for an ordinary (non-landmark) archetype — what actually
27
+ * sizes a standard bake. Its landmark sibling stays in derive-settings.ts, which
28
+ * is the only thing that reads it; this one crosses because the pipeline's own
29
+ * bake-loop tests assert against it.
30
+ */
31
+ export declare const ASSET_STANDARD_LOD0_TARGET = 50000;
32
+ /**
33
+ * Spawn this far above the marker so the player drops onto the surface —
34
+ * outdoors only. A dungeon spawn instead is authored with clearance 0: the
35
+ * entrance cell's Y (see `dressing.ts` — "FLOOR TRUTH", taken from the floor
36
+ * grid, never from `room.floorY`) already IS the true floor, so `player_0` is
37
+ * written exactly there. The engine (`game/src/engine/loaders/PlayerLoader.ts`)
38
+ * seats the capsule on the floor beneath a configured interior spawn itself (a
39
+ * bounded downward search) rather than lifting an authored point, so the
40
+ * forger no longer needs to predict engine lift constants or bake-regime floor
41
+ * heights. See the `clearanceM` choice in `place-and-persist-level.ts`.
42
+ */
43
+ export declare const SPAWN_CLEARANCE_M = 1.5;
44
+ /** Sea level (world Y) the engine renders the water surface at — just below the land base so the
45
+ * land occludes the plane and only the dug basins (floor at -WATER_DEPTH) reveal the see-through sea. */
46
+ export declare const WATER_SURFACE_Y = -2;
47
+ /** Bake pitch of a wall module. Every relief feature is a whole multiple of it. */
48
+ export declare const VOXEL_M = 0.0625;
49
+ /** Modules bake at this pitch, pinned rather than left to the archetype
50
+ * budget's clamp — a coarser bake silently deletes ALL relief. */
51
+ export declare const MODULE_MIN_VOXEL_M = 0.0625;
52
+ /** Top-level GLB node-name prefix. The bake and structural fail-fast path both
53
+ * branch on it; used modules are never dropped or degraded to shell. */
54
+ export declare const MODULE_NAME_PREFIX = "Mod_";
55
+ /**
56
+ * Question: MIGHT this archetype's instance group be a module kit's, and so
57
+ * bloat the world GLB the way the kit's groups do? Deliberately loose — the
58
+ * reserved `Mod_` name prefix (module-kit.ts) and nothing else.
59
+ *
60
+ * Fails safe by OVER-matching. A false positive drops one redundant
61
+ * self-description copy of an object from a file only a manual GLB viewer and
62
+ * the Assets-tab bake fallback ever read; the archetype's own asset and every
63
+ * placement are written elsewhere and are untouched. A false negative puts a
64
+ * several-hundred-instance group back into the world GLB — the measured case
65
+ * was 567 module placements replaying a shared mesh for 23.7M effective
66
+ * triangles, which burned the full 20-minute bake timeout on a level that
67
+ * forged in 95 s without them. Over-matching costs a viewer copy;
68
+ * under-matching costs the run.
69
+ */
70
+ export declare function isModuleNamedArchetype(name: string): boolean;
71
+ /**
72
+ * Question: IS this archetype really one of the kit's own pieces, so its bake
73
+ * may be PINNED to the kit's voxel size and its interior left unfilled? The
74
+ * reserved prefix AND the non-colliding decorative flag `dungeon-expand.ts`'s
75
+ * `moduleArchetype` sets on every piece — the same pair `archetype-skips.ts`'s
76
+ * `isCladdingModule` requires.
77
+ *
78
+ * Fails safe by UNDER-matching, the opposite direction from the predicate
79
+ * above, which is why the two must stay separate rather than share one test. A
80
+ * false negative costs nothing today: every real kit piece is small enough that
81
+ * `deriveArchetypeVoxelBake` floor-clamps to this same value anyway, so the pin
82
+ * is a guarantee against future kit or budget changes, not a live behaviour
83
+ * change. A false positive is the expensive direction, and the pin is the only
84
+ * branch here with a live effect at all: `bake.minVoxelSize` is already floored
85
+ * at ASSET_MIN_VOXEL_SIZE, which IS MODULE_MIN_VOXEL_M, so pinning can only
86
+ * make a bake FINER, never coarser. `scene-spec.ts`'s `nodeName` lets an LLM
87
+ * legally name any object `Mod_*` in any genre and nothing in the repo reserves
88
+ * the prefix, so a prefix-only pin would bake, say, a `Mod_Tower` in a city
89
+ * forge at roughly 13x the surface cells — and that timeout is FATAL, because
90
+ * `archetype-skips.ts`'s `isCladdingModule` would (correctly) refuse to class a
91
+ * colliding object as droppable. Nothing downstream rescues it either: the
92
+ * pipeline's coarsen-rebake loop, which used to double a misfired pin back out
93
+ * of trouble, now leaves modules at their pinned size precisely so a REAL
94
+ * module's relief survives. Same mechanism, opposite roles — with that net
95
+ * gone, this narrowing is the guard.
96
+ *
97
+ * This lives in the leaf rather than in `forge-world.ts` because BOTH halves
98
+ * decide with it: the forger pins the bake resolution here, and the pipeline's
99
+ * `isCladdingModule` classifies the same archetype the same way. Restating it
100
+ * on one side would silently mis-resolve bakes with every test still green.
101
+ */
102
+ export declare function isKitModuleArchetype(archetype: {
103
+ name: string;
104
+ collision: boolean;
105
+ }): boolean;
106
+ //# sourceMappingURL=forge-constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forge-constants.d.ts","sourceRoot":"","sources":["../src/forge-constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,SAAU,CAAC;AAE/C;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,QAAS,CAAC;AAIjD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAIrC;0GAC0G;AAC1G,eAAO,MAAM,eAAe,KAAK,CAAC;AAIlC,mFAAmF;AACnF,eAAO,MAAM,OAAO,SAAS,CAAC;AAE9B;mEACmE;AACnE,eAAO,MAAM,kBAAkB,SAAU,CAAC;AAE1C;yEACyE;AACzE,eAAO,MAAM,kBAAkB,SAAS,CAAC;AAEzC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAE7F"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * The dependency-free leaf: every constant and pure predicate that BOTH halves
3
+ * of the world forger need.
4
+ *
5
+ * The forger splits in two — the private design/geometry half (`forge-world.ts`,
6
+ * `scene-spec.ts`, the geometry tree, the designer and the director) and the
7
+ * publishable half that drives the browser steps (archetype bakes, the level
8
+ * bake, instance placement + persist). A handful of numbers and one predicate
9
+ * are genuinely shared. Left where they were, importing them would drag
10
+ * `forge-world.ts` (700+ lines, and through it `build-scene`, `glb-write`,
11
+ * `dungeon/nav-compile`, `marker-transform` and `heightfield`) or `city/zones.ts`
12
+ * (`geometry`, `street-graph`, `ground-style`) — and therefore three.js — into
13
+ * the publishable half for the sake of three numbers.
14
+ *
15
+ * So this file imports NOTHING, and every previous home re-exports from here so
16
+ * each symbol still has exactly one definition. Add to it only what both halves
17
+ * actually need; it is a boundary, not a junk drawer.
18
+ */
19
+ // ── Archetype bake budgets (derive-settings.ts) ──────────────────────────────
20
+ /**
21
+ * Absolute LOD0 leaf ceiling for one archetype bake — the bake loop re-bakes at
22
+ * doubled voxel sizes until the count fits. Per-archetype TARGETS below are what
23
+ * actually size the bake; this is only the runaway backstop.
24
+ */
25
+ export const ASSET_LOD0_VOXEL_BUDGET = 500000;
26
+ /**
27
+ * The LOD0 leaf TARGET for an ordinary (non-landmark) archetype — what actually
28
+ * sizes a standard bake. Its landmark sibling stays in derive-settings.ts, which
29
+ * is the only thing that reads it; this one crosses because the pipeline's own
30
+ * bake-loop tests assert against it.
31
+ */
32
+ export const ASSET_STANDARD_LOD0_TARGET = 50000;
33
+ // ── Spawn (forge-world.ts) ───────────────────────────────────────────────────
34
+ /**
35
+ * Spawn this far above the marker so the player drops onto the surface —
36
+ * outdoors only. A dungeon spawn instead is authored with clearance 0: the
37
+ * entrance cell's Y (see `dressing.ts` — "FLOOR TRUTH", taken from the floor
38
+ * grid, never from `room.floorY`) already IS the true floor, so `player_0` is
39
+ * written exactly there. The engine (`game/src/engine/loaders/PlayerLoader.ts`)
40
+ * seats the capsule on the floor beneath a configured interior spawn itself (a
41
+ * bounded downward search) rather than lifting an authored point, so the
42
+ * forger no longer needs to predict engine lift constants or bake-regime floor
43
+ * heights. See the `clearanceM` choice in `place-and-persist-level.ts`.
44
+ */
45
+ export const SPAWN_CLEARANCE_M = 1.5;
46
+ // ── Water (city/zones.ts) ────────────────────────────────────────────────────
47
+ /** Sea level (world Y) the engine renders the water surface at — just below the land base so the
48
+ * land occludes the plane and only the dug basins (floor at -WATER_DEPTH) reveal the see-through sea. */
49
+ export const WATER_SURFACE_Y = -2;
50
+ // ── Dungeon module kit (dungeon/module-stone.ts, dungeon/module-kit.ts) ──────
51
+ /** Bake pitch of a wall module. Every relief feature is a whole multiple of it. */
52
+ export const VOXEL_M = 0.0625;
53
+ /** Modules bake at this pitch, pinned rather than left to the archetype
54
+ * budget's clamp — a coarser bake silently deletes ALL relief. */
55
+ export const MODULE_MIN_VOXEL_M = VOXEL_M;
56
+ /** Top-level GLB node-name prefix. The bake and structural fail-fast path both
57
+ * branch on it; used modules are never dropped or degraded to shell. */
58
+ export const MODULE_NAME_PREFIX = 'Mod_';
59
+ /**
60
+ * Question: MIGHT this archetype's instance group be a module kit's, and so
61
+ * bloat the world GLB the way the kit's groups do? Deliberately loose — the
62
+ * reserved `Mod_` name prefix (module-kit.ts) and nothing else.
63
+ *
64
+ * Fails safe by OVER-matching. A false positive drops one redundant
65
+ * self-description copy of an object from a file only a manual GLB viewer and
66
+ * the Assets-tab bake fallback ever read; the archetype's own asset and every
67
+ * placement are written elsewhere and are untouched. A false negative puts a
68
+ * several-hundred-instance group back into the world GLB — the measured case
69
+ * was 567 module placements replaying a shared mesh for 23.7M effective
70
+ * triangles, which burned the full 20-minute bake timeout on a level that
71
+ * forged in 95 s without them. Over-matching costs a viewer copy;
72
+ * under-matching costs the run.
73
+ */
74
+ export function isModuleNamedArchetype(name) {
75
+ return name.startsWith(MODULE_NAME_PREFIX);
76
+ }
77
+ /**
78
+ * Question: IS this archetype really one of the kit's own pieces, so its bake
79
+ * may be PINNED to the kit's voxel size and its interior left unfilled? The
80
+ * reserved prefix AND the non-colliding decorative flag `dungeon-expand.ts`'s
81
+ * `moduleArchetype` sets on every piece — the same pair `archetype-skips.ts`'s
82
+ * `isCladdingModule` requires.
83
+ *
84
+ * Fails safe by UNDER-matching, the opposite direction from the predicate
85
+ * above, which is why the two must stay separate rather than share one test. A
86
+ * false negative costs nothing today: every real kit piece is small enough that
87
+ * `deriveArchetypeVoxelBake` floor-clamps to this same value anyway, so the pin
88
+ * is a guarantee against future kit or budget changes, not a live behaviour
89
+ * change. A false positive is the expensive direction, and the pin is the only
90
+ * branch here with a live effect at all: `bake.minVoxelSize` is already floored
91
+ * at ASSET_MIN_VOXEL_SIZE, which IS MODULE_MIN_VOXEL_M, so pinning can only
92
+ * make a bake FINER, never coarser. `scene-spec.ts`'s `nodeName` lets an LLM
93
+ * legally name any object `Mod_*` in any genre and nothing in the repo reserves
94
+ * the prefix, so a prefix-only pin would bake, say, a `Mod_Tower` in a city
95
+ * forge at roughly 13x the surface cells — and that timeout is FATAL, because
96
+ * `archetype-skips.ts`'s `isCladdingModule` would (correctly) refuse to class a
97
+ * colliding object as droppable. Nothing downstream rescues it either: the
98
+ * pipeline's coarsen-rebake loop, which used to double a misfired pin back out
99
+ * of trouble, now leaves modules at their pinned size precisely so a REAL
100
+ * module's relief survives. Same mechanism, opposite roles — with that net
101
+ * gone, this narrowing is the guard.
102
+ *
103
+ * This lives in the leaf rather than in `forge-world.ts` because BOTH halves
104
+ * decide with it: the forger pins the bake resolution here, and the pipeline's
105
+ * `isCladdingModule` classifies the same archetype the same way. Restating it
106
+ * on one side would silently mis-resolve bakes with every test still green.
107
+ */
108
+ export function isKitModuleArchetype(archetype) {
109
+ return isModuleNamedArchetype(archetype.name) && archetype.collision === false;
110
+ }
111
+ //# sourceMappingURL=forge-constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forge-constants.js","sourceRoot":"","sources":["../src/forge-constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,gFAAgF;AAEhF;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAO,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,KAAM,CAAC;AAEjD,gFAAgF;AAEhF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAErC,gFAAgF;AAEhF;0GAC0G;AAC1G,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,CAAC;AAElC,gFAAgF;AAEhF,mFAAmF;AACnF,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC;AAE9B;mEACmE;AACnE,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAE1C;yEACyE;AACzE,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAEzC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,OAAO,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAA+C;IAClF,OAAO,sBAAsB,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,SAAS,KAAK,KAAK,CAAC;AACjF,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * `@bitmagic/world-forger` — the CLIENT half of the world forger.
3
+ *
4
+ * The forger runs in two halves. The DESIGN and GEOMETRY half (an LLM designs a
5
+ * level, deterministic code builds its meshes) is private, is not published, and
6
+ * stays server-side. This package is everything a host needs to consume what
7
+ * that half produces:
8
+ *
9
+ * - the forged-level ARTIFACT SCHEMA (artifact-types.ts, pipeline/job-types.ts)
10
+ * — placements, markers, resolved gameplay features, dungeon doors/keys/
11
+ * lights, the terrain height grid and the level bake options,
12
+ * - the HOST SEAMS the pipeline runs behind (storage, model, transport,
13
+ * world.json, logger — see pipeline/deps.ts),
14
+ * - the three BROWSER STEPS themselves: create the archetype library assets,
15
+ * bake the level, place the instances and plan the world.json write.
16
+ *
17
+ * Nothing here touches geometry, and it deliberately has no three.js — the steps
18
+ * orchestrate a browser that does the heavy work, and the artifact that reaches
19
+ * them is already plain JSON.
20
+ *
21
+ * The pipeline is reachable as `@bitmagic/world-forger/pipeline/index.js`;
22
+ * every module is reachable by its own subpath (e.g.
23
+ * `@bitmagic/world-forger/pipeline/transport-types.js`).
24
+ */
25
+ export * from './artifact-types.js';
26
+ export * from './forge-constants.js';
27
+ export * from './terrain-height-grid.js';
28
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * `@bitmagic/world-forger` — the CLIENT half of the world forger.
3
+ *
4
+ * The forger runs in two halves. The DESIGN and GEOMETRY half (an LLM designs a
5
+ * level, deterministic code builds its meshes) is private, is not published, and
6
+ * stays server-side. This package is everything a host needs to consume what
7
+ * that half produces:
8
+ *
9
+ * - the forged-level ARTIFACT SCHEMA (artifact-types.ts, pipeline/job-types.ts)
10
+ * — placements, markers, resolved gameplay features, dungeon doors/keys/
11
+ * lights, the terrain height grid and the level bake options,
12
+ * - the HOST SEAMS the pipeline runs behind (storage, model, transport,
13
+ * world.json, logger — see pipeline/deps.ts),
14
+ * - the three BROWSER STEPS themselves: create the archetype library assets,
15
+ * bake the level, place the instances and plan the world.json write.
16
+ *
17
+ * Nothing here touches geometry, and it deliberately has no three.js — the steps
18
+ * orchestrate a browser that does the heavy work, and the artifact that reaches
19
+ * them is already plain JSON.
20
+ *
21
+ * The pipeline is reachable as `@bitmagic/world-forger/pipeline/index.js`;
22
+ * every module is reachable by its own subpath (e.g.
23
+ * `@bitmagic/world-forger/pipeline/transport-types.js`).
24
+ */
25
+ export * from './artifact-types.js';
26
+ export * from './forge-constants.js';
27
+ export * from './terrain-height-grid.js';
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC"}
package/dist/log.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Minimal dependency-free logger for this package. `shared/world-forger` must
3
+ * stay free of game-play-agent's pino/fs-backed logger (`src/utils/logger.ts`)
4
+ * — see the package README-equivalent purity rule in the extraction task —
5
+ * so this mirrors just the pino call shape `city-expand.ts` uses
6
+ * (`log.warn(context, message)` / `log.info(context, message)`) over plain
7
+ * console output.
8
+ *
9
+ * This is NOT a general injectable-logger seam, and deliberately stays that
10
+ * way. Two modules use it — `pipeline/asset-catalog.ts` and
11
+ * `pipeline/forged-work-store.ts` — and both log housekeeping detail (a
12
+ * skipped catalog entry, a store read) that no host has ever needed to route
13
+ * anywhere. Everything a host DOES care about already goes through the real
14
+ * seam: `ForgeDeps.logger` (see pipeline/deps.ts), which every pipeline step
15
+ * logs through and which the web lane points at pino and the CLI lane at the
16
+ * creator's terminal. Adding a second injectable logger for these two call
17
+ * sites would duplicate that seam rather than complete it.
18
+ */
19
+ export interface Logger {
20
+ info(context: Record<string, unknown>, message: string): void;
21
+ warn(context: Record<string, unknown>, message: string): void;
22
+ error(context: Record<string, unknown>, message: string): void;
23
+ debug(context: Record<string, unknown>, message: string): void;
24
+ }
25
+ export declare function createLogger(name: string): Logger;
26
+ //# sourceMappingURL=log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9D,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9D,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/D,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAChE;AAQD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOjD"}