Add Dream Machine grammar layer

This commit is contained in:
Meta Vens 2026-05-07 01:13:59 +01:00
commit 3cb2bd56bc
13 changed files with 564 additions and 53 deletions

8
Cargo.lock generated
View file

@ -807,6 +807,14 @@ dependencies = [
"bevy_math",
]
[[package]]
name = "vg_grammar"
version = "0.1.0"
dependencies = [
"bevy_math",
"vg_csg",
]
[[package]]
name = "wasip2"
version = "1.0.3+wasi-0.2.9"

View file

@ -1,3 +1,3 @@
[workspace]
members = ["crates/vg_csg"]
members = ["crates/vg_csg", "crates/vg_grammar"]
resolver = "3"

View file

@ -51,6 +51,8 @@ Currently present:
- starter architecture notes for the Blender scene-generation pipeline
- a small `vibegeometry/` helper library for coordinate frames, deterministic
fields, batching, Blender object/material/camera helpers, and verifier checks
- experimental Rust crates: `vg_csg` for Bevy-math brush assembly and
`vg_grammar` for semantic procedural claims feeding the CSG tree
- a repo structure for schemas, prompts, examples, experiments, scripts, tools,
notes, and durable state
- small state inspection and pre-compaction helpers

View file

@ -0,0 +1,10 @@
[package]
name = "vg_grammar"
version = "0.1.0"
edition = "2024"
description = "Procedural grammar layer that emits semantic CSG claims for VibeGeometry"
license = "MIT"
[dependencies]
bevy_math = "0.17"
vg_csg = { path = "../vg_csg" }

View file

@ -0,0 +1,30 @@
use bevy_math::Vec3;
use vg_grammar::{ClaimTree, CorridorSpec, DoorSpec, GrammarContext, RoomSpec, Rule};
fn main() {
let ctx = GrammarContext::new(7);
let mut tree = ClaimTree::new();
RoomSpec::new("dream gallery", Vec3::ZERO, Vec3::new(6.0, 5.0, 3.0)).emit(&ctx, &mut tree);
CorridorSpec::along_x("east artery", Vec3::new(5.0, 0.0, 0.0), 5.0).emit(&ctx, &mut tree);
DoorSpec::new(
"gallery to artery",
Vec3::new(3.0, 0.0, 1.1),
Vec3::new(0.7, 1.4, 2.2),
)
.emit(&ctx, &mut tree);
let compiled = tree.compile();
let output = compiled.assembler.build();
println!(
"claims={} solids={} voids={} brushes={} vertices={} triangles={} warnings={}",
tree.claims().len(),
compiled.solid_claims,
compiled.void_claims,
compiled.brush_ids.len(),
output.mesh.vertex_count(),
output.mesh.triangle_count(),
output.report.warnings.len()
);
}

View file

