@adatechnology/game-floorplan-structure 0.0.0-stage → 1.0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Anderson Fernandes
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/MIGRATION.md ADDED
@@ -0,0 +1,94 @@
1
+ # Migration: structure of the Visor de casas 3D (VC3) to `@adatechnology/game-floorplan-structure`
2
+
3
+ What the team's `PlantasSDK.gerar` returned as `construcao`, `estrutura`, `telhado` and `caixaDagua`, and `Casa3DSDK.specDe`, now live here with English names. With `wallDetail: 'coarse'`
4
+ the output equals the team page in 900 recorded plans (`tests/team-golden-vc3-structure.test.ts`, which translates back with the tables below).
5
+
6
+ ## Result
7
+
8
+ | VC3 | SDK |
9
+ |---|---|
10
+ | `res.construcao` | `result.construction` (`system`, `walls`, `floor`, `roof`, `frame`, `foundation`) |
11
+ | `res.estrutura` `{ pecas, apoios, niveis, elevacao }` | `result.structure` `{ parts, supports, levels, elevation, framed }` |
12
+ | `res.telhado` | `result.roof` (`shape`, `covering`, `material`, `pitch`, `bearingFloor`, `panes`, `trusses`, `axis`, `ridge`, `eave`, `y0`, `aabb`) |
13
+ | `res.caixaDagua` | `result.waterTank` (`place`, `floor`, `room`, `capacity`, `platform`, `stand`) |
14
+ | extras of the template (`chamine`, `poco`, `sotao`, `tendas`) | `result.structureExtras` (`chimney`, `well`, `attic`, `tents`) |
15
+ | `Casa3DSDK.specDe(est, { vedacao, fs, n1, fsOutros, filtro, projeto })` | `toDestructibleSpec(structure, { portico, safety, redundancy, safetyOthers, filter, sized })` |
16
+ | `Casa3DSDK.cargasProjeto` | `loadsAtRest` (internal; `sizeStructure` of game-destruction agrees except for beams of a framed building) |
17
+
18
+ ## Part
19
+
20
+ | VC3 | SDK |
21
+ |---|---|
22
+ | `id` `role` `material` `aabb` `y0` `y1` `andar` `massa` | `id` `role` `material` `aabb` `y0` `y1` `floor` `mass` |
23
+ | `pilar`, `viga`, `laje`, `parede_portante`, `parede_vedacao`, `telhado`, `escada`, `caixa_dagua` | `column`, `beam`, `slab`, `wall`, `partition`, `roof`, `stair`, `none` (StructureRole of game-contracts) |
24
+ | `espacamento`, `tipoViga` (`prato`, `cinta`), `degraus`, `porta`, `cobertura`, `capacidade`, `inclinacao`, `barraca`, `forma`, `montantes` | `spacing`, `beamKind` (`plate`, `bond_beam`), `steps`, `door`, `cover`, `liters`, `pitch`, `tent`, `form`, `studs` |
25
+ | support `{ de, sobre, tipo }`, `'chao'` | `{ part, on, joint }`, `'ground'` |
26
+ | joints `mortar`, `rebar`, `bolt`, `resting`, `nail`, `rope` | the same except `rope` is `tie` (JointKind) |
27
+
28
+ ## Part ids
29
+
30
+ | VC3 | SDK | VC3 | SDK |
31
+ |---|---|---|---|
32
+ | `w<floor>_<n>` | `wall_<floor>_<n>` | `prato_<f>_<n>` | `plate_<f>_<n>` |
33
+ | `pilar_<f>_<n>` | `column_<f>_<n>` | `pilar_predio_<n>` | `building_column_<n>` |
34
+ | `pilar_fund_<j>_<i>` | `footing_pier_<j>_<i>` | `pilar_sacada_<room>` | `balcony_column_<room>` |
35
+ | `viga_<f>_<n>` (barrotes) | `joist_<f>_<n>` | `viga_base_<n>` | `base_beam_<n>` |
36
+ | `viga_teto_<n>` | `ceiling_joist_<n>` | `laje_<f>` | `slab_<f>` |
37
+ | `laje_<f>_<room>` (sacada) | `slab_<f>_<room>` | `laje_base`, `laje_forro`, `laje_topo`, `laje_caixa`, `laje_sotao` | `slab_base`, `slab_ceiling`, `slab_top`, `tank_slab`, `attic_floor` |
38
+ | `fund_radier` | `foundation_raft` | `porao_laje`, `porao_parede_<lado>`, `porao_pilar_<n>`, `escada_porao` | `basement_slab`, `basement_wall_<side>`, `basement_column_<n>`, `basement_stairs` |
39
+ | `piso_varanda_<room>` | `porch_floor_<room>` | `pier_varanda_<room>_<n>`, `poste_varanda_<room>_<n>` | `porch_footing_<room>_<n>`, `porch_post_<room>_<n>` |
40
+ | `viga_varanda_<room>[_e\|_d]` | `porch_beam_<room>[_e\|_d]` | `telhado_varanda_<room>` | `porch_roof_<room>` |
41
+ | `escada_<porta>`, `escada_<de>_<para>` | `steps_<door>`, `stairs_<from>_<to>` | `tesoura[_<room>]_<n>` | `truss[_<room>]_<n>` (`rafter_a_<n>`, `rafter_b_<n>`, `ridge` in `panels`) |
42
+ | `telhado[_<room>]_a\|b\|anexo` | `roof[_<room>]_a\|b\|annex` | `caixa_dagua`, `chamine`, `poco` | `water_tank`, `chimney`, `well` |
43
+ | `pilar_caixa_<n>`, `pilar_cavalete_<n>`, `viga_cavalete_<n>` | `tank_column_<n>`, `trestle_column_<n>`, `trestle_beam_<n>` | `piso_<tenda>`, `lona_<tenda>`, `vareta_<tenda>_<n>`, `estaca_<tenda>_<n>`, `prumo_<f>_<n>_<k>` | `groundsheet_<tent>`, `canvas_<tent>`, `pole_<tent>_<n>`, `peg_<tent>_<n>`, `post_<f>_<n>_<k>` |
44
+ | `chao` (terreno do spec) | `ground` | | |
45
+
46
+ ## Construction, roof and tank
47
+
48
+ | VC3 | SDK |
49
+ |---|---|
50
+ | `sistema` `alvenaria`, `wood_frame`, `tronco`, `improvisado`, `lona` | `system` `masonry`, `wood_frame`, `log`, `improvised`, `canvas` |
51
+ | `parede` `{ material, interna, revestimento, acabamento, espessura, materiais }` | `walls` `{ material, interior, cladding, finish, thickness, mixed }` |
52
+ | `piso` `{ material, acabamento }` | `floor` `{ material, finish }` |
53
+ | `telhado` `{ material, cobertura, forma, inclinacao, madeiramento, beiral, eixo, apoiaEm }` | `roof` `{ material, covering, shape, pitch, timber, eave, axis, bearingFloor }` |
54
+ | `estrutura` `{ material, pilares, vigas, lajes, madeiramento, armadura }` | `frame` `{ material, pillars, beams, slabs, timber, rebar }` |
55
+ | `fundacao` `{ tipo, material, elevacao, profundidade }`; `sapata_corrida`, `predio`, `radier`, `vazio_sanitario`, `pilotis`, `porao`, `terra` | `foundation` `{ type, material, elevation, depth }`; `strip_footing`, `building`, `raft`, `crawl_space`, `piles`, `basement`, `ground` |
56
+ | coverings `colonial`, `fibrocimento`, `laje`, `asfaltica`, `zinco`, `madeira`, `lona`, `palha` | `colonial`, `fiber_cement`, `slab`, `asphalt`, `zinc`, `wood`, `canvas`, `thatch` |
57
+ | forms `duas_aguas`, `laje`, `tenda` | `gable`, `slab`, `tent` |
58
+ | tank `local` `laje`, `laje_caixa`, `sotao`, `cavalete`; `plataforma` `{ yBase, altura, espessura, yTopo, pilares, escada }` | `place` `slab`, `raised_slab`, `attic`, `trestle`; `platform` `{ baseY, height, thickness, topY, pillars, ladder }` |
59
+ | `tpl.construcao(plano, sem)`, `tpl.extras`, `tpl.caixa`, `tpl.caixaLocal` | `registerConstruction(id, builder)` named by `TemplateDef.construction`, `result.structureExtras`, `TemplateDef.tank`, `TemplateDef.tankLocation` |
60
+ | options `semente` ... | `options.wallDetail` (`coarse`, `panels` default, `units`), `options.construction` |
61
+
62
+ ## Installations (T2.2e)
63
+
64
+ | VC3 | SDK |
65
+ |---|---|
66
+ | `res.gas`, `res.eletrica`, `res.paineisSolares`, `res.hidraulica` | `result.utilities.gas`, `.electrical`, `.solar`, `.plumbing` |
67
+ | `res.edificacoes`; `res.lote.caminhos` of the outbuilding doors | `result.outbuildings`; `result.lot.paths` (`path_<door>`) |
68
+ | `moveis[i].conteudo` and `conteudoAereo` (`CONTEUDO`, `sorteiaConteudo`) | `result.contents[itemId]` and `result.contents['<id>#overhead']` (`FindStack[]` from `engine.findsFor`; default tables in `utilities/content-tables.ts`) |
69
+ | item `botijao_gas` (13 kg cylinder added by `montarGas`) | item `cooking_gas_cylinder` (category the same), added to `result.items`; `liga` is `link`, `local` `ao_lado`/`nicho_externo`/`sob_bancada` is `placement` `beside`/`external_niche`/`under_counter`, `mangueira` is `hose`, `capacidade_kg` is `capacityKg`, `oculto` is `hidden` |
70
+ | gas `{ tipo: botijao\|encanado, medidor }`; stove `gas`, `botijao`, `gasMedidor` | `{ type: cylinder\|piped, meter }`; stove `gas`, `cylinder`, `gasMeter` |
71
+ | electricity `modo` `rede`\|`gato`\|`offgrid`, `entradaEnergia` `{ poste, ramal, medidor, descida, ramalInterno, gato, ligacao }`, `quadro`, `tomadas`, `interruptores`, `circuitos`, `eletrodutos`, `exposta`, `lampadasExternas`, `fonte` | `mode` `grid`\|`tap`\|`offgrid`, `serviceEntrance` `{ pole, drop, meter, descent, internalRun, tap, connection }`, `panel`, `outlets`, `switches`, `circuits`, `conduits`, `exposed`, `outdoorLamps`, `source` (`solar`\|`lamp`) |
72
+ | `tom<n>`, `int<n>`, `circ_<room>_<floor>`, `ed_<id>`, `ext_<door>`; item `tomada`, `chuveiro` `{ eletrico, potencia_w, tomada }` | `outlet<n>`, `switch<n>`, `circuit_<room>_<floor>`, `conduit_<id>`, `outdoor_<door>`; item `outlet`, `showerHeater` `{ electric, powerW, outlet }` |
73
+ | `tpl.config(op).energia`, `.solar` (cabin, shack) | `TemplateDef.energy(options, w, d)` returning `{ mode, solar }` |
74
+ | solar `{ tipo rack_laje\|telhado, norte, ladoVertente, inclinacao, areaM2, n, paineis, inversor }` | `{ type slab_rack\|roof, north, slopeSide, tilt, areaM2, count, panels, inverter }` |
75
+ | plumbing `{ caixa, capacidade_l, pontos, trechosVisiveis }`, points `torneira`, `chuveiro`, `descarga`, `tanque`, `maquina`, `vazao_lpm`, `trecho`; runs `tr_saida`, `tr_sob_<pt>`, `tr_parede_<room>` | `{ tank, capacityL, points, visibleRuns }`, `tap`, `shower`, `flush`, `tub`, `machine`, `flowLpm`, `run`; `run_outlet`, `run_under_<pt>`, `run_wall_<room>` |
76
+ | outbuilding `{ tipo edicula, uso, paredes, portas, janelas, itens, pe, esp, frente }`, uses `quarto_visita`, `escritorio`, `deposito`, `gourmet`; ids `<id>.p0`, `<id>.j0`, `<id>.j1` | `{ type outbuilding, use, walls, doors, windows, items, ceiling, thickness, front }`, uses `guest_room`, `office`, `storage`, `gourmet`; ids `<id>.d0`, `<id>.w0`, `<id>.w1` |
77
+ | contents by state `protegida`, `abandonada` | `fortified`, `abandoned` rules in `CONTENT_STATES` (`registerContentState`) |
78
+
79
+ The streams of the installations keep the names of the team (`gas`, `eletrica`, `solar`, `edif:quintal.edicula`), so an old seed draws the same gas, sockets, panels and outbuilding use. The golden
80
+ (`tests/team-golden-vc3-structure.test.ts`, with the ids of the items in `tests/fixtures/team-golden/vc3-item-ids.json`) compares the seven lists in 900 plans.
81
+
82
+ ## New with no team original
83
+
84
+ `wallDetail` `panels` and `units` and `buildWallSpecimen` (spec 001, T2.2d). Ids of the pieces of a wall: `wall_<f>_<n>_pier_<k>`, `_sill_<k>`, `_lintel_<k>`, `_spandrel_<k>`; of bricks `wall_<f>_<n>_pier_<k>_u<row>_<i>`;
85
+ of logs `wall_<f>_<n>_log<row>_<i>`; of a door lintel `lintel_<door>`; of rafters `rafter_a_<n>`, `rafter_b_<n>` and `ridge`.
86
+
87
+ ## Differences on purpose
88
+
89
+ - `wallDetail: 'coarse'` is the team's structure. Every other detail also: rafters of each roof side and a `ridge` beam instead of whole trusses (a roof side falls with the wall it rests on, the other stands);
90
+ the porch roof rests on its posts alone (the tie to the house wall carries nothing: take the posts away and only the porch roof falls); a framed building (apartment, commercial, three storeys or more) carries by
91
+ its pillars and beams (`portico`).
92
+ - `door.steps` is written by the structure extension on the doors that get steps, as the team wrote `degraus` (not by `buildStructure`, which does not change its input).
93
+ - Ids of wall hashes (`mixed` materials of the shack) use the legacy key `w<floor>_<n>` so old seeds keep their draws.
94
+ - The terrain part of the spec is `ground` (was `chao`) with the tag `terrain`.
package/README.md CHANGED
@@ -1,3 +1,15 @@
1
- # Temporary Holding Version
1
+ # @adatechnology/game-floorplan-structure
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Structure pack for `@adatechnology/game-floorplan`: construction systems, the load path of every plan and its `DestructibleSpec`.
4
+
5
+ ```ts
6
+ import { engine } from '@adatechnology/game-floorplan'
7
+ import { register } from '@adatechnology/game-floorplan-structure'
8
+
9
+ register(engine)
10
+ const plan = engine.generate('townhouse', { seed: 7 })
11
+ plan.structure.parts // the parts that carry load, each with role, material, box, mass
12
+ plan.structure.supports // what each part rests on, down to 'ground'
13
+ ```
14
+
15
+ See `.claude/skills/game-floorplan-structure/SKILL.md` for the API and `MIGRATION.md` for the names the Visor de casas 3D used.
@@ -0,0 +1,480 @@
1
+ import { FloorplanEngine, ViewerLayer } from '@adatechnology/game-floorplan';
2
+ import { MaterialId, JointKind, StructureRole, DestructibleSpec } from '@adatechnology/game-contracts';
3
+
4
+ interface StructurePackOptions {
5
+ /** Litres of the tank by template id or style id. */
6
+ tankCapacities?: Record<string, number>;
7
+ }
8
+ /**
9
+ * Registers the structure into the engine: `result.construction`, `result.structureExtras`, `result.waterTank`, `result.structure` and `result.roof` of every plan,
10
+ * and the structure layer of the 2D viewer. Register the content packs first.
11
+ */
12
+ declare function register(engine: FloorplanEngine, options?: StructurePackOptions): void;
13
+
14
+ /** Axis-aligned rectangle `[u0, v0, u1, v1]` in the plan (metres). */
15
+ type Rect = [number, number, number, number];
16
+ type ConstructionSystem = 'masonry' | 'wood_frame' | 'log' | 'improvised' | 'canvas';
17
+ type WallDetail = 'coarse' | 'panels' | 'units';
18
+ /** What a structural part is called in a plan: a column is a pillar, `wall` is a bearing wall, `partition` a wall that only closes. */
19
+ type PartRole = Exclude<StructureRole, 'foundation'>;
20
+ declare const GROUND = "ground";
21
+ /** A piece of the structure with its box in the plan, its height range and the mass it weighs. `y` is absolute: the ground floor sits at `foundation.elevation`. */
22
+ interface StructurePart {
23
+ id: string;
24
+ role: PartRole;
25
+ material: MaterialId;
26
+ aabb: Rect;
27
+ y0: number;
28
+ y1: number;
29
+ floor: number;
30
+ mass: number;
31
+ /** Part this one is cut out of (a pier of a wall in `panels` detail). */
32
+ host?: string;
33
+ /** Wall assembly of `game-destruction` the part is built from in the destructible spec (layers, units, rebar, breach). */
34
+ assembly?: string;
35
+ /** A brick, block or log: the unit of a wall (`units` detail, log courses), not a piece of it. */
36
+ unit?: true;
37
+ /** Distance between repeated members (joists, ceiling joists). */
38
+ spacing?: number;
39
+ /** `plate` (timber top plate) or `bond_beam` (masonry bond beam). */
40
+ beamKind?: 'plate' | 'bond_beam';
41
+ steps?: number;
42
+ door?: string;
43
+ /** Slab that is the roof (flat roof). */
44
+ cover?: boolean;
45
+ /** Litres a tank holds. */
46
+ liters?: number;
47
+ studs?: {
48
+ spacing: number;
49
+ section: string;
50
+ };
51
+ pitch?: number;
52
+ tent?: string;
53
+ form?: string;
54
+ }
55
+ /** `part` rests on `on` (`GROUND` or another part) through `joint`. `bears: false` ties the two without carrying load. */
56
+ interface Support {
57
+ part: string;
58
+ on: string;
59
+ joint: JointKind;
60
+ bears?: false;
61
+ }
62
+ interface RoofPane {
63
+ id: string;
64
+ aabb: Rect;
65
+ y0: number;
66
+ y1: number;
67
+ flat?: true;
68
+ }
69
+ type RoofShape = 'gable' | 'slab' | 'tent';
70
+ interface Roof {
71
+ shape: RoofShape;
72
+ covering: string;
73
+ material: MaterialId;
74
+ pitch: number;
75
+ /** Floor the roof rests on. */
76
+ bearingFloor: number;
77
+ panes: (RoofPane | string)[];
78
+ trusses: number;
79
+ axis?: 'u' | 'v';
80
+ ridge?: number;
81
+ eave?: number;
82
+ y0?: number;
83
+ aabb?: Rect;
84
+ }
85
+ /** A window in a wall (the doors are gaps between walls: a lintel part bridges them). Heights are absolute. */
86
+ interface Opening {
87
+ id: string;
88
+ kind: 'window' | 'door';
89
+ wall: string;
90
+ /** Along the wall (u for a wall along u, v for one along v). */
91
+ from: number;
92
+ to: number;
93
+ y0: number;
94
+ y1: number;
95
+ }
96
+ interface Structure {
97
+ parts: StructurePart[];
98
+ supports: Support[];
99
+ openings: Opening[];
100
+ /** Absolute height of the floor level of each storey. */
101
+ levels: number[];
102
+ elevation: number;
103
+ roof: Roof;
104
+ construction: Construction;
105
+ /** A reinforced concrete frame carries the building (apartments, commercial buildings, three storeys or more); the walls are infill. */
106
+ framed: boolean;
107
+ }
108
+ interface WallMaterials {
109
+ material: MaterialId;
110
+ interior?: MaterialId;
111
+ cladding?: MaterialId | null;
112
+ finish?: string;
113
+ /** Wall assembly of `game-destruction` (default by system, and by finish in masonry). */
114
+ assembly?: string;
115
+ thickness: number;
116
+ studs?: string;
117
+ /** Materials drawn per wall by a hash of its legacy key (the improvised shack). */
118
+ mixed?: MaterialId[];
119
+ [extra: string]: unknown;
120
+ }
121
+ interface Construction {
122
+ system: ConstructionSystem;
123
+ walls: WallMaterials;
124
+ floor: {
125
+ material: MaterialId;
126
+ finish: string;
127
+ };
128
+ roof: {
129
+ material: MaterialId;
130
+ covering: string;
131
+ shape: RoofShape;
132
+ pitch: number;
133
+ timber: MaterialId;
134
+ eave?: number;
135
+ axis?: 'u' | 'v';
136
+ bearingFloor?: number;
137
+ profile?: string;
138
+ gables?: string[];
139
+ fastening?: string;
140
+ };
141
+ frame: {
142
+ material: MaterialId;
143
+ pillars: MaterialId;
144
+ beams: MaterialId;
145
+ slabs: MaterialId;
146
+ timber: MaterialId;
147
+ rebar: MaterialId | null;
148
+ };
149
+ foundation: {
150
+ type: FoundationType;
151
+ material: MaterialId;
152
+ elevation: number;
153
+ depth?: number;
154
+ };
155
+ guard?: MaterialId;
156
+ stairs?: MaterialId;
157
+ }
158
+ type FoundationType = 'strip_footing' | 'building' | 'raft' | 'crawl_space' | 'piles' | 'basement' | 'ground';
159
+ interface Chimney {
160
+ kind: 'fireplace' | 'flue';
161
+ material: MaterialId;
162
+ aabb: Rect;
163
+ flue?: boolean;
164
+ top?: number;
165
+ height?: number;
166
+ }
167
+ interface Tent {
168
+ id: string;
169
+ kind: string;
170
+ height: number;
171
+ aabb: Rect;
172
+ }
173
+ /** What a construction needs besides walls and roof, from the template: a chimney, a well, an attic floor, tents. */
174
+ interface StructureExtras {
175
+ chimney?: Chimney;
176
+ well?: {
177
+ aabb: Rect;
178
+ height?: number;
179
+ };
180
+ attic?: boolean;
181
+ tents?: Tent[];
182
+ [extra: string]: unknown;
183
+ }
184
+ interface TankPlatform {
185
+ aabb: Rect;
186
+ baseY: number;
187
+ height: number;
188
+ thickness: number;
189
+ topY: number;
190
+ pillars: {
191
+ u: number;
192
+ v: number;
193
+ side: number;
194
+ }[];
195
+ ladder: boolean;
196
+ }
197
+ interface WaterTank {
198
+ id: 'water_tank';
199
+ kind: 'water_tank';
200
+ itemType: string;
201
+ place: 'slab' | 'attic' | 'raised_slab' | 'trestle' | string;
202
+ floor: number;
203
+ room: string;
204
+ u: number;
205
+ v: number;
206
+ y: number;
207
+ w: number;
208
+ d: number;
209
+ h: number;
210
+ capacity: number;
211
+ material?: MaterialId;
212
+ aabb: Rect;
213
+ platform?: TankPlatform;
214
+ /** Trestle tank (a stand of its own: rural water). */
215
+ stand?: {
216
+ pillars: {
217
+ u: number;
218
+ v: number;
219
+ side: number;
220
+ }[];
221
+ material: MaterialId;
222
+ height: number;
223
+ baseJoint?: JointKind;
224
+ joint?: JointKind;
225
+ tie?: JointKind;
226
+ braces?: boolean;
227
+ };
228
+ }
229
+ /** The fields of a generated plan the structure reads. */
230
+ interface StructureSource {
231
+ floors: {
232
+ y0: number;
233
+ ceiling: number;
234
+ }[];
235
+ rooms: {
236
+ id: string;
237
+ type: string;
238
+ floor: number;
239
+ parts: Rect[];
240
+ ceiling?: number | null;
241
+ }[];
242
+ walls: SourceWall[];
243
+ doors: SourceDoor[];
244
+ windows?: SourceWindow[];
245
+ items: {
246
+ id?: string;
247
+ type: string;
248
+ category?: string;
249
+ floor: number;
250
+ aabb?: Rect;
251
+ link?: {
252
+ from: number;
253
+ to: number;
254
+ } | null;
255
+ }[];
256
+ facade: {
257
+ roof?: string;
258
+ finish?: string;
259
+ [extra: string]: unknown;
260
+ };
261
+ style?: string;
262
+ template?: string;
263
+ lot?: unknown;
264
+ w: number;
265
+ d: number;
266
+ floorNumber?: number;
267
+ waterTank?: WaterTank | null;
268
+ construction?: Construction;
269
+ structureExtras?: StructureExtras;
270
+ [extra: string]: unknown;
271
+ }
272
+ interface SourceWall {
273
+ floor: number;
274
+ axis: 'u' | 'v';
275
+ u0: number;
276
+ v0: number;
277
+ u1: number;
278
+ v1: number;
279
+ thickness?: number;
280
+ sides: string[];
281
+ exterior: boolean;
282
+ type: string;
283
+ h?: number;
284
+ /** Gable wall: the plate does not sit on top of it. */
285
+ gable?: boolean;
286
+ structureHeight?: number;
287
+ }
288
+ interface SourceWindow {
289
+ id: string;
290
+ floor: number;
291
+ axis: 'u' | 'v';
292
+ /** Coordinate of the wall line across its axis. */
293
+ pos: number;
294
+ /** Centre along the wall. */
295
+ at: number;
296
+ width: number;
297
+ y0: number;
298
+ y1: number;
299
+ }
300
+ interface SourceDoor {
301
+ id: string;
302
+ floor: number;
303
+ a: string;
304
+ b: string;
305
+ exterior?: boolean;
306
+ model?: string;
307
+ type?: string;
308
+ u: number;
309
+ v: number;
310
+ width: number;
311
+ side?: string;
312
+ axis: 'u' | 'v';
313
+ steps?: number;
314
+ }
315
+ interface StructureOptions {
316
+ construction?: Construction;
317
+ extras?: StructureExtras;
318
+ tank?: WaterTank | null;
319
+ /** The porch roof is carried by its posts alone (the tie to the house wall carries nothing). Default: when the detail is not `coarse`. */
320
+ porchRoofOnPostsOnly?: boolean;
321
+ /** Gable roofs as rafters of each side and a ridge beam (a side falls with the wall it rests on) instead of whole trusses. Default: when the detail is not `coarse`. */
322
+ rafterRoof?: boolean;
323
+ wallDetail?: WallDetail;
324
+ }
325
+ /** What a construction builder and the tank get to see: the generated plan, its seed and the template. */
326
+ interface PlanContext {
327
+ result: StructureSource;
328
+ seed: number | string;
329
+ /** The template definition (`TemplateDef`) when known: it may carry `tank` and `tankLocation` hooks. */
330
+ template?: Record<string, unknown>;
331
+ options?: {
332
+ floors?: number;
333
+ [extra: string]: unknown;
334
+ };
335
+ }
336
+
337
+ /**
338
+ * The structure of a generated plan: every part that carries load (foundation, floors, walls, plates and bond beams, pillars, porch posts, trusses,
339
+ * roof, stairs, tank) with what each rests on. The plan itself is not modified.
340
+ */
341
+ declare function buildStructure(source: StructureSource, options?: StructureOptions): Structure;
342
+
343
+ interface DestructibleSpecOptions {
344
+ /** Fraction of its capacity a pillar or bearing wall uses at rest (default 0.65). */
345
+ safety?: number;
346
+ /** After losing any other pillar or bearing wall, the most of its capacity one of them uses (default 0.97: the house holds one loss and falls with two). */
347
+ redundancy?: number;
348
+ /** Fraction of capacity beams, slabs, roofs, stairs and partitions use at rest (default 0.45). */
349
+ safetyOthers?: number;
350
+ /** Bearing walls close but do not carry: a frame of pillars and beams carries the building. Default: for a framed building unless the detail is `coarse`. */
351
+ portico?: boolean;
352
+ /** How finely the walls are split (default `panels`; `coarse` is one part per wall as the Visor de casas 3D builds it). */
353
+ wallDetail?: WallDetail;
354
+ /** Name of the spec (default `house`). */
355
+ name?: string;
356
+ /** Leaves parts out (and what rests on them is dropped from the joints). */
357
+ filter?: (part: StructurePart) => boolean;
358
+ /** `false` keeps the capacity of the material instead of sizing it from the load. */
359
+ sized?: boolean;
360
+ /** Metres the anchored terrain slab reaches beyond the parts (default 6). */
361
+ terrainMargin?: number;
362
+ }
363
+ /**
364
+ * The structure as a `DestructibleSpec` in the space of the house (x = u, y = height, z = v; the ground is y = 0), one box per part and a terrain slab
365
+ * that anchors it. Capacities are sized from the loads at rest, as a designer would: a house stands whole, holds the loss of one pillar or bearing wall
366
+ * and falls with two.
367
+ */
368
+ declare function toDestructibleSpec(structure: Structure, options?: DestructibleSpecOptions): DestructibleSpec;
369
+
370
+ interface WallSpecimenOptions {
371
+ /** Wall assembly of `game-destruction` (`brick_wall_plastered`, `concrete_block_wall`, `reinforced_concrete`, `drywall`, `wood_frame_wall`, `log_wall`, `sheet_metal_shack`...). */
372
+ assembly: string;
373
+ /** Width and height in metres (the test area uses 2.4 x 2.1). */
374
+ w: number;
375
+ h: number;
376
+ opening?: 'door' | 'window' | null;
377
+ /** Default `panels`: piers, lintel with its 0.2 m bearing, sill, plaster and rebar; `units` also lays the bricks, blocks or concrete panels one by one. */
378
+ detail?: WallDetail;
379
+ }
380
+ /**
381
+ * A test wall as its assembly builds it, standing on a plinth: in `panels` the piers beside the opening, the lintel over it (reinforced concrete bearing 0.2 m on
382
+ * the piers; a header in timber walls), the sill under a window and the wall above; with the plaster coat and the rebar of the assembly. The mass is the
383
+ * assembly's for the whole w x h, whatever the detail.
384
+ */
385
+ declare function buildWallSpecimen(options: WallSpecimenOptions): DestructibleSpec;
386
+
387
+ type Rng = () => number;
388
+ interface TankPlanOptions {
389
+ /** Litres by template id or style id (default: budget 500, mid 1000, mansion 3000, any other 2000). */
390
+ capacities?: Record<string, number>;
391
+ /** Where the tank goes; default: on the slab of a flat roof, else on a raised platform (the attic one time in eight). */
392
+ location?: (source: StructureSource, rng: Rng) => WaterTank['place'];
393
+ /** A template with its own tank (a trestle for the rural water) answers here instead. */
394
+ custom?: (source: StructureSource, rng: Rng) => WaterTank | null;
395
+ }
396
+ /**
397
+ * The water tank of a house: on the roof slab, in the attic, or on a platform that rises out of the roof, never in the yard. Null for a plan without
398
+ * a lot (an apartment) or a commercial building, and when no room has space.
399
+ */
400
+ declare function planWaterTank(source: StructureSource, rng: Rng, options?: TankPlanOptions): WaterTank | null;
401
+
402
+ /** What a wall system is made of and how its parts are tied. Timber systems sit on joists, carry the roof on timber plates and have wooden porch posts. */
403
+ interface ConstructionSystemDef {
404
+ /** Wall assembly of `game-destruction` (`registerAssembly`) the detailed wall is built from. Empty: no walls (a tent). */
405
+ walls: string;
406
+ joints: Record<'wall' | 'slab' | 'beam' | 'column' | 'truss', JointKind>;
407
+ /** Thickness of the structural floor under each storey (m). */
408
+ slabThickness: number;
409
+ /** Height of the top plate or bond beam (m). */
410
+ plateThickness: number;
411
+ timber: boolean;
412
+ /** `rules`: bearing when external, under another wall or beside a porch; `bearing`: every wall (logs); `partition`: none (posts carry the roof). */
413
+ wallRole: 'rules' | 'bearing' | 'partition';
414
+ /** Solid fraction of a bearing wall in the structure weight (studs and air). */
415
+ wallFill: number;
416
+ studs?: {
417
+ spacing: number;
418
+ section: string;
419
+ };
420
+ }
421
+ declare const CONSTRUCTION_SYSTEMS: Map<string, ConstructionSystemDef>;
422
+ /** Adds or replaces a construction system (`id` is a `ConstructionSystem` or any name a construction refers to). */
423
+ declare function registerConstructionSystem(id: ConstructionSystem | string, def: ConstructionSystemDef): void;
424
+ interface RoofCoveringDef {
425
+ material: string;
426
+ /** How the covering is fixed to the trusses. */
427
+ joint: JointKind;
428
+ }
429
+ declare const ROOF_COVERINGS: Map<string, RoofCoveringDef>;
430
+ declare function registerRoofCovering(id: string, def: RoofCoveringDef): void;
431
+ interface ConstructionBuild {
432
+ construction: Construction;
433
+ extras?: StructureExtras;
434
+ }
435
+ type ConstructionBuilder = (context: PlanContext) => ConstructionBuild;
436
+ declare const CONSTRUCTIONS: Map<string, ConstructionBuilder>;
437
+ /** Registers how a template's building is made: `TemplateDef.construction` names it. A template without one gets the masonry default. */
438
+ declare function registerConstruction(id: string, builder: ConstructionBuilder): void;
439
+
440
+ /** Masonry house of the engine's own templates: brick with plaster, concrete frame, tiles by facade; a unit in a building gets a flat slab roof. */
441
+ declare function masonryConstruction(source: StructureSource): Construction;
442
+ interface WoodFrameOptions {
443
+ foundation?: 'basement' | 'crawl_space' | 'raft';
444
+ covering?: string;
445
+ finish?: string;
446
+ /** Cladding of the outer face (default soft wood). */
447
+ cladding?: string;
448
+ }
449
+ /** American wood frame house: 38x89 studs every 40 cm, plaster inside, wood outside, asphalt shingles. */
450
+ declare function woodFrameConstruction(options?: WoodFrameOptions): Construction;
451
+ interface ChaletOptions {
452
+ covering?: string;
453
+ finish?: string;
454
+ piles?: boolean;
455
+ }
456
+ /** Mountain chalet: A-frame roof at 52 degrees with gables front and back, 38x140 studs. */
457
+ declare function chaletConstruction(options?: ChaletOptions): Construction;
458
+ /** Log cabin: every wall is a stack of 26 cm logs, notched at the corners, on stone piles. */
459
+ declare function logCabinConstruction(options?: {
460
+ covering?: string;
461
+ }): Construction;
462
+ interface ShackOptions {
463
+ material?: 'wood' | 'zinc' | 'mixed';
464
+ floor?: 'soil' | 'concrete';
465
+ }
466
+ /** Shack of scrap boards and zinc sheets: timber posts carry the roof, the walls only close. */
467
+ declare function shackConstruction(options?: ShackOptions): Construction;
468
+ /** Camping: canvas over aluminium poles on the ground; there are no walls. */
469
+ declare function campConstruction(): Construction;
470
+ /** The construction a system gets on any plan when the options force it (`options.construction`). */
471
+ declare function constructionOfSystem(system: string, source: StructureSource): Construction | undefined;
472
+
473
+ declare const structureLayer: ViewerLayer;
474
+
475
+ /** kg/m3 the plan structure weighs its parts with (the table of the Visor de casas 3D; a material outside it weighs like soft wood). */
476
+ declare const DENSITY: Readonly<Record<string, number>>;
477
+
478
+ declare const version = "0.1.0";
479
+
480
+ export { CONSTRUCTIONS, CONSTRUCTION_SYSTEMS, type ChaletOptions, type Chimney, type Construction, type ConstructionBuild, type ConstructionBuilder, type ConstructionSystem, type ConstructionSystemDef, DENSITY, type DestructibleSpecOptions, type FoundationType, GROUND, type Opening, type PartRole, type PlanContext, ROOF_COVERINGS, type Rect, type Roof, type RoofCoveringDef, type RoofPane, type RoofShape, type ShackOptions, type SourceDoor, type SourceWall, type SourceWindow, type Structure, type StructureExtras, type StructureOptions, type StructurePackOptions, type StructurePart, type StructureSource, type Support, type TankPlanOptions, type TankPlatform, type Tent, type WallDetail, type WallMaterials, type WallSpecimenOptions, type WaterTank, type WoodFrameOptions, buildStructure, buildWallSpecimen, campConstruction, chaletConstruction, constructionOfSystem, logCabinConstruction, masonryConstruction, planWaterTank, register, registerConstruction, registerConstructionSystem, registerRoofCovering, shackConstruction, structureLayer, toDestructibleSpec, version, woodFrameConstruction };