code wiki / _hdl_build / nx_m2d_engine.nx

nx_m2d_engine.nx

buildroot/runtime/_hdl_build/nx_m2d_engine.nx

56854 B1167 linesdepth 5pulls 26 transitivereach 0 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_m2d_engine.nx -- M2D "NISHI GLADE": the first TIER-1 game of the approved program plan (2026-07-26, plans/temporal-meandering-moore.md rung 1) -- a top-down action-adventure in the Steam-volume-floor class, COMPOSED ENTIRELY FROM CERTIFIED PARTS, zero re-authored game systems: nx_worldpipe the staged six-parameter overworld (biomes/heights/surface colours) nx_procgen the dungeon maze (pg_maze, flood-verified connectivity) nx_pathfind enemy chase (pf_astar on the live maze grid) nx_creature_battle combat resolution (typed moves, cb_damage/cb_best) nx_rpgstats xp curve + derived hp (order-independent, saturating) nx_loottable kill drops (weighted tiers, 0-dup law) nx_wardrobe_state the adult invariant, FAIL-CLOSED BY CONSTRUCTION (age<18 refuse) nx_input_abstract every policy drives the loop through SEMANTIC ACTIONS (device-independent) nx_gamesave bit-exact mid-run save/load (transparency proof) nx_game_raster the rendered frame; scored by nx_game_critic the hardened visual critic (anti-noise, coherence-capped) PROOF BATTERY (the M1/frontier standard -- a battery that cannot pass a hollow game): P1 WINNABLE the cautious policy grinds, heals, then takes the warden -> WIN P2 LOSABLE the reckless policy rushes the warden under-levelled -> DIES (real stakes) P3 DETERMINISTIC two P1 replays produce bit-identical frame chains P4 SAVE-TRANSPARENT save mid-run, load, continue -> same final chain as the unbroken run P5 ADULT-GATE HOLDS the spring event tries to expose a gated zone: adult proceeds, a minor is REFUSED with state bit-identical -- the invariant holds THROUGH the whole game loop P6 DEPTH the two policies genuinely diverge (win vs death) AND each replays identically -- outcome differences are STRATEGY, not luck (the hardened nx_game_depth principle) P7 QUALITY the rendered frame clears the critic's TOY line; score published, never inflated. Emits its frame as knowledge/nx_m2d_frame.nxfh (the ecosystem's text-hex format) so nx_frame_score can re-grade it over MCP -- the same instrument that grades the reference titles. license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0

dependencies 14 imports · 0 importers

nx_syscalls.nx nx_worldpipe.nx nx_procgen.nx nx_pathfind.nx nx_creature_battle.nx nx_rpgstats.nx nx_loottable.nx nx_wardrobe_state.nx nx_input_abstract_part.nx nx_gamesave.nx nx_m2d_engine.nx

diagram shows first 10 each side; +4 more imports, +0 more importers in the complete lists below.

imports: nx_syscalls.nxnx_worldpipe.nxnx_procgen.nxnx_pathfind.nxnx_creature_battle.nxnx_rpgstats.nxnx_loottable.nxnx_wardrobe_state.nxnx_input_abstract_part.nxnx_gamesave.nxnx_game_raster.nxnx_game_critic.nxnx_game_engine_lib.nxnx_png.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main sys_mmap nxa_die sys_write sys_exit nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ ocat onum sys_mmap ↻ hexd sys_openat_wr sys_write ↻ sys_fsync sys_close tm_hash3 rlf_hash3 write_png png_publish png_buf_cap sys_mmap_try write_png_buf png_buf_cap ↻ write_png_buf_checked png_buf_cap ↻ sys_mmap_try ↻ sys_munmap_direct png_g png_paeth png_sabs dfe_compress

structs

none

consts

