Super Mango manualPlay

Collectibles & Surfaces


Collectibles are items the player can pick up. Surfaces are interactive terrain the player can stand on, jump from, or climb. All positions are in logical pixels (400×300 space).


Collectibles

Coin

File: src/collectibles/coin.c / coin.h
Sprite: assets/sprites/collectibles/coin.png — 16×16 px display size
Pickup: AABB overlap with player. Plays gs->audio.coin on collection.

Constant Value Description
MAX_COINS 64 Coin slots in GameState
COIN_DISPLAY_W/H 16 Render size in logical px
COIN_SCORE 100 Points awarded per coin
SCORE_PER_LIFE 1000 Score threshold for a bonus life
[[coins]]
x = 46.0
y = 236.0   # top edge in logical pixels

With defaults, every 1000 points (10 coins) earns a bonus life. Both coin_score and score_per_life are configurable in the level file.

Collected coins stay gone for the whole attempt. Losing a life respawns enemies, hazards, surfaces and stars, but not coins: score and the bonus-life threshold survive a death, so returning coins would let a player farm points and lives by dying on purpose. Coins come back only for a fresh attempt — Retry after game over, Replay, or loading a level — and the completion summary counts every coin collected during the attempt. Health stars and the last star do respawn after a life loss: they award no score, so each life simply meets the healing the level was designed with.


Star Yellow

File: src/collectibles/health_star.c / health_star.h (shared by all three star colours)
Sprite: assets/sprites/collectibles/star_yellow.png — 16×16 px display size
Pickup: AABB overlap. Restores 1 heart (up to MAX_HEARTS, 3). No score awarded.

The three colours are one collectible: a single HealthStar struct, health_stars_render() and health_star_get_hitbox(), and one collect_health_stars() loop in src/collision/game_collision.c. The level file and GameState still keep a separate array and texture per colour.

Constant Value Description
MAX_STAR_YELLOWS 16 Slots in GameState
HEALTH_STAR_DISPLAY_W/H 16 Render size of every star colour in logical px
[[star_yellows]]
x = 272.0
y = 108.0

Star Green

File: src/collectibles/health_star.c / health_star.h (same HealthStar module as yellow; MAX_STAR_GREENS 16)
Sprite: assets/sprites/collectibles/star_green.png — 16×16 px
Pickup: Same as star yellow — restores 1 heart.

[[star_greens]]
x = 500.0
y = 80.0

Star Red

File: src/collectibles/health_star.c / health_star.h (same HealthStar module as yellow; MAX_STAR_REDS 16)
Sprite: assets/sprites/collectibles/star_red.png — 16×16 px
Pickup: Same as star yellow — restores 1 heart.

[[star_reds]]
x = 800.0
y = 100.0

Last Star

File: src/collectibles/last_star.c / last_star.h
Sprite: assets/sprites/collectibles/last_star.png
Display size: 24×24 px
Pickup: Collecting it sets collected = 1, snapshots the level-completion summary, and shows the completion overlay. With next_phase, terminal actions are Next Level, Replay, Level Select, and Exit; otherwise they are Replay, Level Select, and Exit. Up/Down or D-pad changes focus, Enter/Space/Start (or A) confirms, and Esc/Back (or B) exits. Only one instance per level, defined with [last_star].

Constant Value Description
LAST_STAR_DISPLAY_W/H 24 Render size in logical px
[last_star]
x = 1492.0
y = 100.0

Surfaces

Platform (Ground Pillar)

File: src/surfaces/platform.c / platform.h
Sprite: assets/sprites/levels/grass_platform.png by default, or the pillar’s own tile_path — 48×48 tile, 9-slice rendered
Behaviour: Static ground pillar. The player can land on the top surface. Pillars are positioned on the floor and extend upward, sunk 16 px into the ground. Rendered before the floor so the pillar base sinks into the ground naturally.

Constant Value Description
MAX_PLATFORMS 32 Pillar slots per level
[[platforms]]
x           = 80.0   # left edge in logical pixels
tile_height = 2      # height in 48px tiles (1–5)
tile_width  = 1      # width in 48px tiles (0 or omitted = 1)

