MCP Pine vs MCP Bizhawk — MCP Server Comparison | AllMCPs
Side-by-Side Model Context Protocol Comparison
MCP Pine vs MCP Bizhawk
In-depth architectural comparison of the MCP Pine and MCP Bizhawk MCP servers. Compare execution transports, security boundaries, tool capabilities, quality scores, and ready-to-paste client installation snippets for Claude, Cursor, Windsurf, and VS Code.
At a Glance & Executive Verdict
MCP Pine
Gaming · Local stdio
Quality: 64/100 (Good) | Auth: No auth required
MCP Bizhawk
Gaming · Local stdio
Quality: 61/100 (Good) | Auth: No auth required
Verdict Summary: Choose MCP Pine if you need specialized Gaming tools running via a local process. Choose MCP Bizhawk if your workspace requires Gaming integration with local subprocess execution. Both servers can be configured concurrently in your client's mcpServers manifest.
Which MCP Server Should You Choose?
Choose MCP Pine when:
You need dedicated capabilities in the Gaming domain.
You prefer local stdio subprocess transport architecture.
Your security boundary fits: No auth required (Free / Open Source).
Memory inspection and savestate control for PCSX2 and other emulators speaking the PINE protocol. Read/write 8/16/32/64-bit memory, save/load state slots, query game metadata. TCP on Windows, Unix sockets on Linux/macOS.
Drive the BizHawk multi-system emulator from any MCP client. Memory r/w across named domains, joypad input, frame-advance, screenshot, save/load state. One bridge unlocks NES, SNES, GB/GBC/GBA, Genesis, N64, PSX, Saturn, and more.
Category & Scope
Tools & Capabilities Breakdown
MCP Pine Tools (14)
pine_ping
PURPOSE: Verify the PINE server (PCSX2) is reachable and responding. USAGE: Call once at session start before other tool calls. Issues PINE Version opcode (0x08) — doubles as liveness probe and emulator-version sniff. BEHAVIOR: No side effects. Bridge connects on demand — Unix socket at $XDG_RUNTIME_DIR/pcsx2.sock.<slot> (Linux/macOS, with $TMPDIR/$/tmp fallback) or TCP to 127.0.0.1:<slot> (Windows, default slot 28011). 10-second timeout if the emulator isn't running, PINE isn't enabled (For PCSX2: Settings > Advanced > Enable PINE Server (default port 28011).), or slot/port mismatches. RETURNS: 'OK — emulator: VERSION_STRING', e.g. 'OK — emulator: PCSX2 <version>'.
pine_get_info
PURPOSE: Get the loaded game's metadata — title, serial code, disc CRC, in-game version string — plus the current emulator run state in one call. USAGE: Call after pine_ping to confirm what game is loaded (don't poke memory blindly — the same address means different things across games). For just the run state without the metadata round-trips use pine_get_status (1 PINE call vs 5 here). The serial (e.g. 'SLUS-21274' for PS2, 'SLUS-00067' for PS1) uniquely identifies the disc release region; combine with disc CRC to identify a specific revision. BEHAVIOR: No side effects — pure read of emulator metadata. Issues five PINE opcodes in parallel (Title, ID, UUID, GameVersion, Status). Any individual field that the emulator doesn't expose or that fails is replaced with the literal string '(unavailable)' and the rest still come back. If the entire connection fails the call propagates an error. RETURNS: Multi-line text with Title, Serial, Disc CRC, Game version, and Status — one field per line.
Ready-to-Paste Client Configurations
Paste either (or both) of these JSON server blocks into your client config file (e.g. claude_desktop_config.json or ~/.cursor/mcp.json).
MCP Pine is categorized under Gaming and uses a local stdio subprocess. In contrast, MCP Bizhawk belongs to Gaming using local stdio subprocess. Select MCP Pine when you need capabilities focused on gaming and MCP Bizhawk when you require tools for gaming.
PURPOSE: Get the emulator run state — 'running', 'paused', 'shutdown', or 'unknown'. USAGE: Cheap (1 PINE round-trip) check before timing-sensitive sequences — writes work while paused but only take visible effect after unpause. For game metadata (title, serial, CRC) use pine_get_info (batches Status with Title/ID/UUID/GameVersion). PINE has no pause/resume opcode; this tool only reports state. BEHAVIOR: No side effects. Issues PINE Status opcode (0x0F), decodes the 32-bit response (0=running, 1=paused, 2=shutdown). Errors on connection failure or PINE FAIL. RETURNS: 'Status: STATE' where STATE ∈ {running, paused, shutdown, unknown}.
pine_read8
PURPOSE: Read an unsigned 8-bit byte from the emulator's EE main address space at the given absolute address. USAGE: Use for single-byte fields — status flags, counters, 8-bit enums, character bytes. For 16/32/64-bit values use pine_read16/read32/read64 (one call instead of multi-byte assembly); for spans of more than ~4 bytes use pine_read_range (one batched call instead of N round-trips). BEHAVIOR: No side effects — pure read. Reads work whether the emulator is running or paused. No alignment requirement (byte access is naturally aligned). Returns an error if the address is unmapped, the connection drops, or PINE returns its FAIL response (0xFF). The 10-second per-call timeout fires if the emulator drops the reply (PCSX2 has been observed to do this under heavy pipeline load — see pine_read_range for the wider context).
PlayStation 2 main address space landmarks (PCSX2):
0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target
0x10000000 Hardware registers (DMA, GIF, VIF, etc.)
0x11000000 VU0 / VU1 memory
0x12000000 GS privileged registers
0x1C000000-0x1C1FFFFF IOP RAM (2 MiB)
0x1F800000 IOP scratchpad
0x70000000 EE scratchpad (16 KiB)
PINE memory operations target the EE address space.
RETURNS: Single line 'ADDR_HEX: VAL_DEC (0xVAL_HEX)', e.g. '0x00200000: 99 (0x63)'.
pine_read16
PURPOSE: Read an unsigned 16-bit little-endian value from the emulator's EE main address space at the given absolute address. USAGE: Use for 16-bit fields (HP, score, coordinates on many PlayStation 2 titles). For single bytes use pine_read8; for 32/64-bit use pine_read32/read64; for unaligned reads or big-endian fields, use pine_read_range and decode the bytes yourself (this tool always interprets bytes as little-endian, which matches MIPS byte order on PS1/PS2). BEHAVIOR: No side effects — pure read. Reads two consecutive bytes (low byte at `address`, high byte at `address+1`) and combines them as little-endian. Address MUST be 2-byte aligned. PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Returns a PINE FAIL response on unmapped addresses; times out after ~10s if the reply is dropped.
PlayStation 2 main address space landmarks (PCSX2):
0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target
0x10000000 Hardware registers (DMA, GIF, VIF, etc.)
0x11000000 VU0 / VU1 memory
0x12000000 GS privileged registers
0x1C000000-0x1C1FFFFF IOP RAM (2 MiB)
0x1F800000 IOP scratchpad
0x70000000 EE scratchpad (16 KiB)
PINE memory operations target the EE address space.
RETURNS: Single line 'ADDR_HEX: VAL_DEC (0xVAL_HEX)'.
pine_read32
PURPOSE: Read an unsigned 32-bit little-endian value from the emulator's EE main address space at the given absolute address. USAGE: Use for 32-bit fields — timestamps, large counters, RGBA colors, and the lower half of 64-bit pointers. For single byte / 16-bit / 64-bit values use pine_read8/read16/read64; for big-endian or unaligned multi-word reads use pine_read_range and decode yourself. BEHAVIOR: No side effects — pure read. Reads four consecutive bytes starting at `address` and combines them as little-endian (LSB at `address`, MSB at `address+3`). Address MUST be 4-byte aligned. PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Returns a PINE FAIL response on unmapped addresses; times out after ~10s if the reply is dropped.
PlayStation 2 main address space landmarks (PCSX2):
0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target
0x10000000 Hardware registers (DMA, GIF, VIF, etc.)
0x11000000 VU0 / VU1 memory
0x12000000 GS privileged registers
0x1C000000-0x1C1FFFFF IOP RAM (2 MiB)
0x1F800000 IOP scratchpad
0x70000000 EE scratchpad (16 KiB)
PINE memory operations target the EE address space.
RETURNS: Single line 'ADDR_HEX: VAL_DEC (0xVAL_HEX)'.
pine_read64
PURPOSE: Read an unsigned 64-bit little-endian value from the emulator's EE main address space at the given absolute address. USAGE: Use for true 64-bit fields — full pointers, large IDs, packed double-word state. The PS2 EE is a 128-bit MIPS where 64-bit slots are common; PS1 and PS3 use 64-bit less heavily but the opcode still works. Reach for this rather than chaining two pine_read32 calls when you want atomicity. For 8/16/32-bit values use the corresponding sibling; for byte spans use pine_read_range. BEHAVIOR: No side effects — pure read. Reads eight consecutive bytes starting at `address` and combines them as little-endian. Address MUST be 8-byte aligned. PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. The result is returned as a decimal STRING (not a JSON number) to preserve precision past 2^53 (JavaScript number limit) — parse with BigInt if you need to do arithmetic. Returns a PINE FAIL response on unmapped addresses; times out after ~10s if the reply is dropped.
PlayStation 2 main address space landmarks (PCSX2):
0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target
0x10000000 Hardware registers (DMA, GIF, VIF, etc.)
0x11000000 VU0 / VU1 memory
0x12000000 GS privileged registers
0x1C000000-0x1C1FFFFF IOP RAM (2 MiB)
0x1F800000 IOP scratchpad
0x70000000 EE scratchpad (16 KiB)
PINE memory operations target the EE address space.
RETURNS: Single line 'ADDR_HEX: VAL_DEC (0xVAL_HEX)' — VAL_DEC is a decimal string that may exceed 2^53.
pine_read_range
PURPOSE: Read a contiguous range of bytes from EE main address space memory as a hex dump. USAGE: For >4 bytes — far cheaper than looping pine_read8. Max 4096 bytes/call; chunk larger reads in 4 KiB. Powers snapshot-diff RAM hunts (snapshot before/after a known change, diff for matching deltas), unknown-struct inspection, and region capture/restore. BEHAVIOR: No side effects. PINE has no native bulk-read opcode; the tool synthesizes the range from read64/32/16/8 calls (largest aligned load at each step) and assembles client-side. Issued FULLY SERIALLY by default because PCSX2's PINE queue silently drops replies past ~7 in-flight requests, desyncing the bridge until emulator restart. Loopback serial is fast enough (~52 ms for 4096 bytes on PCSX2 v2.6.3); other targets are typically similar or faster. Override via PINE_PIPELINE_BATCH env var at your own risk. Errors on length out of 1-4096, any underlying FAIL, or reply timeout.
PlayStation 2 main address space landmarks (PCSX2):
0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target
0x10000000 Hardware registers (DMA, GIF, VIF, etc.)
0x11000000 VU0 / VU1 memory
0x12000000 GS privileged registers
0x1C000000-0x1C1FFFFF IOP RAM (2 MiB)
0x1F800000 IOP scratchpad
0x70000000 EE scratchpad (16 KiB)
PINE memory operations target the EE address space.
RETURNS: 'ADDR_HEX [N bytes]:' header + space-separated 2-digit uppercase hex bytes.
pine_write8
PURPOSE: Write a single unsigned byte (0-255) to the emulator's EE main address space at the given absolute address. USAGE: Use for single-byte cheats, debug pokes, and game-state mutations (give a player N lives, unlock a flag, set a counter). For 16/32/64-bit values prefer pine_write16/write32/write64 (single call instead of byte-at-a-time, and atomic from the emulator's perspective). For seeding many bytes there is no native bulk write — loop pine_write8 yourself or batch via pine_write64 on aligned regions. To roll back later use pine_save_state BEFORE the write and pine_load_state to restore. BEHAVIOR: DESTRUCTIVE: overwrites whatever was at `address` with no undo. The write is direct memory access — bypasses TLB protection and any DMA semantics — so writes to read-only regions (BIOS, etc.) are silently dropped by the emulator with no error. The write takes effect immediately, but visible game-state effects only appear when the emulator next ticks (so writing while paused shows changes only after unpause or frame-step). No alignment requirement for byte access. Returns an error if the connection drops or PINE returns FAIL on a wholly invalid address.
PlayStation 2 main address space landmarks (PCSX2):
0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target
0x10000000 Hardware registers (DMA, GIF, VIF, etc.)
0x11000000 VU0 / VU1 memory
0x12000000 GS privileged registers
0x1C000000-0x1C1FFFFF IOP RAM (2 MiB)
0x1F800000 IOP scratchpad
0x70000000 EE scratchpad (16 KiB)
PINE memory operations target the EE address space.
RETURNS: Single line 'Wrote VAL_DEC (0xVAL_HEX) → ADDR_HEX'.
pine_write16
PURPOSE: Write an unsigned 16-bit little-endian value to EE main address space. USAGE: For 16-bit cheats/pokes (HP, score, coordinates). For single bytes use pine_write8; for 32/64-bit use pine_write32/write64; for big-endian fields byteswap first (this tool always writes little-endian). Snapshot via pine_save_state for rollback. BEHAVIOR: DESTRUCTIVE: overwrites two bytes (low at `address`, high at `address+1`) with no undo. Direct write — bypasses TLB; writes to read-only regions (BIOS) are silently dropped. Address MUST be 2-byte aligned. PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Errors on connection drop or PINE FAIL.
PlayStation 2 main address space landmarks (PCSX2):
0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target
0x10000000 Hardware registers (DMA, GIF, VIF, etc.)
0x11000000 VU0 / VU1 memory
0x12000000 GS privileged registers
0x1C000000-0x1C1FFFFF IOP RAM (2 MiB)
0x1F800000 IOP scratchpad
0x70000000 EE scratchpad (16 KiB)
PINE memory operations target the EE address space.
RETURNS: 'Wrote VAL_DEC (0xVAL_HEX) → ADDR_HEX'.
pine_write32
PURPOSE: Write an unsigned 32-bit little-endian value to the emulator's EE main address space at the given absolute address. USAGE: Use for 32-bit cheats and pokes — timestamps, large counters, RGBA colors, the lower half of pointers. For single byte / 16-bit values use pine_write8/write16; for true 64-bit fields use pine_write64 — chaining two pine_write32 calls is non-atomic and can be observed mid-update by the running game. For big-endian layouts, byteswap into a little-endian value yourself first. BEHAVIOR: DESTRUCTIVE: overwrites four bytes starting at `address` with no undo. Direct memory write — bypasses TLB protection and DMA mediation; writes to read-only regions (BIOS) are silently dropped with no error. Address MUST be 4-byte aligned. PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. Values are NOT truncated by this tool: the schema rejects anything outside 0-4294967295 (0x00000000-0xFFFFFFFF) before the call ever reaches PINE. Returns an error if the connection drops or PINE returns FAIL on a wholly invalid address.
PlayStation 2 main address space landmarks (PCSX2):
0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target
0x10000000 Hardware registers (DMA, GIF, VIF, etc.)
0x11000000 VU0 / VU1 memory
0x12000000 GS privileged registers
0x1C000000-0x1C1FFFFF IOP RAM (2 MiB)
0x1F800000 IOP scratchpad
0x70000000 EE scratchpad (16 KiB)
PINE memory operations target the EE address space.
RETURNS: Single line 'Wrote VAL_DEC (0xVAL_HEX) → ADDR_HEX'.
pine_write64
PURPOSE: Write an unsigned 64-bit little-endian value to EE main address space. USAGE: For true 64-bit writes — full pointers, large IDs, packed doubleword state. Atomic from the emulator's perspective; preferred over chaining two pine_write32 calls (a running game can observe the in-between state). For 8/16/32-bit values use the corresponding sibling. BEHAVIOR: DESTRUCTIVE: overwrites eight bytes from `address` with no undo. Direct write — bypasses TLB; writes to read-only regions silently dropped. Address MUST be 8-byte aligned. PINE on PCSX2 does NOT enforce alignment — unaligned access typically returns whatever bytes are at the aligned address below, silently corrupting the value. If you need an unaligned multi-byte read, use pine_read_range and assemble the bytes yourself. `value` is a DECIMAL STRING (0 through 18446744073709551615) to preserve precision past JS's 2^53 number limit. Errors on connection drop or PINE FAIL.
PlayStation 2 main address space landmarks (PCSX2):
0x00100000-0x01FFFFFF EE main RAM (32 MiB) — game code & data; the most common target
0x10000000 Hardware registers (DMA, GIF, VIF, etc.)
0x11000000 VU0 / VU1 memory
0x12000000 GS privileged registers
0x1C000000-0x1C1FFFFF IOP RAM (2 MiB)
0x1F800000 IOP scratchpad
0x70000000 EE scratchpad (16 KiB)
PINE memory operations target the EE address space.
RETURNS: 'Wrote VAL_DEC (0xVAL_HEX) → ADDR_HEX' — VAL_DEC may exceed 2^53.
+2 more tools listed on main page
MCP Bizhawk Tools (22)
bizhawk_ping
PURPOSE: Verify that the BizHawk Lua bridge is connected and responding to RPC over the TCP socket. USAGE: Call this once at start-of-session before issuing other tool calls; if it succeeds, every other tool will work. BEHAVIOR: No side effects — pure liveness probe. Times out after ~10 seconds with a clear error if BizHawk isn't running, isn't pointed at the right host:port, or hasn't loaded lua/bridge.lua via Tools → Lua Console. RETURNS: The literal string 'pong' on success.
bizhawk_get_info
PURPOSE: Get the loaded ROM's name and hash, current frame count, the list of available memory domains, the active default domain (the one used when 'domain' is omitted on read/write tool calls), and the bridge's capability map (which optional emu/client/savestate/joypad/memory methods this BizHawk build exposes). USAGE: Call after bizhawk_ping to learn what system is loaded and which optional features are available; before any memory tool call to confirm the active domain and avoid silent reads from the wrong address space; before pause / unpause / reset / screenshot / save_state to check the corresponding `capabilities.*` flag. BEHAVIOR: No side effects — pure read of emulator metadata. Returns 'unavailable' for fields the loaded core doesn't expose (rom_name when no ROM is loaded, framecount on cores without emu.framecount, etc.). RETURNS: Multi-line text with ROM, ROM hash, framecount, memory_domains list, active domain, and a list of any missing capabilities for this build.
bizhawk_list_memory_domains
PURPOSE: List the memory domains available on the loaded core (e.g. 'WRAM', 'CARTRAM', 'VRAM', 'System Bus' on SNES; 'RAM', 'PPU', 'OAM' on NES). USAGE: Call before any memory r/w tool when you don't know the domain layout for the loaded system. The returned names are exactly what to pass as the `domain` parameter on bizhawk_read*/write* tools (case-sensitive). BEHAVIOR: No side effects — pure read. Returns an error if the loaded BizHawk core doesn't implement memory.getmemorydomainlist (extremely rare). RETURNS: Newline-formatted list of domain names, one per line.
bizhawk_read8
PURPOSE: Read an unsigned 8-bit byte from emulator memory at the given address. USAGE: Use for single-byte status flags, counters, and 8-bit fields. For 16- or 32-bit values use bizhawk_read16/read32 (one call instead of multi-byte assembly); for spans of more than ~4 bytes use bizhawk_read_range (one round-trip instead of N frame-latency hops). BEHAVIOR: No side effects — pure read. Reads work the same way whether emulation is paused or running. Returns an error if the named domain doesn't exist, the address is out of range for the domain, or the loaded core doesn't expose memory.read_u8. RETURNS: Single line 'ADDR_HEX: VAL_DEC (0xVAL_HEX)', e.g. '0x09C6: 99 (0x63)'.
bizhawk_read16
PURPOSE: Read an unsigned 16-bit little-endian value from emulator memory at the given address. USAGE: Use for 16-bit fields (most game-state values: HP, score, coordinates). For single bytes use bizhawk_read8; for 32-bit values use bizhawk_read32; for non-aligned spans or big-endian fields use bizhawk_read_range and decode the bytes yourself (this tool always interprets bytes as little-endian regardless of the target system's native endianness). BEHAVIOR: No side effects — pure read. Reads two consecutive bytes (low byte at `address`, high byte at `address+1`) and combines them as little-endian. Returns an error if the named domain doesn't exist, address+2 exceeds domain size, or the core doesn't expose memory.read_u16_le. RETURNS: Single line 'ADDR_HEX: VAL_DEC (0xVAL_HEX)'.
bizhawk_read32
PURPOSE: Read an unsigned 32-bit little-endian value from emulator memory at the given address. USAGE: Use for 32-bit fields (timestamps, large counters, pointers on 32-bit systems, RGBA colors). For 8/16-bit reads use bizhawk_read8/read16; for big-endian or unaligned multi-word reads use bizhawk_read_range and decode yourself. BEHAVIOR: No side effects — pure read. Reads four consecutive bytes starting at `address` and combines them as little-endian (LSB at `address`, MSB at `address+3`). Returns an error if the domain doesn't exist, address+4 exceeds the domain, or the core lacks memory.read_u32_le. RETURNS: Single line 'ADDR_HEX: VAL_DEC (0xVAL_HEX)'.
bizhawk_read_range
PURPOSE: Read a contiguous range of bytes from emulator memory as a hex dump. USAGE: Use for >4 bytes (one round-trip vs N frame-latency hops). Max 4096 bytes/call (BizHawk serialization limit); chunk larger reads in 4 KiB. Powers the two-snapshot RAM-hunt workflow (snapshot before/after a known change, diff for matching deltas). BEHAVIOR: No side effects — pure read. Returns an error if domain is unknown, length is out of 1-4096, or address+length exceeds the domain. RETURNS: 'ADDR_HEX [N bytes, DOMAIN]:' header + space-separated 2-digit uppercase hex bytes.
bizhawk_write8
PURPOSE: Write a single unsigned byte (0-255) to emulator memory at the given address. USAGE: Use for single-byte cheats, debug pokes, and game-state mutations (give a player N lives, unlock a flag, set a counter). For 16/32-bit values prefer bizhawk_write16/write32 (single call instead of byte-at-a-time); for spans use bizhawk_write_range. To seed cart save RAM realistically (with proper MBC behavior), prefer bizhawk_load_state with a pre-prepared .State file rather than poking SRAM bytes here. BEHAVIOR: DESTRUCTIVE: overwrites whatever was at `address` with no undo (snapshot via bizhawk_save_state first if you need rollback). The write is direct memory access — bypasses MBC bank switches, cartridge mapper side-effects, and DMA semantics — so it cannot be used to emulate cartridge hardware. Returns an error if the domain is unknown, address is out of range, value < 0 or > 255, or the core lacks memory.write_u8. Works whether emulation is paused or running. RETURNS: Single line 'Wrote VAL_DEC (0xVAL_HEX) → ADDR_HEX (DOMAIN)'.
bizhawk_write16
PURPOSE: Write an unsigned 16-bit little-endian value to emulator memory at the given address. USAGE: Use for 16-bit cheats and pokes (HP, score, coordinates). For single bytes use bizhawk_write8; for 32-bit use bizhawk_write32; for big-endian fields, byteswap and use bizhawk_write_range; for cart save RAM seeding, use bizhawk_load_state. BEHAVIOR: DESTRUCTIVE: overwrites two bytes (low byte at `address`, high byte at `address+1`) with no undo. Direct memory write — no MBC/mapper/DMA mediation, see bizhawk_write8 notes. Returns an error if the domain is unknown, address+2 exceeds the domain, value < 0 or > 65535, or the core lacks memory.write_u16_le. RETURNS: Single line 'Wrote VAL_DEC (0xVAL_HEX) → ADDR_HEX (DOMAIN)'.
bizhawk_write32
PURPOSE: Write an unsigned 32-bit little-endian value to emulator memory at the given address. USAGE: Use for 32-bit cheats and pokes (timestamps, large counters, pointers on 32-bit systems). For 8/16-bit values use bizhawk_write8/write16; for big-endian layouts byteswap and use bizhawk_write_range. BEHAVIOR: DESTRUCTIVE: overwrites four bytes starting at `address` with no undo (snapshot via bizhawk_save_state first if you need rollback). Direct memory write — bypasses MBC/mapper/DMA, see bizhawk_write8 notes. Returns an error if the domain is unknown, address+4 exceeds the domain, value < 0 or > 4294967295, or the core lacks memory.write_u32_le. RETURNS: Single line 'Wrote VAL_DEC (0xVAL_HEX) → ADDR_HEX (DOMAIN)'.
bizhawk_write_range
PURPOSE: Write a contiguous byte sequence to emulator memory starting at the given address. USAGE: Use whenever you're seeding more than ~4 bytes — one round-trip vs N frame-latency hops compared to looping bizhawk_write8. Maximum 4096 bytes per call (BizHawk serialization limit); for larger writes, batch in 4 KiB chunks. Useful for installing cheat tables, patching code blocks, restoring a captured byte window after experiments, and writing big-endian multi-byte values (byteswap them yourself first). For cart save RAM seeding with proper MBC semantics, use bizhawk_load_state instead. BEHAVIOR: DESTRUCTIVE: overwrites N bytes starting at `address` with no undo. Direct memory write — bypasses MBC/mapper/DMA, see bizhawk_write8 notes. Bytes are written sequentially address, address+1, ..., address+N-1. Returns an error if the domain is unknown, address+N exceeds the domain, the array contains a value outside 0-255, or the array length is < 1 or > 4096. RETURNS: Single line 'Wrote N bytes → ADDR_HEX (DOMAIN)'.
bizhawk_search_memory
PURPOSE: Find every address in a memory domain whose value equals a target — a Cheat-Engine-style value scan with iterative narrowing. USAGE: Two modes. FIRST scan — omit `addresses`: sweeps the whole domain (or the [start, start+length) window you give) and returns matching offsets. NEXT scan — pass `addresses` (the offsets a prior scan returned): keeps only those that STILL equal `value`, the classic 'the value changed to X — which of my candidates match now?' narrowing. Typical RAM hunt: search a known value (lives=3) → play until it changes → search the new value passing the prior addresses → repeat until a handful remain, then poke them with bizhawk_write*. Pick `width` to match the field size; leave `aligned` true (steps by the width — fast and standard) unless you suspect an unaligned value. BEHAVIOR: No side effects — pure read. A FIRST scan runs synchronously inside one bridge tick and briefly stalls the emulator: it bulk-reads the window in one engine call where the build supports it (cap 16 MiB per scan) and falls back to a byte-by-byte read otherwise (cap 256 KiB per scan — chunk larger windows with start+length). Results are capped at `max_results` (default 200); when more matched, `count` reports the true total and the result is flagged truncated — narrow with a more specific value or range. A NEXT scan is exact over whatever addresses you pass. Returns an error on unknown domain, a value out of range for the width, or a scan window over the cap. RETURNS: A summary line (match count, value, width, bytes scanned) followed by the matching offsets as per-domain hex (0-based — the same offsets the read/write tools take).