Spaces:
Sleeping
Sleeping
| # ARCEngine Overview | |
| ## Design Goals | |
| 1. The engine only enforces the same opinions as ARC-AGI-3: | |
| a. Visual: 64×64 output grid, 16 colors | |
| b. Inputs: limited to 6 actions plus a `RESET` | |
| c. Turn-based: no time advances without input | |
| d. Frames: each input generates 1–N frames | |
| 2. Beyond those opinions, ARCEngine handles: | |
| a. Creation and rendering of sprites | |
| b. Organization of sprites into levels | |
| c. Organization of levels into a game | |
| d. Sprite-based collisions | |
| e. Main rendering pipeline | |
| f. Sensible default settings | |
| ## Sensible Default Settings | |
| #### Camera Auto-Scaling (Not Overridable) | |
| The camera automatically scales up to fill as much of the 64×64 area as possible. You can only control this by setting the camera’s `width` and `height`. Examples: | |
| * `32×32` – Upscaled by 2×, fits perfectly into 64×64 | |
| * `30×30` – Upscaled by 2×, adds a 2-pixel letterbox around the screen | |
| * `30×15` – Upscaled by 2×, adds 2-pixel borders on the sides and 17-pixel borders on top and bottom | |
| * `15×15` – Upscaled by 4×, adds a 2-pixel letterbox around the screen | |
| #### `self.next_level()` Behavior (Overridable) | |
| By default, calling `self.next_level()` will: | |
| * Increment `_current_level_index` by 1 on `frame + 1` (the frame after `self.next_level()` is called) | |
| * Increment `_score` by 1 | |
| * Call `self.win()` if that was the last level | |
| You can override this entire method if you need custom behavior. | |
| #### `RESET` Action (Overridable) | |
| By default, a `RESET` action will: | |
| * Restart the current level (via `level_reset()`) if any actions have been taken | |
| * Otherwise, perform a full game reset (via `full_reset()`) | |
| Both `level_reset()` and `full_reset()` can be overridden with custom logic. | |
| ## Main Game and Render Loops | |
| #### Main Game Loop | |
| The main game loop is fixed. In pseudocode: | |
| ```pseudocode | |
| handle RESET action | |
| if game is won or lost: | |
| return [] | |
| frames = [] | |
| while action is not complete: | |
| STEP() ── game logic | |
| frames.append(RENDER()) | |
| return frames | |
| ``` | |
| #### Main Render Loop | |
| 1. Render all sprites visible to the camera at the camera’s resolution | |
| a. Uses the camera’s x and y properties | |
| 2. Upscale the raw render from step 1 and add letterboxing | |
| 3. Render the 64×64 UI on top | |
| a. UI always spans 0,0 to 63,63 | |
| ## Example Games | |
| [Simple Maze](https://github.com/arcprize/ARCEngine/blob/main/examples/simple_maze.py) - Dead simple game that really only uses Engine Logic (Pixel Perfect Collision). | |
| [Merge](https://github.com/arcprize/ARCEngine/blob/main/examples/merge.py) - Another Dead simple game that shows off Pixel Perfect Collision and Sprite Merging. | |
| [Complex Maze](https://github.com/arcprize/ARCEngine/blob/main/examples/complex_maze.py) - Added Mechanics onto Simple Maze and demonstrates `ToggleableUserDisplay` | |
| [Merge/Detatch](https://github.com/arcprize/ARCEngine/blob/main/examples/merge_detach.py) - Adds in the ability to detatch merged sprites and demonstrates writing a custom `RenderableUserDisplay` |