Skip to main content

World

Struct World 

Source
pub struct World {
    pub meta: WorldMeta,
    pub owners: IndexMap<Guid, Owner>,
    pub bricks: Vec<Brick>,
    pub grids: Vec<(Entity, Vec<Brick>)>,
    pub wires: Vec<WireConnection>,
    pub entities: Vec<Entity>,
    pub microchip_links: Vec<(usize, usize)>,
    pub prefabs: IndexMap<String, Vec<u8>>,
    pub global_data: BrdbSchemaGlobalData,
    pub component_schema: BrdbSchema,
    pub entity_schema: BrdbSchema,
}

Fields§

§meta: WorldMeta§owners: IndexMap<Guid, Owner>§bricks: Vec<Brick>

Bricks on the main grid

§grids: Vec<(Entity, Vec<Brick>)>

Non-main grids require an entity to be created for them

§wires: Vec<WireConnection>§entities: Vec<Entity>§microchip_links: Vec<(usize, usize)>

Per-microchip linkage pairs: (brick_id, entity_id) where the brick is the outer microchip shell and the entity is the inner grid.

§prefabs: IndexMap<String, Vec<u8>>

Embedded prefab archives (the root Prefabs/ folder), keyed by root-relative path (Prefabs/Uploads/<BLAKE3>.brz) with raw .brz bytes as values. Populate via World::add_prefab; the returned path is what a Prefab component property references.

The game requires the Prefabs/Uploads/<BLAKE3>.brz naming — it crashes loading a bundle whose embedded prefab has any other filename. Use World::add_prefab rather than inserting a custom key here.

§global_data: BrdbSchemaGlobalData§component_schema: BrdbSchema§entity_schema: BrdbSchema

Implementations§

Source§

impl World

Source

pub fn new() -> Self

