Files
prosperon/docs/rendering.md
John Alanbrook 83b798e365 Add Hugo website and rewrite docs to match current engine
New Hugo site in website/ with prosperon.dev theme (blue/gold/castle
aesthetic), docs sidebar navigation, and content pages. Rewrote all
doc files to align with the actual codebase: compositor+film2d
rendering, use() modules (no global prosperon object), Pit language,
script+JSON entity model. Added entities.md, front matter to all
70+ API docs, and updated API index for current module architecture.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 18:09:55 -06:00

114 lines
4.0 KiB
Markdown

---
title: "Rendering"
type: docs
---
# Rendering
Prosperon's rendering is **data-driven**. You create sprites and other drawables, set their properties, and the engine handles drawing them. You never touch the GPU directly.
## The Model
Think of it like programming sprites on a classic console:
1. **Create** a sprite (or text, shape, tilemap, particle emitter)
2. **Set** its position, image, layer, and visual properties
3. The engine **draws** everything each frame, sorted and batched automatically
```javascript
var sprite = use('sprite')
var player = sprite({
image: "player.png",
pos: {x: 100, y: 200},
layer: 5
})
// Move it later
player.pos.x = 150
player.pos.y = 250
```
That's it. The sprite is registered with the engine when created and drawn every frame until destroyed.
## Coordinate System
There are two coordinate spaces:
**World space** is the game world. The camera's position determines what's visible. If the camera is at `[100, 100]`, that world coordinate is at the center of the screen. X+ goes right, Y+ goes up.
**HUD space** is the screen itself. `[0, 0]` is the bottom-left corner, `[camera.width, camera.height]` is the top-right. HUD elements don't move with the camera.
## Layers
Every drawable has a `layer` — an integer that determines draw order. Lower layers draw first (behind), higher layers draw last (in front).
Within a layer, objects can be sorted by different criteria:
- **explicit** (default) — engine may reorder for performance
- **y-sort** — sort by Y position, useful for top-down games where "lower" objects appear in front
## Planes
Drawables are organized into **planes**. A plane is a named group that can have its own resolution, camera, and effects. By default, everything goes into the `'default'` plane.
Planes render independently and composite onto the screen. This lets you have a game world at 320x240 pixel-art resolution and a HUD at native resolution, for example.
## Effects
Planes and groups of sprites can have effects applied:
- **Bloom** — threshold + multi-pass Gaussian blur
- **Mask** — stencil masking using other sprites as the mask shape
Effects are declared in the compositor config and applied automatically. You tag sprites with groups, then apply effects to those groups.
## Presentation Modes
The final composited frame is presented to the window in one of three modes:
| Mode | Behavior |
|------|----------|
| `stretch` | Fill the window, may distort |
| `letterbox` | Fit inside window, preserve aspect ratio, black bars |
| `integer_scale` | Scale by whole numbers only, nearest-neighbor, pixel-perfect |
## Camera
A camera defines the viewport into the world:
```javascript
var camera = use('camera')
var cam = camera.make({
pos: {x: 0, y: 0},
width: 320,
height: 240
})
```
The camera's `width` and `height` set the game's internal resolution. The `pos` determines what world coordinate is at the center of the screen.
## Drawable Types
| Type | Module | Description |
|------|--------|-------------|
| Sprite | `sprite` | Textured quad with transform, tint, UV mapping |
| Text | `text2d` | Rendered text with font, size, wrapping |
| Shape | `shape2d` | SDF-rendered rectangles, circles, ellipses, pills |
| Tilemap | `tilemap2d` | Grid of tiles on a single layer |
| Particles | `particles2d` | Particle emitter producing sprite-like particles |
| Line | `line2d` | Polylines and line segments as triangle meshes |
All drawable types share common properties: `pos`, `layer`, `plane`, `groups`, `visible`, `opacity`, `tint`.
## How It Works Internally
For those curious about the pipeline (you don't need to know this to use Prosperon):
1. Drawables register with `film2d` — the internal sprite registry
2. Each frame, the **compositor** queries film2d for all visible drawables
3. Drawables are sorted by layer, batched by texture/material
4. Effect groups are rendered to intermediate targets, effects applied
5. Planes composite to the screen via the **SDL GPU backend**
6. The backend uses Metal, Vulkan, or DirectX depending on platform