Top surface Y for a pillar: FLOOR_Y − (tile_height × TILE_SIZE) + 16 = 268 − (h × 48).

tile_height Top Y Typical use
1 220 Step / obstacle
2 172 Standard platform
3 124 Tall — use a bouncepad, climbable or intermediate ledge
4 76 Very tall
5 28 Maximum height

Float Platform

File: src/surfaces/float_platform.c / float_platform.h
Sprite: assets/sprites/surfaces/float_platform.png — 48×16 px, 3-slice (left cap | centre fill | right cap)
Behaviour: Hovering one-way surface. Player lands on the top face only (one-way collision — can jump through from below). Three modes:

Mode Behaviour
STATIC Fixed position, never moves
CRUMBLE Begins falling after the player stands on it for 0.75 s without stepping off (stepping off resets the timer); it reappears when the level resets after a life loss
RAIL Travels along a rail path at constant speed, carrying the player; on an open rail it bounces at both ends and never detaches
Constant Value Description
MAX_FLOAT_PLATFORMS 16 Slots in GameState
FLOAT_PLATFORM_PIECE_W 16 Width of each 3-slice piece
FLOAT_PLATFORM_H 16 Platform height in px
CRUMBLE_STAND_LIMIT 0.75 s Time before crumble fall starts
CRUMBLE_FALL_GRAVITY 250 px/s² Downward acceleration during fall
[[float_platforms]]
mode       = "STATIC"   # "STATIC" | "CRUMBLE" | "RAIL"
x          = 172.0
y          = 200.0
tile_count = 4          # width in 16px pieces (1–16)
rail_index = 0          # RAIL mode only: index into [[rails]]
t_offset   = 0.0        # RAIL mode only: starting position on rail
speed      = 0.0        # RAIL mode only: traversal speed in tiles/s

Bridge

File: src/surfaces/bridge.c / bridge.h
Sprite: assets/sprites/surfaces/bridge.png — 16×16 px brick tile
Behaviour: Tiled crumble walkway. Each brick under the player’s centre starts its own timer on first contact and falls BRIDGE_FALL_DELAY later, so only the bricks the player actually steps on drop, creating a time-limited path. Fallen bricks stay gone until the level resets after a life loss (or a fresh attempt).

Constant Value Description
MAX_BRIDGES 16 Bridge slots in GameState
MAX_BRIDGE_BRICKS 16 Maximum bricks in one bridge
BRIDGE_FALL_DELAY 0.2 s Delay between touching a brick and its fall

Bricks do not cascade on their own: each brick falls only after the player steps on it.

[[bridges]]
x           = 1350.0
y           = 172.0
brick_count = 8   # number of 16×16 brick tiles (1–16)

Bouncepad

File: src/surfaces/bouncepad.c / bouncepad.h
Sprites: bouncepad_small.png, bouncepad_medium.png (wood), bouncepad_high.png
Sheet: 144×48 px, 3 columns × 1 row — Frame 0: extended, Frame 1: mid-compress, Frame 2: compressed (default idle state)
Behaviour: Spring pad that launches the player upward on landing. Plays a 3-frame squash/release animation (2→1→0, 80 ms/frame) then resets to idle. The small, medium and high pads stay in their three GameState arrays; player_update receives them as BouncepadList views (pointer + count) and reports the landed pad as a flat index across the lists, so nothing is copied per frame.

Constant Value Description
BOUNCEPAD_W/H 48 Display size in logical px
BOUNCEPAD_VY_SMALL −380.0 Usual launch impulse for green pad (the loader uses each pad’s authored launch_vy as written)
BOUNCEPAD_VY_MEDIUM −536.25 Launch impulse for wood pad
BOUNCEPAD_VY_HIGH −700.0 Launch impulse for red pad
BOUNCEPAD_FRAME_MS 80 ms per animation frame during release
BOUNCEPAD_SRC_Y 14 Art starts at row 14 (transparent above)
BOUNCEPAD_SRC_H 18 Art height = rows 14–31
BOUNCEPAD_ART_X 16 Art starts at col 16 (transparent outside)
BOUNCEPAD_ART_W 16 Hitbox width = cols 16–31
MAX_BOUNCEPADS_SMALL 16 Small bouncepad slots
MAX_BOUNCEPADS_MEDIUM 16 Medium bouncepad slots
MAX_BOUNCEPADS_HIGH 16 High bouncepad slots
[[bouncepads_small]]
x         = 734.0
launch_vy = -380.0
pad_type  = "GREEN"