Examples found in repository?
examples/write_fixtures.rs (line 21)
19fn brick_world() -> World {
20    // Mirror of examples/write_brz.rs — the historical example_brick world.
21    let mut world = World::new();
22    world.meta.bundle.description = "Example World".to_string();
23    world.bricks.push(Brick {
24        position: (0, 0, 6).into(),
25        color: (255, 0, 0).into(),
26        ..Default::default()
27    });
28    world
29}
30
31fn features_world() -> World {
32    // Single chunk (all coords in [0, 2048)): registries, owners, procedural
33    // size run-length grouping (new/extend/reuse), a basic asset, collision
34    // and visibility variants, orientations, material intensity.
35    let mut world = World::new();
36    world.meta.bundle.description = "Feature fixture".to_string();
37
38    let alice = Guid::from_uuid(uuid::Uuid::parse_str(ALICE_UUID).unwrap());
39    let bob = Guid::from_uuid(uuid::Uuid::parse_str(BOB_UUID).unwrap());
40    world.owners.insert(alice, Owner {
41        user_id: alice,
42        user_name: "alice".to_string(),
43        display_name: "Alice".to_string(),
44    });
45    world.owners.insert(bob, Owner {
46        user_id: bob,
47        user_name: "bob".to_string(),
48        display_name: "Bob".to_string(),
49    });
50
51    let tile = |size: (u16, u16, u16)| BrickType::Procedural {
52        asset: assets::bricks::PB_DEFAULT_TILE, // "PB_DefaultTile"
53        size: BrickSize { x: size.0, y: size.1, z: size.2 },
54    };
55
56    // 1: default brick (PB_DefaultBrick 5x5x6, plastic, intensity 5) — new size slot
57    world.bricks.push(Brick {
58        position: (0, 0, 6).into(),
59        color: (255, 0, 0).into(),
60        owner_index: Some(1),
61        ..Default::default()
62    });
63    // 2: tile 10x10x2, metallic, intensity 7, XPositive/Deg90 — new counter entry
64    world.bricks.push(Brick {
65        asset: tile((10, 10, 2)),
66        position: (20, 0, 2).into(),
67        color: (0, 255, 0).into(),
68        owner_index: Some(1),
69        material: assets::materials::METALLIC, // "BMC_Metallic"
70        material_intensity: 7,
71        direction: Direction::XPositive,
72        rotation: Rotation::Deg90,
73        ..Default::default()
74    });
75    // 3: same tile size — size_index_map reuse
76    world.bricks.push(Brick {
77        asset: tile((10, 10, 2)),
78        position: (40, 0, 2).into(),
79        color: (0, 0, 255).into(),
80        owner_index: Some(2),
81        ..Default::default()
82    });
83    // 4: tile 20x20x2 — extends the tail counter (same asset, new size)
84    world.bricks.push(Brick {
85        asset: tile((20, 20, 2)),
86        position: (80, 0, 2).into(),
87        color: (255, 255, 0).into(),
88        owner_index: Some(2),
89        ..Default::default()
90    });
91    // 5: default brick again — reuses slot from brick 1 (map hit after other asset)
92    world.bricks.push(Brick {
93        position: (100, 0, 6).into(),
94        color: (255, 255, 255).into(),
95        owner_index: Some(1),
96        ..Default::default()
97    });
98    // 6: BASIC asset, PUBLIC owner, glow, partial collision, YNegative/Deg180
99    world.bricks.push(Brick {
100        asset: assets::bricks::B_2X2_OVERHANG, // "B_2x2_Overhang"
101        position: (200, 0, 10).into(),
102        color: (128, 64, 32).into(),
103        material: assets::materials::GLOW, // "BMC_Glow"
104        material_intensity: 3,
105        direction: Direction::YNegative,
106        rotation: Rotation::Deg180,
107        collision: Collision { player: false, ..Default::default() },
108        ..Default::default()
109    });
110    // 7: invisible, all-collision-off, tiny proc brick
111    world.bricks.push(Brick {
112        asset: BrickType::Procedural {
113            asset: assets::bricks::PB_DEFAULT_BRICK,
114            size: BrickSize { x: 2, y: 2, z: 2 },
115        },
116        position: (300, 0, 2).into(),
117        color: (10, 20, 30).into(),
118        owner_index: Some(1),
119        visible: false,
120        collision: Collision {
121            player: false,
122            weapon: false,
123            interact: false,
124            physics: false,
125            ..Default::default()
126        },
127        ..Default::default()
128    });
129    world
130}
131
132fn chunks_world() -> World {
133    // Multi-chunk: euclidean chunking with negative coords, plus chunks
134    // 0_0_0 and 1_0_0 carry byte-identical SoA payloads → blob dedup.
135    // NOTE: multi-chunk Rust output has nondeterministic FILE ORDER
136    // (HashMap iteration), so this fixture is hashes-gate only — never
137    // byte-compare its container.
138    let mut world = World::new();
139    world.meta.bundle.description = "Chunk fixture".to_string();
140    for (pos, color) in [
141        ((0, 0, 0), (1, 2, 3)),
142        ((-1, -1, -1), (4, 5, 6)),
143        ((2048, 0, 0), (1, 2, 3)),      // same rel pos + color as brick 1
144        ((-2048, 4096, 10), (10, 11, 12)),
145        ((500, 500, 500), (42, 42, 42)),
146        ((2548, 500, 500), (42, 42, 42)), // same rel pos + color as brick 5
147    ] {
148        world.bricks.push(Brick {
149            position: pos.into(),
150            color: color.into(),
151            ..Default::default()
152        });
153    }
154    world
155}
156
157fn wires_world() -> World {
158    // Mirror of examples/write_wire.rs (single grid, single chunk — fully
159    // deterministic), extended to 3 bricks/2 wires: a boolean NOT gate feeds
160    // one input of an AND gate, whose output feeds a rerouter.
161    let mut world = World::new();
162    world.register_all_components();
163    world.meta.bundle.description = "Wire fixture".to_string();
164
165    let (a, a_id) = Brick {
166        position: (30, 0, 1).into(),
167        color: (255, 0, 0).into(),
168        asset: assets::bricks::B_REROUTE,
169        ..Default::default()
170    }
171    .with_component(assets::components::Rerouter)
172    .with_id_split();
173    let (b, b_id) = Brick {
174        position: (15, 0, 1).into(),
175        color: (0, 255, 0).into(),
176        asset: assets::components::LogicGate::BoolAnd.brick(),
177        ..Default::default()
178    }
179    .with_component(assets::components::LogicGate::BoolAnd.component())
180    .with_id_split();
181    let (c, c_id) = Brick {
182        position: (0, 0, 1).into(),
183        color: (0, 0, 255).into(),
184        asset: assets::components::LogicGate::BoolNot.brick(),
185        ..Default::default()
186    }
187    .with_component(assets::components::LogicGate::BoolNot.component())
188    .with_id_split();
189
190    world.add_bricks([a, b, c]);
191    // Wire 1: NOT.output -> AND.inputA
192    world.add_wire_connection(
193        assets::components::LogicGate::BoolNot.output_of(c_id),
194        assets::components::LogicGate::BoolAnd.input_a_of(b_id),
195    );
196    // Wire 2: AND.output -> Rerouter.input
197    world.add_wire_connection(
198        assets::components::LogicGate::BoolAnd.output_of(b_id),
199        assets::components::Rerouter::input_of(a_id),
200    );
201
202    world
203}
204
205fn components_world() -> World {
206    // Single grid, single chunk (all positions < 2048) — fully deterministic.
207    // register_all_components() embeds the full component catalog so every
208    // type below (light/interact/wiregraph-pseudo/expr) resolves; each
209    // component below carries non-default property values, and #4/#5 exercise
210    // a WireGraphVariant-typed property (BufferTicks' Input/Output, and the
211    // Constant gate's Value).
212    let mut world = World::new();
213    world.register_all_components();
214    world.meta.bundle.description = "Component fixture".to_string();
215
216    // 1: Point light — non-default brightness/radius/color, decoupled from
217    // brick color (bUseBrickColor: false).
218    world.bricks.push(
219        Brick {
220            position: (0, 0, 6).into(),
221            color: (255, 255, 255).into(),
222            ..Default::default()
223        }
224        .with_component(assets::LiteralComponent::new("Component_PointLight").with_data([
225            ("bMatchBrickShape", Box::new(false) as Box<dyn AsBrdbValue>),
226            ("bEnabled", Box::new(true)),
227            ("Brightness", Box::new(500.0f32)),
228            ("Radius", Box::new(800.0f32)),
229            (
230                "Color",
231                Box::new(SavedBrickColor { r: 10, g: 20, b: 30, a: 255 }),
232            ),
233            ("bUseBrickColor", Box::new(false)),
234            ("bCastShadows", Box::new(true)),
235        ])),
236    );
237
238    // 2: Spot light — narrow cone, non-default brightness/color.
239    world.bricks.push(
240        Brick {
241            position: (20, 0, 6).into(),
242            color: (255, 255, 0).into(),
243            ..Default::default()
244        }
245        .with_component(assets::LiteralComponent::new("Component_SpotLight").with_data([
246            ("InnerConeAngle", Box::new(15.0f32) as Box<dyn AsBrdbValue>),
247            ("OuterConeAngle", Box::new(45.0f32)),
248            ("bEnabled", Box::new(true)),
249            ("Brightness", Box::new(300.0f32)),
250            ("Radius", Box::new(600.0f32)),
251            (
252                "Color",
253                Box::new(SavedBrickColor { r: 255, g: 0, b: 0, a: 255 }),
254            ),
255            ("bUseBrickColor", Box::new(false)),
256            ("bCastShadows", Box::new(true)),
257        ])),
258    );
259
260    // 3: Interact — custom prompt text, hidden interaction.
261    world.bricks.push(
262        Brick {
263            position: (40, 0, 6).into(),
264            color: (0, 255, 255).into(),
265            ..Default::default()
266        }
267        .with_component(assets::LiteralComponent::new("Component_Interact").with_data([
268            (
269                "Message",
270                Box::new("You interacted!".to_string()) as Box<dyn AsBrdbValue>,
271            ),
272            ("ConsoleTag", Box::new("fixture_interact".to_string())),
273            ("bAllowNearbyInteraction", Box::new(false)),
274            ("bHiddenInteraction", Box::new(true)),
275            ("PromptCustomLabel", Box::new("Open Door".to_string())),
276        ])),
277    );
278
279    // 4: Buffer (ticks) — WireGraphPseudo component whose Input/Output are
280    // WireGraphVariant; non-default counters plus a Number/Bool variant pair.
281    world.bricks.push(
282        Brick {
283            position: (60, 0, 1).into(),
284            color: (128, 0, 128).into(),
285            asset: assets::components::BufferTicks::default().brick(),
286            ..Default::default()
287        }
288        .with_component(assets::components::BufferTicks {
289            current_ticks: 3,
290            ticks_to_wait: 10,
291            input: WireVariant::Number(2.5),
292            output: WireVariant::Bool(true),
293        }),
294    );
295
296    // 5: Blend gate — WireGraph_Expr_MathBlend's InputA/InputB are each a
297    // WireGraphPrimMathVariant (here an f64 and an i64 tag, showing the
298    // variant is polymorphic per-port); Blend itself is a plain f64.
299    world.bricks.push(
300        Brick {
301            position: (80, 0, 1).into(),
302            color: (0, 128, 0).into(),
303            asset: assets::components::LogicGate::Blend.brick(),
304            ..Default::default()
305        }
306        .with_component(assets::components::LogicGate::Blend.component_with_overrides(
307            HashMap::from([
308                (
309                    "InputA".into(),
310                    Box::new(WireVariant::Number(10.0)) as Box<dyn AsBrdbValue>,
311                ),
312                ("InputB".into(), Box::new(WireVariant::Int(7))),
313                ("Blend".into(), Box::new(0.75f64)),
314            ]),
315        )),
316    );
317
318    world
319}
320
321fn entities_world() -> World {
322    // Mirror of examples/write_entity.rs's floating sub-grid — the first
323    // grid added after the always-present main grid 1 gets persistent index
324    // 2, so it lands at Grids/2 — plus a couple of main-grid (Grids/1)
325    // bricks. Both grids are single-chunk; note the *outer* Grids/1 vs
326    // Grids/2 folder order comes from a HashMap<usize, UnsavedGrid> in the
327    // writer and is NOT guaranteed stable run-to-run (see stability notes).
328    //
329    // register_all_components() is required here (matching
330    // test_write_entity_save, NOT the plain write_entity.rs example): without
331    // it, Entity_DynamicBrickGrid's class name is never registered and the
332    // write fails with `UnknownType("Entity_DynamicBrickGrid")` — confirmed
333    // by running the crate's own unmodified write_entity example.
334    let mut world = World::new();
335    world.register_all_components();
336    world.meta.bundle.description = "Entity fixture".to_string();
337
338    world.bricks.push(Brick {
339        position: (0, 0, 6).into(),
340        color: (200, 50, 50).into(),
341        ..Default::default()
342    });
343    world.bricks.push(Brick {
344        position: (20, 0, 6).into(),
345        color: (50, 200, 50).into(),
346        ..Default::default()
347    });
348
349    world.add_brick_grid(
350        Entity {
351            frozen: true,
352            location: (0.0, 0.0, 40.0).into(),
353            ..Default::default()
354        },
355        [Brick {
356            position: (0, 0, 3).into(),
357            color: (0, 255, 0).into(),
358            ..Default::default()
359        }],
360    );
361
362    world
363}
364
365fn spawner_world() -> World {
366    // Prefab-embedding fixture: an outer prefab whose spawner gate references
367    // an inner single-brick prefab embedded at Prefabs/Uploads/<BLAKE3>.brz.
368    // Single grid, single chunk, one insertion-ordered prefab map entry —
369    // fully deterministic. The inner archive is written raw (no zstd) so the
370    // embedded bytes are cross-language reproducible.
371    let mut inner = World::new();
372    inner.meta.bundle.description = "Inner prefab".to_string();
373    inner.bricks.push(Brick {
374        position: (0, 0, 6).into(),
375        color: (255, 0, 0).into(),
376        ..Default::default()
377    });
378    inner.make_prefab();
379    let inner_bytes = {
380        let pending = inner.to_unsaved().unwrap().to_pending().unwrap();
381        let mut buf = Vec::new();
382        pending
383            .to_brz_data(None)
384            .unwrap()
385            .write(&mut buf, None)
386            .unwrap();
387        buf
388    };
389
390    let mut world = World::new();
391    world.register_all_components();
392    world.meta.bundle.description = "Spawner fixture".to_string();
393    let prefab_path = world.add_prefab(inner_bytes);
394    world.bricks.push(
395        Brick {
396            asset: brdb::BrickType::str("B_1x1_Gate_Exec_PrefabSpawner"),
397            position: (0, 0, 1).into(),
398            ..Default::default()
399        }
400        .with_component(
401            assets::LiteralComponent::new("BrickComponentType_WireGraph_Exec_PrefabSpawner")
402                .with_data([(
403                    "Prefab",
404                    Box::new(prefab_path) as Box<dyn AsBrdbValue>,
405                )]),
406        ),
407    );
408    world.make_prefab();
409    world
410}
More examples
Hide additional examples
examples/write_brick.rs (line 8)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    let path = PathBuf::from("./example_brick.brdb");
7
8    let mut world = World::new();
9    world.meta.bundle.description = "Example World".to_string();
10    world.bricks.push(Brick {
11        position: (0, 0, 6).into(),
12        color: (255, 0, 0).into(),
13        ..Default::default()
14    });
15
16    world.write_brdb(&path)?;
17
18    let db = Brdb::new(&path)?.into_reader();
19
20    println!("file structure: {}", db.get_fs()?.render());
21
22    let soa = db.brick_chunk_soa(1, (0, 0, 0).into())?;
23    let color = soa.colors_and_alphas[0];
24    assert_eq!(color.r, 255);
25    assert_eq!(color.g, 0);
26    assert_eq!(color.b, 0);
27    assert_eq!(color.a, 5);
28
29    Ok(())
30}
examples/write_entity.rs (line 10)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    let path = PathBuf::from("./example_entity.brdb");
7
8    // Ensures the memory db can be created without errors
9    let db = Brdb::new(&path)?.into_reader();
10    let mut world = World::new();
11    world.meta.bundle.description = "Example World".to_string();
12    world.add_brick_grid(
13        Entity {
14            frozen: true,
15            location: (0.0, 0.0, 40.0).into(),
16            ..Default::default()
17        },
18        [Brick {
19            position: (0, 0, 3).into(),
20            color: (0, 255, 0).into(),
21            ..Default::default()
22        }],
23    );
24
25    db.save("example world", &world)?;
26
27    println!("{}", db.get_fs()?.render());
28
29    Ok(())
30}
examples/write_brz.rs (line 8)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    let path = PathBuf::from("./example_brick.brz");
7
8    let mut world = World::new();
9    world.meta.bundle.description = "Example World".to_string();
10    world.bricks.push(Brick {
11        position: (0, 0, 6).into(),
12        color: (255, 0, 0).into(),
13        ..Default::default()
14    });
15
16    if path.exists() {
17        std::fs::remove_file(&path)?;
18    }
19    world.write_brz(&path)?;
20
21    let db = Brz::new(&path)?.into_reader();
22
23    println!("{}", db.get_fs()?.render());
24
25    let soa = db.brick_chunk_soa(1, (0, 0, 0).into())?;
26    let color = soa.colors_and_alphas[0];
27    assert_eq!(color.r, 255);
28    assert_eq!(color.g, 0);
29    assert_eq!(color.b, 0);
30    assert_eq!(color.a, 5);
31
32    Ok(())
33}
examples/write_prefab.rs (line 8)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    let path = PathBuf::from("./example_prefab.brz");
7
8    let mut world = World::new();
9    // A single 1x1 plate-ish brick (half-extent 5,5,2) at the origin so the
10    // bounds match the hand-captured reference prefab.
11    world.bricks.push(Brick {
12        asset: BrickType::Procedural {
13            asset: assets::bricks::PB_DEFAULT_BRICK.into(),
14            size: BrickSize { x: 5, y: 5, z: 2 },
15        },
16        position: (0, 0, 0).into(),
17        ..Default::default()
18    });
19
20    world.make_prefab();
21    println!(
22        "Prefab.json:\n{}",
23        serde_json::to_string_pretty(world.meta.prefab.as_ref().unwrap())?
24    );
25    println!(
26        "Bundle.json:\n{}",
27        serde_json::to_string_pretty(&world.meta.bundle)?
28    );
29
30    if path.exists() {
31        std::fs::remove_file(&path)?;
32    }
33    world.write_brz(&path)?;
34    println!("wrote {}", path.display());
35    Ok(())
36}
examples/write_wire.rs (line 10)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    let path = PathBuf::from("./example_wire.brdb");
7
8    // Ensures the memory db can be created without errors
9    let db = Brdb::new(&path)?.into_reader();
10    let mut world = World::new();
11    // Register the built-in component type/struct mappings so the gate and
12    // rerouter component types resolve when writing.
13    world.register_all_components();
14    world.meta.bundle.description = "Example World".to_string();
15
16    let (a, a_id) = Brick {
17        position: (0, 0, 1).into(),
18        color: (255, 0, 0).into(),
19        asset: assets::bricks::B_REROUTE,
20        ..Default::default()
21    }
22    .with_component(assets::components::Rerouter)
23    .with_id_split();
24    let (b, b_id) = Brick {
25        position: (15, 0, 1).into(),
26        color: (255, 0, 0).into(),
27        asset: assets::components::LogicGate::BoolNot.brick(),
28        ..Default::default()
29    }
30    .with_component(assets::components::LogicGate::BoolNot.component())
31    .with_id_split();
32
33    world.add_bricks([a, b]);
34    world.add_wire_connection(
35        assets::components::LogicGate::BoolNot.output_of(b_id),
36        assets::components::Rerouter::input_of(a_id),
37    );
38
39    db.save("example world", &world)?;
40
41    println!("{}", db.get_fs()?.render());
42
43    Ok(())
44}
Source