@ -0,0 +1,154 @@
use bevy_math::Vec3;
use vg_csg::{Assembler, BrushId, MaterialId};
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ClaimTag(pub String);
impl ClaimTag {
pub fn new(value: impl Into<String>) -> Self {
Self(value.into())
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ClaimKind {
Solid,
Void,
}
#[derive(Clone, Debug)]
pub struct Claim {
pub name: String,
pub kind: ClaimKind,
pub center: Vec3,
pub size: Vec3,
pub material: MaterialId,
pub tags: Vec<ClaimTag>,
}
impl Claim {
pub fn solid_box(
name: impl Into<String>,
center: Vec3,
size: Vec3,
material: MaterialId,
) -> Self {
Self {
name: name.into(),
kind: ClaimKind::Solid,
center,
size,
material,
tags: Vec::new(),
}
}
pub fn void_box(name: impl Into<String>, center: Vec3, size: Vec3) -> Self {
Self {
name: name.into(),
kind: ClaimKind::Void,
center,
size,
material: MaterialId::default(),
tags: Vec::new(),
}
}
pub fn tagged(mut self, tag: impl Into<String>) -> Self {
self.tags.push(ClaimTag::new(tag));
self
}
}
#[derive(Clone, Debug, Default)]
pub struct ClaimTree {
claims: Vec<Claim>,
}
impl ClaimTree {
pub fn new() -> Self {
Self::default()
}
pub fn push(&mut self, claim: Claim) {
self.claims.push(claim);
}
pub fn extend(&mut self, claims: impl IntoIterator<Item = Claim>) {
self.claims.extend(claims);
}
pub fn claims(&self) -> &[Claim] {
&self.claims
}
pub fn count_kind(&self, kind: ClaimKind) -> usize {
self.claims
.iter()
.filter(|claim| claim.kind == kind)
.count()
}
pub fn compile(&self) -> CompileReport {
let mut assembler = Assembler::new();
let mut brush_ids = Vec::with_capacity(self.claims.len());
for claim in &self.claims {
let brush_id = match claim.kind {
ClaimKind::Solid => assembler.solid_box(
&claim.name,
vg_csg::Aabb::from_center_size(claim.center, claim.size),
claim.material,
),
ClaimKind::Void => assembler.cut_box(
&claim.name,
vg_csg::Aabb::from_center_size(claim.center, claim.size),
),
};
brush_ids.push(brush_id);
}
CompileReport {
assembler,
brush_ids,
solid_claims: self.count_kind(ClaimKind::Solid),
void_claims: self.count_kind(ClaimKind::Void),
}
}
}
#[derive(Clone, Debug)]
pub struct CompileReport {
pub assembler: Assembler,
pub brush_ids: Vec<BrushId>,
pub solid_claims: usize,
pub void_claims: usize,
}
#[cfg(test)]
mod tests {
use bevy_math::Vec3;
use super::*;
#[test]
fn claim_tree_compiles_solids_and_voids_to_brushes() {
let mut tree = ClaimTree::new();
tree.push(Claim::solid_box(
"wall",
Vec3::ZERO,
Vec3::new(4.0, 0.25, 3.0),
MaterialId(1),
));
tree.push(Claim::void_box(
"door",
Vec3::new(0.0, 0.0, -0.25),
Vec3::new(1.0, 0.5, 1.5),
));
let report = tree.compile();
assert_eq!(report.solid_claims, 1);
assert_eq!(report.void_claims, 1);
assert_eq!(report.brush_ids.len(), 2);
assert_eq!(report.assembler.brushes().len(), 2);
}
}

View file

@ -0,0 +1,43 @@
use vg_csg::MaterialId;
#[derive(Clone, Copy, Debug)]
pub struct Materials {
pub wall: MaterialId,
pub floor: MaterialId,
pub ceiling: MaterialId,
pub trim: MaterialId,
}
impl Default for Materials {
fn default() -> Self {
Self {
wall: MaterialId(1),
floor: MaterialId(2),
ceiling: MaterialId(3),
trim: MaterialId(4),
}
}
}
#[derive(Clone, Debug)]
pub struct GrammarContext {
pub seed: u64,
pub materials: Materials,
pub world_scale: f32,
}
impl GrammarContext {
pub fn new(seed: u64) -> Self {
Self {
seed,
materials: Materials::default(),
world_scale: 1.0,
}
}
}
impl Default for GrammarContext {
fn default() -> Self {
Self::new(0)
}
}

View file

@ -0,0 +1,12 @@
//! Procedural grammar for emitting semantic CSG claims.
//!
//! `vg_grammar` is the authoring layer above `vg_csg`: rules describe why
//! space exists, then compile into solid and void brush claims.
mod claim;
mod context;
mod rules;
pub use claim::{Claim, ClaimKind, ClaimTag, ClaimTree, CompileReport};
pub use context::{GrammarContext, Materials};
pub use rules::{CorridorSpec, DoorSpec, RoomSpec, Rule};

View file

@ -0,0 +1,237 @@
use bevy_math::Vec3;
use crate::{Claim, ClaimTree, GrammarContext};
pub trait Rule {
fn emit(&self, ctx: &GrammarContext, tree: &mut ClaimTree);
}
#[derive(Clone, Debug)]
pub struct RoomSpec {
pub name: String,
pub center: Vec3,
pub size: Vec3,
pub wall_thickness: f32,
}
impl RoomSpec {
pub fn new(name: impl Into<String>, center: Vec3, size: Vec3) -> Self {
Self {
name: name.into(),
center,
size,
wall_thickness: 0.25,
}
}
}
impl Rule for RoomSpec {
fn emit(&self, ctx: &GrammarContext, tree: &mut ClaimTree) {
let half = self.size * 0.5;
let t = self.wall_thickness;
let wall_height = self.size.z;
let wall_z = self.center.z + wall_height * 0.5;
tree.push(
Claim::solid_box(
format!("{} floor", self.name),
self.center + Vec3::new(0.0, 0.0, -t * 0.5),
Vec3::new(self.size.x, self.size.y, t),
ctx.materials.floor,
)
.tagged("room")
.tagged("floor"),
);
tree.push(
Claim::solid_box(
format!("{} ceiling", self.name),
self.center + Vec3::new(0.0, 0.0, wall_height + t * 0.5),
Vec3::new(self.size.x, self.size.y, t),
ctx.materials.ceiling,
)
.tagged("room")
.tagged("ceiling"),
);
tree.push(
Claim::solid_box(
format!("{} north wall", self.name),
Vec3::new(self.center.x, self.center.y + half.y, wall_z),
Vec3::new(self.size.x, t, wall_height),
ctx.materials.wall,
)
.tagged("room")
.tagged("wall"),
);
tree.push(
Claim::solid_box(
format!("{} south wall", self.name),
Vec3::new(self.center.x, self.center.y - half.y, wall_z),
Vec3::new(self.size.x, t, wall_height),
ctx.materials.wall,
)
.tagged("room")
.tagged("wall"),
);
tree.push(
Claim::solid_box(
format!("{} east wall", self.name),
Vec3::new(self.center.x + half.x, self.center.y, wall_z),
Vec3::new(t, self.size.y, wall_height),
ctx.materials.wall,
)
.tagged("room")
.tagged("wall"),
);
tree.push(
Claim::solid_box(
format!("{} west wall", self.name),
Vec3::new(self.center.x - half.x, self.center.y, wall_z),
Vec3::new(t, self.size.y, wall_height),
ctx.materials.wall,
)
.tagged("room")
.tagged("wall"),
);
}
}
#[derive(Clone, Debug)]
pub struct CorridorSpec {
pub name: String,
pub center: Vec3,
pub length: f32,
pub width: f32,
pub height: f32,
pub wall_thickness: f32,
}
impl CorridorSpec {
pub fn along_x(name: impl Into<String>, center: Vec3, length: f32) -> Self {
Self {
name: name.into(),
center,
length,
width: 2.0,
height: 2.6,
wall_thickness: 0.2,
}
}
}
impl Rule for CorridorSpec {
fn emit(&self, ctx: &GrammarContext, tree: &mut ClaimTree) {
let t = self.wall_thickness;
let z = self.center.z + self.height * 0.5;
tree.push(
Claim::solid_box(
format!("{} floor", self.name),
self.center + Vec3::new(0.0, 0.0, -t * 0.5),
Vec3::new(self.length, self.width, t),
ctx.materials.floor,
)
.tagged("corridor")
.tagged("floor"),
);
tree.push(
Claim::solid_box(
format!("{} left wall", self.name),
Vec3::new(self.center.x, self.center.y + self.width * 0.5, z),
Vec3::new(self.length, t, self.height),
ctx.materials.wall,
)
.tagged("corridor")
.tagged("wall"),
);
tree.push(
Claim::solid_box(
format!("{} right wall", self.name),
Vec3::new(self.center.x, self.center.y - self.width * 0.5, z),
Vec3::new(self.length, t, self.height),
ctx.materials.wall,
)
.tagged("corridor")
.tagged("wall"),
);
tree.push(
Claim::solid_box(
format!("{} ceiling", self.name),
self.center + Vec3::new(0.0, 0.0, self.height + t * 0.5),
Vec3::new(self.length, self.width, t),
ctx.materials.ceiling,
)
.tagged("corridor")
.tagged("ceiling"),
);
}
}
#[derive(Clone, Debug)]
pub struct DoorSpec {
pub name: String,
pub center: Vec3,
pub size: Vec3,
}
impl DoorSpec {
pub fn new(name: impl Into<String>, center: Vec3, size: Vec3) -> Self {
Self {
name: name.into(),
center,
size,
}
}
}
impl Rule for DoorSpec {
fn emit(&self, _ctx: &GrammarContext, tree: &mut ClaimTree) {
tree.push(
Claim::void_box(&self.name, self.center, self.size)
.tagged("door")
.tagged("void"),
);
}
}
#[cfg(test)]
mod tests {
use vg_csg::Aabb;
use super::*;
use crate::ClaimKind;
#[test]
fn room_corridor_door_grammar_emits_semantic_claims_and_mesh() {
let ctx = GrammarContext::new(42);
let mut tree = ClaimTree::new();
RoomSpec::new("gallery", Vec3::ZERO, Vec3::new(6.0, 5.0, 3.0)).emit(&ctx, &mut tree);
CorridorSpec::along_x("artery", Vec3::new(5.0, 0.0, 0.0), 5.0).emit(&ctx, &mut tree);
DoorSpec::new(
"gallery east doorway",
Vec3::new(3.0, 0.0, 1.1),
Vec3::new(0.7, 1.4, 2.2),
)
.emit(&ctx, &mut tree);
assert_eq!(tree.count_kind(ClaimKind::Solid), 10);
assert_eq!(tree.count_kind(ClaimKind::Void), 1);
assert!(
tree.claims()
.iter()
.any(|claim| claim.tags.iter().any(|tag| tag.0 == "door"))
);
let report = tree.compile();
let output = report.assembler.build();
let door_void = Aabb::from_center_size(Vec3::new(3.0, 0.0, 1.1), Vec3::new(0.7, 1.4, 2.2));
assert!(output.mesh.triangle_count() > 60);
assert!(output.report.warnings.is_empty());
for tri in output.mesh.indices.chunks_exact(3) {
let center = (output.mesh.positions[tri[0] as usize]
+ output.mesh.positions[tri[1] as usize]
+ output.mesh.positions[tri[2] as usize])
/ 3.0;
assert!(!door_void.contains_point_strict(center, 1.0e-4));
}
}
}

View file

@ -0,0 +1,35 @@
# Dream Machine Grammar
The grammar layer is the authoring mind above CSG.
```text
brief / lore / level intent
-> procedural grammar rules
-> semantic solid and void claims
-> CSG tree classification
-> visible polygon set
-> Bevy mesh cache
-> inspection loop
```
`crates/vg_grammar` starts this layer. It deliberately emits claims before
geometry:
- `Solid` claims say matter exists.
- `Void` claims say space must stay empty.
- tags preserve why the claim exists: `room`, `corridor`, `door`, `wall`,
`floor`, `ceiling`.
The first rules are small on purpose:
- `RoomSpec`
- `CorridorSpec`
- `DoorSpec`
They prove the shape of the pipeline: grammar emits semantic claims, claims
compile into `vg_csg` brushes, and the CSG assembler produces the mesh verdict.
The rule is simple: future procedural generators should feed CSG with authored
space claims instead of bypassing the tree with final triangles. Cities,
habitats, corridors, and districts can grow from fields and grammars, but hard
architectural legality belongs in the CSG tree.

View file

@ -22,44 +22,23 @@ git log --oneline -5
## Current State
VibeGeometry is an incubation scaffold with persistence, graph-translation
corpus notes, repo-local Geometry Script tooling, verifiers, doctrine, a Python
helper library, and now a first Rust CSG assembler. Artifact schemas are still
pending.
VibeGeometry now has three live implementation organs:
Corpus inventory, graph maps, verification notes, and doctrine live in
`docs/research/`; this handoff is not the ledger. Accepted corpus families
include local Shriinivas samples, Quellenform `CurveToMeshUV`, official Blender
demos, and IRCSS French Houses footholds. IRCSS blockers remain repeat-zone
feedback, repeat `Top` outputs, foreach zones, gizmo nodes, and the rejected
empty-output `WindowBeams` harness.
- `vibegeometry/`: Python helpers for Blender coordinate frames, deterministic
fields, batching, object/material/camera setup, and verifier checks.
- `crates/vg_csg`: Rust/Bevy-math CSG brush assembler.
- `crates/vg_grammar`: Dream Machine grammar layer emitting semantic solid/void
claims into `vg_csg`.
From-scratch story-bound builds live in `examples/geometry_script/`:
- `aetheria_bloom_habitat.py`: whole Bloom study with explicit lore coordinate
frames, cylindrical/endcap attachment, golden-angle transfer curves,
deterministic settlement noise, batched dense detail, and inspection cameras.
- `lucent_tether_habitat.py`: Ghostlight/Lucent tether habitat with orthogonal
spin-gravity city plane, flat-cut dome base, street-field city, shader work,
tether attachment, and exterior Citadel-scale solar/radiator florets.
Build notes and verifiers:
- `docs/research/builds/aetheria-bloom-habitat.md`
- `docs/research/builds/lucent-tether-habitat.md`
- `tools/verify_aetheria_bloom_habitat.py`
- `tools/verify_lucent_tether_habitat.py`
Corpus maps, story-bound builds, translation notes, RealtimeCSG doctrine, and
procedural doctrine live under `docs/research/`; this handoff is not the ledger.
Artifact schemas are still pending.
Current authoring prior: use the full Python stack. Python structures intent,
tables, loops, variants, cleanup, validation, docs, and scene/render
orchestration; Geometry Script emits inspectable Geometry Nodes groups; `bpy`
handles Blender scene machinery and evaluated evidence.
`vibegeometry/` is the first reusable helper library. It currently holds
coordinate-frame helpers, deterministic field/noise helpers, mesh batching,
thin Blender object/material/camera helpers, and verifier helpers. The Bloom
script imports these primitives directly, so the library is not just a shrine.
`crates/vg_csg` is the first Rust/Bevy-side interactive geometry organ.
RealtimeCSG's public Unity repo exposes a useful brush/tree/operation/generation
model, but not the optimized native C++ kernel or a supported runtime editing
@ -70,25 +49,22 @@ additive `CylinderZ`, `DomeCapZ`, and `FloretArm` primitives, Bevy-math mesh
buffers, `LevelDsl`, tests, clippy, and an example room. Research note:
`docs/research/realtime-csg-bevy-assembler.md`.
The repo-local Geometry Script clone has Blender 5.1 work for nested `@tree`
group reuse, a ported `nodes_to_script` converter, and menu-socket default
tolerance. See `docs/research/geometry-script-fork-notes.md`. Run
`crates/vg_grammar` is the first Dream Machine grammar layer above CSG. Rules
emit semantic solid/void claims with tags, then compile those claims into
`vg_csg` brushes. Current rules: `RoomSpec`, `CorridorSpec`, `DoorSpec`.
Example: `cargo run -p vg_grammar --example dream_room`. Research note:
`docs/research/dream-machine-grammar.md`.
Repo-local Geometry Script clone notes live in
`docs/research/geometry-script-fork-notes.md`. Run
`.\tools\setup_geometry_script_clone.ps1` if `external/geometry-script` is
missing in a fresh workspace.
missing.
The local toolchain branch is `vibegeometry/blender-5-nodes-to-script`.
The upstream PR branch is `vibegeometry/blender-5-nested-tree-groups`, and PR
#69 is intentionally limited to the nested-group fix:
https://github.com/carson-katri/geometry-script/pull/69.
The GameCult fork is intentionally pruned to `main` plus VibeGeometry-owned
tooling branches. Do not copy upstream branch soup forward unless a future patch
actually needs it.
The current next action is to move `vg_csg` toward the public RealtimeCSG demo's
faster model: add explicit polygon categories, classify brush polygons through
boolean tree operations, preserve source/cutter surfaces and material intent,
then add spatial rejection/indexing and Bevy `Mesh`/ECS plugin boundaries for
the interactive loop.
The current next action is to grow `vg_grammar` from room/corridor/door claims
into a real procedural level grammar: add frames, seeded variation, rule
composition, semantic materials/tags, and generated CSG tree structure, while
moving `vg_csg` toward explicit polygon categories and boolean-tree
classification.
## Important Invariants

View file

@ -51,3 +51,4 @@
{"ts": "2026-05-06T23:06:51+00:00", "type": "implementation", "status": "accepted", "note": "Added vg_csg, a Rust workspace crate for the new interactive Bevy-compatible CSG path: RealtimeCSG-inspired brush ordering and generations, exact AABB box subtraction, additive cylinder/dome/floret primitives, mesh-array output, DSL, tests, clippy, example, and research doctrine. Public RealtimeCSG source informed the shape but not the hidden native kernel."}
{"ts": "2026-05-06T23:20:20+00:00", "type": "implementation", "status": "accepted", "note": "Upgraded vg_csg from AABB-only subtraction to a convex-brush stepping-stone kernel: oriented-box brushes, plane splitting, convex fragment emission, angled-cut tests, and updated RealtimeCSG doctrine. Public LogicalError Realtime-CSG-demo and Sander van Rossen blog/article material are now preferred clean research inputs for the faster target model: polygon classification through boolean trees, not decompiled native internals."}
{"ts": "2026-05-06T23:31:47+00:00", "type": "research", "status": "accepted", "note": "Distilled public Realtime CSG ecosystem doctrine from Sander van Rossen blog posts, LogicalError/Realtime-CSG-demo, BSO3, GDC talk listing, and downstream engine discussions: target vg_csg should migrate from fragment carving toward polygon classification through boolean trees with explicit categories, half-edge/topology working data, bounds early-outs, dirty affected-brush rebuilds, separate mesh optimization, and CSG as one procedural grammar operator."}
{"ts": "2026-05-07T00:12:44+00:00", "type": "implementation", "status": "accepted", "note": "Built the first Dream Machine grammar layer: new vg_grammar crate with semantic solid/void ClaimTree, GrammarContext materials, RoomSpec/CorridorSpec/DoorSpec rules, a dream_room example, and tests proving grammar emits claims that compile into vg_csg brushes and leave doorway voids empty. The authoring split is now grammar writes spatial claims, CSG adjudicates matter, mesh is cache."}

View file

@ -46,6 +46,7 @@ live_architecture:
- Geometry Script emits inspectable reusable Geometry Nodes groups.
- bpy handles Blender objects, modifiers, materials, cameras, lights, files, renders, and evaluated-geometry checks.
- Rust/Bevy-side CSG tooling provides an interactive brush-and-boolean assembler path for fast level geometry, starting with box CSG and habitat-specific additive primitives.
- `vg_grammar` provides the authoring grammar above CSG: procedural rules emit semantic solid/void claims, then `vg_csg` adjudicates the space.
- External Python tools inspect source blends, generate converter drafts, compare outputs, and maintain corpus evidence.
persistence:
- `state/map.yaml` stores canonical mission, boundaries, architecture, artifacts, and next action.
@ -72,6 +73,7 @@ current_artifacts:
- docs/architecture/pipeline-overview.md
- docs/research/procedural-doctrine.md
- docs/research/realtime-csg-doctrine.md
- docs/research/dream-machine-grammar.md
- docs/research/geometry-script-fork-notes.md
- docs/research/translations/ircss-french-houses-system-map.md
- docs/research/translations/ircss-french-houses-node-atlas.md
@ -80,6 +82,7 @@ current_artifacts:
- docs/research/builds/lucent-tether-habitat.md
- docs/research/realtime-csg-bevy-assembler.md
- crates/vg_csg/
- crates/vg_grammar/
- vibegeometry/
tools:
- tools/vibegeometry_state.py
@ -106,8 +109,8 @@ data_flow:
- If state grows faster than understanding, cut it back.
current_status:
summary: VibeGeometry has verified Geometry Script translations for local samples, official Blender demos, and IRCSS French Houses footholds, plus from-scratch Aetheria Bloom and Lucent tether habitat builds. Durable lessons now driving the pipeline: Python orchestrates intent and batching; Geometry Script emits inspectable node groups; source-bound scenes need explicit coordinate contracts before ornament; spin-gravity habitats need ground planes orthogonal to their tether/rotation axis; utility petals, radiators, and solar arrays belong outside pressure glass and may need Citadel-scale presence; large habitat parts need visible load paths across coordinate frames; organic city maps need street fields, irregular parcels, parks, and land-use gradients rather than grids; dense detail must be batched; institutional spaces should model power as surfaces, rails, overlays, thresholds, shader behavior, and camera evidence; and visual acceptance needs domain-facing inspection renders plus verifier checks, not only overview renders. The first reusable `vibegeometry/` helper library now carries coordinate frames, fields, batching, Blender scene primitives, and verifier helpers used by the Bloom and Lucent builds. The Rust crate `vg_csg` now has a convex-brush stepping-stone kernel: RealtimeCSG-inspired ordered brushes, operation types, generation tracking, exact AABB and oriented-box subtraction via convex plane splitting, additive cylinder/dome/floret primitives, mesh-array output, DSL coverage, tests, clippy, and a sample room. Public RealtimeCSG demo/source research points the target away from fragment carving and toward faster polygon classification through boolean trees. Known graph-tooling blockers remain repeat-zone feedback, repeat Top outputs, foreach zones, and gizmo nodes.
next_action: Move `vg_csg` toward the public RealtimeCSG demo's faster model: add explicit polygon categories, classify brush polygons through boolean tree operations, preserve source/cutter surfaces and material intent, then add spatial rejection/indexing and Bevy `Mesh`/ECS plugin boundaries for the interactive loop.
summary: VibeGeometry has verified Geometry Script translations for local samples, official Blender demos, and IRCSS French Houses footholds, plus from-scratch Aetheria Bloom and Lucent tether habitat builds. Durable lessons now driving the pipeline: Python orchestrates intent and batching; Geometry Script emits inspectable node groups; source-bound scenes need explicit coordinate contracts before ornament; spin-gravity habitats need ground planes orthogonal to their tether/rotation axis; utility petals, radiators, and solar arrays belong outside pressure glass and may need Citadel-scale presence; large habitat parts need visible load paths across coordinate frames; organic city maps need street fields, irregular parcels, parks, and land-use gradients rather than grids; dense detail must be batched; institutional spaces should model power as surfaces, rails, overlays, thresholds, shader behavior, and camera evidence; and visual acceptance needs domain-facing inspection renders plus verifier checks, not only overview renders. The first reusable `vibegeometry/` helper library now carries coordinate frames, fields, batching, Blender scene primitives, and verifier helpers used by the Bloom and Lucent builds. The Rust crate `vg_csg` now has a convex-brush stepping-stone kernel: RealtimeCSG-inspired ordered brushes, operation types, generation tracking, exact AABB and oriented-box subtraction via convex plane splitting, additive cylinder/dome/floret primitives, mesh-array output, DSL coverage, tests, clippy, and a sample room. The new `vg_grammar` crate is the first Dream Machine authoring layer: room/corridor/door rules emit semantic solid/void claims with tags into `vg_csg`, preserving intent before CSG resolves matter. Public RealtimeCSG demo/source research points the target away from fragment carving and toward faster polygon classification through boolean trees. Known graph-tooling blockers remain repeat-zone feedback, repeat Top outputs, foreach zones, and gizmo nodes.
next_action: Grow `vg_grammar` from room/corridor/door claims into a real procedural level grammar: add frames, seeded variation, rule composition, semantic materials/tags, and generated CSG tree structure, while moving `vg_csg` toward explicit polygon categories and boolean-tree classification.
remotes:
vibegeometry: https://github.com/GameCult/VibeGeometry
geometry_script_fork: https://github.com/GameCult/geometry-script