A fully fleshed-out walkthrough of how to build a browser game from scratch using Kiro IDE β from research to deployment. Follow this during the game jam.
This guide uses a text adventure game as the running example, but the workflow applies to any genre.
The Workflow
Research (Gemini) β Deep Research (ChatGPT) β Download as MD
β Kiro Spec-Driven Planning β Build β Supabase β Deploy to GitHub Pages
Step 1: Research with Gemini β What Game to Build
Before opening Kiro, use an AI provider to brainstorm whatβs actually feasible in 90 minutes.
Sample Gemini Prompt
I'm joining a 90-minute game jam. I need to build a browser-playable game
using vanilla HTML/CSS/JS. I'm a beginner at game dev.
Give me 5 realistic game ideas that:
- Can be built in 90 minutes with AI assistance (Kiro IDE)
- Run in the browser with no backend required for the core game
- Are fun to play and easy to judge
- Don't require art assets or sprites
For each idea, include:
- One-line description
- Core mechanic (what the player does repeatedly)
- Minimum viable features to be "done"
- Optional stretch goals if time allows
What You Get Back
Gemini will give you ideas like:
- Escape Room Text Adventure β Navigate rooms, find items, solve puzzles. Core: explore + use items. MVP: 3 rooms, 2 items, 1 puzzle.
- Reaction Time Clicker β Click targets as fast as possible. Core: click + score. MVP: random targets, timer, scoreboard.
- Trivia Showdown β Answer timed questions. Core: read + answer. MVP: 10 questions, score tracker, timer.
- Survival Dodge β Move to dodge falling objects. Core: move + avoid. MVP: player, falling objects, score timer.
- Word Scramble β Unscramble words against a timer. Core: type + guess. MVP: word bank, timer, scoring.
Pick one. For this guide, weβll go with the Escape Room Text Adventure.
Step 2: Deep Research with ChatGPT β Flesh Out the Idea
Now use ChatGPT Deep Research to get a detailed breakdown of how to actually build the game you picked.
Sample ChatGPT Deep Research Prompt
I'm building an escape room text adventure game that runs in the browser
using vanilla HTML, CSS, and JavaScript. I want to use Supabase as a
backend for a leaderboard (tracking player name and escape time).
Research and give me a detailed technical breakdown:
1. Game Architecture
- How to structure rooms, items, and puzzles in JS
- Data structure for game state (inventory, current room, flags)
- How to handle player commands (parser approach)
2. UI/UX Design
- Terminal/retro text interface design patterns
- How to display room descriptions, inventory, and feedback
- Responsive layout for mobile and desktop
3. Supabase Integration
- How to set up a leaderboard table
- How to submit scores from the client side
- How to display the leaderboard
- Row Level Security policies for public insert + read
4. Deployment
- How to deploy a static site to GitHub Pages
- Folder structure for a clean deployment
5. Similar Games for Inspiration
- Links or descriptions of browser text adventures
- Common puzzle patterns that work well
Download the Research
Once ChatGPT finishes the deep research:
- Click the Share or Copy button on the response
- Save it as a markdown file, e.g.
escape-room-research.md - Place this file in your project root β youβll feed it to Kiro next
Step 3: Set Up Your Project
Create the Project Folder
mkdir escape-room-game
cd escape-room-game
npm create vite@latest . -- --template vanilla
npm install
npm install @supabase/supabase-jsOpen in Kiro
kiro .Create the Research Reference
Copy your escape-room-research.md into the project root. Kiro can see it and use it as context.
Step 4: Spec-Driven Planning in Kiro
This is where Kiro shines. Instead of jumping straight to code, you write a spec that Kiro uses to plan and generate structured code.
How Specs Work in Kiro
Kiro uses .kiro/specs/ files to understand your project design. When you create a spec, Kiro generates:
- Requirements β What the feature should do
- Design β How it should be built (data structures, components)
- Tasks β Step-by-step implementation plan
Create Your First Spec
In Kiro, open the Spec panel and use this prompt:
I want to build an escape room text adventure game. I have a research
document at escape-room-research.md that covers architecture, UI design,
Supabase integration, and deployment.
Using that research as reference, create a spec for the full game with
these features:
Core Game:
- 5 interconnected rooms (lobby, hallway, library, lab, exit)
- Each room has a description, items to examine, and exits
- Player can: look, go [direction], take [item], use [item], inventory
- 3 puzzles that gate progression (need key for lab, need code for exit,
need combination from clues)
- Win condition: reach the exit room after solving all puzzles
- Timer tracking how long it takes to escape
Data Structure:
- Rooms stored as a JS object/map with id, description, exits, items
- Game state object tracking: currentRoom, inventory, flags, startTime
- Command parser that splits input into verb + noun
UI:
- Retro terminal style (dark background, green/amber text, monospace font)
- Scrollable output area showing game text
- Input field at the bottom
- Side panel showing inventory and timer
Supabase:
- Leaderboard table: id, player_name, escape_time_seconds, created_at
- On win: prompt for name, submit to leaderboard
- Display top 10 fastest escapes on a leaderboard screen
Tech: Vanilla HTML/CSS/JS with Vite, @supabase/supabase-js
What Kiro Generates
Kiro will create a spec in .kiro/specs/ with:
Requirements:
- REQ-1: Player can navigate between 5 rooms using directional commands
- REQ-2: Player can examine, take, and use items
- REQ-3: Three puzzles gate progression through the game
- REQ-4: Timer tracks escape duration from start to finish
- REQ-5: Leaderboard stores and displays top 10 escape times
- β¦
Design:
- Room data structure with exits map
- GameState class/object
- CommandParser with verb-noun splitting
- Supabase client setup and queries
Tasks:
- Task 1: Create room data and game state
- Task 2: Build command parser
- Task 3: Create terminal UI
- Task 4: Implement game logic (navigation, items, puzzles)
- Task 5: Add timer
- Task 6: Set up Supabase leaderboard
- Task 7: Connect win condition to leaderboard submission
- Task 8: Style and polish
Walk Through the Tasks
Click through each task in the Kiro spec panel. Kiro will generate the code for each one. Review each step before moving to the next.
Step 5: Build with Kiro β Task by Task
Task 1: Room Data and Game State
Kiro generates something like:
// src/rooms.js
export const rooms = {
lobby: {
id: 'lobby',
name: 'Lobby',
description: 'A dimly lit lobby. There is a door to the NORTH and a hallway to the EAST.',
exits: { north: 'library', east: 'hallway' },
items: ['note'],
examineText: {
note: 'A crumpled note reads: "The code is hidden in the books."'
}
},
hallway: {
id: 'hallway',
name: 'Hallway',
description: 'A long hallway with flickering lights. Doors lead WEST and NORTH.',
exits: { west: 'lobby', north: 'lab' },
items: ['key'],
examineText: {
key: 'A rusty brass key. Looks like it fits a lab door.'
}
},
// ... library, lab, exit
}// src/state.js
export function createGameState() {
return {
currentRoom: 'lobby',
inventory: [],
flags: {
labUnlocked: false,
codeFound: false,
exitUnlocked: false
},
startTime: Date.now()
}
}Review it. Make sure the rooms connect logically. Ask Kiro to adjust if needed:
βAdd a description for the library room that hints at a hidden code in one of the books.β
Task 2: Command Parser
// src/parser.js
export function parseCommand(input) {
const words = input.toLowerCase().trim().split(/\s+/)
const verb = words[0]
const noun = words.slice(1).join(' ')
return { verb, noun }
}
export const VERBS = ['look', 'go', 'take', 'use', 'examine', 'inventory', 'help']Task 3: Terminal UI
Kiro builds the HTML/CSS for the retro terminal look. The key pieces:
<!-- index.html -->
<div id="game-container">
<div id="output"></div>
<div id="input-line">
<span class="prompt">></span>
<input type="text" id="command-input" autofocus />
</div>
</div>
<div id="sidebar">
<div id="inventory-panel">
<h3>Inventory</h3>
<ul id="inventory-list"></ul>
</div>
<div id="timer-panel">
<h3>Time</h3>
<span id="timer">00:00</span>
</div>
</div>Task 4β5: Game Logic and Timer
Kiro implements the core loop β handling commands, moving between rooms, solving puzzles, and tracking time. Test as you go:
npm run devOpen the browser and play through your game. If something is broken, tell Kiro:
βThe βuse keyβ command doesnβt unlock the lab. Fix the game logic so that using the key in the hallway sets labUnlocked to true and changes the lab exit description.β
Task 6: Set Up Supabase
Create the Supabase Project
- Go to supabase.com and create a new project
- Go to Table Editor β New Table
- Create a
leaderboardtable:
| Column | Type | Default |
|---|---|---|
| id | uuid | gen_random_uuid() |
| player_name | text | β |
| escape_time_seconds | int4 | β |
| created_at | timestamptz | now() |
-
Go to Authentication β Policies and add:
- Enable RLS on the
leaderboardtable - INSERT policy: Allow anonymous inserts (
true) - SELECT policy: Allow public reads (
true)
- Enable RLS on the
-
Go to Settings β API and copy your:
- Project URL
- anon/public key
Tell Kiro to Integrate Supabase
Add Supabase integration for the leaderboard.
Use these environment variables:
- VITE_SUPABASE_URL
- VITE_SUPABASE_ANON_KEY
Create:
1. A Supabase client in src/supabase.js
2. A submitScore function that inserts player_name and escape_time_seconds
3. A getLeaderboard function that fetches top 10 by fastest time
4. When the player wins, show an input for their name and submit to the leaderboard
5. A leaderboard view accessible from the start screen
Kiro generates:
// src/supabase.js
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
const supabaseKey = import.meta.env.VITE_SUPABASE_ANON_KEY
export const supabase = createClient(supabaseUrl, supabaseKey)
export async function submitScore(playerName, escapeTimeSeconds) {
const { error } = await supabase
.from('leaderboard')
.insert({ player_name: playerName, escape_time_seconds: escapeTimeSeconds })
if (error) console.error('Submit error:', error)
}
export async function getLeaderboard() {
const { data, error } = await supabase
.from('leaderboard')
.select('player_name, escape_time_seconds, created_at')
.order('escape_time_seconds', { ascending: true })
.limit(10)
if (error) console.error('Fetch error:', error)
return data || []
}Create your .env file
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key-hereWarning
Add
.envto your.gitignore. Never commit your keys.
Step 6: Test Everything
npm run devChecklist:
- Can navigate all 5 rooms
- Can take and use items
- All 3 puzzles work
- Timer runs and shows elapsed time
- Winning prompts for player name
- Score submits to Supabase
- Leaderboard shows top 10
- Looks good on both desktop and mobile
Step 7: Deploy to GitHub Pages
Set Up the Repository
git init
git add .
git commit -m "feat: escape room text adventure"
git branch -M main
git remote add origin git@github.com:YOUR_USERNAME/escape-room-game.git
git push -u origin mainConfigure Vite for GitHub Pages
Update vite.config.js:
import { defineConfig } from 'vite'
export default defineConfig({
base: '/escape-room-game/',
})Add GitHub Actions Workflow
Create .github/workflows/deploy.yml:
name: Deploy to GitHub Pages
on:
push:
branches: [main]
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run build
- uses: actions/upload-pages-artifact@v3
with:
path: dist
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4Set Up GitHub Pages Environment Secrets
For Supabase to work in production:
-
Go to your repo β Settings β Secrets and variables β Actions
-
Add these repository secrets:
VITE_SUPABASE_URLβ Your Supabase project URLVITE_SUPABASE_ANON_KEYβ Your Supabase anon key
-
Update the build step in the workflow to use them:
- run: npm run build
env:
VITE_SUPABASE_URL: ${{ secrets.VITE_SUPABASE_URL }}
VITE_SUPABASE_ANON_KEY: ${{ secrets.VITE_SUPABASE_ANON_KEY }}Enable GitHub Pages
- Go to repo β Settings β Pages
- Source: GitHub Actions
- Push your code:
git add .
git commit -m "feat: add GitHub Pages deployment"
git push- Wait for the action to complete
- Your game is live at
https://YOUR_USERNAME.github.io/escape-room-game/
Step 8: Submit to itch.io
Once deployed, follow the Itch.io Submission and Judging guide to submit your game to the jam.
You can either:
- Upload the zip of your
dist/folder directly to itch.io - Link to your GitHub Pages URL in the game description
Quick Reference β Kiro Prompts During the Jam
Use these as-needed during development:
| When | Prompt |
|---|---|
| Stuck on game logic | βThe [command] isnβt working. Hereβs what should happen: [expected]. Fix it.β |
| Need more content | βAdd 2 more rooms: a kitchen with a clue and a basement with a locked chest.β |
| Polish UI | βMake the terminal text animate like itβs being typed out, character by character.β |
| Add sound | βAdd a typewriter click sound when text appears and a success chime when a puzzle is solved.β |
| Fix a bug | βWhen I use the key in the wrong room, the game crashes. Add error handling.β |
| Supabase issue | βThe leaderboard isnβt loading. Check the Supabase query and add error feedback to the UI.β |
Resources
- Workshop Proper β Full workshop schedule
- Itch.io Submission and Judging β How to submit and judge
- Pre Workshop Reminders β Setup checklist
- Deploying with GitHub Pages β Deployment guide
- Supabase Docs β Database and auth reference
- Vite Docs β GitHub Pages deployment