pub fn write_brdb(&self, path: impl AsRef<Path>) -> Result<(), BrError>

Examples found in repository?
examples/write_brick.rs (line 16)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    let path = PathBuf::from("./example_brick.brdb");
7
8    let mut world = World::new();
9    world.meta.bundle.description = "Example World".to_string();
10    world.bricks.push(Brick {
11        position: (0, 0, 6).into(),
12        color: (255, 0, 0).into(),
13        ..Default::default()
14    });
15
16    world.write_brdb(&path)?;
17
18    let db = Brdb::new(&path)?.into_reader();
19
20    println!("file structure: {}", db.get_fs()?.render());
21
22    let soa = db.brick_chunk_soa(1, (0, 0, 0).into())?;
23    let color = soa.colors_and_alphas[0];
24    assert_eq!(color.r, 255);
25    assert_eq!(color.g, 0);
26    assert_eq!(color.b, 0);
27    assert_eq!(color.a, 5);
28
29    Ok(())
30}
Source

pub fn write_brz(&self, path: impl AsRef<Path>) -> Result<(), BrError>

Examples found in repository?
examples/write_brz.rs (line 19)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    let path = PathBuf::from("./example_brick.brz");
7
8    let mut world = World::new();
9    world.meta.bundle.description = "Example World".to_string();
10    world.bricks.push(Brick {
11        position: (0, 0, 6).into(),
12        color: (255, 0, 0).into(),
13        ..Default::default()
14    });
15
16    if path.exists() {
17        std::fs::remove_file(&path)?;
18    }
19    world.write_brz(&path)?;
20
21    let db = Brz::new(&path)?.into_reader();
22
23    println!("{}", db.get_fs()?.render());
24
25    let soa = db.brick_chunk_soa(1, (0, 0, 0).into())?;
26    let color = soa.colors_and_alphas[0];
27    assert_eq!(color.r, 255);
28    assert_eq!(color.g, 0);
29    assert_eq!(color.b, 0);
30    assert_eq!(color.a, 5);
31
32    Ok(())
33}
More examples
Hide additional examples
examples/write_prefab.rs (line 33)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    let path = PathBuf::from("./example_prefab.brz");
7
8    let mut world = World::new();
9    // A single 1x1 plate-ish brick (half-extent 5,5,2) at the origin so the
10    // bounds match the hand-captured reference prefab.
11    world.bricks.push(Brick {
12        asset: BrickType::Procedural {
13            asset: assets::bricks::PB_DEFAULT_BRICK.into(),
14            size: BrickSize { x: 5, y: 5, z: 2 },
15        },
16        position: (0, 0, 0).into(),
17        ..Default::default()
18    });
19
20    world.make_prefab();
21    println!(
22        "Prefab.json:\n{}",
23        serde_json::to_string_pretty(world.meta.prefab.as_ref().unwrap())?
24    );
25    println!(
26        "Bundle.json:\n{}",
27        serde_json::to_string_pretty(&world.meta.bundle)?
28    );
29
30    if path.exists() {
31        std::fs::remove_file(&path)?;
32    }
33    world.write_brz(&path)?;
34    println!("wrote {}", path.display());
35    Ok(())
36}
examples/write_prefab_spawner.rs (line 80)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11    // 1. Build the prefab that gets spawned: a single red brick.
12    let mut prefab = World::new();
13    prefab.meta.bundle.name = "Spawned Brick".to_string();
14    prefab.bricks.push(Brick {
15        position: (0, 0, 6).into(),
16        color: (255, 0, 0).into(),
17        ..Default::default()
18    });
19    prefab.make_prefab();
20    let prefab_bytes = prefab.to_brz_vec()?;
21
22    // 2. Build the outer world holding the button + spawner.
23    let mut world = World::new();
24    // Registers the built-in component/port tables so the Button and
25    // PrefabSpawner component types and their wire ports resolve.
26    world.register_all_components();
27    world.meta.bundle.description = "Button-triggered prefab spawner".to_string();
28
29    // Embed the prefab; the returned path is what the spawner references.
30    let prefab_path = world.add_prefab(prefab_bytes);
31
32    // A pressable button (Component_Button on a 1x1 flat round brick). The
33    // crate exposes brick assets as constants; components it doesn't model as
34    // typed gates (like the button and spawner) are built from string names
35    // via LiteralComponent.
36    let (button, button_id) = Brick {
37        position: (0, 0, 2).into(),
38        color: (0, 255, 0).into(),
39        asset: assets::bricks::B_1X1F_ROUND,
40        ..Default::default()
41    }
42    .with_component(assets::LiteralComponent::new("Component_Button").with_data([(
43        "PromptCustomLabel",
44        Box::new("Spawn Brick".to_string()) as Box<dyn AsBrdbValue>,
45    )]))
46    .with_id_split();
47
48    // The prefab-spawner gate, pointed at the embedded prefab.
49    let (spawner, spawner_id) = Brick {
50        position: (15, 0, 1).into(),
51        color: (0, 0, 255).into(),
52        asset: assets::bricks::B_1X1_GATE_EXEC_PREFAB_SPAWNER,
53        ..Default::default()
54    }
55    .with_component(
56        assets::LiteralComponent::new("BrickComponentType_WireGraph_Exec_PrefabSpawner").with_data(
57            [(
58                "Prefab",
59                Box::new(prefab_path.clone()) as Box<dyn AsBrdbValue>,
60            )],
61        ),
62    )
63    .with_id_split();
64
65    world.add_bricks([button, spawner]);
66
67    // Wire the button's held signal into the spawner's Exec input, so a
68    // press fires the spawn.
69    world.add_wire_connection(
70        WirePort::new(button_id, "Component_Button", "bHeld"),
71        WirePort::new(
72            spawner_id,
73            "BrickComponentType_WireGraph_Exec_PrefabSpawner",
74            "Exec",
75        ),
76    );
77
78    // 3. Write it out.
79    let path = PathBuf::from("./example_prefab_spawner.brz");
80    world.write_brz(&path)?;
81    println!("wrote {}", path.display());
82
83    // Read it back to confirm the embedded prefab and wire survived.
84    let reader = Brz::open(&path)?.into_reader();
85    println!("embedded prefab: {}", prefab_path);
86    println!("prefab paths in archive: {:?}", reader.prefab_paths()?);
87    println!("{}", reader.get_fs()?.render());
88
89    Ok(())
90}
Source

pub fn to_brz_vec(&self) -> Result<Vec<u8>, BrError>

Examples found in repository?
examples/write_prefab_spawner.rs (line 20)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11    // 1. Build the prefab that gets spawned: a single red brick.
12    let mut prefab = World::new();
13    prefab.meta.bundle.name = "Spawned Brick".to_string();
14    prefab.bricks.push(Brick {
15        position: (0, 0, 6).into(),
16        color: (255, 0, 0).into(),
17        ..Default::default()
18    });
19    prefab.make_prefab();
20    let prefab_bytes = prefab.to_brz_vec()?;
21
22    // 2. Build the outer world holding the button + spawner.
23    let mut world = World::new();
24    // Registers the built-in component/port tables so the Button and
25    // PrefabSpawner component types and their wire ports resolve.
26    world.register_all_components();
27    world.meta.bundle.description = "Button-triggered prefab spawner".to_string();
28
29    // Embed the prefab; the returned path is what the spawner references.
30    let prefab_path = world.add_prefab(prefab_bytes);
31
32    // A pressable button (Component_Button on a 1x1 flat round brick). The
33    // crate exposes brick assets as constants; components it doesn't model as
34    // typed gates (like the button and spawner) are built from string names
35    // via LiteralComponent.
36    let (button, button_id) = Brick {
37        position: (0, 0, 2).into(),
38        color: (0, 255, 0).into(),
39        asset: assets::bricks::B_1X1F_ROUND,
40        ..Default::default()
41    }
42    .with_component(assets::LiteralComponent::new("Component_Button").with_data([(
43        "PromptCustomLabel",
44        Box::new("Spawn Brick".to_string()) as Box<dyn AsBrdbValue>,
45    )]))
46    .with_id_split();
47
48    // The prefab-spawner gate, pointed at the embedded prefab.
49    let (spawner, spawner_id) = Brick {
50        position: (15, 0, 1).into(),
51        color: (0, 0, 255).into(),
52        asset: assets::bricks::B_1X1_GATE_EXEC_PREFAB_SPAWNER,
53        ..Default::default()
54    }
55    .with_component(
56        assets::LiteralComponent::new("BrickComponentType_WireGraph_Exec_PrefabSpawner").with_data(
57            [(
58                "Prefab",
59                Box::new(prefab_path.clone()) as Box<dyn AsBrdbValue>,
60            )],
61        ),
62    )
63    .with_id_split();
64
65    world.add_bricks([button, spawner]);
66
67    // Wire the button's held signal into the spawner's Exec input, so a
68    // press fires the spawn.
69    world.add_wire_connection(
70        WirePort::new(button_id, "Component_Button", "bHeld"),
71        WirePort::new(
72            spawner_id,
73            "BrickComponentType_WireGraph_Exec_PrefabSpawner",
74            "Exec",
75        ),
76    );
77
78    // 3. Write it out.
79    let path = PathBuf::from("./example_prefab_spawner.brz");
80    world.write_brz(&path)?;
81    println!("wrote {}", path.display());
82
83    // Read it back to confirm the embedded prefab and wire survived.
84    let reader = Brz::open(&path)?.into_reader();
85    println!("embedded prefab: {}", prefab_path);
86    println!("prefab paths in archive: {:?}", reader.prefab_paths()?);
87    println!("{}", reader.get_fs()?.render());
88
89    Ok(())
90}
Source

