Gradient Bang is an online multiplayer universe where you explore, trade, battle, and collaborate with other players and with LLMs. Everything in the game is an AI agent, including the ship you command.
The projects demonstrates the full capabilities of realtime agentic workflows, such as multi-tasking, advanced tool calling and low latency voice.
- Prerequisites
- Quickstart
- Running a game server
- Running the bot
- Deployment
- Auth & secrets quick guide
- uv: Python package manager
- Supabase Account: Game server functions, auth and database
- Docker: Required for local Supabase stack and agent deployment
- Node.js 18+: For edge function deployment and client
- (Optional) Pipecat Cloud Account: Production agent hosting
- (Optional) - Supabase CLI: If you cannot use
npx, install the CLI globally instead
Note
Docker must be available and running on your system
This may take some time on first run as required images are downloaded.
npx supabase start --workdir deployment/ Grab the required API keys to create an .env.supabase file for your local Supabase stack configuration:
tok=$(openssl rand -hex 32)
npx supabase status -o env --workdir deployment | awk -F= -v tok="$tok" '
$1=="API_URL" {v=$2; gsub(/"/,"",v); print "SUPABASE_URL=" v}
$1=="ANON_KEY" {v=$2; gsub(/"/,"",v); print "SUPABASE_ANON_KEY=" v}
$1=="SERVICE_ROLE_KEY" {v=$2; gsub(/"/,"",v); print "SUPABASE_SERVICE_ROLE_KEY=" v}
END {
print "POSTGRES_POOLER_URL=postgresql://postgres:postgres@db:5432/postgres"
print "EDGE_API_TOKEN=" tok
}
' > .env.supabase- Run the helper after
supabase start(and after any manual reset) to keep combat rounds auto-resolving:
scripts/supabase-reset-with-cron.shSee docs/combat_tick_cron_setup.md for local/production seeding details and verification queries.
set -a && source .env.supabase && set +a && USE_SUPABASE_TESTS=1 uv run pytest tests/integration -vRun the universe bang script with number of sectors to chart and random seed
uv run universe-bang 5000 1234This will create a world-data folder in the root of your project
uv run -m gradientbang.scripts.load_universe_to_supabase --from-json world-data/Run Supabase edge functions process (leave running)
npx supabase functions serve --no-verify-jwt --workdir deployment --env-file .env.supabaseOption 1: Manually via Studio dashboard: http://127.0.0.1:54323/project/default/auth/users
Option 2: Via terminal:
curl -X POST http://127.0.0.1:54321/functions/v1/register \
-H "Content-Type: application/json" \
-d '{
"email": "test@example.com",
"password": "secret123"
}'Open Inbucket (local email viewer) and click confirmation link. Note: In local dev, the redirect URL will not be found.
open http://127.0.0.1:54324curl -X POST http://127.0.0.1:54321/functions/v1/login \
-H "Content-Type: application/json" \
-d '{
"email": "test@example.com",
"password": "secret123"
}'Grab the access_token for the next steps!
Create a character (replace YOUR_ACCESS_TOKEN with the token from step 3):
curl -X POST http://127.0.0.1:54321/functions/v1/user_character_create \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"name": "SpaceTrader"
}'Install Python dependencies:
uv sync --all-groupsRun agent process:
set -a && source .env.supabase && set +a
uv run botWith both your Supabase functions and Pipecat bot running, in a new terminal window:
cd client/
pnpm i
pnpm run devIf you want to run your own game world in the cloud, you will need a Supabase project.
Note
You can create a Supabase project via the Supabase Dashboard or using the comman line below.
npx supabase login
npx supabase projects create gb-game-server \
--db-password <some-secure-password> \
--region us-west-1 \
--org-id <my-supabase-org-slug> \
--size smallPush config from /deployment/supabase template:
npx supabase link --workdir deployment
npx supabase config push --workdir deploymentGenerate it in one step (prompts for project ref and DB password).
Note, this will create a POSTGRES_POOLER_URL that requires IPv6 routing from your machine. If you cannot use IPv6, you will need to click on the "" button that's in the top bar of your Supabase project dashboard and look up the "Method: Session Pooler" connection string. Change your POSTGRES_POOLER_URL to the Session Pooler format.
printf "Project ref (from Supabase dashboard URL): "; read PROJECT_REF
printf "DB password (from Settings → Database): "; read -s DB_PASS; echo
EDGE_API_TOKEN=$(openssl rand -hex 32)
npx supabase projects api-keys --project-ref "$PROJECT_REF" --workdir deployment \
| awk -v tok="$EDGE_API_TOKEN" -v pw="$DB_PASS" -v pr="$PROJECT_REF" '
/anon[[:space:]]*\|/ {anon=$3}
/service_role[[:space:]]*\|/ {srv=$3}
END {
print "SUPABASE_URL=https://" pr ".supabase.co";
print "SUPABASE_ANON_KEY=" anon;
print "SUPABASE_SERVICE_ROLE_KEY=" srv;
print "POSTGRES_POOLER_URL=postgres://postgres:" pw "@db." pr ".supabase.co:6543/postgres";
print "EDGE_API_TOKEN=" tok;
}' > .env.cloudLoad environment variables, so the next steps will work:
set -a && source .env.cloud && set +aApply all SQL migrations to the linked project
npx supabase migration up --workdir deployment/ --db-url "$POSTGRES_POOLER_URL"Populate app_runtime_config with the Supabase URL and edge token (run after migrations).
scripts/setup-production-combat-tick.shVerify:
psql "$POSTGRES_POOLER_URL" -c "SELECT key, updated_at FROM app_runtime_config WHERE key IN ('supabase_url','edge_api_token');"Deploy edge functions to your Supabase project. You will see warnings about decorator flags. You can ignore them.
npx supabase functions deploy --workdir deployment/Add required secrets. Ignore the warnings about the SUPABASE_ variables. They are set automatically in the project.
npx supabase secrets set --env-file .env.cloudNote: we will need to add BOT_START_START_URL and BOT_START_API_KEY later
set -a && source .env.cloud && set +a && USE_SUPABASE_TESTS=1 uv run pytest tests/integration -vIf you don't already have a universe, create it like this:
uv run universe-bang 5000 1234Now load it into your Supabase project:
uv run -m gradientbang.scripts.load_universe_to_supabase --from-json world-data/Create .env.bot
DEEPGRAM_API_KEY=...
CARTESIA_API_KEY=...
GOOGLE_API_KEY=...
SUPABASE_URL=https://{SUPABASE_PROJECT_ID}.supabase.co
SUPABASE_SERVICE_ROLE_KEY=...
# Optional:
TOKEN_USAGE_LOG=logs/token_usage.csv
BOT_USE_KRISP=1Create a new secret set on Pipecat Cloud:
pipecat cloud secrets set gb-bot-secrets --file .env.botBuild and deploy bot
Note: create image pull credentials if publishing to a private repository
docker build -f deployment/Dockerfile.bot -t gb-bot:latest .
docker push gb-bot:latest
cd deployment/
pipecat cloud deploy
# ... or if public
# pipecat cloud deploy --no-credentialsCreate and note down Public API Key
pipecat cloud organizations keys createUpdate .env.cloud with additional bot envs:
SUPABASE_URL=...
SUPABASE_ANON_KEY=...
SUPABASE_SERVICE_ROLE_KEY=...
POSTGRES_POOLER_URL=...
EDGE_API_TOKEN=...
# Add these for bot integration
BOT_START_URL=https://api.pipecat.daily.co/v1/public/{AGENT_NAME}/start
BOT_START_API_KEY=...Apply to edge functions
npx supabase secrets set --env-file .env.cloud- Gateway check (Supabase): default
verify_jwt=truerequiresAuthorization: Bearer $SUPABASE_ANON_KEY(or a user access token). Keep this on in production; optional--no-verify-jwtonly for local. - App gate (gameplay): every gameplay edge function expects
X-API-Token: $EDGE_API_TOKENand usesSUPABASE_SERVICE_ROLE_KEYinternally for DB access. - Bot/client calls: send both headers. The anon key can be public; the gameplay token must stay secret.
- Production secrets to set:
SUPABASE_URL,SUPABASE_ANON_KEY,SUPABASE_SERVICE_ROLE_KEY,POSTGRES_POOLER_URL,EDGE_API_TOKEN(+ bot envs if used). - Combat cron: ensure
app_runtime_confighassupabase_urlandedge_api_tokenset to the live values (usescripts/setup-production-combat-tick.sh).
touch client/app/.env
VITE_SERVER_URL=https://{SUPABASE_PROJECT_ID}.supabase.co/functions/v1
VITE_PIPECAT_TRANSPORT=dailyRun the client
cd client/
pnpm run dev