code wiki / _hdl_build / nx_game_agent.nx
nx_game_agent.nx
buildroot/runtime/_hdl_build/nx_game_agent.nx
about
nx_game_agent.nx -- the NPC/enemy BRAIN (ws=game-interact rung 2; the Palworld wilds half).
A wild roams its home range, PERCEIVES the player (radius + genuine Bresenham LOS through the shared
wall grid), CHASES via the certified pf_astar (real routing -- proven in-gate against a maze that
jams a greedy chaser), ATTACKS when adjacent, FLEES when weak, and can SUBMIT (the breeders hook).
Design split (single-responsibility): the brain DECIDES and EMITS EVENTS; the game RESOLVES them
(battle, capture, dialogue). No resolution logic lives here.
Species behaviour numbers are DATA ROWS (aggro radius, flee threshold), never inline constants --
tuning a species touches data, not logic. All integer, per-actor seeded, deterministic. LIB, no main.
license_tier: ORIGINAL
dependencies 3 imports · 2 importers
imports: nx_syscalls.nxnx_game_actor.nxnx_pathfind.nx
imported by: nx_breeder_arena.nxnx_game_agent_gate.nx
structs
| none |
consts
| 15 | const AG_IDLE: i64 = 0 |
| 16 | const AG_PATROL: i64 = 1 |
| 17 | const AG_CHASE: i64 = 2 |
| 18 | const AG_ATTACK: i64 = 3 // adjacent this tick; event emitted, game resolves |
| 19 | const AG_FLEE: i64 = 4 |
| 20 | const AG_SUBMIT: i64 = 5 // out of the brain's hands (breeders lane owns it) |
| 21 | const AG_DEAD: i64 = 6 |
| 25 | const SP_STRIDE: i64 = 4 |
| 41 | const EV_STRIDE: i64 = 4 |
| 42 | const EV_ATTACK: i64 = 1 |
| 43 | const EV_SPOTTED: i64 = 2 // patrol->chase transition (the aggro moment; UI/audio hook) |
| 44 | const EV_LOST: i64 = 3 // chase->patrol (player escaped) |
| 45 | const EV_FLED: i64 = 4 // entered flee |
functions
| 26 | func ag_species_default(tbl: *i64) -> i64 |
| 35 | func ag_aggro(tbl: *i64, spec: i64) -> i64 { return tbl[spec*SP_STRIDE + 0] } called by 1: ag_tick |
| 36 | func ag_fleehp(tbl: *i64, spec: i64) -> i64 { return tbl[spec*SP_STRIDE + 1] } called by 1: ag_tick |
| 37 | func ag_patrolr(tbl: *i64, spec: i64) -> i64 { return tbl[spec*SP_STRIDE + 2] } called by 1: ag_step_patrol |
| 38 | func ag_speed(tbl: *i64, spec: i64) -> i64 { return tbl[spec*SP_STRIDE + 3] } called by 1: ag_tick |
| 46 | func ev_count(ev: *i64) -> i64 { return ev[0] } called by 1: main |
| 47 | func ev_push(ev: *i64, cap: i64, tick: i64, kind: i64, a: i64, t: i64) -> i64 called by 1: ag_tick |
| 57 | func ev_kind(ev: *i64, i: i64) -> i64 { return ev[1 + i*EV_STRIDE + 1] } called by 1: main |
| 58 | func ev_actor(ev: *i64, i: i64) -> i64 { return ev[1 + i*EV_STRIDE + 2] } |
| 59 | func ev_tick(ev: *i64, i: i64) -> i64 { return ev[1 + i*EV_STRIDE + 0] } |
| 62 | func ag_rng(ar: *i64, hnd: i64) -> i64 |
| 71 | func ag_step_toward(wd: *i64, ar: *i64, hnd: i64, tx: i64, ty: i64, out: *i64) -> i64 |
| 96 | func ag_scratch_words(w: i64, h: i64) -> i64 { return w*h*6 } |
| 100 | func ag_step_astar(wd: *i64, ar: *i64, hnd: i64, tx: i64, ty: i64, scr: *i64, out: *i64) -> i64 |
| 129 | func ag_step_patrol(wd: *i64, ar: *i64, hnd: i64, tbl: *i64, out: *i64) -> i64 |
| 153 | func ag_tick(wd: *i64, ar: *i64, hnd: i64, hplayer: i64, tbl: *i64, scr: *i64, |