pub fn register_all_components(&mut self)

Load the full component schema and register all known type→struct mappings and wire port names from the built-in component database.

Examples found in repository?
examples/write_wire.rs (line 13)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    let path = PathBuf::from("./example_wire.brdb");
7
8    // Ensures the memory db can be created without errors
9    let db = Brdb::new(&path)?.into_reader();
10    let mut world = World::new();
11    // Register the built-in component type/struct mappings so the gate and
12    // rerouter component types resolve when writing.
13    world.register_all_components();
14    world.meta.bundle.description = "Example World".to_string();
15
16    let (a, a_id) = Brick {
17        position: (0, 0, 1).into(),
18        color: (255, 0, 0).into(),
19        asset: assets::bricks::B_REROUTE,
20        ..Default::default()
21    }
22    .with_component(assets::components::Rerouter)
23    .with_id_split();
24    let (b, b_id) = Brick {
25        position: (15, 0, 1).into(),
26        color: (255, 0, 0).into(),
27        asset: assets::components::LogicGate::BoolNot.brick(),
28        ..Default::default()
29    }
30    .with_component(assets::components::LogicGate::BoolNot.component())
31    .with_id_split();
32
33    world.add_bricks([a, b]);
34    world.add_wire_connection(
35        assets::components::LogicGate::BoolNot.output_of(b_id),
36        assets::components::Rerouter::input_of(a_id),
37    );
38
39    db.save("example world", &world)?;
40
41    println!("{}", db.get_fs()?.render());
42
43    Ok(())
44}
More examples
Hide additional examples
examples/write_fixtures.rs (line 162)
157fn wires_world() -> World {
158    // Mirror of examples/write_wire.rs (single grid, single chunk — fully
159    // deterministic), extended to 3 bricks/2 wires: a boolean NOT gate feeds
160    // one input of an AND gate, whose output feeds a rerouter.
161    let mut world = World::new();
162    world.register_all_components();
163    world.meta.bundle.description = "Wire fixture".to_string();
164
165    let (a, a_id) = Brick {
166        position: (30, 0, 1).into(),
167        color: (255, 0, 0).into(),
168        asset: assets::bricks::B_REROUTE,
169        ..Default::default()
170    }
171    .with_component(assets::components::Rerouter)
172    .with_id_split();
173    let (b, b_id) = Brick {
174        position: (15, 0, 1).into(),
175        color: (0, 255, 0).into(),
176        asset: assets::components::LogicGate::BoolAnd.brick(),
177        ..Default::default()
178    }
179    .with_component(assets::components::LogicGate::BoolAnd.component())
180    .with_id_split();
181    let (c, c_id) = Brick {
182        position: (0, 0, 1).into(),
183        color: (0, 0, 255).into(),
184        asset: assets::components::LogicGate::BoolNot.brick(),
185        ..Default::default()
186    }
187    .with_component(assets::components::LogicGate::BoolNot.component())
188    .with_id_split();
189
190    world.add_bricks([a, b, c]);
191    // Wire 1: NOT.output -> AND.inputA
192    world.add_wire_connection(
193        assets::components::LogicGate::BoolNot.output_of(c_id),
194        assets::components::LogicGate::BoolAnd.input_a_of(b_id),
195    );
196    // Wire 2: AND.output -> Rerouter.input
197    world.add_wire_connection(
198        assets::components::LogicGate::BoolAnd.output_of(b_id),
199        assets::components::Rerouter::input_of(a_id),
200    );
201
202    world
203}
204
205fn components_world() -> World {
206    // Single grid, single chunk (all positions < 2048) — fully deterministic.
207    // register_all_components() embeds the full component catalog so every
208    // type below (light/interact/wiregraph-pseudo/expr) resolves; each
209    // component below carries non-default property values, and #4/#5 exercise
210    // a WireGraphVariant-typed property (BufferTicks' Input/Output, and the
211    // Constant gate's Value).
212    let mut world = World::new();
213    world.register_all_components();
214    world.meta.bundle.description = "Component fixture".to_string();
215
216    // 1: Point light — non-default brightness/radius/color, decoupled from
217    // brick color (bUseBrickColor: false).
218    world.bricks.push(
219        Brick {
220            position: (0, 0, 6).into(),
221            color: (255, 255, 255).into(),
222            ..Default::default()
223        }
224        .with_component(assets::LiteralComponent::new("Component_PointLight").with_data([
225            ("bMatchBrickShape", Box::new(false) as Box<dyn AsBrdbValue>),
226            ("bEnabled", Box::new(true)),
227            ("Brightness", Box::new(500.0f32)),
228            ("Radius", Box::new(800.0f32)),
229            (
230                "Color",
231                Box::new(SavedBrickColor { r: 10, g: 20, b: 30, a: 255 }),
232            ),
233            ("bUseBrickColor", Box::new(false)),
234            ("bCastShadows", Box::new(true)),
235        ])),
236    );
237
238    // 2: Spot light — narrow cone, non-default brightness/color.
239    world.bricks.push(
240        Brick {
241            position: (20, 0, 6).into(),
242            color: (255, 255, 0).into(),
243            ..Default::default()
244        }
245        .with_component(assets::LiteralComponent::new("Component_SpotLight").with_data([
246            ("InnerConeAngle", Box::new(15.0f32) as Box<dyn AsBrdbValue>),
247            ("OuterConeAngle", Box::new(45.0f32)),
248            ("bEnabled", Box::new(true)),
249            ("Brightness", Box::new(300.0f32)),
250            ("Radius", Box::new(600.0f32)),
251            (
252                "Color",
253                Box::new(SavedBrickColor { r: 255, g: 0, b: 0, a: 255 }),
254            ),
255            ("bUseBrickColor", Box::new(false)),
256            ("bCastShadows", Box::new(true)),
257        ])),
258    );
259
260    // 3: Interact — custom prompt text, hidden interaction.
261    world.bricks.push(
262        Brick {
263            position: (40, 0, 6).into(),
264            color: (0, 255, 255).into(),
265            ..Default::default()
266        }
267        .with_component(assets::LiteralComponent::new("Component_Interact").with_data([
268            (
269                "Message",
270                Box::new("You interacted!".to_string()) as Box<dyn AsBrdbValue>,
271            ),
272            ("ConsoleTag", Box::new("fixture_interact".to_string())),
273            ("bAllowNearbyInteraction", Box::new(false)),
274            ("bHiddenInteraction", Box::new(true)),
275            ("PromptCustomLabel", Box::new("Open Door".to_string())),
276        ])),
277    );
278
279    // 4: Buffer (ticks) — WireGraphPseudo component whose Input/Output are
280    // WireGraphVariant; non-default counters plus a Number/Bool variant pair.
281    world.bricks.push(
282        Brick {
283            position: (60, 0, 1).into(),
284            color: (128, 0, 128).into(),
285            asset: assets::components::BufferTicks::default().brick(),
286            ..Default::default()
287        }
288        .with_component(assets::components::BufferTicks {
289            current_ticks: 3,
290            ticks_to_wait: 10,
291            input: WireVariant::Number(2.5),
292            output: WireVariant::Bool(true),
293        }),
294    );
295
296    // 5: Blend gate — WireGraph_Expr_MathBlend's InputA/InputB are each a
297    // WireGraphPrimMathVariant (here an f64 and an i64 tag, showing the
298    // variant is polymorphic per-port); Blend itself is a plain f64.
299    world.bricks.push(
300        Brick {
301            position: (80, 0, 1).into(),
302            color: (0, 128, 0).into(),
303            asset: assets::components::LogicGate::Blend.brick(),
304            ..Default::default()
305        }
306        .with_component(assets::components::LogicGate::Blend.component_with_overrides(
307            HashMap::from([
308                (
309                    "InputA".into(),
310                    Box::new(WireVariant::Number(10.0)) as Box<dyn AsBrdbValue>,
311                ),
312                ("InputB".into(), Box::new(WireVariant::Int(7))),
313                ("Blend".into(), Box::new(0.75f64)),
314            ]),
315        )),
316    );
317
318    world
319}
320
321fn entities_world() -> World {
322    // Mirror of examples/write_entity.rs's floating sub-grid — the first
323    // grid added after the always-present main grid 1 gets persistent index
324    // 2, so it lands at Grids/2 — plus a couple of main-grid (Grids/1)
325    // bricks. Both grids are single-chunk; note the *outer* Grids/1 vs
326    // Grids/2 folder order comes from a HashMap<usize, UnsavedGrid> in the
327    // writer and is NOT guaranteed stable run-to-run (see stability notes).
328    //
329    // register_all_components() is required here (matching
330    // test_write_entity_save, NOT the plain write_entity.rs example): without
331    // it, Entity_DynamicBrickGrid's class name is never registered and the
332    // write fails with `UnknownType("Entity_DynamicBrickGrid")` — confirmed
333    // by running the crate's own unmodified write_entity example.
334    let mut world = World::new();
335    world.register_all_components();
336    world.meta.bundle.description = "Entity fixture".to_string();
337
338    world.bricks.push(Brick {
339        position: (0, 0, 6).into(),
340        color: (200, 50, 50).into(),
341        ..Default::default()
342    });
343    world.bricks.push(Brick {
344        position: (20, 0, 6).into(),
345        color: (50, 200, 50).into(),
346        ..Default::default()
347    });
348
349    world.add_brick_grid(
350        Entity {
351            frozen: true,
352            location: (0.0, 0.0, 40.0).into(),
353            ..Default::default()
354        },
355        [Brick {
356            position: (0, 0, 3).into(),
357            color: (0, 255, 0).into(),
358            ..Default::default()
359        }],
360    );
361
362    world
363}
364
365fn spawner_world() -> World {
366    // Prefab-embedding fixture: an outer prefab whose spawner gate references
367    // an inner single-brick prefab embedded at Prefabs/Uploads/<BLAKE3>.brz.
368    // Single grid, single chunk, one insertion-ordered prefab map entry —
369    // fully deterministic. The inner archive is written raw (no zstd) so the
370    // embedded bytes are cross-language reproducible.
371    let mut inner = World::new();
372    inner.meta.bundle.description = "Inner prefab".to_string();
373    inner.bricks.push(Brick {
374        position: (0, 0, 6).into(),
375        color: (255, 0, 0).into(),
376        ..Default::default()
377    });
378    inner.make_prefab();
379    let inner_bytes = {
380        let pending = inner.to_unsaved().unwrap().to_pending().unwrap();
381        let mut buf = Vec::new();
382        pending
383            .to_brz_data(None)
384            .unwrap()
385            .write(&mut buf, None)
386            .unwrap();
387        buf
388    };
389
390    let mut world = World::new();
391    world.register_all_components();
392    world.meta.bundle.description = "Spawner fixture".to_string();
393    let prefab_path = world.add_prefab(inner_bytes);
394    world.bricks.push(
395        Brick {
396            asset: brdb::BrickType::str("B_1x1_Gate_Exec_PrefabSpawner"),
397            position: (0, 0, 1).into(),
398            ..Default::default()
399        }
400        .with_component(
401            assets::LiteralComponent::new("BrickComponentType_WireGraph_Exec_PrefabSpawner")
402                .with_data([(
403                    "Prefab",
404                    Box::new(prefab_path) as Box<dyn AsBrdbValue>,
405                )]),
406        ),
407    );
408    world.make_prefab();
409    world
410}
examples/write_prefab_spawner.rs (line 26)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11    // 1. Build the prefab that gets spawned: a single red brick.
12    let mut prefab = World::new();
13    prefab.meta.bundle.name = "Spawned Brick".to_string();
14    prefab.bricks.push(Brick {
15        position: (0, 0, 6).into(),
16        color: (255, 0, 0).into(),
17        ..Default::default()
18    });
19    prefab.make_prefab();
20    let prefab_bytes = prefab.to_brz_vec()?;
21
22    // 2. Build the outer world holding the button + spawner.
23    let mut world = World::new();
24    // Registers the built-in component/port tables so the Button and
25    // PrefabSpawner component types and their wire ports resolve.
26    world.register_all_components();
27    world.meta.bundle.description = "Button-triggered prefab spawner".to_string();
28
29    // Embed the prefab; the returned path is what the spawner references.
30    let prefab_path = world.add_prefab(prefab_bytes);
31
32    // A pressable button (Component_Button on a 1x1 flat round brick). The
33    // crate exposes brick assets as constants; components it doesn't model as
34    // typed gates (like the button and spawner) are built from string names
35    // via LiteralComponent.
36    let (button, button_id) = Brick {
37        position: (0, 0, 2).into(),
38        color: (0, 255, 0).into(),
39        asset: assets::bricks::B_1X1F_ROUND,
40        ..Default::default()
41    }
42    .with_component(assets::LiteralComponent::new("Component_Button").with_data([(
43        "PromptCustomLabel",
44        Box::new("Spawn Brick".to_string()) as Box<dyn AsBrdbValue>,
45    )]))
46    .with_id_split();
47
48    // The prefab-spawner gate, pointed at the embedded prefab.
49    let (spawner, spawner_id) = Brick {
50        position: (15, 0, 1).into(),
51        color: (0, 0, 255).into(),
52        asset: assets::bricks::B_1X1_GATE_EXEC_PREFAB_SPAWNER,
53        ..Default::default()
54    }
55    .with_component(
56        assets::LiteralComponent::new("BrickComponentType_WireGraph_Exec_PrefabSpawner").with_data(
57            [(
58                "Prefab",
59                Box::new(prefab_path.clone()) as Box<dyn AsBrdbValue>,
60            )],
61        ),
62    )
63    .with_id_split();
64
65    world.add_bricks([button, spawner]);
66
67    // Wire the button's held signal into the spawner's Exec input, so a
68    // press fires the spawn.
69    world.add_wire_connection(
70        WirePort::new(button_id, "Component_Button", "bHeld"),
71        WirePort::new(
72            spawner_id,
73            "BrickComponentType_WireGraph_Exec_PrefabSpawner",
74            "Exec",
75        ),
76    );
77
78    // 3. Write it out.
79    let path = PathBuf::from("./example_prefab_spawner.brz");
80    world.write_brz(&path)?;
81    println!("wrote {}", path.display());
82
83    // Read it back to confirm the embedded prefab and wire survived.
84    let reader = Brz::open(&path)?.into_reader();
85    println!("embedded prefab: {}", prefab_path);
86    println!("prefab paths in archive: {:?}", reader.prefab_paths()?);
87    println!("{}", reader.get_fs()?.render());
88
89    Ok(())
90}
Source

