using flecs.script
struct Position(x: f32, y: f32, z: f32)
struct Rotation(x: f32, y: f32, z: f32)
struct Rgb(r: u8, g: u8, b: u8)
struct Box(width: f32, height: f32, depth: f32)
struct Sphere(radius: f32)
struct Cylinder(radius: f32, length: f32, segments: i32)
struct Cone(radius: f32, length: f32, segments: i32)
struct Torus(radius: f32, tube: f32, segments: i32, rings: i32)
struct TrianglePrism(x: f32, y: f32, z: f32)
const timber: Rgb = {91, 65, 57}
const roofTile: Rgb = {66, 83, 99}
const cream: Rgb = {248, 230, 196}
const glass: Rgb = {119, 176, 183}
const iron: Rgb = {62, 77, 80}
const leaf: Rgb = {112, 158, 109}
const pink: Rgb = {242, 178, 191}
struct Facade(width: f32, height: f32, color: Rgb)
struct Roof(width: f32, depth: f32, color: Rgb)
@tree Parent
template Window {
prop width: f32 = 1.2
prop height: f32 = 1.2
prop frame: Rgb = {91, 65, 57}
prop panes: i32 = 2
{
Position: {}
Box: {width, height, 0.13}
Rgb: frame
}
{
Position: {0, 0, 0.08}
Box: {width - 0.12, height - 0.12, 0.04}
Rgb: glass
}
for i in 1..panes {
{
Position: {-width / 2 + width * i / panes, 0, 0.12}
Box: {0.045, height, 0.04}
Rgb: frame
}
}
{
Position: {0, -height / 2, 0.12}
Box: {width + 0.16, 0.09, 0.24}
Rgb: frame
}
}
@tree Parent
template Planter {
prop blossoms: bool = false
{
Position: {0, 0.16, 0}
Cylinder: {0.21, 0.32, 10}
Rgb: {186, 116, 89}
}
{
Position: {0, 0.31, 0}
Torus: {0.2, 0.035, 12, 6}
Rgb: {214, 145, 112}
}
{
Position: {0, 0.46, 0}
Sphere: {0.28}
Rgb: leaf
}
if blossoms {
for i in 0..5 {
{
Position: {math.cos(i * 1.26) * 0.19, 0.64, math.sin(i * 1.26) * 0.19}
Sphere: {0.07}
Rgb: pink
}
}
}
}
@tree Parent
template AirConditioner {
{
Position: {}
Box: {0.95, 0.58, 0.4}
Rgb: {232, 231, 215}
}
{
Position: {-0.17, 0, 0.215}
Rotation: {math.PI / 2, 0, 0}
Cylinder: {0.21, 0.035, 20}
Rgb: iron
}
{
Position: {-0.17, 0, 0.24}
Rotation: {math.PI / 2, 0, 0}
Torus: {0.16, 0.025, 20, 6}
Rgb: {173, 184, 177}
}
for i in 0..5 {
{
Position: {0.29, -0.17 + i * 0.08, 0.22}
Box: {0.2, 0.025, 0.025}
Rgb: iron
}
}
for i in 0..2 {
{
Position: {-0.32 + i * 0.64, -0.35, -0.05}
Box: {0.07, 0.12, 0.62}
Rgb: iron
}
}
{
Position: {0.55, -0.35, -0.1}
Cylinder: {0.035, 1.05, 8}
Rgb: cream
}
}
@tree Parent
template Lantern {
{
Position: {0, 0.31, 0}
Cylinder: {0.025, 0.26, 8}
Rgb: iron
}
{
Position: {}
Sphere: {0.25}
Rgb: {241, 116, 91}
}
for i in 0..3 {
{
Position: {0, (i - 1) * 0.12, 0}
Torus: {0.22 - math.abs(i - 1) * 0.035, 0.014, 16, 4}
Rgb: {182, 67, 58}
}
}
{
Position: {0, -0.23, 0}
Cylinder: {0.1, 0.07, 12}
Rgb: timber
}
}
@tree Parent
template TimberFacade : Facade {
{
Position: {0, height / 2, 0}
Box: {width, height - 0.08, 0.18}
Rgb: color
}
for i in 0..3 {
{
Position: {(i - 1) * (width / 2 - 0.1), height / 2, 0.13}
Box: {0.13, height, 0.14}
Rgb: timber
}
}
for i in 0..2 {
{
Position: {0, 0.15 + i * (height - 0.3), 0.13}
Box: {width, 0.15, 0.17}
Rgb: timber
}
Window(width: width * 0.35, height: height * 0.5, panes: 4) {
Position: {(i - 0.5) * width * 0.5, height * 0.56, 0.17}
}
}
for i in 0..12 {
{
Position: {-width / 2 + (i + 0.5) * width / 12, 0.42, 0.14}
Box: {0.06, 0.44, 0.1}
Rgb: timber
}
}
}
@tree Parent
template StuccoFacade : Facade {
{
Position: {0, height / 2, 0}
Box: {width, height - 0.08, 0.18}
Rgb: color
}
{
Position: {0, height - 0.13, 0.13}
Box: {width + 0.12, 0.17, 0.24}
Rgb: cream
}
for i in 0..2 {
Window(width: width * 0.32, height: height * 0.52, frame: iron) {
Position: {(i - 0.5) * width * 0.5, height * 0.56, 0.18}
}
}
{
Position: {0, 0.32, 0.43}
Box: {width * 0.85, 0.13, 0.85}
Rgb: cream
}
{
Position: {0, 0.98, 0.83}
Box: {width * 0.85, 0.06, 0.07}
Rgb: iron
}
for i in 0..9 {
{
Position: {(i - 4) * width * 0.1, 0.65, 0.83}
Box: {0.035, 0.63, 0.035}
Rgb: iron
}
}
Planter(blossoms: true) { Position: {-width * 0.3, 0.39, 0.46} }
}
@tree Parent
template ShutterFacade : Facade {
{
Position: {0, height / 2, 0}
Box: {width, height - 0.08, 0.18}
Rgb: color
}
for i in 0..9 {
{
Position: {0, (i + 0.5) * height / 9, 0.11}
Box: {width, 0.035, 0.055}
Rgb: cream
}
}
for i in 0..2 {
Window(width: width * 0.24, height: height * 0.48, frame: cream) {
Position: {(i - 0.5) * width * 0.51, height * 0.57, 0.18}
}
for side in 0..2 {
{
Position: {(i - 0.5) * width * 0.51 + (side * 2 - 1) * width * 0.165, height * 0.57, 0.2}
Box: {width * 0.08, height * 0.48, 0.12}
Rgb: {107, 141, 134}
for slat in 0..6 {
{
Position: {0, (slat - 2.5) * height * 0.065, 0.08}
Box: {width * 0.065, 0.035, 0.04}
Rgb: cream
}
}
}
}
}
{
Position: {0, 0.45, 0.28}
Box: {width * 0.5, 0.23, 0.36}
Rgb: timber
}
for i in 0..3 {
Planter(blossoms: true) { Position: {(i - 1) * width * 0.17, 0.43, 0.3} }
}
}
@tree Parent
template LatticeFacade : Facade {
{
Position: {0, height / 2, 0}
Box: {width, height - 0.08, 0.18}
Rgb: color
}
Window(width: width * 0.8, height: height * 0.58, panes: 4) {
Position: {0, height * 0.54, 0.14}
}
for i in 0..15 {
{
Position: {(i - 7) * width * 0.059, height * 0.54, 0.36}
Box: {0.065, height * 0.66, 0.09}
Rgb: timber
}
}
for i in 0..3 {
{
Position: {0, height * (0.22 + i * 0.32), 0.35}
Box: {width * 0.9, 0.09, 0.13}
Rgb: timber
}
}
{
Position: {0, height - 0.08, 0.32}
Rotation: {0.15, 0, 0}
Box: {width + 0.16, 0.12, 0.72}
Rgb: roofTile
}
}
@tree Parent
template BayFacade : Facade {
{
Position: {0, height / 2, 0}
Box: {width, height - 0.08, 0.18}
Rgb: color
}
{
Position: {0, height * 0.56, 0.38}
Box: {width * 0.66, height * 0.64, 0.65}
Rgb: cream
Window(width: width * 0.61, height: height * 0.49, frame: cream, panes: 3) {
Position: {0, 0.04, 0.37}
}
for side in 0..2 {
Window(width: 0.42, height: height * 0.49, frame: cream) {
Position: {(side * 2 - 1) * width * 0.33, 0.04, 0}
Rotation: {0, (side * 2 - 1) * math.PI / 2, 0}
}
}
}
{
Position: {0, height * 0.9, 0.46}
Rotation: {0.12, 0, 0}
Box: {width * 0.72, 0.13, 1.02}
Rgb: {115, 145, 133}
}
for side in 0..2 {
{
Position: {(side * 2 - 1) * width * 0.25, height * 0.2, 0.34}
Box: {0.12, 0.25, 0.45}
Rgb: timber
}
}
}
@tree Parent
template TiledRoof : Roof {
const span = width + 0.6
const run = depth + 0.65
{
Position: {0, 0.58, 0}
TrianglePrism: {span, 1.16, run}
Rgb: color
}
for side in 0..2 {
for course in 0..5 {
const distance = (course + 0.5) * span / 10
{
Position: {(side * 2 - 1) * distance, 1.2 - distance * 2.32 / span, 0}
Rotation: {0, 0, (1 - side * 2) * math.atan(2.32 / span)}
Box: {span / 10 + 0.12, 0.1, run + 0.24}
Rgb: color
}
}
}
for i in 0..16 {
{
Position: {0, 0, -run / 2 + (i + 0.5) * run / 16}
for side in 0..2 {
{
Position: {(side * 2 - 1) * span / 4, 0.66, 0}
Rotation: {0, 0, (1 - side * 2) * math.atan(2.32 / span)}
Box: {math.sqrt(span * span / 4 + 1.3456), 0.04, 0.035}
Rgb: {94, 111, 122}
}
}
}
}
{
Position: {0, 1.24, 0}
Rotation: {math.PI / 2, 0, 0}
Cylinder: {0.13, run + 0.42, 12}
Rgb: color
}
}
@tree Parent
template FlatRoof : Roof {
{
Position: {0, 0, 0}
Box: {width + 0.35, 0.2, depth + 0.35}
Rgb: cream
}
for side in 0..2 {
{
Position: {(side * 2 - 1) * width / 2, 0.22, 0}
Box: {0.13, 0.4, depth}
Rgb: color
}
}
{
Position: {-width * 0.22, 0.6, -depth * 0.22}
Cylinder: {0.5, 1.05, 16}
Rgb: {184, 200, 195}
}
{
Position: {-width * 0.22, 1.15, -depth * 0.22}
Cone: {0.55, 0.18, 16}
Rgb: iron
}
AirConditioner() { Position: {width * 0.23, 0.45, 0} }
{
Position: {0, 0, depth * 0.28}
for i in 0..2 {
{
Position: {(i - 0.5) * width * 0.7, 0.75, 0}
Cylinder: {0.025, 1.5, 8}
Rgb: iron
}
}
{
Position: {0, 1.4, 0}
Box: {width * 0.7, 0.025, 0.025}
Rgb: iron
}
for i in 0..3 {
{
Position: {(i - 1) * width * 0.2, 1.08, 0}
Box: {width * 0.15, 0.64, 0.035}
if i == 1 { Rgb: pink } else { Rgb: cream }
}
}
}
}
@tree Parent
template ShedRoof : Roof {
const slope = 0.16
const length = depth + 0.65
for i in 0..12 {
const z = -depth / 2 + (i + 0.5) * depth / 12
const rise = 0.55 + z * slope
{
Position: {0, rise / 2, z}
Box: {width, rise, depth / 12 + 0.015}
Rgb: cream
}
}
{
Position: {0, 0.59, 0}
Rotation: {-math.atan(slope), 0, 0}
Box: {width + 0.6, 0.1, length * math.sqrt(1 + slope * slope)}
Rgb: color
}
for i in 0..11 {
{
Position: {(i - 5) * (width + 0.5) / 10, 0.66, 0}
Rotation: {-math.atan(slope), 0, 0}
Box: {0.035, 0.045, length * math.sqrt(1 + slope * slope)}
Rgb: iron
}
}
{
Position: {0, 0.54 - length * slope / 2, -length / 2}
Rotation: {0, 0, math.PI / 2}
Cylinder: {0.08, width + 0.7, 10}
Rgb: iron
}
for i in 0..3 {
Window(width: width * 0.22, height: 0.28, frame: iron) {
Position: {(i - 1) * width * 0.28, 0.4, depth / 2 + 0.08}
}
}
}
@tree Parent
template DormerRoof : Roof {
TiledRoof(width: width, depth: depth, color: color) { Position: {} }
{
Position: {0, 1.08, depth / 2 - 0.48}
Box: {1.5, 0.86, 1.2}
Rgb: cream
Window(width: 1.18, height: 0.6, panes: 3) {
Position: {0, 0.04, 0.64}
}
{
Position: {0, 0.65, 0}
TrianglePrism: {1.85, 0.5, 1.55}
Rgb: color
}
{
Position: {0, 0.93, 0}
Rotation: {math.PI / 2, 0, 0}
Cylinder: {0.07, 1.7, 10}
Rgb: color
}
}
}
@tree Parent
template GardenRoof : Roof {
{
Position: {}
Box: {width + 0.35, 0.2, depth + 0.35}
Rgb: cream
}
for side in 0..2 {
{
Position: {(side * 2 - 1) * width / 2, 0.25, 0}
Box: {0.13, 0.4, depth}
Rgb: color
}
for end in 0..2 {
{
Position: {(side * 2 - 1) * width * 0.32, 0.78, -depth * 0.12 + (end * 2 - 1) * depth * 0.25}
Box: {0.09, 1.4, 0.09}
Rgb: timber
}
}
{
Position: {(side * 2 - 1) * width * 0.32, 1.5, -depth * 0.12}
Box: {0.1, 0.12, depth * 0.65}
Rgb: timber
}
Planter(blossoms: true) {
Position: {(side * 2 - 1) * width * 0.35, 0.12, depth * 0.36}
}
}
for i in 0..7 {
{
Position: {0, 1.6, -depth * 0.12 + (i - 3) * depth * 0.09}
Box: {width * 0.76, 0.09, 0.09}
Rgb: timber
}
}
for i in 0..3 {
{
Position: {(i - 1) * width * 0.22, 1.63, -depth * 0.15}
Sphere: {0.3}
Rgb: leaf
}
Planter() { Position: {(i - 1) * width * 0.24, 0.12, -depth * 0.32} }
}
{
Position: {width * 0.25, 0.42, depth * 0.12}
Box: {0.8, 0.65, 0.9}
Rgb: color
}
}
@tree Parent
template VendingMachine {
prop color: Rgb = {206, 71, 70}
{
Position: {0, 0.93, 0}
Box: {1.05, 1.86, 0.72}
Rgb: color
}
{
Position: {-0.09, 1.22, 0.38}
Box: {0.74, 0.91, 0.05}
Rgb: {220, 242, 234}
}
for row in 0..3 {
for col in 0..4 {
{
Position: {-0.36 + col * 0.18, 0.95 + row * 0.28, 0.43}
Cylinder: {0.055, 0.17, 8}
if (row + col) % 2 == 0 {
Rgb: {242, 178, 73}
} else {
Rgb: {81, 159, 158}
}
}
{
Position: {-0.36 + col * 0.18, 0.83 + row * 0.28, 0.44}
Box: {0.07, 0.035, 0.02}
Rgb: cream
}
}
}
{
Position: {0.39, 1.07, 0.39}
Box: {0.13, 0.39, 0.045}
Rgb: iron
}
{
Position: {0, 0.35, 0.38}
Box: {0.67, 0.24, 0.055}
Rgb: iron
}
{
Position: {0, 1.77, 0.39}
Box: {0.86, 0.1, 0.04}
Rgb: cream
}
}
@tree Parent
template Shopfront {
prop width: f32 = 4.4
prop accent: Rgb = {181, 81, 72}
Window(width: width * 0.4, height: 1.45, panes: 4) {
Position: {-width * 0.24, 1.05, 0.15}
}
Window(width: width * 0.28, height: 1.9, panes: 2) {
Position: {width * 0.2, 1.02, 0.15}
}
{
Position: {width * 0.2, 0.08, 0.34}
Box: {width * 0.34, 0.16, 0.8}
Rgb: {184, 182, 165}
}
{
Position: {0, 2.17, 0.24}
Box: {width - 0.25, 0.42, 0.24}
Rgb: timber
}
for i in 0..5 {
{
Position: {(i - 2) * 0.43, 2.18, 0.38}
Box: {0.31, 0.28, 0.04}
Rgb: cream
}
{
Position: {(i - 2) * 0.43, 2.18, 0.41}
Box: {0.05, 0.18, 0.03}
Rgb: accent
}
{
Position: {(i - 2) * 0.43, 2.22, 0.42}
Box: {0.18, 0.04, 0.025}
Rgb: accent
}
}
{
Position: {0, 1.91, 0.57}
Rotation: {0.18, 0, 0}
Box: {width + 0.18, 0.1, 0.95}
Rgb: accent
}
for i in 0..6 {
{
Position: {-width / 2 + (i + 0.5) * width / 6, 1.68, 0.99}
Box: {width / 6 - 0.035, 0.38, 0.045}
Rgb: accent
}
{
Position: {-width / 2 + (i + 0.5) * width / 6, 1.69, 1.02}
Rotation: {math.PI / 2, 0, 0}
Cylinder: {0.065, 0.016, 12}
Rgb: cream
}
}
Lantern() { Position: {-width / 2 - 0.1, 1.68, 0.62} }
Planter(blossoms: true) { Position: {-width * 0.34, 0, 0.7} }
}
@tree Parent
template Building {
prop facade: template Facade = TimberFacade
prop floors: i32 = 2
prop width: f32 = 4.4
prop depth: f32 = 4.2
prop floorHeight: f32 = 2.5
prop color: Rgb = {242, 218, 177}
prop accent: Rgb = {181, 81, 72}
prop roof: template Roof = TiledRoof
prop roofColor: Rgb = {66, 83, 99}
prop shop: bool = true
const height = floors * floorHeight
{
Position: {0, height / 2, 0}
Box: {width, height, depth}
Rgb: color
}
{
Position: {0, 0.12, 0}
Box: {width + 0.16, 0.24, depth + 0.16}
Rgb: {178, 176, 158}
}
for floor in 0..floors {
if floor == 0 && shop {
Shopfront(width: width, accent: accent) { Position: {0, 0, depth / 2} }
} else if floor == 0 {
{
Position: {0, 0, depth / 2}
Window(width: 0.95, height: 1.9, frame: timber) {
Position: {width * 0.23, 1.04, 0.15}
}
Window(width: width * 0.36, height: 1.05, frame: cream) {
Position: {-width * 0.22, 1.4, 0.15}
}
{
Position: {width * 0.23, 0.08, 0.38}
Box: {1.18, 0.16, 0.75}
Rgb: cream
}
{
Position: {width * 0.23, 2.12, 0.35}
Box: {1.35, 0.1, 0.85}
Rgb: accent
}
Planter(blossoms: true) { Position: {-width * 0.3, 0, 0.5} }
}
} else {
{
Position: {0, floor * floorHeight, depth / 2}
facade: {width: width, height: floorHeight, color: color}
}
}
for side in 0..2 {
{
Position: {(side * 2 - 1) * width / 2, floor * floorHeight, 0}
Rotation: {0, (side * 2 - 1) * math.PI / 2, 0}
Window(width: depth * 0.36, height: 1.1, frame: cream) {
Position: {0.3, 1.5, 0.1}
}
AirConditioner() { Position: {-0.4, 0.56, 0.25} }
}
}
{
Position: {0, floor * floorHeight, -depth / 2}
Rotation: {0, math.PI, 0}
Window(width: width * 0.45, height: 1.1, frame: cream) {
Position: {0, 1.45, 0.1}
}
}
}
for side in 0..2 {
{
Position: {(side * 2 - 1) * (width / 2 + 0.07), height / 2, -depth / 2}
Cylinder: {0.055, height, 8}
Rgb: iron
}
}
{
Position: {0, height, 0}
roof: {width: width, depth: depth, color: roofColor}
}
}
@tree Parent
template CherryTree {
{
Position: {0, 0.95, 0}
Cylinder: {0.12, 1.9, 9}
Rgb: timber
}
for i in 0..5 {
{
Position: {math.cos(i * 1.26) * 0.48, 2.05 + (i % 2) * 0.3, math.sin(i * 1.26) * 0.48}
Sphere: {0.66}
Rgb: {243, 179 + i * 5, 196 + i * 4}
}
}
{
Position: {0, 0.07, 0}
Cylinder: {0.66, 0.14, 12}
Rgb: {159, 177, 139}
}
}
@tree Parent
template PowerPole {
{
Position: {0, 3.6, 0}
Cylinder: {0.11, 7.2, 12}
Rgb: {149, 151, 140}
}
{
Position: {0, 0.32, 0}
Cylinder: {0.17, 0.64, 12}
Rgb: iron
}
for i in 0..2 {
{
Position: {0, 6.45 + i * 0.5, 0}
Box: {0.14, 0.12, 1.35}
Rgb: iron
}
}
for i in 0..3 {
{
Position: {0, 7.06, (i - 1) * 0.53}
Cylinder: {0.085, 0.2, 10}
Rgb: cream
}
}
{
Position: {0.26, 5.8, 0}
Cylinder: {0.23, 0.65, 12}
Rgb: {187, 199, 188}
}
for i in 0..4 {
{
Position: {0, 0.85 + i * 0.2, 0}
Cylinder: {0.115, 0.1, 12}
Rgb: {233, 191, 85}
}
}
}
@tree Parent
template PowerSpan {
prop length: f32 = 8
for wire in 0..3 {
for i in 0..16 {
const x0 = length * i / 16
const x1 = length * (i + 1) / 16
const y0 = 7.16 - 0.65 * 4 * (x0 / length) * (1 - x0 / length)
const y1 = 7.16 - 0.65 * 4 * (x1 / length) * (1 - x1 / length)
{
Position: {(x0 + x1) / 2, (y0 + y1) / 2, (wire - 1) * 0.53}
Rotation: {0, 0, math.atan((y1 - y0) / (x1 - x0)) - math.PI / 2}
Cylinder: {0.018, math.sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)), 6}
Rgb: iron
}
}
}
}
@tree Parent
template UtilityLine {
prop poles: i32 = 3
prop spacing: f32 = 8
for i in 0..poles {
PowerPole() { Position: {i * spacing, 0, 0} }
if i < poles - 1 {
PowerSpan(length: spacing) { Position: {i * spacing, 0, 0} }
}
}
}
@tree Parent
template Bench {
for i in 0..3 {
{
Position: {0, 0.46, (i - 1) * 0.16}
Box: {1.6, 0.09, 0.13}
Rgb: {171, 121, 80}
}
}
{
Position: {0, 0.81, -0.24}
Box: {1.6, 0.3, 0.09}
Rgb: {171, 121, 80}
}
for i in 0..2 {
{
Position: {(i - 0.5) * 1.15, 0.22, 0}
Box: {0.09, 0.44, 0.42}
Rgb: iron
}
}
}
@tree Parent
template Bollard {
prop radius: f32 = 0.075
prop height: f32 = 0.52
prop color: Rgb = iron
Cylinder: {radius, height, 10}
Rgb: color
}
@tree Parent
template TrafficCone {
{
Position: {}
Box: {0.38, 0.07, 0.38}
Rgb: iron
}
{
Position: {0, 0.24, 0}
Cone: {0.16, 0.48, 12}
Rgb: {231, 127, 88}
}
{
Position: {0, 0.23, 0}
Cylinder: {0.089, 0.07, 12}
Rgb: cream
}
}
@tree Parent
template Pavement {
{
Position: {}
Box: {6.4, 0.2, 6.4}
Rgb: {215, 210, 190}
}
for i in 0..8 {
{
Position: {(i - 3.5) * 0.8, 0.105, 2.83}
Box: {0.018, 0.012, 0.72}
Rgb: {177, 181, 165}
}
}
}
@tree Parent
template RoadMarkings {
prop rows: i32 = 3
prop columns: i32 = 3
const halfRows = (rows - 1) / 2.0
const halfColumns = (columns - 1) / 2.0
for road in 0..(rows + 1) {
for dash in 0..(columns * 4) {
{
Position: {(dash - (columns * 4 - 1) / 2.0) * 2, 0.048, (road - rows / 2.0) * 8}
Box: {0.85, 0.012, 0.055}
Rgb: cream
}
}
}
for road in 0..(columns + 1) {
for dash in 0..(rows * 4) {
{
Position: {(road - columns / 2.0) * 8, 0.048, (dash - (rows * 4 - 1) / 2.0) * 2}
Box: {0.055, 0.012, 0.85}
Rgb: cream
}
}
}
for row in 0..(rows - 1) {
for col in 0..(columns - 1) {
{
Position: {(col - halfColumns + 0.5) * 8 + 1.25, 0.052, (row - halfRows + 0.5) * 8}
for i in 0..5 {
{
Position: {0, 0, (i - 2) * 0.29}
Box: {0.65, 0.014, 0.16}
Rgb: cream
}
}
}
}
}
}
@tree Parent
template Town {
prop rows: i32 = 3
prop columns: i32 = 3
prop seed: u64 = 42
const halfRows = (rows - 1) / 2.0
const halfColumns = (columns - 1) / 2.0
const middleRow: i32 = (rows - 1) / 2
const middleColumn: i32 = (columns - 1) / 2
const facades = [TimberFacade, StuccoFacade, ShutterFacade, LatticeFacade, BayFacade]
const roofs = [TiledRoof, TiledRoof, FlatRoof, ShedRoof, DormerRoof, GardenRoof]
const sage: Rgb = {183, 207, 185}
const peach: Rgb = {239, 203, 178}
const blue: Rgb = {188, 211, 214}
const rose: Rgb = {227, 192, 190}
const plaster: Rgb = {237, 224, 199}
const red: Rgb = {181, 81, 72}
const teal: Rgb = {77, 139, 136}
const ochre: Rgb = {186, 142, 75}
const plum: Rgb = {135, 105, 128}
const patina: Rgb = {99, 132, 127}
const clay: Rgb = {141, 106, 93}
const walls = [cream, sage, peach, blue, rose, plaster]
const accents = [red, teal, ochre, plum]
const roofColors = [roofTile, roofTile, patina, clay]
const floorCounts = [1, 2, 2, 2, 2, 3]
base {
Position: {0, -0.42, 0}
Box: {columns * 8 + 2, 0.8, rows * 8 + 2}
Rgb: {170, 190, 168}
}
asphalt {
Position: {0, 0, 0}
Box: {columns * 8 + 1.5, 0.08, rows * 8 + 1.5}
Rgb: {101, 112, 115}
}
for row in 0..rows {
for col in 0..columns {
"lot_{row}_{col}" {
Position: {(col - halfColumns) * 8, 0.12, (row - halfRows) * 8}
Pavement() { Position: {} }
const rng: math.Rng = {seed: seed + row * 92821 + col * 68917}
const facadeKind = facades[rng.u(5)]
const roofKind = roofs[rng.u(6)]
const wallColor = walls[rng.u(6)]
const shopColor = accents[rng.u(4)]
const tileColor = roofColors[rng.u(4)]
const floors = floorCounts[rng.u(6)]
const width = 3.7 + rng.f(0.7)
const depth = 3.6 + rng.f(0.6)
const shop = rng.u(5) != 0
Building building(facade: facadeKind, roof: roofKind, floors: floors,
width: width, depth: depth, color: wallColor, accent: shopColor,
roofColor: tileColor, shop: shop) {
Position: {-0.3, 0.1, -0.35}
}
VendingMachine(color: accents[rng.u(4)]) { Position: {2.45, 0.1, 1.6} }
Planter() { Position: {2.52, 0.1, 2.45} }
CherryTree() { Position: {2.35, 0.1, -2.35} }
}
}
}
RoadMarkings markings(rows: rows, columns: columns) { Position: {} }
for row in 0..rows {
UtilityLine(poles: columns) {
Position: {-halfColumns * 8 - 2.85, 0.22, (row - halfRows) * 8 + 2.8}
}
}
for col in 0..columns {
if col % 2 == 0 {
Bench() { Position: {(col - halfColumns) * 8, 0.22, halfRows * 8 + 2.7} }
}
}
for i in 0..3 {
Bollard() {
Position: {(middleColumn - halfColumns) * 8 - 1 + i, 0.46, halfRows * 8 + 3.08}
}
}
for i in 0..2 {
TrafficCone() {
Position: {halfColumns * 8 + 3.15, 0.2, (middleRow - halfRows) * 8 - 0.5 + i * 0.8}
}
}
}
Town sakura_machi(rows: 3, columns: 3, seed: 42)