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:

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 - Dead simple game that really only uses Engine Logic (Pixel Perfect Collision). Merge - Another Dead simple game that shows off Pixel Perfect Collision and Sprite Merging. Complex Maze - Added Mechanics onto Simple Maze and demonstrates ToggleableUserDisplay Merge/Detatch - Adds in the ability to detatch merged sprites and demonstrates writing a custom RenderableUserDisplay