pub fn register_used_components(&mut self)

Register only the components actually used by this world’s bricks, mirroring how the game embeds a bundle: ComponentsShared.schema and the global-data component tables carry only the data structs that appear, not the full catalog (which [register_all_components] embeds).

Call this AFTER all bricks/grids have been added. The component schema starts from the minimal SoA scaffolding and gains each used component’s data struct plus its transitive type dependencies; global-data component type/struct/port tables are rebuilt to match. Entity types are registered in full (the catalog is a single microchip-grid entry).

This keeps generated bundles byte-compatible with what the current game build writes — embedding the stale full catalog can make the game reject the schema (“while building schema: while reading struct count”).

Source

pub fn register_component_schema(&mut self, schema_str: &str)

Parse a schema string and merge its definitions.

Source

pub fn register_component(&mut self, struct_name: &str)

Pull a single struct from the max schema.

Source

pub fn brick_bounds(&self) -> Option<(Position, Position)>

Inclusive axis-aligned bounding box over the main-grid bricks, in brick units, as (min, max). Returns None if there are no main-grid bricks. Non-main grids (microchips) are excluded — their bricks live inside an entity and are offset to the chunk center.

Source

pub fn make_prefab(&mut self)

Mark this world’s metadata as a prefab: sets the bundle type to "Prefab" and fills Meta/Prefab.json with pivots/bounds computed from the main-grid brick bounding box (see World::brick_bounds). The write path then emits a prefab bundle (Bundle.json + Prefab.json, plus the optional Screenshot/Thumbnail; no World.json).

Examples found in repository?
examples/write_prefab.rs (line 20)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    let path = PathBuf::from("./example_prefab.brz");
7
8    let mut world = World::new();
9    // A single 1x1 plate-ish brick (half-extent 5,5,2) at the origin so the
10    // bounds match the hand-captured reference prefab.
11    world.bricks.push(Brick {
12        asset: BrickType::Procedural {
13            asset: assets::bricks::PB_DEFAULT_BRICK.into(),
14            size: BrickSize { x: 5, y: 5, z: 2 },
15        },
16        position: (0, 0, 0).into(),
17        ..Default::default()
18    });
19
20    world.make_prefab();
21    println!(
22        "Prefab.json:\n{}",
23        serde_json::to_string_pretty(world.meta.prefab.as_ref().unwrap())?
24    );
25    println!(
26        "Bundle.json:\n{}",
27        serde_json::to_string_pretty(&world.meta.bundle)?
28    );
29
30    if path.exists() {
31        std::fs::remove_file(&path)?;
32    }
33    world.write_brz(&path)?;
34    println!("wrote {}", path.display());
35    Ok(())
36}
More examples
Hide additional examples
examples/write_fixtures.rs (line 378)
365fn spawner_world() -> World {
366    // Prefab-embedding fixture: an outer prefab whose spawner gate references
367    // an inner single-brick prefab embedded at Prefabs/Uploads/<BLAKE3>.brz.
368    // Single grid, single chunk, one insertion-ordered prefab map entry —
369    // fully deterministic. The inner archive is written raw (no zstd) so the
370    // embedded bytes are cross-language reproducible.
371    let mut inner = World::new();
372    inner.meta.bundle.description = "Inner prefab".to_string();
373    inner.bricks.push(Brick {
374        position: (0, 0, 6).into(),
375        color: (255, 0, 0).into(),
376        ..Default::default()
377    });
378    inner.make_prefab();
379    let inner_bytes = {
380        let pending = inner.to_unsaved().unwrap().to_pending().unwrap();
381        let mut buf = Vec::new();
382        pending
383            .to_brz_data(None)
384            .unwrap()
385            .write(&mut buf, None)
386            .unwrap();
387        buf
388    };
389
390    let mut world = World::new();
391    world.register_all_components();
392    world.meta.bundle.description = "Spawner fixture".to_string();
393    let prefab_path = world.add_prefab(inner_bytes);
394    world.bricks.push(
395        Brick {
396            asset: brdb::BrickType::str("B_1x1_Gate_Exec_PrefabSpawner"),
397            position: (0, 0, 1).into(),
398            ..Default::default()
399        }
400        .with_component(
401            assets::LiteralComponent::new("BrickComponentType_WireGraph_Exec_PrefabSpawner")
402                .with_data([(
403                    "Prefab",
404                    Box::new(prefab_path) as Box<dyn AsBrdbValue>,
405                )]),
406        ),
407    );
408    world.make_prefab();
409    world
410}
examples/write_prefab_spawner.rs (line 19)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11    // 1. Build the prefab that gets spawned: a single red brick.
12    let mut prefab = World::new();
13    prefab.meta.bundle.name = "Spawned Brick".to_string();
14    prefab.bricks.push(Brick {
15        position: (0, 0, 6).into(),
16        color: (255, 0, 0).into(),
17        ..Default::default()
18    });
19    prefab.make_prefab();
20    let prefab_bytes = prefab.to_brz_vec()?;
21
22    // 2. Build the outer world holding the button + spawner.
23    let mut world = World::new();
24    // Registers the built-in component/port tables so the Button and
25    // PrefabSpawner component types and their wire ports resolve.
26    world.register_all_components();
27    world.meta.bundle.description = "Button-triggered prefab spawner".to_string();
28
29    // Embed the prefab; the returned path is what the spawner references.
30    let prefab_path = world.add_prefab(prefab_bytes);
31
32    // A pressable button (Component_Button on a 1x1 flat round brick). The
33    // crate exposes brick assets as constants; components it doesn't model as
34    // typed gates (like the button and spawner) are built from string names
35    // via LiteralComponent.
36    let (button, button_id) = Brick {
37        position: (0, 0, 2).into(),
38        color: (0, 255, 0).into(),
39        asset: assets::bricks::B_1X1F_ROUND,
40        ..Default::default()
41    }
42    .with_component(assets::LiteralComponent::new("Component_Button").with_data([(
43        "PromptCustomLabel",
44        Box::new("Spawn Brick".to_string()) as Box<dyn AsBrdbValue>,
45    )]))
46    .with_id_split();
47
48    // The prefab-spawner gate, pointed at the embedded prefab.
49    let (spawner, spawner_id) = Brick {
50        position: (15, 0, 1).into(),
51        color: (0, 0, 255).into(),
52        asset: assets::bricks::B_1X1_GATE_EXEC_PREFAB_SPAWNER,
53        ..Default::default()
54    }
55    .with_component(
56        assets::LiteralComponent::new("BrickComponentType_WireGraph_Exec_PrefabSpawner").with_data(
57            [(
58                "Prefab",
59                Box::new(prefab_path.clone()) as Box<dyn AsBrdbValue>,
60            )],
61        ),
62    )
63    .with_id_split();
64
65    world.add_bricks([button, spawner]);
66
67    // Wire the button's held signal into the spawner's Exec input, so a
68    // press fires the spawn.
69    world.add_wire_connection(
70        WirePort::new(button_id, "Component_Button", "bHeld"),
71        WirePort::new(
72            spawner_id,
73            "BrickComponentType_WireGraph_Exec_PrefabSpawner",
74            "Exec",
75        ),
76    );
77
78    // 3. Write it out.
79    let path = PathBuf::from("./example_prefab_spawner.brz");
80    world.write_brz(&path)?;
81    println!("wrote {}", path.display());
82
83    // Read it back to confirm the embedded prefab and wire survived.
84    let reader = Brz::open(&path)?.into_reader();
85    println!("embedded prefab: {}", prefab_path);
86    println!("prefab paths in archive: {:?}", reader.prefab_paths()?);
87    println!("{}", reader.get_fs()?.render());
88
89    Ok(())
90}
Source

