Build a game in Studio
Write Genzimnify on the web, run it, and watch the game canvas beside the console. The editor, diagnostics, and generated Python view work as before; the game preview stays visible on the right.
1. Open the starter
Open Genzimnify Studio and select the ▣ rizzgame activity. Choose Open starter game, then press Run vibe or Ctrl/⌘ + Enter. The first run downloads Pyodide, the browser’s Python/WASM runtime. Native gzim uses Nim and raylib instead and does not need Python.
The lower panel is split: console, problems, and generated Python on the left; a live canvas on the right. Click the canvas before using WASD or arrow keys. Press Escape in the canvas or Stop game to finish.
2. Read the game loop
pull up rizzgame as rg
let screen be call up rg.display.pull_up([640, 360]) yo
let clock be call up rg.time.Clock() yo
let player be call up rg.Rect(300, 160, 36, 36) yo
let running be nocap
vibe running:
let dt be call up clock.keep_up(60) yo / 1000
for real event up in call up rg.event.catch_vibes() yo:
vibecheck event.type == rg.KEYDOWN both event.key == rg.K_ESCAPE:
running be cap
let keys be call up rg.key.check_the_vibe() yo
vibecheck keys[rg.K_LEFT] either keys[rg.K_a]: player.x be player.x - 220 * dt
vibecheck keys[rg.K_RIGHT] either keys[rg.K_d]: player.x be player.x + 220 * dt
call up screen.glow_up([14, 19, 32]) yo
call up rg.draw.flex_rect(screen, [103, 245, 201], player) yo
call up rg.display.show_off() yo
call up rg.dip_out() yokeep_up(60) returns elapsed milliseconds. Divide by 1000 to move by pixels per second, so motion stays consistent when the frame rate varies. catch_vibes() handles discrete key and mouse events, while check_the_vibe() reports held keys. Clear the surface each frame with glow_up(), draw shapes, then call show_off() to present and yield to browser input.
3. Add a scene
Add these calls between screen.glow_up(...) and display.show_off(). Shape color is an RGB or RGBA list; positions use pixels from the top left.
call up rg.draw.flex_circle(screen, [92, 247, 224], [320, 180], 70) yo
call up rg.draw.flex_line(screen, [255, 210, 95], [0, 0], player.center, 3) yo
call up rg.draw.yap_text(screen, "MOVE THE SQUARE", [18, 18], 20, [235, 242, 255]) yoUse rg.Surface([width, height]) for an offscreen layer, call layer.glow_up(color) or draw onto it, then place it with screen.blit(layer, [x, y]). A Rect has x, y, center, collidepoint(), and colliderect() for simple collision checks.
4. Try mouse input
for real event up in call up rg.event.catch_vibes() yo:
vibecheck event.type == rg.MOUSEBUTTONDOWN:
player.center be event.posPut this event handler near the start of the loop. The preview canvas must have focus for keyboard input. Mouse positions are scaled into game coordinates even when the preview is resized.
Browser support and native projects
Studio’s Canvas adapter supports the Gen Z and pygame-style aliases for display creation, frame presentation, surfaces, rectangle geometry, fills, blits, shapes, text, keyboard and mouse events, frame timing, math helpers, cameras, particles, and sprite sheets made from offscreen surfaces. The repository’s procedural Neon Arena example also runs in the preview. show_off() or flip() must be in the top-level game loop so the browser can render and handle input between frames. Browser preview does not yet support file-backed raylib images, custom fonts, sound/music, or saving images. Those APIs work in the native rizzgame runtime; download the same .gzim file and run it with gzim run game.gzim when you need them.
Studio loads Pyodide from a CDN on first run and keeps code in your browser. The preview is a browser implementation of the supported API, so rendering details may differ from the native GPU backend.