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>
4.1 KiB
title, type
| title | type |
|---|---|
| Graphics | docs |
Graphics Concepts
This page covers the fundamental graphics concepts in Prosperon.
Textures and Images
A texture is a set of bytes on the GPU — not directly accessible from script code.
An image is a texture combined with a UV rect that specifies which region to draw:
image = {
texture: GPU texture handle,
rect: {x, y, width, height} // UV coordinates
}
This means multiple images can share one texture (a sprite sheet or atlas), each referencing a different region.
Supported Image Formats
| Format | Notes |
|---|---|
| PNG | Standard, lossless |
| QOI | Fast decode, lossless |
| GIF | Animated frames supported |
| JPG/JPEG | Lossy |
| Aseprite (.ase) | Frames, tags, slices, durations, pivots |
Aseprite files are fully parsed — named animation tags, per-frame durations, pivot points, and slice data are all available.
Sprites
A sprite is the fundamental drawable. Create one with the sprite module:
var sprite = use('sprite')
var s = sprite({
image: "player.png",
pos: {x: 100, y: 200},
width: 32,
height: null, // derived from aspect ratio
anchor_x: 0.5, // center horizontally
anchor_y: 0, // bottom edge
layer: 5,
rotation: 0,
flip: {x: false, y: false},
color: {r: 1, g: 1, b: 1, a: 1},
opacity: 1,
tint: {r: 1, g: 1, b: 1, a: 1},
filter: 'nearest',
plane: 'default',
groups: [],
visible: true
})
Fit Modes
When both width and height are specified, the fit property controls how the texture maps into the rectangle:
| Fit | Behavior |
|---|---|
none |
Use the texture's native pixel size |
fill |
Stretch to exactly fill the rectangle (may distort) |
contain |
Fit inside the rectangle, preserving aspect ratio |
cover |
Fill the rectangle, preserving aspect ratio (crops via UV) |
If only one dimension is given (e.g. width: 32, height: null), the other is derived from the texture's aspect ratio.
Anchors
The anchor determines which point of the sprite sits at pos:
anchor_x: 0, anchor_y: 0— top-left at posanchor_x: 0.5, anchor_y: 0.5— center at posanchor_x: 0.5, anchor_y: 0— bottom-center at pos (good for characters)
UV Mapping
For sprite sheets, control which region of the texture is drawn:
sprite({
image: spritesheet_texture,
uv: {offset: {x: 0.25, y: 0}, scale: {x: 0.25, y: 0.5}}
})
Text
Create text with the text2d module:
var text2d = use('text2d')
var label = text2d({
text: "Hello World",
font: "myfont.ttf",
size: 24,
pos: {x: 100, y: 100},
layer: 10
})
Shapes
SDF-rendered shapes via the shape2d module:
var shape2d = use('shape2d')
var box = shape2d.rect({
pos: {x: 50, y: 50},
width: 100,
height: 80,
color: {r: 1, g: 0, b: 0, a: 1},
layer: 3
})
var ball = shape2d.circle({
pos: {x: 200, y: 200},
radius: 25,
color: {r: 0, g: 1, b: 0, a: 1}
})
Available shapes: rect, circle, ellipse, pill.
Tilemaps
Grid-based tile rendering:
var tilemap2d = use('tilemap2d')
var map = tilemap2d({
tiles: tiles_2d_array,
tile_width: 16,
tile_height: 16,
layer: 0
})
Tiles can be flipped, and the entire tilemap can have an affine transform applied. Camera culling for large maps is planned.
Particles
Particle emitters produce sprite-like particles:
var particles2d = use('particles2d')
var emitter = particles2d({
texture: "spark.png",
pos: {x: 100, y: 100},
layer: 8
})
Coordinate System
Prosperon uses a Y-up coordinate system:
- X+ goes right
- Y+ goes up
[0, 0]in world space is where the camera starts[0, 0]in HUD space is the bottom-left of the screen
Camera
A camera defines the viewport into the world. Its width and height set the game's internal resolution. Its pos determines what world coordinate is at the center of the screen.
var camera = use('camera')
var cam = camera.make({
pos: {x: 0, y: 0},
width: 320,
height: 240
})
Everything in world space is drawn relative to the camera's position. HUD space is always screen-relative.