ART / Assets
Assets
Sprite sheets, tilesets, fonts, folder rules, and visual resource notes.
Assets
All visual assets live in the assets/ directory, organized into categorized subdirectories. Sprites are PNG files (loaded via SDL2_image), sounds are WAV files in assets/sounds/, and fonts are in assets/fonts/.
assets/
├── fonts/ ← TrueType fonts
├── sounds/ ← Audio files (see Sounds page)
│ ├── collectibles/
│ ├── entities/
│ ├── hazards/
│ ├── levels/
│ ├── player/
│ ├── screens/
│ ├── surfaces/
│ └── unused/
└── sprites/ ← PNG sprite sheets and textures
├── backgrounds/ ← Parallax background layers
├── collectibles/ ← Coins, stars
├── entities/ ← Enemy sprites
├── foregrounds/ ← Fog, water, lava, clouds
├── hazards/ ← Spike, saw, flame sprites
├── levels/ ← Level tilesets and themes
├── player/ ← Player sprite sheet
├── screens/ ← HUD, menu assets
├── surfaces/ ← Platforms, bridges, vines, etc.
└── unused/ ← Reserve assets for future use
Coordinate note: All game objects use logical space (400x300). SDL scales to the 800x600 OS window 2x. A 48x48 sprite appears as 96x96 physical pixels on screen.
Per-Level Asset Configuration
Several visual elements are configurable per TOML level file, allowing different themes without changing code:
Floor Tile
floor_tile_path = "assets/sprites/levels/grass_tileset.png"
Any 48×48 PNG tile can be substituted here. The engine 9-slice renders it across FLOOR_Y to form the ground.
Parallax Background Layers
[[background_layers]]
path = "assets/sprites/backgrounds/sky_blue.png"
speed = 0.0
[[background_layers]]
path = "assets/sprites/backgrounds/glacial_mountains.png"
speed = 0.2
Layers are TOML array-of-tables and are drawn in array order (first = furthest back). speed is the parallax scroll factor: 0.0 = static sky, 1.0 = locks to camera, 0.1–0.5 = typical mid-ground parallax. Up to 8 layers are supported. See Level Design for the full list of available background images and suggested speeds.
Foreground Strip and Fog Layers
foreground_layers currently select the level foreground strip texture used by the water/lava renderer; the active runtime takes the last valid configured path. Atmospheric overlays are configured separately with fog_layers and loaded into the fog system.
[[foreground_layers]]
path = "assets/sprites/foregrounds/water.png"
speed = 0.0
[[fog_layers]]
path = "assets/sprites/foregrounds/fog_1.png"
[[fog_layers]]
path = "assets/sprites/foregrounds/fog_2.png"
Currently Used Assets
Backgrounds — assets/sprites/backgrounds/
| File | Used By | Description |
|---|---|---|
sky_blue.png | levels/00_sandbox_01.toml | Static sky gradient backdrop |
clouds_bg.png | levels/00_sandbox_01.toml | Background cloud layer |
glacial_mountains.png | levels/00_sandbox_01.toml | Distant mountains |
clouds_mg_3.png | levels/00_sandbox_01.toml | Midground cloud layer 3 |
clouds_mg_2.png | levels/00_sandbox_01.toml | Midground cloud layer 2 |
clouds_lonely.png | levels/00_sandbox_01.toml | Single cloud layer |
clouds_mg_1.png | levels/00_sandbox_01.toml | Foreground cloud layer |
sky_fire.png | levels/01_lugio_01.toml, 02_lugio_02.toml | Volcanic sky backdrop |
sky_fire_lightened.png | levels/01_lugio_01.toml, 02_lugio_02.toml | Lightened volcanic sky variant |
volcanic_mountains.png | levels/01_lugio_01.toml, 02_lugio_02.toml | Volcanic mountain layer |
volcanic_mountains_lightened.png | levels/01_lugio_01.toml, 02_lugio_02.toml | Lightened volcanic mountains |
smoke_bg.png, smoke_mg_1.png, smoke_mg_2.png, smoke_mg_3.png, smoke_lonely.png | Volcanic levels | Smoke parallax layers |
Foregrounds — assets/sprites/foregrounds/
| File | Used By | Description |
|---|---|---|
fog_1.png | fog_layers / fog.c (fog->textures[0]) | Fog overlay layer, semi-transparent sliding effect |
fog_2.png | fog_layers / fog.c (fog->textures[1]) | Fog overlay layer, semi-transparent sliding effect |
water.png | foreground_layers / water->texture | 384x64 sprite sheet, 8 frames of 48x64 with 16x31 art crop |
lava.png | foreground_layers / water->texture | Lava-themed foreground strip |
clouds.png | foreground clouds | Decorative cloud layer |
fog_fire_1.png, fog_fire_2.png, smoke.png | Volcanic levels | Fire fog / smoke overlay layers |
Player — assets/sprites/player/
| File | Used By | Description |
|---|---|---|
player.png | player->texture | 192x288 sprite sheet, 4 cols x 6 rows, 48x48 frames |
Entities — assets/sprites/entities/
| File | Used By | Description |
|---|---|---|
spider.png | gs->textures.spider | Spider enemy sprite sheet (ground patrol) |
jumping_spider.png | gs->textures.jumping_spider | Jumping spider enemy sprite sheet |
bird.png | gs->textures.bird | Slow sine-wave bird enemy sprite sheet |
faster_bird.png | gs->textures.faster_bird | Fast aggressive bird enemy sprite sheet |
fish.png | gs->textures.fish | Jumping fish enemy sprite sheet |
faster_fish.png | gs->textures.faster_fish | Faster fish enemy sprite sheet |
Collectibles — assets/sprites/collectibles/
| File | Used By | Description |
|---|---|---|
coin.png | gs->textures.coin | 16x16 coin collectible sprite |
star_yellow.png | gs->textures.star_yellow | Yellow star collectible sprite |
star_green.png | gs->textures.star_green | Green star collectible sprite |
star_red.png | gs->textures.star_red | Red star collectible sprite |
last_star.png | gs->textures.last_star | Last star goal collectible sprite |
Hazards — assets/sprites/hazards/
| File | Used By | Description |
|---|---|---|
spike.png | gs->textures.spike | Floor/ceiling spike hazard |
spike_block.png | gs->textures.spike_block | Rail-riding rotating hazard sprite |
spike_platform.png | gs->textures.spike_platform | Spiked platform hazard sprite |
circular_saw.png | gs->textures.circular_saw | Rotating saw blade hazard |
axe_trap.png | gs->textures.axe_trap | Swinging axe trap hazard |
blue_flame.png | gs->textures.blue_flame | Blue flame hazard sprite |
fire_flame.png | gs->textures.fire_flame | Fire flame hazard sprite |
Surfaces — assets/sprites/surfaces/
| File | Used By | Description |
|---|---|---|
float_platform.png | gs->textures.float_platform | 48x16 sprite, 3-slice horizontal strip (left cap, centre fill, right cap) |
bridge.png | gs->textures.bridge | 16x16 single-frame brick tile for crumble walkways |
bouncepad_small.png | gs->textures.bouncepad_small | Small bouncepad sprite (low launch) |
bouncepad_medium.png | gs->textures.bouncepad_medium | Medium bouncepad sprite (standard launch) |
bouncepad_high.png | gs->textures.bouncepad_high | High bouncepad sprite (max launch) |
rail.png | gs->textures.rail | 64x64 sprite sheet, 4x4 grid of 16x16 bitmask rail tiles |
vine_green.png | gs->textures.vine_green | 16x48 green climbable vine sprite |
vine_brown.png | gs->textures.vine_brown | 16x48 brown climbable vine sprite |
ladder.png | gs->textures.ladder | Climbable ladder sprite |
rope.png | gs->textures.rope | Climbable rope sprite |
Levels — assets/sprites/levels/
| File | Used By | Description |
|---|---|---|
grass_tileset.png | gs->textures.floor_tile | 48x48 tile, 9-slice rendered across FLOOR_Y to form the floor |
grass_platform.png | gs->textures.platform | 48x48 tile, 9-slice rendered as one-way platform pillars |
stone_tileset.png | Volcanic levels | 48x48 stone floor tileset |
stone_platform.png | Volcanic levels | Stone platform pillar tile |
grass_rock_tileset.png, grass_rock_platform.png | Reserve / level theming | Grass-rock floor/platform variants |
brick_tileset.png, brick_platform.png | Reserve / level theming | Brick floor/platform variants |
leaf_tileset.png, leaf_platform.png | Reserve / level theming | Forest leaf floor/platform variants |
cloud_tileset.png | Reserve / level theming | Cloud tileset |
Screens — assets/sprites/screens/
| File | Used By | Description |
|---|---|---|
hud_coins.png | hud.c | Coin count UI icon used in the HUD |
start_menu_logo.png | start_menu.c | Game logo displayed on the start menu screen |
Fonts — assets/fonts/
| File | Used By | Description |
|---|---|---|
round9x13.ttf | hud.c (hud->font) | Bitmap font for score and lives text in the HUD |
Player Sprite Sheet — player.png
Sheet dimensions: 192 x 288 px Grid: 4 columns x 6 rows Frame size: 48 x 48 px
Animation Row Map
| Row | AnimState | Frame Count | Frame Duration | Notes |
|---|---|---|---|---|
| 0 | ANIM_IDLE | 4 | 150 ms/frame | Subtle breathing cycle |
| 1 | ANIM_WALK | 4 | 100 ms/frame | Looping run cycle |
| 2 | ANIM_JUMP | 2 | 150 ms/frame | Rising phase poses |
| 3 | ANIM_FALL | 1 | 200 ms/frame | Descent pose |
| 4 | ANIM_CLIMB | 2 | 100 ms/frame | Vine climbing cycle |
| 5 | (unused) | — | — | Available for future states |
Frame Source Rect Formula
frame.x = anim_frame_index * FRAME_W; // column x 48
frame.y = ANIM_ROW[anim_state] * FRAME_H; // row x 48
Horizontal Flipping
When player->facing_left == 1, the sprite is drawn with SDL_FLIP_HORIZONTAL via SDL_RenderCopyEx. This means the same right-facing animation frames are used for both directions — no duplicate assets needed.
Unused Assets
The following asset is stored in assets/sprites/unused/ and is not loaded by the game. It is available as a reserve for future use.
| File | Description |
|---|---|
sky_background_0.png | Sky gradient background |
Additional background variants are stored alongside used backgrounds in assets/sprites/backgrounds/:
| File | Description |
|---|---|
castle_pillars.png | Castle/dungeon pillar background |
clouds_mg_1_lightened.png | Lightened midground cloud variant |
forest_leafs.png | Forest leaf layer |
glacial_mountains_lightened.png | Lightened mountain variant |
sky_blue_lightened.png | Lightened sky variant |
Additional tilesets are stored in assets/sprites/levels/:
| File | Description |
|---|---|
brick_platform.png | Brick platform tile |
brick_tileset.png | Brick wall / platform tile |
cloud_tileset.png | Cloud platform tile |
grass_rock_platform.png | Grass + rock platform tile |
grass_rock_tileset.png | Grass + rock mixed tileset |
leaf_platform.png | Leaf / foliage platform tile |
leaf_tileset.png | Leaf / foliage platform tile |
stone_platform.png | Stone platform tile |
stone_tileset.png | Stone floor / wall tile |
Sprite Sheet Analysis
To inspect any sprite sheet’s exact dimensions and pixel layout:
python3 .agents/scripts/analyze_sprite.py assets/sprites/<category>/<sprite>.png
Frame Math Reference
Sheet width = cols x frame_w
Sheet height = rows x frame_h
source_x = (frame_index % cols) * frame_w
source_y = (frame_index / cols) * frame_h
Loading an Asset
// In game_init or an entity's init function:
SDL_Texture *tex = IMG_LoadTexture(gs->renderer, "assets/sprites/collectibles/coin.png");
if (!tex) {
fprintf(stderr, "Failed to load coin.png: %s\n", IMG_GetError());
return -1;
}
// At cleanup (reverse init order):
if (tex) { SDL_DestroyTexture(tex); tex = NULL; }