Jam Roulette
Make a game that lasts five to ten seconds. It plays back to back with everyone else's.
Every entry is a microgame: one instruction, a 3-2-1, a few seconds of play, then win or lose, straight into the next. Build yours in Unity, Godot or plain JavaScript, upload the web build here, watch it run, and submit it to a jam.
Jams
How to take part
Six steps, from nothing to an entry. Each one takes minutes except the part where you make the game.
-
Sign in with Discord
Your Discord account is your account here. Sign-in only asks Discord who you are; your display name becomes the author name on your games, and you can change it per game.
-
Get the SDK for your engine
The SDK is how your game talks to the runner: it tells the runner your prompt and round length, hears when the round starts, and reports whether the player won. One small file per engine.
In Unity, choose Assets › Import Package › Custom Package… and pick the file. It adds
Assets/JamRoulette/.Example/MicrogameTemplate.csin there runs a full round with placeholder Win and Lose buttons: put it on a GameObject in your first scene, press Play, then replace the parts markedTODO.The minimal version:
using JamRoulette; void Start() { Microgame.GameStarted += gameTime => enabled = true; Microgame.GameEnded += condition => enabled = false; Microgame.Register("Dodge!", "arrows", gameTime: 5, winOnTimeOut: true); } void OnHit() => Microgame.SetGameState(GameOverCondition.Lose, immediatelyEnd: true);On Unity 6 and later, the package's editor script turns off the Unity splash screen for WebGL. The runner shows its own splash, and Unity's would only delay your
Registercall.Unzip it into your project folder so you have
addons/jam_roulette/, then turn on Jam Roulette in Project › Project Settings › Plugins. That adds theMicrogameautoload.addons/jam_roulette/microgame_template.gdruns a full round with placeholder keys: attach it to your main scene's root node and replace the parts markedTODO.The minimal version:
func _ready() -> void: Microgame.game_started.connect(func(game_time): set_process(true)) Microgame.game_ended.connect(func(condition): set_process(false)) Microgame.register("Dodge!", "arrows", 5.0, true) func _on_hit() -> void: Microgame.set_game_state(Microgame.GameOverCondition.LOSE, true)Godot has no global error hook, so if something goes wrong call
Microgame.report_error()yourself.Put it next to your
index.htmland load it with<script src="microgame.js"></script>. It has no dependencies, so it works with any engine or framework that exports to the web. The example is a complete click game in one file; view its source.The minimal version:
Microgame.on('gameStart', (msg) => startPlaying(msg.gameTime)); Microgame.on('gameEnd', (msg) => freeze(msg.condition)); // 'win', 'lose', 'error' or null (skipped) Microgame.register({ prompt: 'Dodge!', interaction: 'arrows', gameTime: 5, winOnTimeOut: true }); // when the player wins or loses: Microgame.setGameState('win', false); // won; the round runs on to the timer Microgame.setGameState('lose', true); // lost; the round ends nowUncaught errors and unhandled promise rejections end the round as an error automatically.
-
Make a 5–10 second microgame
The runner owns everything around your game: the splash, the countdown, the timer and the result. Your game only has to do three things: register once it has booted, wait for the round to start, and say whether the player won.
-
Your game
registerOnce booted. Sets the prompt, the controls, the round length and whether surviving counts as a win.
-
Runner
splash, 3-2-1Shows your prompt over your game, which is loaded but held. Nothing should move yet.
-
Your game
gameStartStart play. You get the round length, and the time left every frame after.
-
Your game
setGameStateWin or lose, and whether to end the round now. The last call before the end counts.
-
Runner
gameEndFreeze. The result shows for a second, then your game is unloaded.
- Register when you are ready, not before. The runner boots your game in the background while the previous one is being played, so load what you need first, then register.
-
The prompt is the one-line instruction shown huge on the splash, like “Dodge!”.
The controls label is one of
mouse,click,keyboard,arrows,wasd,space,touch,gamepad, or any short word. -
The round length is clamped to 5–10 seconds. If you never report a result,
winOnTimeOutdecides it: on for “survive until the end” games, off (the default) for “do this before time runs out”. -
Report as you go.
setGameState(win, false)marks a win and lets the round run on;setGameState(lose, true)ends it at once. Uncaught errors end the round as an error. - Test without the runner. In the Unity editor, a Godot desktop run, or opening your page directly, the SDK runs the round itself: the start comes about a second after you register, then a local timer.
-
Your game
-
Export a web build and zip it
- Unity: build for WebGL. Brotli or Gzip compression works as exported, and so do multithreaded builds.
-
Godot 4: add a Web export preset and export to a file named
index.html. Thread support on or off both work. - JavaScript: your folder, with
index.htmlas the page that starts the game.
Zip the contents of the build folder, so
index.htmlis at the top level of the zip. A zip holding just one folder is fine too: the uploader looks inside it. You can also skip the zip and drop the folder itself onto the upload area.250 MBtotal, unzipped95 MBlargest single file2,000files at mostindex.htmlat the top levelPages that need SharedArrayBuffer (threaded Unity and Godot builds) get it: builds run cross-origin isolated.
-
Upload it and watch it run
Open a jam that is taking entries and choose Enter this jam. Give your game a title and you land on its page. Drop the zip there. It is unzipped and checked in your browser before anything is sent, so a missing
index.htmlor an oversized file shows up straight away, with what to fix.When the upload finishes, your game plays in the runner right there on the page: splash, countdown, round, result, on repeat. This is your draft. Only you can see it.
-
Submit it to the jam
Uploading does not enter you. When you are happy with the draft, press Submit: that build becomes your entry, and it is what everyone plays.
Keep going after that. Upload again and the jam keeps playing your submitted build until you submit the new one. You can re-upload, re-submit or withdraw until the jam closes; then entries are frozen.