pub fn add_prefab(&mut self, brz_bytes: impl Into<Vec<u8>>) -> String

Embed a prefab archive, content-addressed the way the game does: Prefabs/Uploads/<BLAKE3-uppercase-hex>.brz. Returns that path — the exact string to store in a Prefab component property (bundle_path_ref), e.g. on BrickComponentType_PrefabSpawn or BrickComponentType_WireGraph_Exec_PrefabSpawner.

Examples found in repository?
examples/write_fixtures.rs (line 393)
365fn spawner_world() -> World {
366    // Prefab-embedding fixture: an outer prefab whose spawner gate references
367    // an inner single-brick prefab embedded at Prefabs/Uploads/<BLAKE3>.brz.
368    // Single grid, single chunk, one insertion-ordered prefab map entry —
369    // fully deterministic. The inner archive is written raw (no zstd) so the
370    // embedded bytes are cross-language reproducible.
371    let mut inner = World::new();
372    inner.meta.bundle.description = "Inner prefab".to_string();
373    inner.bricks.push(Brick {
374        position: (0, 0, 6).into(),
375        color: (255, 0, 0).into(),
376        ..Default::default()
377    });
378    inner.make_prefab();
379    let inner_bytes = {
380        let pending = inner.to_unsaved().unwrap().to_pending().unwrap();
381        let mut buf = Vec::new();
382        pending
383            .to_brz_data(None)
384            .unwrap()
385            .write(&mut buf, None)
386            .unwrap();
387        buf
388    };
389
390    let mut world = World::new();
391    world.register_all_components();
392    world.meta.bundle.description = "Spawner fixture".to_string();
393    let prefab_path = world.add_prefab(inner_bytes);
394    world.bricks.push(
395        Brick {
396            asset: brdb::BrickType::str("B_1x1_Gate_Exec_PrefabSpawner"),
397            position: (0, 0, 1).into(),
398            ..Default::default()
399        }
400        .with_component(
401            assets::LiteralComponent::new("BrickComponentType_WireGraph_Exec_PrefabSpawner")
402                .with_data([(
403                    "Prefab",
404                    Box::new(prefab_path) as Box<dyn AsBrdbValue>,
405                )]),
406        ),
407    );
408    world.make_prefab();
409    world
410}
More examples
Hide additional examples
examples/write_prefab_spawner.rs (line 30)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11    // 1. Build the prefab that gets spawned: a single red brick.
12    let mut prefab = World::new();
13    prefab.meta.bundle.name = "Spawned Brick".to_string();
14    prefab.bricks.push(Brick {
15        position: (0, 0, 6).into(),
16        color: (255, 0, 0).into(),
17        ..Default::default()
18    });
19    prefab.make_prefab();
20    let prefab_bytes = prefab.to_brz_vec()?;
21
22    // 2. Build the outer world holding the button + spawner.
23    let mut world = World::new();
24    // Registers the built-in component/port tables so the Button and
25    // PrefabSpawner component types and their wire ports resolve.
26    world.register_all_components();
27    world.meta.bundle.description = "Button-triggered prefab spawner".to_string();
28
29    // Embed the prefab; the returned path is what the spawner references.
30    let prefab_path = world.add_prefab(prefab_bytes);
31
32    // A pressable button (Component_Button on a 1x1 flat round brick). The
33    // crate exposes brick assets as constants; components it doesn't model as
34    // typed gates (like the button and spawner) are built from string names
35    // via LiteralComponent.
36    let (button, button_id) = Brick {
37        position: (0, 0, 2).into(),
38        color: (0, 255, 0).into(),
39        asset: assets::bricks::B_1X1F_ROUND,
40        ..Default::default()
41    }
42    .with_component(assets::LiteralComponent::new("Component_Button").with_data([(
43        "PromptCustomLabel",
44        Box::new("Spawn Brick".to_string()) as Box<dyn AsBrdbValue>,
45    )]))
46    .with_id_split();
47
48    // The prefab-spawner gate, pointed at the embedded prefab.
49    let (spawner, spawner_id) = Brick {
50        position: (15, 0, 1).into(),
51        color: (0, 0, 255).into(),
52        asset: assets::bricks::B_1X1_GATE_EXEC_PREFAB_SPAWNER,
53        ..Default::default()
54    }
55    .with_component(
56        assets::LiteralComponent::new("BrickComponentType_WireGraph_Exec_PrefabSpawner").with_data(
57            [(
58                "Prefab",
59                Box::new(prefab_path.clone()) as Box<dyn AsBrdbValue>,
60            )],
61        ),
62    )
63    .with_id_split();
64
65    world.add_bricks([button, spawner]);
66
67    // Wire the button's held signal into the spawner's Exec input, so a
68    // press fires the spawn.
69    world.add_wire_connection(
70        WirePort::new(button_id, "Component_Button", "bHeld"),
71        WirePort::new(
72            spawner_id,
73            "BrickComponentType_WireGraph_Exec_PrefabSpawner",
74            "Exec",
75        ),
76    );
77
78    // 3. Write it out.
79    let path = PathBuf::from("./example_prefab_spawner.brz");
80    world.write_brz(&path)?;
81    println!("wrote {}", path.display());
82
83    // Read it back to confirm the embedded prefab and wire survived.
84    let reader = Brz::open(&path)?.into_reader();
85    println!("embedded prefab: {}", prefab_path);
86    println!("prefab paths in archive: {:?}", reader.prefab_paths()?);
87    println!("{}", reader.get_fs()?.render());
88
89    Ok(())
90}
Source

pub fn add_prefab_world(&mut self, world: &World) -> Result<String, BrError>

Serialize world to an in-memory .brz and embed it as a prefab.

Source

pub fn to_unsaved(&self) -> Result<UnsavedFs, BrError>

