Dream impacts and destruction
Shared category rules apply one impact definition to every
matching measure.kind, including imported models. The live world uses these
for tables and benches. Objects retain independent damage and their authored
fragment groups; retained bench supports can survive board damage.
For new model output, use Dream 2. Dream 1 examples below remain supported.
Impact behavior describes what an assembly does when the car hits it. It is
bounded data compiled into the existing fixed-step simulation, never code or
an object-name recipe. Examples are in
impact-creations.dream: a ball, table,
produce crate and terracotta planter. All four appear near the mock orchard.
Intact bouncing objects
dream 1;
material paint = toon #d97054;
object "Ball" {
body knockable radius 13 height 26 friction 0.55;
impact bounce restitution 0.74 lift 0.42;
part ball sphere paint at [0,13,0] size [26,26,26] roll z 13;
}restitution (0.1–0.9) controls rebound from the floor, boundary and solid
cylinders. lift (0.05–0.8) converts closing speed into a capped initial hop.
Body friction damps horizontal speed. A hit from above the object's body does
not push it. Geometry stays intact; existing wheel-roll motion can make its
parts roll around their centers. Objects without an impact declaration keep
their existing solid, knockable or decorative behavior.
Assemblies that break
dream 1;
material timber = grain #92613d #bd905d;
object "Small table" {
body solid radius 25 height 30;
impact break speed 90 scatter 62 lift 100 spin 4 lifetime 6;
fragment tabletop {
repeat plank 3 {
part plank box timber at [0,28,(plank-1)*9] size [46,4,8];
}
}
repeat side 2 {
fragment leg {
part leg box timber at [side*36-18,13,0] size [6,26,9];
}
}
}fragment name { … } groups parts that should stay connected during
destruction. A tabletop can remain a single piece while its legs separate;
the larger mock table instead releases each plank. Components may contain
fragment blocks, and repeats create separate fragment instances. Fragment
blocks may contain groups, static joints and component uses, but cannot nest
other fragment blocks. An ungrouped part becomes its own piece.
| Parameter | Bounds | Meaning |
|---|---|---|
speed |
40–400 | Minimum closing speed into the body to break it |
scatter |
0–160 | Outward velocity added to each piece |
lift |
0–180 | Upward launch speed |
spin |
0–8 | Maximum angular speed per axis, radians/second |
lifetime |
2–8 | Seconds before fragments disappear |
Low scatter/lift/spin gives a collapse; larger values give a scattered breakup. Pieces also inherit some car velocity. Directions and spins are deterministic. A glancing pass or a gentle bump below the threshold leaves the object solid. A hard hit removes the whole intact collider exactly once, releases the authored pieces, and creates a small puff in the existing particle pool.
Rest-pose geometry defines each fragment's center and bounds. Rendering and simulation share those frames, including part rotations, static joint frames, object heading and scale. Pieces fall under gravity, rotate, rebound and settle on the terrain. They shrink away over their final 0.8 seconds. The broken object stays broken after the pieces expire. R preserves destruction; Start over restores the entire world. Pause freezes motion and lifetime. A passenger ride continues debris and ball simulation without treating the passenger as a car hit. Directly controlled vehicles use their own body dimensions for impacts. Walking does not fracture objects or launch balls. Reduced motion applies destruction without flying fragments or impact puffs.
Validation, runtime budget and limits
JSON v2 uses impact: {kind: "bounce", restitution, lift} or
impact: {kind: "break", speed, scatter, lift, spin, lifetime}. A part's optional
fragment string names its group. No new executable field is accepted.
- Bounce requires a knockable body; break requires a solid body.
- At most 8 fragments per breakable assembly; existing 32-part bounds remain.
- Legacy scenes retain at most 24 impact objects and 128 potential fragments.
world(...,damage_pool=true)supports instanced static break/topple props under separate record and active/cache bounds. Pooled destruction. - Impact objects cannot carry foundations, compound/offset contacts, seats or emitters.
A break/topple object may use one
contactat[0,0,0]for its actual cylinder. Player and route actors do not support these impact behaviors yet. - Scattered parts and joints use a defined static rest pose. A pooled whole-object topple can retain part sway; bouncing parts retain their supported rigid motion.
- Intact breakable geometry batches by material. Fragment meshes are created on first use, shared by template, and evicted after ten unused simulation seconds or to make room. Active transforms are released when pieces expire. Static scenery remains instanced. Impact puffs share the 256-particle pool.
This slice separates authored components; it does not cut an arbitrary mesh
into new shards. Debris is cosmetic and collides with terrain, not cars, other
pieces or buildings. Bouncing bodies use upright cylinder contacts, not a
general sphere/rigid-body solver. No chain destruction, building collapse,
damage accumulation or repair gameplay. The visual review page at
/tests/visual/destruction.html replays the real simulation at fixed times.
Everything remains a handmade mock; Muse provider integration is unchanged.
Dream 2: toppling, splinters and building sections
The live world's sixteen planted tubs and two produce stalls now use local
whole-object topple impacts. They return through the finite caretaker service,
with no new physics bodies or fragment budget. The complete
plant and
furniture examples use the same data.
Impact and paid repair recordings.
The destructible world library contains
six complete, executable mock definitions and ten placements. Whole-object
break behavior now accepts optional pattern=scatter|splinter|crumble.
Omitting it preserves the original scatter motion. Splinters inherit forward
impact motion and spread laterally; crumble releases pieces with much less
horizontal inheritance, lift, spin and rebound. Their puffs use different
colors/sizes in the existing bounded particle pool. These patterns separate
explicitly authored parts; they do not synthesize additional shards.
impact(mode=topple(speed=110,duration=1.1,lifetime=8));
impact(mode=break(speed=95,scatter=65,lift=65,spin=4,lifetime=6,pattern=splinter));
zone storefront(at=[42,0,0],radius=16,height=39,
mode=break(speed=135,scatter=55,lift=45,spin=3,lifetime=7,pattern=crumble)){
part panel(shape=box,material=brick,at=[0,16,0],size=[8,32,28]);
}topple requires a solid body. Pooled static props may keep engine-owned part sway;
spin, roll, cloth and moving joints remain invalid. The crown retains its original
GPU wind phase, material finish and matching shadow throughout the fall. Use
world(...,damage_pool=true) with explicit prop ownership. A complete wind-tree
and finite replanting world is runnable.
Dream 2 source without
fragment blocks compiles the entire assembly into one stable rigid fragment.
Explicit fragment blocks must still form exactly one falling group. speed retains the 40–400 bound;
duration is 0.25–2 seconds, and lifetime is 2–8 seconds with at least the fall
plus 0.8 seconds for fading. The engine picks a fixed hinge at the far edge of
the physical body in the impact direction. The rest pose rotates as one rigid
assembly, accelerates through the fall and stops when its surveyed lower
geometry meets terrain. It removes the original collider once; the fallen
piece remains cosmetic. Hills, object heading and scale use the same rest pose
and terrain sampling as the renderer. Reduced motion removes the intact object
without animating its fall.
A zone declares a detachable section while leaving an object's root body and
structural parts intact. Its at is an object-local base offset in XYZ, Y up.
Visual coordinates inside the block are relative to that offset. Its independent
upright cylinder uses radius 1–64 and height 1–160. Only break(...) is allowed
as its mode. Nested fragment, group, static joint and use blocks are
supported. A fragment cannot span zones. Every zone must contain parts, and the
assembly must retain at least one structural part outside its zones.
On a qualifying contact only that zone's geometry/collider disappear. Core
contacts, foundations and other zones remain. In Object DSL v2 this is the
allowlisted breakZones array and each affected part's zone reference. A zone
can accompany an upright solid's foundation and compound core contacts; it
cannot accompany whole-object impact, seats, emitters or animated geometry.
Player/route actors cannot carry zones. There are at most four zones and eight
total fragments per assembly. These resident assemblies still share the 24-object and 128-potential-fragment
bounds. Whole static impacts may instead use the explicit pooled policy below. Foundations remain rendered and surveyed
when a section is removed.
R preserves whole-object and zone damage; Start over restores both. Fragment expiry does not restore geometry or collision. Pause and reduced motion retain the same gameplay result. The r14 mock has 21 reactive objects and 97 potential fragments, including six toppling trees, two slatted benches, a detachable timber porch and a brick storefront. Existing table/crate/planter/ball examples remain.
Voxel geometry
Dream 2 now supports bounded filled/carved voxel parts, greedy surface meshing and optional fracture chunks. The city uses voxel building shells, bench boards and carved park walls; the library bakehouse adds chunked masonry; measured proportions and explicit contacts remain unchanged. See the voxel guide for syntax, limits, a complete example and current boundaries.
The r78 furniture example retains the bench, table, crate and planter's original break-group identities while refining their construction. Additional supporting parts stay inside those groups. Saved pieces keep their motion; reconstructed extents follow the new shapes. All fragment and live-assembly budgets remain unchanged.