From 3cb2bd56bcd24a168e94732cfebeb24198e732db Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Thu, 7 May 2026 01:13:59 +0100 Subject: [PATCH] Add Dream Machine grammar layer --- Cargo.lock | 8 + Cargo.toml | 2 +- README.md | 2 + crates/vg_grammar/Cargo.toml | 10 + crates/vg_grammar/examples/dream_room.rs | 30 +++ crates/vg_grammar/src/claim.rs | 154 +++++++++++++++ crates/vg_grammar/src/context.rs | 43 ++++ crates/vg_grammar/src/lib.rs | 12 ++ crates/vg_grammar/src/rules.rs | 237 +++++++++++++++++++++++ docs/research/dream-machine-grammar.md | 35 ++++ notes/fresh-workspace-handoff.md | 70 +++---- state/evidence.jsonl | 1 + state/map.yaml | 7 +- 13 files changed, 561 insertions(+), 50 deletions(-) create mode 100644 crates/vg_grammar/Cargo.toml create mode 100644 crates/vg_grammar/examples/dream_room.rs create mode 100644 crates/vg_grammar/src/claim.rs create mode 100644 crates/vg_grammar/src/context.rs create mode 100644 crates/vg_grammar/src/lib.rs create mode 100644 crates/vg_grammar/src/rules.rs create mode 100644 docs/research/dream-machine-grammar.md diff --git a/Cargo.lock b/Cargo.lock index e6499e4..91730ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index bed690a..c8cb568 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,3 @@ [workspace] -members = ["crates/vg_csg"] +members = ["crates/vg_csg", "crates/vg_grammar"] resolver = "3" diff --git a/README.md b/README.md index 7237549..1796730 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/crates/vg_grammar/Cargo.toml b/crates/vg_grammar/Cargo.toml new file mode 100644 index 0000000..0283e0c --- /dev/null +++ b/crates/vg_grammar/Cargo.toml @@ -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" } diff --git a/crates/vg_grammar/examples/dream_room.rs b/crates/vg_grammar/examples/dream_room.rs new file mode 100644 index 0000000..8c549f5 --- /dev/null +++ b/crates/vg_grammar/examples/dream_room.rs @@ -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() + ); +} diff --git a/crates/vg_grammar/src/claim.rs b/crates/vg_grammar/src/claim.rs new file mode 100644 index 0000000..f7a87bf --- /dev/null +++ b/crates/vg_grammar/src/claim.rs @@ -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) -> 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, +} + +impl Claim { + pub fn solid_box( + name: impl Into, + 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, 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) -> Self { + self.tags.push(ClaimTag::new(tag)); + self + } +} + +#[derive(Clone, Debug, Default)] +pub struct ClaimTree { + claims: Vec, +} + +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) { + 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, + 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); + } +} diff --git a/crates/vg_grammar/src/context.rs b/crates/vg_grammar/src/context.rs new file mode 100644 index 0000000..6343832 --- /dev/null +++ b/crates/vg_grammar/src/context.rs @@ -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) + } +} diff --git a/crates/vg_grammar/src/lib.rs b/crates/vg_grammar/src/lib.rs new file mode 100644 index 0000000..3c08305 --- /dev/null +++ b/crates/vg_grammar/src/lib.rs @@ -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}; diff --git a/crates/vg_grammar/src/rules.rs b/crates/vg_grammar/src/rules.rs new file mode 100644 index 0000000..dca68b1 --- /dev/null +++ b/crates/vg_grammar/src/rules.rs @@ -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, 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, 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, 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)); + } + } +} diff --git a/docs/research/dream-machine-grammar.md b/docs/research/dream-machine-grammar.md new file mode 100644 index 0000000..a24152b --- /dev/null +++ b/docs/research/dream-machine-grammar.md @@ -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. diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index 3d6c054..022abf0 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -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 diff --git a/state/evidence.jsonl b/state/evidence.jsonl index d83bfd3..0d87bcf 100644 --- a/state/evidence.jsonl +++ b/state/evidence.jsonl @@ -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."} diff --git a/state/map.yaml b/state/map.yaml index 65d0430..342cb90 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -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