42const MD_MAGIC_65536: i64 = 65536
43const MD_MAGIC_4096: i64 = 4096
53const MD_DW: i64 = 15 // dungeon maze width (odd, pg_maze contract)
54const MD_DH: i64 = 9
55const MD_SEED: i64 = 20260726
56const MD_WSCALE: i64 = 280 // world units per overworld tile fed to wp_*
58const MD_XP_BASE: i64 = 50
59const MD_XP_QUAD: i64 = 30
60const MD_CON: i64 = 10
61const MD_HPB: i64 = 20
62const MD_HPCON: i64 = 2
63const MD_HPLVL: i64 = 6
65const MD_F_PX: i64 = 0
66const MD_F_PY: i64 = 1
67const MD_F_HP: i64 = 2
68const MD_F_XP: i64 = 3
69const MD_F_POT: i64 = 4 // potions held
70const MD_F_SHARD: i64 = 5 // key shards (3 open the warden door)
71const MD_F_KILLS: i64 = 6
72const MD_F_TICK: i64 = 7
73const MD_F_CK: i64 = 8 // rolling frame chain
74const MD_F_OVER: i64 = 9 // 0 running, 1 WIN, 2 DEAD
75const MD_O_WARD: i64 = 10 // wardrobe vector [10..20) (WS_LEN=10)
76const MD_O_ENHP: i64 = 20 // enemy hp x4 (3 lurkers + warden) [20..24)
77const MD_O_ENX: i64 = 24 // enemy x x4
78const MD_O_ENY: i64 = 28 // enemy y x4
79const MD_NSV: i64 = 32
80const MD_SCHEMA: i64 = 2026
81const MD_SAVEAT: i64 = 1785100000
82const MD_CKM: i64 = 4611686018427387903
83const MD_TRBUF: i64 = 8192
84const MD_TRTICKS: i64 = 16
85const MD_PTYPE: i64 = 3 // player is GRASS: counters the Water warden (eff 4 out, 1 in) -- chart-read, not guessed
86const MD_TICKS: i64 = 96
87const MD_HEAL_AT: i64 = 40 // measured: entering the Fire-lurker fight at 32hp was lethal; heal FIRST
88const MD_SNARE_B: i64 = 4 // the den snare: (MD_SNARE_B - level) * MD_SNARE_L opening damage, floor 0.
89const MD_SNARE_L: i64 = 18 // measured: chase-intercept XP let a rusher shrug the old snare; level 4 = earned
90const MD_CK_PRIME: i64 = 16777619
91const MD_CK_SEED: i64 = 2166136261
92const MD_FAR: i64 = 1000000 // a LEVEL CHECK as a game rule -- rushing under-levelled is fatal by design

functions

94func md_mix(ck: i64, v: i64) -> i64 {
called by 1: md_fold
102func md_fold(s: *i64) -> i64 {
called by 2: md_stepmd_init calls 1: md_mix
110func md_level(s: *i64) -> i64 { return rs_level_for_xp(s[MD_F_XP], MD_XP_BASE, MD_XP_QUAD) }
111func md_maxhp(s: *i64) -> i64 { return rs_derived_hp(MD_CON, md_level(s), MD_HPB, MD_HPCON, MD_HPLVL) }
114func md_mkfoe(c: *i64, idx: i64, lvl: i64) -> i64 {
called by 1: md_battle calls 2: cb_setcb_addmove
128func md_battle(s: *i64, foe: i64, brng: *i64) -> i64 {
174func md_step(s: *i64, grid: *i64, act: i64, brng: *i64) -> i64 {
235func md_init(s: *i64, grid: *i64, age: i64) -> i64 {
271func md_target(s: *i64, policy: i64) -> i64 {
called by 1: md_run
288func md_run(s: *i64, grid: *i64, policy: i64, age: i64) -> i64 {
337func md_mat(seed: i64, out: *i64) -> i64
called by 1: md_render calls 1: tm_hash3
364func md_spr(fb: *i64, W: i64, H: i64, cx: i64, cy: i64, kind: i64) -> i64
called by 1: md_render calls 3: gr_discgr_packgr_rect
386func md_render(s: *i64, grid: *i64, fb: *i64, W: i64, H: i64) -> i64 {
595func ocat(o: *u8, at: i64, s: *u8) -> i64 { var i: i64=0; var a: i64=at; while s[i]!=(0 as u8){o[a]=s[i]; a=a+1; i=i+1} return a }
called by 1: main
596func onum(o: *u8, at: i64, v: i64) -> i64 {
called by 1: main calls 1: sys_mmap
606func hexd(v: i64) -> i64 { if v < 10 { return 48+v } return 87+v }
called by 1: main
614func md_ansi_frame(s: *i64, grid: *i64, ob: *u8, off: *i64, plain: i64) -> i64 {
659func md_key_raw(ch: i64) -> i64 {
called by 1: md_play
667func md_play(grid: *i64, script: *u8) -> i64 {
716func main(argc: i64, argv: *i64) -> i64 {