diff --git a/packages/ludic.render3d/tests/fakes/ground_golden_check.ludic b/packages/ludic.render3d/tests/fakes/ground_golden_check.ludic index 289e95bb..a8c5cab5 100644 --- a/packages/ludic.render3d/tests/fakes/ground_golden_check.ludic +++ b/packages/ludic.render3d/tests/fakes/ground_golden_check.ludic @@ -19,3 +19,47 @@ function gft_subset(render3d_st: Render3dState, n: int, l: GroundSolids) -> int } 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 +} diff --git a/packages/ludic.render3d/tests/fakes/ground_golden_things.ludic b/packages/ludic.render3d/tests/fakes/ground_golden_things.ludic index 6e31d0a3..c7d3e3a5 100644 --- a/packages/ludic.render3d/tests/fakes/ground_golden_things.ludic +++ b/packages/ludic.render3d/tests/fakes/ground_golden_things.ludic @@ -37,7 +37,7 @@ function gg_cover_json(render3d_st: mut Render3dState) -> string { 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] @@ -53,7 +53,7 @@ function gg_solid_json(render3d_st: mut Render3dState) -> string { if k > 0 { s = s + ",\n" } 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 diff --git a/packages/ludic.render3d/tests/gen/ground_fill_golden.ludic b/packages/ludic.render3d/tests/gen/ground_fill_golden.ludic index 4a6941f0..10631f22 100644 --- a/packages/ludic.render3d/tests/gen/ground_fill_golden.ludic +++ b/packages/ludic.render3d/tests/gen/ground_fill_golden.ludic @@ -1,6 +1,12 @@ # 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. 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 { numbers float import "../fakes/ground_golden.ludic" diff --git a/packages/ludic.render3d/tests/ground_fill_golden.json b/packages/ludic.render3d/tests/ground_fill_golden.json index daf37581..836a2f3c 100644 --- a/packages/ludic.render3d/tests/ground_fill_golden.json +++ b/packages/ludic.render3d/tests/ground_fill_golden.json @@ -99,7 +99,7 @@ [196620, 1121118525, -1040010303, 1061322280, 1077929596, 1052826214, 1064042924], [589836, 1123092738, -1039727871, 1068558543, 1084332302, 1049315840, 1057920874], [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": [ [16582144, 0, 1120293028, -1032252411, 1068709886, 1085262221, 1065248692, 1058250104, 0], [16582176, 262144, 1122044225, -1032619009, 1070248319, 1073719313, 1064173498, 1063466348, 1], @@ -131,5 +131,5 @@ [16582175, 196615, 1121761085, -1039599090, 1067374368, 1067261885, 1058627350, 1062771573, 0], [16582191, 327687, 1122751322, -1039341503, 1069678485, 1068499230, 1053671156, 1059624745, 0], [16582199, 393223, 1123213029, -1039687681, 1071554254, 1053024656, 1029041920, 1063208826, 1] - ]}} + ]} } diff --git a/packages/ludic.render3d/tests/ground_fill_test.ludic b/packages/ludic.render3d/tests/ground_fill_test.ludic index ee749368..70b2fe25 100644 --- a/packages/ludic.render3d/tests/ground_fill_test.ludic +++ b/packages/ludic.render3d/tests/ground_fill_test.ludic @@ -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" { let a = [1.0, 2.0, 6.04, -2.19] let b = [1.7, 7.0, 1.72, 3.62]