Memory
Read and write the emulator's address space. Client-side — the ROM lives on the client; calling these on the server has no game to address.
Addresses are u32. Out-of-range addresses trap at runtime. The set of valid ranges (RAM, registers, CHR-ROM, …) is console-specific.
Reading
read_u8(addr: u32): u8
read_u16(addr: u32): u16
read_u32(addr: u32): u32
read_i8(addr: u32): i8
read_i16(addr: u32): i16
read_i32(addr: u32): i32One builtin per width and signedness. Multi-byte reads use the console's native byte order, so you get the assembled value directly.
const PLAYER_X: u32 = 0x0086
const SCORE: u32 = 0x07DD
var x = read_u8(PLAYER_X) // u8
var score = read_u16(SCORE) // u16, native byte orderPick the width that matches how the game stores the value, and the sign that matches its meaning (a value that can go negative — a velocity — wants read_i8).
Writing
write_u8(addr: u32, value: u8)
write_u16(addr: u32, value: u16)
write_u32(addr: u32, value: u32)
write_i8(addr: u32, value: i8)
write_i16(addr: u32, value: i16)
write_i32(addr: u32, value: i32)Writing mutates the running game's state — the basis of randomizers, difficulty mods, and cheats.
const LIVES: u32 = 0x075A
write_u8(LIVES, 99)The value argument must match the builtin's width type; cast if needed (write_u8(addr, u8(n))).
Casting reads
Reads come back in their natural width (read_u8 → u8), but most arithmetic and most other builtins want i32. Casting at the read site is idiomatic:
var x = i32(read_u8(PLAYER_X)) // ready for i32 mathSee Types → Conversions.
Identifying the ROM
These builtins read the mapped CPU address space, not the cartridge file itself. To identify which game is loaded, use local_rom_hash().