irregular6612's picture
refactor: restructure proteus into game/web subpackages
426093b
|
Raw
History Blame Contribute Delete
3.04 kB
# 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`