[[bouncepads_medium]]
x         = 310.0
launch_vy = -536.2
pad_type  = "WOOD"

[[bouncepads_high]]
x         = 1420.0
launch_vy = -700.0
pad_type  = "RED"

Rail

File: src/surfaces/rail.c / rail.h
Sprite: assets/sprites/surfaces/rail.png — 64×64 px, 4×4 grid of 16×16 bitmask tiles
Behaviour: A path of interconnected tiles that spike blocks and float platforms ride along. Each tile has a bitmask of connection directions (N/E/S/W) that drives the correct sprite selection. Objects riding a rail store a float t ∈ [0, tile_count) and call rail_get_world_pos() each step. w and h are 2–128 tiles and a RECT loop has at most 128 tiles. At an open (HORIZ) end without a cap, a spike block detaches and falls; float platforms always bounce.

Constant Value Description
RAIL_N/E/S/W 1/2/4/8 Connection bitmask flags
RAIL_TILE_W/H 16 Tile size in the sprite sheet
MAX_RAIL_TILES 128 Max tiles per Rail instance
MAX_RAILS 16 Rail instances in GameState
[[rails]]
layout  = "RECT"   # "RECT" = closed rectangle | "HORIZ" = open horizontal line
x       = 444      # top-left tile x
y       = 35       # top-left tile y
w       = 10       # width in tiles
h       = 6        # height in tiles
end_cap = 0        # HORIZ only: 0 = open end (spike block detaches), 1 = bouncing end

Vine

File: src/surfaces/vine.c / vine.h
Sprites: assets/sprites/surfaces/vine_green.png, assets/sprites/surfaces/vine_brown.png — 16×48 px per tile
Behaviour: Press Up while overlapping to grab (without holding Jump), then Up/Down to climb and Left/Right to drift. Jump dismounts; leaving the grab area also detaches.

Constant Value Description
MAX_VINES 24 Vine slots in GameState
VINE_W/H 16×32 Cropped climbable art size
VINE_STEP 19 Vertical spacing between tile starts
[[vines]]
x          = 88.0
y          = 172.0   # top tile y in logical pixels
tile_count = 2       # cropped height = 32 + (tile_count - 1) * 19 = 51 px
vine_type  = 0       # optional art variant: 0 = green, 1 = brown

For every climbable, tile_count is at least 1 and the whole stack must fit inside the world.


Ladder

File: src/surfaces/ladder.c / ladder.h
Sprite: assets/sprites/surfaces/ladder.png
Behaviour: Uses the same Up-to-grab, Up/Down climb, horizontal drift and Jump-to-dismount controls as vines.

Constant Value Description
MAX_LADDERS 16 Ladder slots in GameState
LADDER_W/H 16×22 Cropped climbable art size
LADDER_STEP 8 Vertical spacing between tile starts
[[ladders]]
x          = 1552.0
y          = 0.0       # top tile y
tile_count = 30        # height in tiles

Rope

File: src/surfaces/rope.c / rope.h
Sprite: assets/sprites/surfaces/rope.png
Behaviour: Same interaction model as the vine: Up to grab, Up/Down to climb, Left/Right to drift, and Jump to dismount. There is no rope-swing simulation.

Constant Value Description
MAX_ROPES 16 Rope slots in GameState
ROPE_W/H 16×36 Cropped climbable art size
ROPE_SRC_X/Y/W/H 0 / 6 / 16 / 36 Source crop from the 16×48 sprite
ROPE_STEP 23 Vertical spacing for stacked rope tiles
[[ropes]]
x          = 460.0
y          = 172.0
tile_count = 1