# IPC Bridge Architecture — D-020 # Godot client + Rust simulation server via subprocess/IPC # Single-player: subprocess + local socket. Multiplayer: TCP (same protocol). vars: { color-bg: "#2a3040" color-stroke: "#333340" color-text: "#c8d0e0" color-accent: "#c8d8f0" color-dim: "#1a1e24" } direction: right godot: Godot Client { shape: hexagon style.fill: ${color-bg} style.stroke: ${color-accent} style.font-color: ${color-text} renderer: Renderer { style.fill: ${color-dim} style.font-color: ${color-text} style.stroke: ${color-stroke} } ui: UI + HUD { style.fill: ${color-dim} style.font-color: ${color-text} style.stroke: ${color-stroke} } audio: AudioManager { style.fill: ${color-dim} style.font-color: ${color-text} style.stroke: ${color-stroke} } input: Input Capture { style.fill: ${color-dim} style.font-color: ${color-text} style.stroke: ${color-stroke} } bridge_client: SimBridge (LocalBridge / NetworkBridge) { style.fill: ${color-dim} style.font-color: ${color-text} style.stroke: ${color-accent} } } transport: Transport Layer { style.fill: ${color-dim} style.stroke: ${color-accent} style.font-color: ${color-text} sp: Single-player\nUnix socket / localhost TCP { style.fill: ${color-bg} style.font-color: ${color-text} style.stroke: ${color-stroke} style.stroke-dash: 4 } mp: Multiplayer\nRemote TCP { style.fill: ${color-bg} style.font-color: ${color-text} style.stroke: ${color-stroke} style.stroke-dash: 4 } } rust: Rust Simulation Server { shape: hexagon style.fill: ${color-bg} style.stroke: ${color-accent} style.font-color: ${color-text} bridge_server: SimBridge (recv end) { style.fill: ${color-dim} style.font-color: ${color-text} style.stroke: ${color-accent} } ecs: bevy_ecs World { style.fill: ${color-dim} style.font-color: ${color-text} style.stroke: ${color-stroke} } perception: Perception System { style.fill: ${color-dim} style.font-color: ${color-text} style.stroke: ${color-stroke} } ai: AI + Storyteller { style.fill: ${color-dim} style.font-color: ${color-text} style.stroke: ${color-stroke} } kg: Knowledge Graph { style.fill: ${color-dim} style.font-color: ${color-text} style.stroke: ${color-stroke} } } msgpack_out: PlayerInput (MessagePack) { shape: queue style.fill: ${color-dim} style.stroke: ${color-accent} style.font-color: ${color-text} } msgpack_in: ObserverSnapshot (MessagePack) { shape: queue style.fill: ${color-dim} style.stroke: ${color-accent} style.font-color: ${color-text} } godot.input -> msgpack_out: "semantic actions\n(MoveNorth, Interact, UsePerceptionMode)" { style.stroke: ${color-accent} } msgpack_out -> godot.bridge_client godot.bridge_client -> transport.sp: "single-player" { style.stroke: ${color-accent} style.stroke-dash: 4 } godot.bridge_client -> transport.mp: "multiplayer" { style.stroke: ${color-accent} style.stroke-dash: 4 } transport.sp -> rust.bridge_server { style.stroke: ${color-accent} style.stroke-dash: 4 } transport.mp -> rust.bridge_server { style.stroke: ${color-accent} style.stroke-dash: 4 } rust.bridge_server -> rust.ecs: "dispatch input" { style.stroke: ${color-stroke} } rust.ecs -> rust.perception rust.ecs -> rust.ai rust.ecs -> rust.kg rust.ecs -> msgpack_in: "ObserverSnapshot\n(entities, fog, sound events,\nmonologue triggers, HUD widgets)" { style.stroke: ${color-accent} } msgpack_in -> godot.bridge_client godot.bridge_client -> godot.renderer godot.bridge_client -> godot.ui godot.bridge_client -> godot.audio