Coding Guide
Everything the Studio can do — blocks, RedScript, objects, and how real games are built.
The big idea
A game is a set of objects (dots, rings, boxes, lines, text, ships). Each object can carry a script: a list of events ("when the game starts", "every frame", "when clicked", "when a key is pressed") filled with actions. You build scripts with blocks — and a 📜 Code block is the exact same language typed as text, so anything blocks can do, code can do, and the two mix freely. That works in both directions: every action on this page is also a block (set, change, if, repeat, say, explode, beep, print, clear), and every event — including when answer for text games — is in the block editor's event menu. Nothing needs typed code.
Fastest way to learn: in the Studio, use Load example… to open any of the 21 reference games — the whole prehistory of video games, 1947–1974, plus Redline Slots for casino machines — click their objects, and read their scripts. Every one is built from the pieces on this page.
Objects & properties
Add objects from the Explorer: Dot, Ring, Box, Line (a vector segment: starts at x/y and runs along its angle for size length — Maze War's whole first-person view is lines), Text, Ship (a triangle that points along its angle — boxes rotate with angle too). Every object has:
x y position (the screen is 480 wide, 360 tall; 0,0 is top-left) size how big it is angle heading in degrees (0 = right, 90 = down) — ships point along it color any color, like "#ff9d4a" glow CRT glow strength visible 1 shows it, 0 hides it text what a Text object says
Scripts read and write these as self.x, ball.y, hud.text — any object, by name. You can also invent custom properties: set self.hp to 3 just works, and other objects can read enemy.hp. A property (or variable) that was never set reads as 0 — so set self.velx to self.velx + 1 is safe on the very first frame.
Events
when start runs once, when the game begins
when tick runs exactly 60 times a second on EVERY screen — physics lives here
when click runs on every tap/click; read mousex() and mousey()
when key "ArrowUp" runs when that key is pressed (works with gamepads too)
when answer runs when the player types into the terminal and hits
Enter — read what they typed with answer()
Actions
set self.x to 240 set a property, variable, or list slot
change self.y by -2 add to it
if score > 5 then … else … end
repeat 10 … end loop (use a counter variable to count)
say "HIT!" for 1.5 big message on screen
explode target1 CRT blast effect at that object
beep 440 for 0.1 a square-wave tone: frequency (Hz) + seconds —
the whole 1972 sound chip (load Pong to hear it)
print "YOU ARE IN ROOM " + pos a line on the on-screen teletype
clear wipe the teletype
Expressions — the same everywhere
Every value field in every block accepts a full expression:
Math + - * / % (% is remainder) · unary minus works: -vy
Compare < > <= >= == != combine with: and, or, not
rand(10, 90) random number in a range
dist(self, target1) distance between two objects (center to center)
touching(self, wall1) 1 while two objects overlap — knows each shape's size
keydown("w") 1 while that key/button is held
mousex() mousey() where the pointer is
abs(x) min(a,b) max(a,b) floor(x) round(x)
sin(deg) cos(deg) trig in degrees — angles into motion
xor(a, b) binary XOR (NIMROD's whole brain)
time() seconds since the game started
answer() what the player just typed (in "when answer")
upper("m") uppercase a string — answer comparisons ignore caps
len(x) length of a string
Variables & lists
set score to 0 variables are shared by every object change score by 1 set board[i] to 5 lists: any expression as the index set board[r * 8 + c] to 1
Lists + repeat = real algorithms. Draughts keeps its whole board in board[0..63]; OXO's perfect brain is loops over a lines[] table. Open those examples and read them.
Recipes
Move with keys (put on the player object):
when tick
if keydown("ArrowRight") then
change self.x by 3
end
if keydown("ArrowLeft") then
change self.x by -3
end
end
A ship that flies like Spacewar (a Ship object):
when tick
if keydown("a") then
set self.angle to self.angle - 3
end
if keydown("d") then
set self.angle to self.angle + 3
end
if keydown("w") then
set self.velx to self.velx + cos(self.angle) * 0.1
set self.vely to self.vely + sin(self.angle) * 0.1
end
change self.x by self.velx
change self.y by self.vely
end
Gravity + bounce:
when tick set self.vy to self.vy + 0.13 change self.y by self.vy if self.y >= 300 then set self.y to 300 set self.vy to -self.vy * 0.7 end end
Why self.vy and not a bare vy? Variables are shared by every object — two bouncing balls would fight over one velocity. A property is the ball's own. One object, one job.
A clickable button (any object):
when click if abs(mousex() - self.x) < 20 and abs(mousey() - self.y) < 20 then set score to score + 1 say "CLICKED!" for 1 end end
Win condition:
when tick if dist(player, goal) < 15 then say "YOU WIN!" for 3 explode goal end end
Text adventures
Any game that uses print gets a teletype: lines appear on the screen, and a text input shows up under it. When the player types and hits Enter, every when answer event runs — read the text with answer(). That's the whole kit: with print, clear and a mode variable for "what question am I asking?", you can build interactive fiction, quizzes, dungeon crawls — anything made of words. Loose comparisons help: answer() == 12 is true when they type 12, and upper(answer()) == "M" ignores caps.
Load Hunt the Wumpus (Teletype) — the real 1973 game, prompts and all — and read its one script: a state machine of questions. The Map version is the same cave with graphics; the teletype is how it actually shipped.
Coins
◎ Coins are the platform's play money — they can't be bought and can't be cashed out, and the database itself guarantees no one can create them from nothing. How they move:
EARN 100 when you sign up
+100 a day — the Claim button on the Market page (resets on UTC days)
your games' price-per-play, paid to you every time someone plays
selling Models on the Market
your casino machine's take (fund the pool, collect the profits)
winning at someone else's machine (92% return, long run — it's a casino)
SPEND playing coin games · buying Models · betting at the casino ·
funding your own machine's pool
The arcade floor
Machines are physical, and every game declares how many seats it has (1–8, set in the Studio). A one-seat game is the classic cabinet; a multi-seat game is a little server in arcade clothes — walk up and take any empty seat, like Roblox with a coin slot. The line only forms once every seat is full, and when one frees, the front of the line sits first. While you wait you see a 🔴 LIVE window onto their screen — several frames a second over the platform's live wire (if the wire hiccups it quietly falls back to a snapshot every few seconds) — and every machine has its own chat, so the line can talk trash like a real arcade. Walk away or close the tab and your seat frees itself after a few seconds. This works on every game and every casino machine automatically — nothing to build.
Turns. On a game with a proper ending (the coin slot comes back when your play is over), finishing your play while people are waiting sends you to the back of the line — one play per turn, like a real cabinet. On a full multi-seat machine the vote-to-skip aims at the player who's been seated the longest, and votes evaporate whenever that player changes — so a fresh player can never be ganged up on. On endless games and casino machines you can sit as long as you like — but the line has rights, earned by waiting: stand in line long enough under the current player and you can ask them to wrap up (the machine announces it in chat). How long is "long enough"? The game's maker decides — every game sets its own line patience in the Studio (1–120 minutes, 15 by default), shown right on the game's page. Kicking is a group effort: it takes at least TWO people who've each waited out the patience clock, and every one of them must vote — unanimous or nothing. One grumpy waiter can never kick alone, a fresh player can't be insta-kicked (the clocks restart when the seat changes hands), and no line means no vote — hogging an empty machine bothers nobody.
Casino machines
The Casino floor runs on one rule: machines do the show, the platform does the math. The odds are locked in the engine — no owner can make a machine pay better or worse. They're public:
multiplier chance · RETURN TO PLAYER: 92% 0x 58.7% · the other 8% stays in the pool — 1x 25% · that's the owner's take 2x 10% 5x 5% · payouts are CAPPED by the pool: 10x 1.2% · a machine can never pay coins 100x 0.1% · it doesn't hold
A machine's script talks to the platform through reserved variables — this loop is REQUIRED to publish to the Casino floor:
set bet to 1 pick a stake (1–10)
set spin to 1 pull the lever — the platform moves the coins
(spin reads 2 while the reels should turn,
then 0 when it's settled)
result the multiplier that came up (-1 = no coins)
win coins paid out this spin
coins pool live balances for your readouts
casino 1 on the floor, 0 in Studio test (free play)
Your script never computes a payout — it reads result and dresses the reels. Bets go into the machine's pool; winnings come out of it — and the bet joins the pool before the payout, so there is always something in the till: on an empty machine the first player can only ever win their own coin back. Nobody wants to be that player, which is exactly why owners fund the pool — a fat pool is what makes a machine worth sitting at. Owners collect the take from the machine's page. In the Studio, ▶ Test plays with pretend coins on the same odds. Load Redline Slots and reskin it into anything.
Machines (and games) can be saved Unlisted — stored under My Games, hidden from the public pages — so you can build over many sessions. A machine only needs the casino loop when you flip it to Public.
Coins can't be bought and can't be cashed out — the casino is for fun, bragging rights and pool-sized jackpots, not for keeps.
The Studio itself
Explorer — add and pick objects; checkboxes select several, and the search box filters by name or type when a game gets big · Workspace — drag things into place, ▶ Test plays your game right there (casino machines test in FREE PLAY: pretend coins, the real odds) · Properties — tune the selected object · Script — the block editor for whatever's selected.
The panels are yours to arrange: click any panel's header to collapse it, and on desktop drag the ⠿ handle to pop it out into a floating window you can park anywhere (⟲ docks it back) — float Properties next to the Script editor and thank yourself later.
📺 Screen — a second scene that plays on your game's card in the Games list (the arcade "attract screen"). Loading any historic example fills the Screen automatically — the Atari coin-ops come with live attract reels; steal their setup.
The settings row, left to right: the description shown on your card · Publish to (the Games page, or the Casino floor — machines need the casino loop to go public) · Visibility (Public, or Unlisted to keep working on it in private — flip it later) · Price per play (◎, paid straight to you; hidden for casino machines, where the bet is the price) · Line patience (how long someone must wait at your machine before the line can vote to skip a player — 1 to 120 minutes, shown on your game's page) · Screen size (your game's whole world: classic 480×360, wide, large 800×600, widescreen, or portrait for phone-first games — bigger screen = bigger maps; games already published stay exactly the size they were built) · Players (seats) (1 is a classic cabinet; 2–8 makes it an online multiplayer cabinet where everyone seated shares one room — see the net contract below) · the Arcade screen mode (None / Static / Live).
Arcade games — the platform runs the coin slot for you, and two reserved variables wire your game into it. arcade is 1 when a paid play is already underway — check it in when start and skip your own insert-coin screen. Set endplay to 1 when the play is over (game over, out of lives, time up): the game stops and the coin slot comes back — the next play costs another coin, just like 1971. Load Computer Space (1971) or Pong (1972) to see the whole pattern working.
★ High scores — a game with points and a real end gets a leaderboard automatically. Count your points in the reserved var score (set or change it like any variable, blocks or code) and end your plays with endplay = 1: that's the whole contract. When a play ends, the platform records the player's score on the game's page — one row per player, personal best only, best at the top. Scores are glory, not coins: they can't be spent and never expire. Computer Space, Space Race, Gotcha, Gran Trak 10, Tank, Maze War, Maze War Arena and Spasim all wear the pattern — load any of them to see it.
⚔ Online duels (the net contract) — any game can host a second HUMAN over the platform's live wire. Six reserved vars carry your state out and theirs in:
net1 … net6 numbers you SET — sent to the opponent ~7×/second
foe1 … foe6 the opponent's net1…net6, arriving live
netev a counter: change it by 1 to send a pulse (a hit, a tag) —
it arrives on their side as foeev
duel 1 while an opponent is connected, 0 otherwise
netslot your seat: 1 = the machine's player, 2 = the challenger —
on a multi-seat cabinet it's your seat number, 1…8
(pick spawn corners with it)
A game that sets net1 and reads foe1 "speaks net": on a 1-seat machine its page grows a ⚔ DUEL button so a second player can pay their coin and challenge. Give the game 2–8 seats in the Studio instead and it becomes a true multiplayer cabinet: everyone who sits shares one room, and the extended contract carries every seat —
fon[s] 1 while seat s has a live player f1[s] … f6[s] seat s's net1…net6, arriving live fev[s] seat s's event counter pcount live players in the room, including you set nettgt to s + change netev by 1 → seat s's `hits` var goes up by 1 hits how many times other players have hit YOU (respawn on change)
Design rule of thumb: simulate your own player, draw the others wherever their f1[s]/f2[s] says, and never move anyone else.
➕ Player (testing multiplayer) — you don't publish to find out if it works. Hit ▶ Test on any game that speaks net (or has 2+ seats) and a ➕ Player button appears: each press opens another window that is a REAL player — its own seat, its own keyboard, its own screen — connected to yours over a local wire inside your browser. No login in those windows, no internet, nothing saved: it's the exact same contract as the online wire (netslot, f-lists, pcount, targeted hits), so a game that works across your test windows works online. Stop the test and the player windows end with it; Test again and any you left open reload your latest edits. Alt-Tab between windows to play each seat.
Load Maze War (1974) for the 2-player duel pattern, or Maze War Arena (1974) for the full 4-seat, humans-only version — it also shows the ROUND pattern for deathmatches: a match needs 2+ players, one life per round (no respawns to camp), last one standing wins, late joiners spectate until the next round deals them in, and the coin's clock only runs while a match is on — waiting for players is free. All of it agreed between browsers with no referee — read its round block. Spasim (1974) is the 8-seat 3D dogfight: its projection block is a working 3D renderer in plain RedScript, its planets ride real orbits around a sun (four lines of trig), and its X·Y·Z position instrument updates once a second — steer in polar, read your position in Cartesian, exactly like the real PLATO machine.
Models — check objects → "Save checked as Model." Models keep their scripts, live in your inventory, insert into any game fully editable, and can be sold on the Market for free or coins. The Page Studio (from your profile: 🎨 Edit my page) is the same editor pointed at your profile page.
Controls come free: keyboards work everywhere, phones get on-screen buttons generated from whatever keys your scripts use — and the ✥ button opens edit mode, where players drag EACH button anywhere and resize it by pinching it with two fingers (or its ◢ corner). Layouts save on their device, one per control set, and a layout made on a big screen pulls itself back into view on a small one — every game gets exactly the controls it calls for. Gamepads just work — press a button on the pad once to wake it up (that press is what tells us it's a controller and not a sim wheel or pedal set). One pad drives any game; plug in TWO and they split into players — pad 1 takes the WASD side, pad 2 the arrows — so any two-player example is a couch game with no setup at all.
🖥 Screen size — every machine (and the Studio) has a size button under the screen: S, M, L, or MAX (as wide as the page goes). Your choice is remembered on your device and applies everywhere, and the screen renders at double resolution so it stays crisp at any size. ⛶ next to it is still the full-monitor version.
⬇ Download — every game you make can be downloaded as a single standalone HTML file: the engine and your game in one file that runs offline by double-click. Upload it to itch.io as a playable browser game, or wrap it with Electron/Tauri to ship it as a desktop app — built on RedlineStudio, published anywhere.
Every reserved variable (the cheat sheet)
Ordinary variables are all yours. These names are the platform's — set or read them and the machine around your game responds. Everything here is explained in the sections above; this is the one-glance list:
THE COIN SLOT arcade (1 = a paid play is underway) · endplay (set 1 to end the play)
★ HIGH SCORES score (+ endplay) — points with a real end get a leaderboard
🎰 THE CASINO bet · spin · result · win · coins · pool · casino (1 on the floor)
⚔ DUELS (2P) net1…net6 out · foe1…foe6 in · netev out / foeev in ·
duel (1 = opponent connected) · netslot (your side)
👥 MULTI-SEAT fon[s] · f1[s]…f6[s] · fev[s] · pcount · netslot (your seat) ·
(2–8 players) set nettgt to s + change netev by 1 → their hits +1 ·
hits (times YOU'VE been hit — react on change)
Rule of one: never use these names for your own bookkeeping — pick any other name and it's yours forever.
Rules of thumb
One object, one job — a ball owns its physics, a referee object owns scoring. Use a variable like game for state (0 = playing, 1 = won…) and gate your when tick logic on it. Runaway loops get stopped automatically, so experiment freely — Test, tweak, Test again. When something's cool, save it as a Model and reuse it forever.