-- Focused Lua 5.1+ policy/registration tests; siblings also work flattened. local target=assert(arg[1],"diversity.lua path required") local passed=0 local api,hearth,D,season,world,fields,claims,protected,missing,lbms,writes local p={x=0,y=1,z=0} local function key(q) return q.x..":"..q.y..":"..q.z end local function meta(q) local k=key(q); fields[k]=fields[k] or {}; local f=fields[k] return {get_string=function(_,n) return f[n] or "" end, set_string=function(_,n,v) writes=writes+1; f[n]=tostring(v) end, to_table=function() return {fields=f} end} end local function reset() season,world,fields,claims,protected,missing,lbms,writes="Summer",{},{},{},{},{},{},0 api={registered_nodes={}} function api.get_meta(q) return meta(q) end function api.get_node_or_nil(q) if missing[key(q)] then return nil end return world[key(q)] or {name=q.y==0 and "hearth:grass" or "air"} end function api.swap_node(q,n) world[key(q)]=n end function api.register_node(n,def) assert(not api.registered_nodes[n],n); api.registered_nodes[n]=def end function api.register_lbm(def) lbms[def.name]=def end hearth={climate_at=function() return {season=season} end, claim_owner_at=function(q) return claims[key(q)] and "owner",claims.ambiguous end, claim_allowed=function() error("nature must not call claim_allowed") end, external_protected=function(q) return protected[key(q)] end} hearth.seasons=dofile(target:gsub("[^/\\]+$","seasons.lua"))(hearth,api) D=dofile(target)(hearth,api); hearth.diversity=D end local function test(label,fn) reset(); local ok,err=pcall(fn); assert(ok,label..": "..tostring(err)) passed=passed+1; print("ok "..passed.." - "..label) end local function habitat(ground,light,moisture) return {ground=ground,light=light or 15,moisture=moisture or 0.5,canopy=0,loaded=true,nutrients=2,heat=20} end local function register() D.register_nodes(function(n,def) api.register_node("hearth:"..n,def) end) for _,s in ipairs(D.species_order) do api.register_node("hearth:"..s.."_leaves",{tiles={"hearth_"..s.."_leaves.png"},groups={leaves=1},drop="hearth:sticks"}) end hearth.seasons.register() end test("exact thirteen species and eight legacy understory plants have cube trunks and sprite seedlings",function() register() assert(table.concat(D.species_order,",")=="oak,birch,pine,willow,alder,beech,aspen,rowan,hazel,spruce,crab_apple,wild_cherry,field_maple") assert(#D.plants==8) for _,s in ipairs(D.species_order) do for _,stage in ipairs({"seedling","young","mature"}) do local k=s.."_"..stage; local def=assert(api.registered_nodes["hearth:"..k]) assert(not def.mesh and not def.selection_box and not def.collision_box) if stage=="seedling" then assert(def.drawtype=="plantlike" and def.tiles[1]=="hearth_botany_"..s..".png") else assert(def.drawtype=="normal" and def.paramtype2=="facedir" and def.walkable) assert(def.tiles[1]=="hearth_"..s.."_log_top.png" and def.tiles[2]==def.tiles[1]) assert(def.tiles[3]=="hearth_"..s.."_log_side.png" and #def.tiles==3) assert(def.groups.tree==1 and def.groups.choppy==2 and not def.groups.snappy) assert(def.groups.not_in_creative_inventory==1 and not def.sunlight_propagates) end assert(def.groups.hearth_ecosystem==1 and not def.buildable_to) local a,b=D.tree_info(k); assert(a==s and b==stage) assert(D.family(k)==({seedling="tree_seedling",young="young_tree",mature="mature_tree"})[stage]) if stage~="seedling" then assert(def.drop=="hearth:"..s.."_log") end end end for _,k in ipairs(D.plants) do local def=assert(api.registered_nodes["hearth:"..k]); assert(def.tiles[1]=="hearth_"..k..".png" and def.drop=="") end assert(not D.tree_info("hearth:pine_log") and D.family("hearth:pine_leaves")=="leaves") assert(D.family("hearth:willow_log")=="log" and not D.is_worldgen_flora("hearth:oak_leaves")) end) test("seasonal foliage changes never replace bark with atlases or meshes; both conifers stay evergreen",function() register() for _,s in ipairs(D.species_order) do for _,stage in ipairs({"seedling","young","mature","leaves"}) do for _,time in ipairs({"Spring","Autumn","Winter"}) do season=time; local k=s.."_"..stage local name=hearth.seasons.name_for(k) assert(hearth.seasons.kind(name)==k) if s=="pine" or s=="spruce" then assert(name=="hearth:"..k and not api.registered_nodes[name.."_winter"]) assert(hearth.seasons.available(k)) elseif stage=="young" or stage=="mature" then assert(name=="hearth:"..k.."_"..time:lower()) assert(api.registered_nodes[name].tiles[1]=="hearth_"..s.."_log_top.png") assert(api.registered_nodes[name].tiles[3]=="hearth_"..s.."_log_side.png" and not api.registered_nodes[name].mesh) assert(hearth.seasons.available(k)==(time~="Winter")) else local def=assert(api.registered_nodes[name]) assert(def.tiles[1]==(stage=="leaves" and "hearth_"..s.."_leaves_"..time:lower()..".png" or "hearth_botany_"..s..".png")) assert(not def.mesh) end end end end end) test("all ten species can recruit deterministically on their supported habitat",function() local found={} for x=0,30 do for z=0,10 do for _,g in ipairs({"grass","forest_floor","podzol","alpine_turf","alluvium","peat"}) do for _,m in ipairs({0.4,0.6,0.9}) do local h=habitat(g,10,m); h.canopy=g=="forest_floor" and 1 or 0 local q={x=x,y=1,z=z}; local k=D.choose_tree(q,h) if k then local s=D.tree_info(k); found[s]=true assert(D.suitable(k,h) and D.choose_tree(q,h)==k) end end end end end for _,s in ipairs(D.species_order) do assert(found[s],s) end end) test("tree plans share mapgen geometry with a canonical rooted identity and no world writes",function() assert(not D.tree_plan("oak","mature")) -- missing biome integration fails closed hearth.biomes=dofile(target:gsub("[^/\\]+$","biomes.lua"))(hearth,api,function() error("unexpected registration") end,{}) local before=writes for _,s in ipairs(D.species_order) do for _,stage in ipairs({"young","mature"}) do local plan=assert(D.tree_plan(s,stage)); local schematic=hearth.biomes.tree_schematic(s,false,stage) assert(plan.size.x==schematic.size.x and plan.size.y==schematic.size.y and #plan>5) local roots,leaves,trunks=0,0,0 local cx,cz=math.floor(plan.size.x/2),math.floor(plan.size.z/2) for _,n in ipairs(plan) do assert(n.name~="air" and n.param2==0) local cell=schematic.data[1+n.x+cx+plan.size.x*(n.y+plan.size.y*(n.z+cz))] if n.x==0 and n.y==0 and n.z==0 then roots=roots+1; assert(n.name=="hearth:"..s.."_"..stage) else assert(n.name==cell.name and cell.prob==255) end if n.name:match("_leaves$") then leaves=leaves+1 else trunks=trunks+1 end end assert(roots==1 and leaves>=5 and trunks>=3) plan[1].name="foreign:node"; plan.size.x=999 assert(D.tree_plan(s,stage)[1].name~="foreign:node" and D.tree_plan(s,stage).size.x<10) end end local generic=D.tree_plan("generic","mature"); local root for _,n in ipairs(generic) do if n.x==0 and n.y==0 and n.z==0 then root=n.name end end assert(root=="hearth:mature_tree" and writes==before) assert(not D.tree_plan("unknown","mature") and not D.tree_plan("oak","seedling")) end) test("tree recruitment uses soils, cold podzol, pioneer gaps, woodland and river niches",function() assert(D.choose_tree(p,habitat("podzol",15,0.4))=="pine_seedling") assert(D.choose_tree(p,habitat("alpine_turf",15,0.35))=="pine_seedling") local warm=habitat("podzol",15,0.4); warm.heat=60 assert(D.choose_tree(p,warm)=="birch_seedling") assert(D.choose_tree(p,habitat("grass",15,0.3))=="birch_seedling") local forest=habitat("forest_floor",10,0.6); forest.canopy=1 assert(D.choose_tree(p,forest)=="oak_seedling") assert(D.choose_tree(p,habitat("alluvium",12,0.9))=="willow_seedling") assert(D.choose_tree(p,habitat("peat",12,0.9))=="alder_seedling") assert(not D.choose_tree(p,habitat("stone",15,0.1))) end) test("optional biome species policy is authoritative without requiring the biome module",function() hearth.biomes={supports_species=function(s,ground) return s=="alder" and ground=="grass" end} assert(not D.supports_species("oak","grass")) assert(D.supports_species("alder","grass")) assert(not D.choose_tree(p,habitat("podzol",15,0.4))) end) test("all eight understory niches recruit deterministically on the first establishment cycle",function() local cases={clover={habitat("grass",15,0.5),{x=3,y=1,z=0},"Summer"}, nettle={habitat("grass",15,0.6),{x=6,y=1,z=0},"Summer"}, heather={habitat("podzol",15,0.4),p,"Summer"}, bluebell={habitat("forest_floor",8,0.6),p,"Spring"}, sedge={habitat("alluvium",15,0.9),p,"Summer"}, bulrush={habitat("peat",15,0.9),{x=3,y=1,z=0},"Summer"}, moss={habitat("forest_floor",8,0.7),p,"Summer"}, lichen={habitat("granite",15,0.1),p,"Summer"}} for k,c in pairs(cases) do season=c[3]; local recruit=D.choose_recruit(c[2],c[1],season) assert(recruit==k,k.." got "..tostring(recruit)) assert(D.choose_recruit(c[2],c[1],season)==recruit) assert(not D.choose_recruit(c[2],c[1],"Winter")) end assert(not D.suitable("clover",habitat("peat",15,1))) assert(not D.suitable("heather",habitat("forest_floor",15,0.4))) assert(not D.suitable("nettle",{ground="grass",light=12,moisture=0.6,nutrients=0})) end) test("dormancy gates herbivore food and spring bluebells while pollination is exposed",function() register(); season="Spring" assert(D.edible("hearth:clover") and D.edible("hearth:sedge")) assert(not D.edible("hearth:bluebell") and D.pollinator("bluebell",season)) for _,s in ipairs({"Summer","Autumn","Winter"}) do season=s; assert(not hearth.seasons.available("bluebell")) assert(api.registered_nodes[hearth.seasons.name_for("bluebell")].tiles[1]=="hearth_bluebell_dormant.png") end assert(not D.edible("hearth:clover_winter") and not D.edible("hearth:sedge_winter")) assert(hearth.seasons.available("moss") and hearth.seasons.available("lichen")) assert(not D.pollinator("bluebell","Summer") and D.pollinator("heather","Autumn")) end) test("load bootstrap and scheduler adoption mark only known unmodified species flora",function() register(); world[key(p)]={name="hearth:alder_seedling"} assert(D.bootstrap(p) and meta(p):get_string("succ_natural")=="1") local before=writes; assert(not D.bootstrap(p) and writes==before) for _,k in ipairs({"oak_log","oak_leaves","log","leaves","wall","berry_bush"}) do fields={}; world[key(p)]={name="hearth:"..k}; assert(not D.bootstrap(p),k) end fields={}; world[key(p)]={name="hearth:clover"} lbms["hearth:diversity_natural_flora"].action(p,world[key(p)]) assert(meta(p):get_string("succ_natural")=="1") end) test("player markers, claims, ambiguity, support protection and unload prevent adoption",function() register() for _,field in ipairs({"owner","planter","player_placed","placed_by","planted_at","third_party:placed"}) do fields={}; world[key(p)]={name="hearth:oak_mature"}; meta(p):set_string(field,"1") local before=writes; assert(not D.bootstrap(p) and writes==before,field) end for _,mode in ipairs({"claim","ambiguous","protected","support","unloaded"}) do reset(); world[key(p)]={name="hearth:clover"} if mode=="claim" then claims[key(p)]=true end if mode=="ambiguous" then claims.ambiguous=true end if mode=="protected" then protected[key(p)]=true end if mode=="support" then protected["0:0:0"]=true end if mode=="unloaded" then missing["0:0:0"]=true end assert(not D.bootstrap(p) and writes==0,mode) end reset(); register(); world[key(p)]={name="hearth:clover"} api.registered_nodes["hearth:clover"].after_place_node(p) assert(not D.bootstrap(p) and meta(p):get_string("player_placed")=="1") end) test("deadwood load adoption is idempotent and does not broaden generic flora policy",function() register(); world[key(p)]={name="hearth:deadwood",param2=2} local loader=lbms["hearth:diversity_natural_flora"] local count=0 for _,n in ipairs(loader.nodenames) do if n=="hearth:deadwood" then count=count+1 end end assert(count==1 and loader.run_at_every_load) loader.action(p,world[key(p)]) assert(meta(p):get_string("succ_natural")=="1" and writes==1) loader.action(p,world[key(p)]); assert(writes==1) assert(world[key(p)].name=="hearth:deadwood" and world[key(p)].param2==2) assert(meta(p):get_string("succ_age")=="") for _,k in ipairs({"litter","fungi","log","oak_log","leaves","oak_leaves","planks"}) do fields={}; world[key(p)]={name="hearth:"..k} local before=writes; assert(not D.bootstrap(p) and writes==before,k) end end) test("deadwood adoption fails closed for source and support provenance, authority, identity and unload",function() local below={x=0,y=0,z=0} for _,q in ipairs({p,below}) do for _,mode in ipairs({"owner","planter","placed_by","player_placed","hearth_placed","hearth_player_placed","planted_at","third_party:placed", "claim","ambiguous","protected","unloaded","ignore"}) do reset(); world[key(p)]={name="hearth:deadwood"} if mode=="claim" then claims[key(q)]=true elseif mode=="ambiguous" then claims.ambiguous=true elseif mode=="protected" then protected[key(q)]=true elseif mode=="unloaded" then missing[key(q)]=true elseif mode=="ignore" then world[key(q)]={name="ignore"} else meta(q):set_string(mode,"1") end local before=writes assert(not D.bootstrap(p) and writes==before,mode.." at "..key(q)) end end for _,support in ipairs({"air","hearth:stone","hearth:log","hearth:water_source"}) do reset(); world[key(p)]={name="hearth:deadwood"}; world[key(below)]={name=support} assert(not D.bootstrap(p) and writes==0,support) end reset(); world[key(p)]={name="air"} assert(not D.bootstrap(p,{name="hearth:deadwood"}) and writes==0) end) test("ground policy is separate from crops and lichen never needs to replace its rock",function() for _,k in ipairs({"grass","soil","forest_floor","podzol","alluvium","peat","alpine_turf"}) do assert(D.is_ground("hearth:"..k)) end assert(not D.is_ground("hearth:granite") and D.is_rock("hearth:granite")) assert(not D.supports_ground("clover","hearth:granite")) assert(D.supports_ground("lichen","hearth:granite")) assert(not D.is_ground("hearth:crop_4") and not D.is_ground("ignore")) end) test("optional missing bases do not panic seasonal registration or install a scheduler",function() local steps=0; api.register_globalstep=function() steps=steps+1 end hearth.seasons.register() assert(steps==0) D.register_nodes(function(n,def) api.register_node("hearth:"..n,def) end) hearth.seasons.register() assert(api.registered_nodes["hearth:oak_seedling_winter"] and api.registered_nodes["hearth:oak_mature"].drawtype=="normal" and steps==0) end) test("bootstrap rechecks loaded source identity and explicit recruitment season wins over clock",function() world[key(p)]={name="air"} assert(not D.bootstrap(p,{name="hearth:clover"}) and writes==0) world[key(p)]={name="hearth:clover"}; missing[key(p)]=true assert(not D.bootstrap(p,{name="hearth:clover"}) and writes==0) for _,bad in ipairs({{}, {x=0/0,y=1,z=0},{x=math.huge,y=1,z=0}}) do assert(not D.bootstrap(bad)) end season="Winter" assert(D.choose_recruit(p,habitat("forest_floor",8,0.6),"Spring")=="bluebell") end) print("LAST_HEARTH_DIVERSITY_PASS "..passed)