Examples found in repository?
examples/write_fixtures.rs (line 380)
365fn spawner_world() -> World {
366    // Prefab-embedding fixture: an outer prefab whose spawner gate references
367    // an inner single-brick prefab embedded at Prefabs/Uploads/<BLAKE3>.brz.
368    // Single grid, single chunk, one insertion-ordered prefab map entry —
369    // fully deterministic. The inner archive is written raw (no zstd) so the
370    // embedded bytes are cross-language reproducible.
371    let mut inner = World::new();
372    inner.meta.bundle.description = "Inner prefab".to_string();
373    inner.bricks.push(Brick {
374        position: (0, 0, 6).into(),
375        color: (255, 0, 0).into(),
376        ..Default::default()
377    });
378    inner.make_prefab();
379    let inner_bytes = {
380        let pending = inner.to_unsaved().unwrap().to_pending().unwrap();
381        let mut buf = Vec::new();
382        pending
383            .to_brz_data(None)
384            .unwrap()
385            .write(&mut buf, None)
386            .unwrap();
387        buf
388    };
389
390    let mut world = World::new();
391    world.register_all_components();
392    world.meta.bundle.description = "Spawner fixture".to_string();
393    let prefab_path = world.add_prefab(inner_bytes);
394    world.bricks.push(
395        Brick {
396            asset: brdb::BrickType::str("B_1x1_Gate_Exec_PrefabSpawner"),
397            position: (0, 0, 1).into(),
398            ..Default::default()
399        }
400        .with_component(
401            assets::LiteralComponent::new("BrickComponentType_WireGraph_Exec_PrefabSpawner")
402                .with_data([(
403                    "Prefab",
404                    Box::new(prefab_path) as Box<dyn AsBrdbValue>,
405                )]),
406        ),
407    );
408    world.make_prefab();
409    world
410}
411
412fn hash_archive(path: &PathBuf) -> Result<BTreeMap<String, serde_json::Value>, Box<dyn std::error::Error>> {
413    fn collect(fs: &BrFs, prefix: &str, out: &mut Vec<(String, Option<i64>)>) {
414        match fs {
415            BrFs::Root(children) => for (n, c) in children { collect(c, n, out); },
416            BrFs::Folder(_, children) => for (n, c) in children {
417                collect(c, &format!("{prefix}/{n}"), out);
418            },
419            BrFs::File(f) => out.push((prefix.to_string(), f.content_id)),
420        }
421    }
422    let reader = Brz::open(path)?.into_reader();
423    let reader = &*reader;
424    let mut files = Vec::new();
425    collect(&reader.get_fs()?, "", &mut files);
426    let mut out = BTreeMap::new();
427    for (p, content_id) in files {
428        let content = match content_id {
429            Some(id) => reader.find_blob(id)?.read()?,
430            None => Vec::new(),
431        };
432        out.insert(p, serde_json::json!({
433            "blake3": blake3::hash(&content).to_hex().to_string(),
434            "len": content.len(),
435        }));
436    }
437    Ok(out)
438}
439
440fn main() -> Result<(), Box<dyn std::error::Error>> {
441    let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("fixtures");
442    fs::create_dir_all(dir.join("schemas"))?;
443
444    let mut hashes = BTreeMap::new();
445    for (name, world) in [
446        ("brick", brick_world()),
447        ("features", features_world()),
448        ("chunks", chunks_world()),
449        ("wires", wires_world()),
450        ("components", components_world()),
451        ("entities", entities_world()),
452        ("spawner", spawner_world()),
453    ] {
454        let pending = world.to_unsaved()?.to_pending()?;
455        // raw variant: no zstd anywhere — byte-comparable across languages
456        let raw_path = dir.join(format!("{name}_raw.brz"));
457        let mut f = fs::File::create(&raw_path)?;
458        pending.clone().to_brz_data(None)?.write(&mut f, None)?;
459        // compressed variant: zstd level 14 (matches Brz::save)
460        let mut f = fs::File::create(dir.join(format!("{name}.brz")))?;
461        pending.to_brz_data(Some(14))?.write(&mut f, Some(14))?;
462
463        // .brdb variant: content parity only (the .brdb container is not
464        // byte-deterministic across runs).
465        let db_path = dir.join(format!("{name}.brdb"));
466        let _ = fs::remove_file(&db_path);
467        Brdb::create(&db_path)?.save("Fixture", &world)?;
468
469        hashes.insert(name.to_string(), hash_archive(&raw_path)?);
470    }
471    fs::write(dir.join("hashes.json"), serde_json::to_string_pretty(&hashes)?)?;
472
473    // The nine embedded schemas as binary msgpack (the exact bytes the
474    // writer embeds as *.schema files inside archives).
475    for (name, schema) in [
476        ("BRSavedGlobalDataSoA", schemas::global_data_schema()),
477        ("BRSavedOwnerTableSoA", schemas::owners_schema()),
478        ("BRSavedBrickChunkIndexSoA", schemas::bricks_chunk_index_schema()),
479        ("BRSavedBrickChunkSoA", schemas::bricks_chunks_schema()),
480        ("BRSavedWireChunkSoA", schemas::bricks_wires_schema()),
481        ("BRSavedComponentChunkSoA", schemas::bricks_components_schema_min()),
482        ("BRSavedComponentChunkSoA_max", schemas::bricks_components_schema_max()),
483        ("BRSavedEntityChunkIndexSoA", schemas::entities_chunk_index_schema()),
484        ("BRSavedEntityChunkSoA", schemas::entities_chunks_schema()),
485    ] {
486        fs::write(dir.join(format!("schemas/{name}.bin")), schema.to_bytes()?)?;
487    }
488    eprintln!("fixtures written to {}", dir.display());
489    Ok(())
490}
Source

pub fn add_brick(&mut self, brick: Brick)

Add a single brick to the world

Source

pub fn add_bricks(&mut self, bricks: impl IntoIterator<Item = Brick>)

Add multiple bricks to the world

Examples found in repository?
examples/write_wire.rs (line 33)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    let path = PathBuf::from("./example_wire.brdb");
7
8    // Ensures the memory db can be created without errors
9    let db = Brdb::new(&path)?.into_reader();
10    let mut world = World::new();
11    // Register the built-in component type/struct mappings so the gate and
12    // rerouter component types resolve when writing.
13    world.register_all_components();
14    world.meta.bundle.description = "Example World".to_string();
15
16    let (a, a_id) = Brick {
17        position: (0, 0, 1).into(),
18        color: (255, 0, 0).into(),
19        asset: assets::bricks::B_REROUTE,
20        ..Default::default()
21    }
22    .with_component(assets::components::Rerouter)
23    .with_id_split();
24    let (b, b_id) = Brick {
25        position: (15, 0, 1).into(),
26        color: (255, 0, 0).into(),
27        asset: assets::components::LogicGate::BoolNot.brick(),
28        ..Default::default()
29    }
30    .with_component(assets::components::LogicGate::BoolNot.component())
31    .with_id_split();
32
33    world.add_bricks([a, b]);
34    world.add_wire_connection(
35        assets::components::LogicGate::BoolNot.output_of(b_id),
36        assets::components::Rerouter::input_of(a_id),
37    );
38
39    db.save("example world", &world)?;
40
41    println!("{}", db.get_fs()?.render());
42
43    Ok(())
44}
More examples
Hide additional examples
examples/write_fixtures.rs (line 190)
157fn wires_world() -> World {
158    // Mirror of examples/write_wire.rs (single grid, single chunk — fully
159    // deterministic), extended to 3 bricks/2 wires: a boolean NOT gate feeds
160    // one input of an AND gate, whose output feeds a rerouter.
161    let mut world = World::new();
162    world.register_all_components();
163    world.meta.bundle.description = "Wire fixture".to_string();
164
165    let (a, a_id) = Brick {
166        position: (30, 0, 1).into(),
167        color: (255, 0, 0).into(),
168        asset: assets::bricks::B_REROUTE,
169        ..Default::default()
170    }
171    .with_component(assets::components::Rerouter)
172    .with_id_split();
173    let (b, b_id) = Brick {
174        position: (15, 0, 1).into(),
175        color: (0, 255, 0).into(),
176        asset: assets::components::LogicGate::BoolAnd.brick(),
177        ..Default::default()
178    }
179    .with_component(assets::components::LogicGate::BoolAnd.component())
180    .with_id_split();
181    let (c, c_id) = Brick {
182        position: (0, 0, 1).into(),
183        color: (0, 0, 255).into(),
184        asset: assets::components::LogicGate::BoolNot.brick(),
185        ..Default::default()
186    }
187    .with_component(assets::components::LogicGate::BoolNot.component())
188    .with_id_split();
189
190    world.add_bricks([a, b, c]);
191    // Wire 1: NOT.output -> AND.inputA
192    world.add_wire_connection(
193        assets::components::LogicGate::BoolNot.output_of(c_id),
194        assets::components::LogicGate::BoolAnd.input_a_of(b_id),
195    );
196    // Wire 2: AND.output -> Rerouter.input
197    world.add_wire_connection(
198        assets::components::LogicGate::BoolAnd.output_of(b_id),
199        assets::components::Rerouter::input_of(a_id),
200    );
201
202    world
203}
examples/write_prefab_spawner.rs (line 65)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11    // 1. Build the prefab that gets spawned: a single red brick.
12    let mut prefab = World::new();
13    prefab.meta.bundle.name = "Spawned Brick".to_string();
14    prefab.bricks.push(Brick {
15        position: (0, 0, 6).into(),
16        color: (255, 0, 0).into(),
17        ..Default::default()
18    });
19    prefab.make_prefab();
20    let prefab_bytes = prefab.to_brz_vec()?;
21
22    // 2. Build the outer world holding the button + spawner.
23    let mut world = World::new();
24    // Registers the built-in component/port tables so the Button and
25    // PrefabSpawner component types and their wire ports resolve.
26    world.register_all_components();
27    world.meta.bundle.description = "Button-triggered prefab spawner".to_string();
28
29    // Embed the prefab; the returned path is what the spawner references.
30    let prefab_path = world.add_prefab(prefab_bytes);
31
32    // A pressable button (Component_Button on a 1x1 flat round brick). The
33    // crate exposes brick assets as constants; components it doesn't model as
34    // typed gates (like the button and spawner) are built from string names
35    // via LiteralComponent.
36    let (button, button_id) = Brick {
37        position: (0, 0, 2).into(),
38        color: (0, 255, 0).into(),
39        asset: assets::bricks::B_1X1F_ROUND,
40        ..Default::default()
41    }
42    .with_component(assets::LiteralComponent::new("Component_Button").with_data([(
43        "PromptCustomLabel",
44        Box::new("Spawn Brick".to_string()) as Box<dyn AsBrdbValue>,
45    )]))
46    .with_id_split();
47
48    // The prefab-spawner gate, pointed at the embedded prefab.
49    let (spawner, spawner_id) = Brick {
50        position: (15, 0, 1).into(),
51        color: (0, 0, 255).into(),
52        asset: assets::bricks::B_1X1_GATE_EXEC_PREFAB_SPAWNER,
53        ..Default::default()
54    }
55    .with_component(
56        assets::LiteralComponent::new("BrickComponentType_WireGraph_Exec_PrefabSpawner").with_data(
57            [(
58                "Prefab",
59                Box::new(prefab_path.clone()) as Box<dyn AsBrdbValue>,
60            )],
61        ),
62    )
63    .with_id_split();
64
65    world.add_bricks([button, spawner]);
66
67    // Wire the button's held signal into the spawner's Exec input, so a
68    // press fires the spawn.
69    world.add_wire_connection(
70        WirePort::new(button_id, "Component_Button", "bHeld"),
71        WirePort::new(
72            spawner_id,
73            "BrickComponentType_WireGraph_Exec_PrefabSpawner",
74            "Exec",
75        ),
76    );
77
78    // 3. Write it out.
79    let path = PathBuf::from("./example_prefab_spawner.brz");
80    world.write_brz(&path)?;
81    println!("wrote {}", path.display());
82
83    // Read it back to confirm the embedded prefab and wire survived.
84    let reader = Brz::open(&path)?.into_reader();
85    println!("embedded prefab: {}", prefab_path);
86    println!("prefab paths in archive: {:?}", reader.prefab_paths()?);
87    println!("{}", reader.get_fs()?.render());
88
89    Ok(())
90}
Source

pub fn add_entity(&mut self, entity: Entity)

Source

pub fn add_brick_grid( &mut self, entity: Entity, bricks: impl IntoIterator<Item = Brick>, )

