code wiki / (root) / nx_aoi_grid.nx

nx_aoi_grid.nx

buildroot/runtime/nx_aoi_grid.nx

13809 B352 linesdepth 2pulls 2 transitivereach 0 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_aoi_grid.nx -- area-of-interest spatial grid for open-world culling. Per the Agar.io/Slither.io lesson (reverse-engineered protocols at ClitherProject + Diep.io / Krunker community wikis): the single biggest bandwidth saver for open-world multiplayer is to ONLY stream entities within the player's view radius. Naive "broadcast all entities to all players" scales as O(N^2) in players-times-entities; area-of-interest culling brings it to O(N * view_density). This primitive provides: - 2D cell-bucket grid over Q14-fixed-point world coordinates - insert / remove / query_radius operations - returns entity IDs within radius for a (player_x, player_z) query Use case: caller maintains an "entity table" keyed by entity ID; the grid is the spatial index that lets a per-player streamer ask "which entities should this player see?" 60 times per second. Bandwidth math (from genre-bench doc): Naive: 100 entities * 60 Hz * 30 B/entity = 180 KB/s -- 25x over the 7 KB/s dial-up ceiling. With AOI (20 in-view): 20 * 60 * 30 = 36 KB/s. Still over. With AOI + nx_state_delta_codec (4 B/entity typical): 20 * 60 * 4 = 4.8 KB/s. FITS UNDER 7 KB/s. Storage layout (i64 cells in flat block + raw bucket bytes): h[0] = cell_size_q14 (size of one cell side in Q14 metres) h[1] = grid_dim (cells per axis; total cells = grid_dim^2) h[2] = origin_x_q14 (world coord of cell (0,0) lower edge) h[3] = origin_z_q14 h[4] = bucket_capacity (max entities per cell) h[5] = bucket_storage (i64 ptr; layout below) Per cell layout (i64 cells): [0] = count of entities in cell [1..1+3*cap] = (id, x_q14, z_q14) triples Cell stride = 1 + 3 * bucket_capacity. Source references (open): - Slither.io protocol: ClitherProject/Slither.io-Protocol (GitHub)

dependencies 2 imports · 0 importers

nx_syscalls.nx nx_tier.nx nx_aoi_grid.nx

imports: nx_syscalls.nxnx_tier.nx

imported by: nobody (leaf or entry point)

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

main nx_aoi_grid_new sys_mmap nx_aoi_grid_insert _aoi_to_cell _aoi_cell_ptr _aoi_cell_stride sys_mmap ↻ nx_aoi_grid_query_radius _aoi_cell_ptr ↻ nx_aoi_grid_remove _aoi_to_cell ↻ _aoi_cell_ptr ↻

structs

none

consts

56const NX_MAGIC_16384: i64 = 16384
57const NX_MAGIC_9999: i64 = 9999
58const NX_MAGIC_2000: i64 = 2000
60const NX_AOI_HDR_CELL_SIZE: nx_int = 0
61const NX_AOI_HDR_GRID_DIM: nx_int = 1
62const NX_AOI_HDR_ORIGIN_X: nx_int = 2
63const NX_AOI_HDR_ORIGIN_Z: nx_int = 3
64const NX_AOI_HDR_BUCKET_CAP: nx_int = 4
65const NX_AOI_HDR_STORAGE: nx_int = 5
66const NX_AOI_HDR_SIZE: nx_int = 6

functions

70func _aoi_cell_stride(g: *i64) -> nx_int
called by 1: _aoi_cell_ptr
75func _aoi_cell_ptr(g: *i64, cx: nx_int, cz: nx_int) -> *i64
88func _aoi_to_cell(g: *i64, world_q14: nx_int, axis: nx_int) -> nx_int
104func nx_aoi_grid_new(
called by 1: main calls 1: sys_mmap
139func nx_aoi_grid_insert(g: *i64, id: i64, x_q14: nx_int, z_q14: nx_int) -> nx_int
called by 1: main calls 2: _aoi_to_cell_aoi_cell_ptr
158func nx_aoi_grid_remove(g: *i64, id: i64, x_q14: nx_int, z_q14: nx_int) -> nx_int
called by 1: main calls 2: _aoi_to_cell_aoi_cell_ptr
195func nx_aoi_grid_query_radius(
called by 1: main calls 1: _aoi_cell_ptr
260func main() -> i64