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>
114 lines
4.0 KiB
Markdown
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
|