---
title: "Graphics"
type: 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:

```javascript
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 pos
- `anchor_x: 0.5, anchor_y: 0.5` — center at pos
- `anchor_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:

```javascript
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:

```javascript
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:

```javascript
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:

```javascript
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:

```javascript
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.

```javascript
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.
