Examples and recipes
Every gallery entry is a complete cartridge under cartridges/<slug>/.
The gallery shows newer publications first by default. Sort by title or author when comparing examples, select any tag on a card to narrow the collection, or use Random to play one game from the visible results.
Learn one idea at a time
starter.tyntcovers lifecycle, movement, A/B input, and score.shapes.tyntdemonstrates every drawing primitive.sprites.tyntdraws the tynt mark and a two-frame character.coin-dash.tyntcombines sprites, tile maps, camera movement, timers, collisions, randomness, and audio.reaction.tyntturns deterministic frame timers into a complete reaction game.tiny-quest.tyntdemonstrates two-axis camera movement, world collisions, collectibles, and a goal zone.platformer.tynt,flappy.tynt,snake.tynt,pong.tynt, andasteroids.tyntare compact complete games.
Find an API in a game
| API | Good examples |
|---|---|
seed() and random() | reaction, snake, lunar, pong, flappy, asteroids, coin dash, tiny quest |
overlap() | pong, platformer, flappy, coin dash, tiny quest |
pointInRect() | snake, tiny quest |
clamp() and wrap() | starter, animation, soundboard |
frame(), every(), and after() | reaction, sprites, lunar, soundboard, coin dash |
camera() | coin dash, tiny quest |
buttonReleased() | starter, soundboard |
triangle() | starter, shapes |
tone() and sfx() | reaction, soundboard, snake, asteroids, platformer, flappy, pong, lunar, sokoban, sprites, coin dash, tiny quest |
Fixed HUD with a moving camera
camera(playerX - 76, 0);
sprite(HERO, 8, 8, playerX, playerY, 0);
camera();
text("SCORE " + score, 6, 6, 3);Deterministic timing
if (every(30)) tone(440, 50, 0.08);
if (after(60 * 10)) text("TIME", 68, 68, 3);frame() counts fixed updates rather than wall-clock time, so replays remain predictable. At 60 updates per second, divide a frame duration by 60 and multiply by 1,000 to display milliseconds.
Collision helpers
if (overlap(playerX, playerY, 8, 8, coinX, coinY, 5, 5)) {
score++;
}
if (pointInRect(playerX + 4, playerY + 4, exitX, exitY, 24, 28)) {
finishLevel();
}Use overlap() when two rectangular objects interact. Use pointInRect() for a center point, cursor, checkpoint, or goal zone.
Movement ranges and input edges
x = clamp(x + velocityX, 0, 152);
shade = wrap(shade + 1, 1, 4);
if (buttonReleased("a")) {
launchChargedShot();
}clamp() includes both ends of its range. wrap() includes min but wraps max back to min. buttonReleased() is true for exactly one update after a held input is released.
Triangles
triangle(80, 36, 104, 84, 56, 84, 3, true);The final argument selects a filled triangle. Omit it or pass false to draw only the three edges. Triangle coordinates follow camera() like every other drawing primitive.
Sound effects and rests
Open the sound editor at tynt.dev/sounds to compose and preview a sixteen-step effect. You can copy its generated code or import an existing generated snippet to continue editing it. Copied sequences use 0 for a silent step:
const pickup = [261.63, 0, 329.63, 392] as const;
sfx(pickup, 80, 0.15, "square");The sprite editor supports the same copy and import workflow for 8 × 8 sprites. Imports are validated as data and never executed: sprites accept exactly 64 color values from 0 to 3, while sounds accept exactly 16 nonnegative frequencies plus optional playback settings.