render3d: ground_fill_golden.json is valid JSON (the cover and solid blocks each closed one brace too many)
gg_cover_json and gg_solid_json ended in plain strings with "}}", which only a template literal reads as one brace: the cover's closed the top-level object before "solid", and the solid's left a stray "}" at the end. The committed golden is fixed by hand to what the generator now writes. ground_fill_test also checks the golden as JSON: one value with nothing after it (Json.parse reads the first value and ignores the rest, so it alone would not have caught this), an object, its eleven sections in order. The generator notes what the studio asked: past the density patch an empty tile reads 0 for R and G (only past the map's edge does a texel clamp), and several clearings multiply. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
176dc79b49
commit
7918103b8b
5 changed files with 58 additions and 4 deletions
|
|
@ -19,3 +19,47 @@ function gft_subset(render3d_st: Render3dState, n: int, l: GroundSolids) -> int
|
||||||
}
|
}
|
||||||
return bad
|
return bad
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# whether s is one JSON value with only whitespace after it: every bracket closed by its own kind, strings
|
||||||
|
# skipped (Json.parse reads the first value and ignores the rest, which is how a stray brace went unseen)
|
||||||
|
function gft_json_whole(s: string) -> bool {
|
||||||
|
let want = new []int
|
||||||
|
var in_str = false
|
||||||
|
var done = false
|
||||||
|
var k = 0
|
||||||
|
while k < Text.length(s) {
|
||||||
|
let c = Text.char_at(s, k)
|
||||||
|
k += 1
|
||||||
|
if in_str {
|
||||||
|
if c == 92 { k += 1 } else if c == 34 { in_str = false }
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if c == 32 or c == 9 or c == 10 or c == 13 { continue }
|
||||||
|
if done { return false }
|
||||||
|
if c == 34 { in_str = true }
|
||||||
|
else if c == 123 { push(want, 125) }
|
||||||
|
else if c == 91 { push(want, 93) }
|
||||||
|
else if c == 125 or c == 93 {
|
||||||
|
if len(want) == 0 or List.pop(want) != c { return false }
|
||||||
|
done = len(want) == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return done and not in_str
|
||||||
|
}
|
||||||
|
|
||||||
|
# what is wrong with the golden's text as JSON, "" when nothing: whole, an object, its sections in order
|
||||||
|
function gft_golden_fault(text: string) -> string {
|
||||||
|
if text == null { return "the golden could not be read" }
|
||||||
|
if not gft_json_whole(text) { return "not one JSON value with nothing after it" }
|
||||||
|
let v = Json.parse(text)
|
||||||
|
if v == null or Value.kind(v) != 6 { return "not a JSON object" }
|
||||||
|
let keys = ["about", "numbers", "lerp_order", "lerp", "yaw", "hash", "density", "clearings_rule", "clearings", "cover", "solid"]
|
||||||
|
var fault = ""
|
||||||
|
if Value.count(v) != len(keys) { fault = `{Value.count(v)} sections, not {len(keys)}` }
|
||||||
|
for k in 0 .. min(Value.count(v), len(keys)) {
|
||||||
|
if fault == "" and Value.key_at(v, k) != keys[k] { fault = `section {k} is {Value.key_at(v, k)}, not {keys[k]}` }
|
||||||
|
}
|
||||||
|
if fault == "" and Value.count(Value.get(Value.get(v, "solid"), "things")) < 8 { fault = "the solid layer lost its things" }
|
||||||
|
Json.free_all(v)
|
||||||
|
return fault
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ function gg_cover_json(render3d_st: mut Render3dState) -> string {
|
||||||
s = s + ` [{c.cell}, {gg_thing(c)}]`
|
s = s + ` [{c.cell}, {gg_thing(c)}]`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s + "\n ]}},\n"
|
return s + "\n ]},\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
# the solid layer's things: [id, cell, x, z, scale, yaw, seed, wind, drawn at band 2]
|
# the solid layer's things: [id, cell, x, z, scale, yaw, seed, wind, drawn at band 2]
|
||||||
|
|
@ -53,7 +53,7 @@ function gg_solid_json(render3d_st: mut Render3dState) -> string {
|
||||||
if k > 0 { s = s + ",\n" }
|
if k > 0 { s = s + ",\n" }
|
||||||
s = s + ` [{c.id}, {c.cell}, {gg_thing(c)}, {far}]`
|
s = s + ` [{c.id}, {c.cell}, {gg_thing(c)}, {far}]`
|
||||||
}
|
}
|
||||||
return s + "\n ]}}\n"
|
return s + "\n ]}\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
# the whole golden, as ground_fill_golden.json holds it
|
# the whole golden, as ground_fill_golden.json holds it
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,12 @@
|
||||||
# gen/ground_fill_golden.ludic - writes tests/ground_fill_golden.json from what ground_fill grows today. Run it
|
# gen/ground_fill_golden.ludic - writes tests/ground_fill_golden.json from what ground_fill grows today. Run it
|
||||||
# from the repository root after a deliberate change to the fill, and commit the file with the change.
|
# from the repository root after a deliberate change to the fill, and commit the file with the change.
|
||||||
import "ludic.render3d/r3d.ludic"
|
import "ludic.render3d/r3d.ludic"
|
||||||
|
|
||||||
|
# Past the patch (tx0 .. tx0 + w - 1, all the chunk reads) an empty tile reads 0 for R and G, never its neighbour;
|
||||||
|
# only a texel past the map's edge clamps to the edge texel (gd_texel, gd_fill), and a missing channel reads 128.
|
||||||
|
|
||||||
|
# Several clearings MULTIPLY (ground_clear_at), in the order handed over: each floor..1, 1 past r_out, floor
|
||||||
|
# clamped to 0..1, at most GD_CLEAR_MAX (32); a layer with trample multiplies its chance by the product.
|
||||||
program GroundFillGolden {
|
program GroundFillGolden {
|
||||||
numbers float
|
numbers float
|
||||||
import "../fakes/ground_golden.ludic"
|
import "../fakes/ground_golden.ludic"
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@
|
||||||
[196620, 1121118525, -1040010303, 1061322280, 1077929596, 1052826214, 1064042924],
|
[196620, 1121118525, -1040010303, 1061322280, 1077929596, 1052826214, 1064042924],
|
||||||
[589836, 1123092738, -1039727871, 1068558543, 1084332302, 1049315840, 1057920874],
|
[589836, 1123092738, -1039727871, 1068558543, 1084332302, 1049315840, 1057920874],
|
||||||
[655372, 1123240528, -1039705474, 1068208532, 1086445325, 1062070265, 1061650604]
|
[655372, 1123240528, -1039705474, 1068208532, 1086445325, 1062070265, 1061650604]
|
||||||
]}},
|
]},
|
||||||
"solid": {"fill": {"layer": 0, "steps": [1082130432, 1084227584, 1090519040, 1094713344], "jitter": 1061997773, "scale_lo": 1061997773, "scale_hi": 1070386381, "wind_lo": 1056964608, "wind_hi": 1065353216, "scale_var": 1045220557, "band_grow": 1050253722, "sink": 1022739087, "trample": 0, "solid": 1}, "ox": 0, "oz": 0, "size": 1107296256, "cx": 3, "cz": -2, "far_band": 2, "things": [
|
"solid": {"fill": {"layer": 0, "steps": [1082130432, 1084227584, 1090519040, 1094713344], "jitter": 1061997773, "scale_lo": 1061997773, "scale_hi": 1070386381, "wind_lo": 1056964608, "wind_hi": 1065353216, "scale_var": 1045220557, "band_grow": 1050253722, "sink": 1022739087, "trample": 0, "solid": 1}, "ox": 0, "oz": 0, "size": 1107296256, "cx": 3, "cz": -2, "far_band": 2, "things": [
|
||||||
[16582144, 0, 1120293028, -1032252411, 1068709886, 1085262221, 1065248692, 1058250104, 0],
|
[16582144, 0, 1120293028, -1032252411, 1068709886, 1085262221, 1065248692, 1058250104, 0],
|
||||||
[16582176, 262144, 1122044225, -1032619009, 1070248319, 1073719313, 1064173498, 1063466348, 1],
|
[16582176, 262144, 1122044225, -1032619009, 1070248319, 1073719313, 1064173498, 1063466348, 1],
|
||||||
|
|
@ -131,5 +131,5 @@
|
||||||
[16582175, 196615, 1121761085, -1039599090, 1067374368, 1067261885, 1058627350, 1062771573, 0],
|
[16582175, 196615, 1121761085, -1039599090, 1067374368, 1067261885, 1058627350, 1062771573, 0],
|
||||||
[16582191, 327687, 1122751322, -1039341503, 1069678485, 1068499230, 1053671156, 1059624745, 0],
|
[16582191, 327687, 1122751322, -1039341503, 1069678485, 1068499230, 1053671156, 1059624745, 0],
|
||||||
[16582199, 393223, 1123213029, -1039687681, 1071554254, 1053024656, 1029041920, 1063208826, 1]
|
[16582199, 393223, 1123213029, -1039687681, 1071554254, 1053024656, 1029041920, 1063208826, 1]
|
||||||
]}}
|
]}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,10 @@ program GroundFillTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "the golden is one JSON object, every section in it and nothing after it" {
|
||||||
|
expect_eq(gft_golden_fault(Fs.read_text("packages/ludic.render3d/tests/ground_fill_golden.json")), "")
|
||||||
|
}
|
||||||
|
|
||||||
test "Math.lerp is a + (b - a) * t" {
|
test "Math.lerp is a + (b - a) * t" {
|
||||||
let a = [1.0, 2.0, 6.04, -2.19]
|
let a = [1.0, 2.0, 6.04, -2.19]
|
||||||
let b = [1.7, 7.0, 1.72, 3.62]
|
let b = [1.7, 7.0, 1.72, 3.62]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue