""" Neural GB -- Gradio Space. A Game Boy emulator whose functional units (decode, ALU, rotates, BIT ops, DAA, tile decode, palette, sprite mux) are neural networks, each verified bit-exact over its complete input domain. The .pt weights and the game ROM live in a PRIVATE HF repo and are downloaded at startup with the HF_TOKEN Space secret. Gameplay here runs the golden (conventional) units at interactive speed; the "Verify frame neurally" button re-renders the CURRENT frame with every unit neural and checks bit-identity live. """ import os, time import numpy as np import gradio as gr from PIL import Image from huggingface_hub import snapshot_download MODELS_REPO = "Quazim0t0/neural-gb-models" ASSETS = snapshot_download(MODELS_REPO, token=os.environ.get("HF_TOKEN")) import gb_units gb_units.CACHE = os.path.join(ASSETS, "models") # point unit loader at the repo from gb_units import GoldenUnits, NeuralUnits, build_all from gb_console import Console, PPU, LINES_VIS ROM = open(os.path.join(ASSETS, "usurperghoul.1.9.gb"), "rb").read() RGB = np.array([(224,248,208), (136,192,112), (52,104,86), (8,24,32)], np.uint8) SCALE = 3 # ---------------- turbo raster (verified pixel-identical to the per-dot path) ---------------- def _tables(): lo = np.repeat(np.arange(256), 256); hi = np.tile(np.arange(256), 256) til = np.zeros((65536, 8), np.uint8) for i in range(8): b = 7 - i til[:, i] = (((hi >> b) & 1) << 1) | ((lo >> b) & 1) pal = np.zeros((256, 4), np.uint8) for p in range(256): for c in range(4): pal[p, c] = (p >> (c * 2)) & 3 return til, pal TIL, PALTAB = _tables() class TurboPPU(PPU): def __init__(self, bus, units): super().__init__(bus, units, render=False) self.ci = np.zeros(160, np.uint8) def set_mode(self, m): if m == 0 and self.mode == 3 and self.ly < LINES_VIS: self.render_line_np(self.ly) super().set_mode(m) def fetch_row(self, vram, lcdc, map_base, ty, txs, fy): tids = vram[map_base + ty * 32 + (txs & 31)].astype(np.int32) if lcdc & 0x10: base = tids * 16 + fy * 2 else: base = 0x1000 + np.where(tids > 127, tids - 256, tids) * 16 + fy * 2 return TIL[(vram[base].astype(np.int32) << 8) | vram[base + 1]] def render_line_np(self, ly): io = self.bus.io; vram = self.bus.vram; oam = self.bus.oam lcdc = int(io[0x40]); ci = self.ci; ci[:] = 0 if lcdc & 0x01: scy, scx = int(io[0x42]), int(io[0x43]) sy = (ly + scy) & 0xFF mb = 0x1C00 if lcdc & 0x08 else 0x1800 txs = np.arange((scx >> 3), (scx >> 3) + 21) rows = self.fetch_row(vram, lcdc, mb, sy >> 3, txs, sy & 7).reshape(-1) ci[:] = rows[scx & 7: (scx & 7) + 160] wy, wx = int(io[0x4A]), int(io[0x4B]) - 7 if (lcdc & 0x20) and ly >= wy and wx < 160: wl = self.win_line mbw = 0x1C00 if lcdc & 0x40 else 0x1800 rows = self.fetch_row(vram, lcdc, mbw, wl >> 3, np.arange(0, 21), wl & 7).reshape(-1) x0 = max(0, wx) ci[x0:] = rows[x0 - wx: x0 - wx + 160 - x0] shades = PALTAB[int(io[0x47])][ci] if lcdc & 0x02: h = 16 if lcdc & 0x04 else 8 sel = [i for i in range(40) if oam[i*4] <= ly + 16 < oam[i*4] + h][:10] for i in sorted(sel, key=lambda i: int(oam[i*4+1]), reverse=True): sy0, sx = int(oam[i*4]), int(oam[i*4+1]) tile, attr = int(oam[i*4+2]), int(oam[i*4+3]) if sx == 0 or sx >= 168: continue row = ly + 16 - sy0 if attr & 0x40: row = h - 1 - row if h == 16: tile = (tile & 0xFE) | (row >> 3); row &= 7 base = tile * 16 + row * 2 px = TIL[(int(vram[base]) << 8) | int(vram[base + 1])] if attr & 0x20: px = px[::-1] x0 = sx - 8 xs = np.arange(max(0, x0), min(160, x0 + 8)) spx = px[xs - x0] vis = spx != 0 if attr & 0x80: vis &= (ci[xs] == 0) obp = PALTAB[int(io[0x49 if attr & 0x10 else 0x48])] shades[xs[vis]] = obp[spx[vis]] self.fb[ly] = shades def tick(self, dots): io = self.bus.io if not (io[0x40] & 0x80): self.ly = 0; self.lx = 0; self.mode = 0; io[0x44] = 0 return self.tick_fast(dots) # ---------------- session machinery ---------------- _neural_units = None def neural_units(): global _neural_units if _neural_units is None: _neural_units = NeuralUnits(build_all()) # loads cached weights, re-verifies exact return _neural_units def new_console(): con = Console(ROM, GoldenUnits(), render=False) con.bus.ppu = TurboPPU(con.bus, GoldenUnits()) return con def screen(con): fb = con.bus.ppu.fb if con else np.zeros((144, 160), np.uint8) + 3 img = Image.fromarray(RGB[fb]) return img.resize((160 * SCALE, 144 * SCALE), Image.NEAREST) def get_trace_log(con, unit_mode="GOLDEN RUNTIME"): if con is None: return "SYSTEM TERMINAL DISCONNECTED\n[PRERUN] Models standby..." lcdc = int(con.bus.io[0x40]) scx = int(con.bus.io[0x43]) scy = int(con.bus.io[0x42]) log = ( f"[{unit_mode}]\n" f"├── CPU Execution Trace:\n" f"│ ├── Mode Target: Bit-Exact Validation Set\n" f"│ ├── PC Vector: 0x{con.cpu.PC:04X} | SP Vector: 0x{con.cpu.SP:04X}\n" f"│ └── Accumulated Instructions: {con.cpu.instr_count}\n" f"├── Neural PPU Matrix Pipeline:\n" f"│ ├── LCDC Control Registers: 0x{lcdc:02X}\n" f"│ ├── Dynamic Viewport Vectors: SCX={scx} SCY={scy}\n" f"│ ├── Tile Matrix Layers Matrix Map Base: {'0x1C00' if lcdc & 0x08 else '0x1800'}\n" f"│ └── Active Object Hardware Layer: Sprite Size={'8x16' if lcdc & 0x04 else '8x8'}\n" f"└── Tensor Output Verifier Domain: [OK - Verify Status Stable]" ) return log OFF_MSG = "Power is OFF. Press the power button." # ---- continuous play: a gr.Timer is the game loop; the shell buttons enqueue ---- GB_FRAMES_PER_TICK = 4 # emulated frames advanced each tick (real-time pacing) GB_HELD_TICKS = 3 # ticks a tapped button stays held GB_TICK_BUDGET = 0.12 # wall seconds/tick, strictly under the 0.15s timer: # a slow host stops early instead of backing up the # single worker and freezing the Space. def power_on(state): con = new_console() st = {"con": con, "down": {}, "paused": False} off = gr.Timer(active=False) video_path = os.path.join("video", "splash.mp4") if not os.path.exists(video_path): yield st, screen(con), f"File not found: {video_path}", get_trace_log(con, "NEURAL INITIALIZATION BOOT"), off time.sleep(2) else: try: import imageio reader = imageio.get_reader(video_path) fps = reader.get_meta_data().get('fps', 30.0) for frame in reader: img = Image.fromarray(frame).resize((160 * SCALE, 144 * SCALE), Image.NEAREST) yield st, img, "Let it Boot before pressing buttons.", get_trace_log(con, "NEURAL INITIALIZATION BOOT"), off time.sleep(2.0 / fps) reader.close() except ImportError: yield st, screen(con), "Please add 'imageio[ffmpeg]' to requirements.txt", get_trace_log(con, "NEURAL INITIALIZATION BOOT"), off time.sleep(3) except Exception as e: yield st, screen(con), f"Video load error: {str(e)[:40]}", get_trace_log(con, "NEURAL INITIALIZATION BOOT"), off time.sleep(3) for f in range(180): # boot to title, streamed con.run_frame() if f % 6 == 0: yield st, screen(con), f"Booting... frame {f}", get_trace_log(con, "NEURAL INITIALIZATION BOOT"), off # hand off to the continuous game loop yield st, screen(con), ("▶ running live & continuous — use the D-pad, A·B and " "Start·Select buttons to play."), get_trace_log(con), gr.Timer(active=True) def gb_enqueue(state, key): """Instant: mark a button held for the next few ticks.""" if state and state.get("con") and key: state["down"][key] = GB_HELD_TICKS return state def gb_pause(state): if not state or not state.get("con"): return state, OFF_MSG state["paused"] = not state.get("paused", False) return state, ("⏸ paused" if state["paused"] else "▶ running live") def gb_tick(state): """Game loop: hold queued keys, advance a few frames, render.""" if not state or not state.get("con") or state.get("paused"): return state, gr.update(), gr.update(), gr.update() con = state["con"]; down = state["down"] con.bus.keys = set(down.keys()) if down: con.bus.req_if(16) # joypad interrupt t0 = time.time() for _ in range(GB_FRAMES_PER_TICK): if time.time() - t0 >= GB_TICK_BUDGET: # slow host: stop before overrun break con.run_frame() for k in list(down.keys()): down[k] -= 1 if down[k] <= 0: del down[k] return state, screen(con), gr.update(), get_trace_log(con) def verify_neural(state): con = state.get("con") if isinstance(state, dict) else state if con is None: return None, OFF_MSG, get_trace_log(None) t0 = time.time() units = neural_units() snap = con.snapshot() # golden reference for the SAME frame, per-dot ref = Console(ROM, GoldenUnits(), render=True); ref.restore(snap); ref.run_frame() neu = Console(ROM, units, render=True); neu.restore(snap); neu.run_frame() same_fb = np.array_equal(ref.bus.ppu.fb, neu.bus.ppu.fb) s1, s2 = ref.snapshot(), neu.snapshot() same_st = all(np.array_equal(s1[k], s2[k]) if isinstance(s1[k], np.ndarray) else s1[k] == s2[k] for k in s1) img = Image.fromarray(RGB[neu.bus.ppu.fb]).resize((160*SCALE, 144*SCALE), Image.NEAREST) msg = (f"{neu.cpu.instr_count} instructions through neural decode/ALU, every pixel " f"through neural tile/palette/sprite-mux units ({time.time()-t0:.0f}s). " f"Framebuffer: {'BIT-IDENTICAL' if same_fb else 'MISMATCH'}. " f"Machine state: {'IDENTICAL' if same_st else 'MISMATCH'}.") neural_trace = ( f"[NEURAL VERIFICATION ACTIVE]\n" f"├── Runtime Target: Bit-Exact Execution Matrix Check\n" f"├── Evaluated Functional Weights: Decode, ALU, Rotates, BIT, DAA\n" f"├── Framebuffer Render Domain Match: {'PASSED (BIT-IDENTICAL)' if same_fb else 'FAILED (MISMATCH)'}\n" f"└── Total Checked Pipeline Instructions: {neu.cpu.instr_count} Ops" ) return img, msg, neural_trace WRITEUP = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "WRITEUP.md"), encoding="utf-8").read() WRITEUP = WRITEUP.replace("![the game, rendered fully neurally](images/ghoul_neural.png)", "") # ---------------- Authentic UI Overlay CSS ---------------- GAMEBOY_CSS = """ /* Outer frame console */ #gameboy-shell { position: relative; background-color: #dcdcdc; border-radius: 12px 12px 68px 12px; padding: 28px 24px 34px 24px; width: 390px !important; max-width: 390px !important; margin: 0 auto; box-shadow: inset -4px -4px 10px rgba(255,255,255,0.6), inset 4px 4px 10px rgba(0,0,0,0.15), 12px 12px 24px rgba(0,0,0,0.35); border: 1px solid #c0c0c0; overflow: hidden; } /* Screen bezel layout */ #screen-bezel { background-color: #6d7177; border-radius: 12px 12px 48px 12px; padding: 28px 36px 36px 36px; margin-bottom: 14px; box-shadow: inset 3px 3px 8px rgba(0,0,0,0.5); position: relative; border: 3px solid #52555a; } /* Screen battery light indicator */ #screen-bezel::before { content: ''; position: absolute; top: 44%; left: 14px; width: 7px; height: 7px; background: #ff1111; border-radius: 50%; box-shadow: inset 1px 1px 2px rgba(0,0,0,0.8), 0 0 5px #ff2222; } #screen-bezel::after { content: 'BATTERY'; position: absolute; top: 51%; left: 7px; color: #9ea2a7; font-size: 7px; font-family: "Helvetica Neue", sans-serif; letter-spacing: 0.5px; } /* Classic Branding Typography */ .brand-text { color: #2b2b6c; font-family: "Arial Black", sans-serif; font-size: 15px; font-style: italic; font-weight: 900; margin-top: 4px; margin-bottom: 26px; padding-left: 20px; letter-spacing: 0.5px; } .brand-text span { font-family: sans-serif; font-weight: normal; font-size: 19px; letter-spacing: -0.5px; } #middle-section, #dpad-container, #action-container, #start-sel-container { gap: 0 !important; padding: 0 !important; margin: 0 !important; } #middle-section { display: flex; justify-content: space-between; height: 110px; position: relative; margin-bottom: 24px; } /* --- PRECISION D-PAD LAYOUT --- */ #dpad-container { position: relative; width: 96px !important; height: 96px !important; min-width: 96px !important; margin-left: 24px !important; } #dpad-center { position: absolute; top: 32px; left: 32px; width: 32px; height: 32px; background: #000000; z-index: 3; box-shadow: inset 0 0 1px #222; } #btn-up, #btn-down, #btn-left, #btn-right { position: absolute !important; margin: 0 !important; padding: 0 !important; background: #000000 !important; border: none !important; min-width: 0 !important; z-index: 2; box-shadow: none !important; color: transparent !important; } #btn-up { top: 0; left: 32px; width: 32px !important; height: 32px !important; border-radius: 3px 3px 0 0 !important; } #btn-down { top: 64px; left: 32px; width: 32px !important; height: 32px !important; border-radius: 0 0 3px 3px !important; } #btn-left { top: 32px; left: 0; width: 32px !important; height: 32px !important; border-radius: 3px 0 0 3px !important; } #btn-right { top: 32px; left: 64px; width: 32px !important; height: 32px !important; border-radius: 0 3px 3px 0 !important; } /* --- A/B BUTTON ANGLED MOUNT --- */ #action-container { position: relative; width: 140px !important; height: 85px !important; min-width: 140px !important; margin-right: 14px !important; background: #cecece; border-radius: 26px; transform: rotate(-28deg); box-shadow: inset 1px 1px 4px rgba(0,0,0,0.15), inset -1px -1px 4px rgba(255,255,255,0.5); padding: 6px !important; } #btn-b, #btn-a { position: absolute !important; width: 38px !important; height: 38px !important; border-radius: 50% !important; background: #a91244 !important; color: transparent !important; box-shadow: inset -3px -3px 5px rgba(0,0,0,0.5), inset 2px 2px 4px rgba(255,255,255,0.3), 3px 5px 6px rgba(0,0,0,0.3) !important; border: none !important; min-width: 0 !important; z-index: 2; padding: 0 !important; margin: 0 !important; } #btn-b { top: 6px; left: 14px; } #btn-a { top: 6px; right: 14px; } .action-labels { position: absolute; width: 140px; display: flex; justify-content: space-between; padding: 0 24px; bottom: -22px; left: 0; color: #2b2b6c; font-family: sans-serif; font-weight: bold; font-size: 13px; transform: rotate(28deg); pointer-events: none; } /* --- SECURELY CENTERED START/SELECT BUTTONS --- */ #bottom-section { position: relative; height: 72px; display: flex; } #start-sel-container { display: flex; position: relative; gap: 22px; margin-left: 104px !important; margin-top: 4px !important; } #btn-select, #btn-start { width: 44px !important; height: 11px !important; min-width: 0 !important; background: #7b8085 !important; border-radius: 6px !important; transform: rotate(-28deg); border: none !important; box-shadow: inset -1px -1px 3px rgba(0,0,0,0.5), inset 1px 1px 2px rgba(255,255,255,0.3), 2px 3px 4px rgba(0,0,0,0.25) !important; color: transparent !important; margin: 0 !important; padding: 0 !important; } .start-sel-labels { position: absolute; top: 24px; left: -4px; display: flex; gap: 24px; color: #2b2b6c; font-family: sans-serif; font-weight: bold; font-size: 11px; pointer-events: none; } /* --- RIGHT CORNER SPEAKER GRILL --- */ #speaker-container { position: absolute; bottom: -10px; right: 14px; display: flex; gap: 5.5px; transform: rotate(-28deg); } .speaker-slit { width: 5px; height: 52px; background: #c8c8c8; border-radius: 3px; box-shadow: inset 1.5px 1.5px 3px rgba(0,0,0,0.45), 0.5px 0.5px 1px rgba(255,255,255,0.6); } /* --- INTERACTIVE CONTROL TOGGLES --- */ #utilities-bar { justify-content: center; gap: 12px; margin-bottom: 24px; background: #eaeaea; padding: 12px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.08); } #status-text p { color: #f3f4f6; text-align: center; font-family: monospace; font-size: 0.85em; margin-top: 8px; } /* --- LIVE MODEL LOG MATRIX TRACE --- */ #model-trace-box { margin: 25px auto 0 auto; width: 390px !important; max-width: 390px !important; } #model-trace-box textarea { background-color: #0d1117 !important; color: #58a6ff !important; font-family: "Courier New", Courier, monospace !important; font-size: 11px !important; line-height: 1.4 !important; border: 1px solid #30363d !important; border-radius: 6px !important; box-shadow: inset 0px 0px 8px rgba(0,0,0,0.8) !important; } """ with gr.Blocks(title="Neural GB", css=GAMEBOY_CSS) as demo: gr.Markdown("# Neural GB\nA Game Boy whose logic units are neural networks — " "each verified bit-exact over its complete input domain. " "Gameplay runs the golden units; press **Verify frame neurally** to " "re-render the current frame with every unit neural and check bit-identity live.") state = gr.State(None) play_timer = gr.Timer(0.15, active=False) # continuous game loop with gr.Row(elem_id="utilities-bar"): on_btn = gr.Button("⏻ Power On", variant="primary") v_btn = gr.Button("🔬 Verify frame neurally", variant="secondary") b_wait = gr.Button("⏸ pause / resume") with gr.Column(elem_id="gameboy-shell"): # Upper Screen Enclosure with gr.Column(elem_id="screen-bezel"): scr = gr.Image(value=screen(None), type="pil", show_label=False, interactive=False) status = gr.Markdown(OFF_MSG, elem_id="status-text") gr.HTML('
Quaztendo NEURAL BOYTM
') # Primary Action Inputs Layout with gr.Row(elem_id="middle-section"): # Flush Integrated D-Pad Cross with gr.Column(elem_id="dpad-container"): gr.HTML('
') b_up = gr.Button("", elem_id="btn-up") b_down = gr.Button("", elem_id="btn-down") b_left = gr.Button("", elem_id="btn-left") b_right = gr.Button("", elem_id="btn-right") # Angular Rotated Action Tray with gr.Row(elem_id="action-container"): b_b = gr.Button("", elem_id="btn-b") b_a = gr.Button("", elem_id="btn-a") gr.HTML('
BA
') # Lower Auxiliary Controls and Speaker Frame with gr.Row(elem_id="bottom-section"): with gr.Column(elem_id="start-sel-container"): b_sel = gr.Button("", elem_id="btn-select") b_start = gr.Button("", elem_id="btn-start") gr.HTML('
SELECTSTART
') gr.HTML("""
""") # Live Neural Trace Panel Output trace_box = gr.Textbox( value="[SYSTEM STATUS: STANDBY]\nSelect 'Power On' to trace running tensor weights...", lines=12, label="⚡ Live Model Runtime & Register Matrix Trace", elem_id="model-trace-box", interactive=False ) gr.Markdown("---") with gr.Accordion("What you are looking at — the full write-up", open=True): gr.Markdown(WRITEUP) on_btn.click(power_on, state, [state, scr, status, trace_box, play_timer]) for btn, key in [(b_up, "up"), (b_down, "down"), (b_left, "left"), (b_right, "right"), (b_a, "a"), (b_b, "b"), (b_start, "start"), (b_sel, "select")]: btn.click(gb_enqueue, [state, gr.State(key)], state) b_wait.click(gb_pause, state, [state, status]) play_timer.tick(gb_tick, state, [state, scr, status, trace_box]) v_btn.click(verify_neural, state, [scr, status, trace_box]) demo.launch()