Examples found in repository?
examples/write_entity.rs (lines 12-23)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    let path = PathBuf::from("./example_entity.brdb");
7
8    // Ensures the memory db can be created without errors
9    let db = Brdb::new(&path)?.into_reader();
10    let mut world = World::new();
11    world.meta.bundle.description = "Example World".to_string();
12    world.add_brick_grid(
13        Entity {
14            frozen: true,
15            location: (0.0, 0.0, 40.0).into(),
16            ..Default::default()
17        },
18        [Brick {
19            position: (0, 0, 3).into(),
20            color: (0, 255, 0).into(),
21            ..Default::default()
22        }],
23    );
24
25    db.save("example world", &world)?;
26
27    println!("{}", db.get_fs()?.render());
28
29    Ok(())
30}
More examples
Hide additional examples
examples/write_fixtures.rs (lines 349-360)
321fn entities_world() -> World {
322    // Mirror of examples/write_entity.rs's floating sub-grid — the first
323    // grid added after the always-present main grid 1 gets persistent index
324    // 2, so it lands at Grids/2 — plus a couple of main-grid (Grids/1)
325    // bricks. Both grids are single-chunk; note the *outer* Grids/1 vs
326    // Grids/2 folder order comes from a HashMap<usize, UnsavedGrid> in the
327    // writer and is NOT guaranteed stable run-to-run (see stability notes).
328    //
329    // register_all_components() is required here (matching
330    // test_write_entity_save, NOT the plain write_entity.rs example): without
331    // it, Entity_DynamicBrickGrid's class name is never registered and the
332    // write fails with `UnknownType("Entity_DynamicBrickGrid")` — confirmed
333    // by running the crate's own unmodified write_entity example.
334    let mut world = World::new();
335    world.register_all_components();
336    world.meta.bundle.description = "Entity fixture".to_string();
337
338    world.bricks.push(Brick {
339        position: (0, 0, 6).into(),
340        color: (200, 50, 50).into(),
341        ..Default::default()
342    });
343    world.bricks.push(Brick {
344        position: (20, 0, 6).into(),
345        color: (50, 200, 50).into(),
346        ..Default::default()
347    });
348
349    world.add_brick_grid(
350        Entity {
351            frozen: true,
352            location: (0.0, 0.0, 40.0).into(),
353            ..Default::default()
354        },
355        [Brick {
356            position: (0, 0, 3).into(),
357            color: (0, 255, 0).into(),
358            ..Default::default()
359        }],
360    );
361
362    world
363}
Source

pub fn add_wire(&mut self, conn: WireConnection)

Add a single wire connection to the world

Source

pub fn add_wires(&mut self, wires: impl IntoIterator<Item = WireConnection>)

Add multiple wire connections to the world

Source

pub fn add_wire_connection(&mut self, source: WirePort, target: WirePort)

Add a wire connection from one port to another

Examples found in repository?
examples/write_wire.rs (lines 34-37)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    let path = PathBuf::from("./example_wire.brdb");
7
8    // Ensures the memory db can be created without errors
9    let db = Brdb::new(&path)?.into_reader();
10    let mut world = World::new();
11    // Register the built-in component type/struct mappings so the gate and
12    // rerouter component types resolve when writing.
13    world.register_all_components();
14    world.meta.bundle.description = "Example World".to_string();
15
16    let (a, a_id) = Brick {
17        position: (0, 0, 1).into(),
18        color: (255, 0, 0).into(),
19        asset: assets::bricks::B_REROUTE,
20        ..Default::default()
21    }
22    .with_component(assets::components::Rerouter)
23    .with_id_split();
24    let (b, b_id) = Brick {
25        position: (15, 0, 1).into(),
26        color: (255, 0, 0).into(),
27        asset: assets::components::LogicGate::BoolNot.brick(),
28        ..Default::default()
29    }
30    .with_component(assets::components::LogicGate::BoolNot.component())
31    .with_id_split();
32
33    world.add_bricks([a, b]);
34    world.add_wire_connection(
35        assets::components::LogicGate::BoolNot.output_of(b_id),
36        assets::components::Rerouter::input_of(a_id),
37    );
38
39    db.save("example world", &world)?;
40
41    println!("{}", db.get_fs()?.render());
42
43    Ok(())
44}
More examples
Hide additional examples
examples/write_fixtures.rs (lines 192-195)
157fn wires_world() -> World {
158    // Mirror of examples/write_wire.rs (single grid, single chunk — fully
159    // deterministic), extended to 3 bricks/2 wires: a boolean NOT gate feeds
160    // one input of an AND gate, whose output feeds a rerouter.
161    let mut world = World::new();
162    world.register_all_components();
163    world.meta.bundle.description = "Wire fixture".to_string();
164
165    let (a, a_id) = Brick {
166        position: (30, 0, 1).into(),
167        color: (255, 0, 0).into(),
168        asset: assets::bricks::B_REROUTE,
169        ..Default::default()
170    }
171    .with_component(assets::components::Rerouter)
172    .with_id_split();
173    let (b, b_id) = Brick {
174        position: (15, 0, 1).into(),
175        color: (0, 255, 0).into(),
176        asset: assets::components::LogicGate::BoolAnd.brick(),
177        ..Default::default()
178    }
179    .with_component(assets::components::LogicGate::BoolAnd.component())
180    .with_id_split();
181    let (c, c_id) = Brick {
182        position: (0, 0, 1).into(),
183        color: (0, 0, 255).into(),
184        asset: assets::components::LogicGate::BoolNot.brick(),
185        ..Default::default()
186    }
187    .with_component(assets::components::LogicGate::BoolNot.component())
188    .with_id_split();
189
190    world.add_bricks([a, b, c]);
191    // Wire 1: NOT.output -> AND.inputA
192    world.add_wire_connection(
193        assets::components::LogicGate::BoolNot.output_of(c_id),
194        assets::components::LogicGate::BoolAnd.input_a_of(b_id),
195    );
196    // Wire 2: AND.output -> Rerouter.input
197    world.add_wire_connection(
198        assets::components::LogicGate::BoolAnd.output_of(b_id),
199        assets::components::Rerouter::input_of(a_id),
200    );
201
202    world
203}
examples/write_prefab_spawner.rs (lines 69-76)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11    // 1. Build the prefab that gets spawned: a single red brick.
12    let mut prefab = World::new();
13    prefab.meta.bundle.name = "Spawned Brick".to_string();
14    prefab.bricks.push(Brick {
15        position: (0, 0, 6).into(),
16        color: (255, 0, 0).into(),
17        ..Default::default()
18    });
19    prefab.make_prefab();
20    let prefab_bytes = prefab.to_brz_vec()?;
21
22    // 2. Build the outer world holding the button + spawner.
23    let mut world = World::new();
24    // Registers the built-in component/port tables so the Button and
25    // PrefabSpawner component types and their wire ports resolve.
26    world.register_all_components();
27    world.meta.bundle.description = "Button-triggered prefab spawner".to_string();
28
29    // Embed the prefab; the returned path is what the spawner references.
30    let prefab_path = world.add_prefab(prefab_bytes);
31
32    // A pressable button (Component_Button on a 1x1 flat round brick). The
33    // crate exposes brick assets as constants; components it doesn't model as
34    // typed gates (like the button and spawner) are built from string names
35    // via LiteralComponent.
36    let (button, button_id) = Brick {
37        position: (0, 0, 2).into(),
38        color: (0, 255, 0).into(),
39        asset: assets::bricks::B_1X1F_ROUND,
40        ..Default::default()
41    }
42    .with_component(assets::LiteralComponent::new("Component_Button").with_data([(
43        "PromptCustomLabel",
44        Box::new("Spawn Brick".to_string()) as Box<dyn AsBrdbValue>,
45    )]))
46    .with_id_split();
47
48    // The prefab-spawner gate, pointed at the embedded prefab.
49    let (spawner, spawner_id) = Brick {
50        position: (15, 0, 1).into(),
51        color: (0, 0, 255).into(),
52        asset: assets::bricks::B_1X1_GATE_EXEC_PREFAB_SPAWNER,
53        ..Default::default()
54    }
55    .with_component(
56        assets::LiteralComponent::new("BrickComponentType_WireGraph_Exec_PrefabSpawner").with_data(
57            [(
58                "Prefab",
59                Box::new(prefab_path.clone()) as Box<dyn AsBrdbValue>,
60            )],
61        ),
62    )
63    .with_id_split();
64
65    world.add_bricks([button, spawner]);
66
67    // Wire the button's held signal into the spawner's Exec input, so a
68    // press fires the spawn.
69    world.add_wire_connection(
70        WirePort::new(button_id, "Component_Button", "bHeld"),
71        WirePort::new(
72            spawner_id,
73            "BrickComponentType_WireGraph_Exec_PrefabSpawner",
74            "Exec",
75        ),
76    );
77
78    // 3. Write it out.
79    let path = PathBuf::from("./example_prefab_spawner.brz");
80    world.write_brz(&path)?;
81    println!("wrote {}", path.display());
82
83    // Read it back to confirm the embedded prefab and wire survived.
84    let reader = Brz::open(&path)?.into_reader();
85    println!("embedded prefab: {}", prefab_path);
86    println!("prefab paths in archive: {:?}", reader.prefab_paths()?);
87    println!("{}", reader.get_fs()?.render());
88
89    Ok(())
90}

Register an outer-microchip-brick ↔ inner-grid-entity pairing. The write path consumes this into ComponentChunkSoA.microchip_brick_indices / microchip_brick_grid_references. Most callers get this for free by going through add_microchip; use this directly only when constructing the pair manually.

Source

pub fn add_microchip( &mut self, position: Position, entity_location: Vector3f, plane_extent: IntVector, collapsed: bool, ) -> (usize, usize, (Entity, Vec<Brick>))

Build a microchip: spawns the outer microchip brick on the main grid, calls register_microchip_link with the pairing, and returns the outer brick’s id, the grid entity’s id, and the (Entity, Vec<Brick>) pair the caller populates before pushing to world.grids.

Typical usage:

let (chip_brick_id, chip_entity_id, mut inner) = world.add_microchip(
    Position { x: 0, y: 0, z: 6 },
    Vector3f { x: 0.0, y: 0.0, z: 40.0 },
    IntVector { x: 14, y: 14, z: 2 },
    true, // collapsed
);
inner.1.push(some_gate_brick);
world.grids.push(inner);

Trait Implementations§

Source§

impl Default for World

Source§

fn default() -> World

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for World

§

impl !UnwindSafe for World

§

impl Freeze for World

§

impl Send for World

§

impl Sync for World

§

impl Unpin for World

§

impl UnsafeUnpin for World

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.