# proteus.game.engine The **game engine subpackage** for PROTEUS. Wraps the vendored ARC-AGI 64×64 grid/sprite engine (`arcengine/`) with PROTEUS-specific layers: grid game logic, difficulty scaling, ASCII visualization, and the core renderer. ``` proteus/game/engine/ ├── __init__.py # re-exports the full public surface (engine + renderer) ├── rendering.py # visualization: 16-color palette, frame -> RGB / terminal ├── grid.py # MotiveGridGame: PROTEUS grid game subclass of ARCBaseGame ├── difficulty.py # difficulty scaling helpers ├── ascii_view.py # ASCII/ANSI terminal view utilities └── arcengine/ # vendored engine (arcprize/ARCEngine, MIT) ├── enums.py # FrameData / FrameDataRaw, GameAction, GameState, color/mode enums ├── sprites.py # Sprite: the pixel-grid primitive (rotation, scale, collision) ├── interfaces.py # RenderableUserDisplay / ToggleableUserDisplay (UI overlays) ├── camera.py # Camera: sprites -> 64×64 frame (auto-scale + letterbox) ├── level.py # Level: a group of sprites + placeable areas ├── base_game.py # ARCBaseGame: the turn-based game loop ├── OVERVIEW.md # engine design notes ├── LICENSE # MIT (ARC Prize Foundation) └── py.typed ``` ## What's the "grid"? A **frame** is a list of layers; each layer is a **64×64** array of integers **0–15** (palette indices). Two representations of the same data live in `arcengine/enums.py`: | Type | `frame` field | Use | |---|---|---| | `FrameData` (pydantic) | `list[list[list[int]]]` | JSON / wire format | | `FrameDataRaw` | `list[numpy.ndarray]` (int8) | runtime format | Engine invariants: 64×64 output · 16 colors · 6 actions + `RESET` · turn-based · each input yields 1–N frames. ## Dependencies | Need | Requires | |---|---| | Engine (`proteus.game.engine.arcengine`) | `numpy`, `pydantic` | | Renderer core (`frame_to_rgb_array`, `COLOR_MAP`) | `numpy` | | Animated display (`render_frames`) | `matplotlib` (optional; guarded by a `try`-import) | ```bash pip install numpy pydantic # minimum pip install matplotlib # only if you use render_frames() ``` ## Usage ### Draw a raw 64×64 grid (engine not required) ```python import numpy as np from proteus.game.engine import frame_to_rgb_array, COLOR_MAP frame = np.zeros((64, 64), dtype=np.int8) frame[10:20, 10:20] = 8 # a red square (palette index 8) rgb = frame_to_rgb_array(0, frame, scale=4) # -> (256, 256, 3) uint8 # COLOR_MAP maps each 0–15 index to its hex color. ``` ### Render in the terminal ```python from proteus.game.engine import render_frames_terminal from proteus.game.engine import FrameDataRaw, GameState fd = FrameDataRaw() fd.frame = [frame] # list of 64×64 arrays fd.state = GameState.NOT_FINISHED render_frames_terminal(0, fd) # ANSI true-color, in-place ``` ### Build a game with the engine ```python from proteus.game.engine import ARCBaseGame, Camera, Level, Sprite # Subclass ARCBaseGame, populate Levels with Sprites, drive it with GameActions. # See arcengine/OVERVIEW.md and the upstream examples for the full loop. ``` ## Provenance * **Engine** — vendored verbatim from the `arcengine` pip package (v0.9.3). Internal imports are all relative, so the folder works unmodified inside `arcengine/`. * **Renderer** — copied from the ARC-AGI toolkit's `arc_agi/rendering.py`; the single external import `from arcengine import FrameDataRaw` was changed to the relative `from .arcengine import FrameDataRaw` so the subpackage is self-contained. The `arcengine/` boundary is preserved: to keep the engine fresh, re-vendor from upstream (`arcprize/ARCEngine`) or swap `arcengine/` for a pip dependency on `arcengine`. No changes outside this subpackage are needed. ## Attribution & License The `arcengine/` subpackage is **vendored from [arcprize/ARCEngine](https://github.com/arcprize/ARCEngine)**, © 2026 ARC Prize Foundation, **MIT License** (see `arcengine/LICENSE`). The renderer originates from the ARC-AGI toolkit (same foundation). Retain these notices when redistributing.