Supabase
Supabase is an open-source backend platform that provides PostgreSQL database, authentication, real-time subscriptions, and serverless edge functions. It's a great fit for game backends that need managed auth, a relational database, and real-time capabilities without running a custom WebSocket server.
How It Works
GameFlow integrates with Supabase through Edge Functions — serverless TypeScript functions that run on Deno. One Edge Function acts as the bridge: when a lobby is ready to start, it calls the GameFlow API to allocate a dedicated game server, then writes the server's address and port back to the database. Supabase Realtime picks up the change and pushes the connection details to all players simultaneously.
┌──────────────┐ HTTP (Edge Functions) ┌──────────────────────┐ GameFlow API ┌──────────────────┐
│ Game Client │ ◄────────────────────────► │ Supabase │ ──────────────────►│ GameFlow │
│ │ Auth, lobby CRUD, │ Edge Functions │ POST /fleets/ │ Server Hosting │
│ │ ready state │ + PostgreSQL │ {id}/allocate │ │
└──────────────┘ └──────────────────────┘ │ └──────────────────┘
▲ │ { address, port } │
│ Supabase Realtime (WebSocket) │◄─────────────────────────────────────────┘
└───────────────────────────────────────────────┘
lobby updated → all clients connect to game server
The Flow
- Player signs in via Supabase Auth (anonymous or with a provider).
- Player creates or joins a lobby — Edge Functions write to PostgreSQL.
- All players mark ready. The lobby owner presses Start.
- The
lobbies-startEdge Function validates readiness, then calls the GameFlow fleet allocation API. - GameFlow returns
addressandportfor the allocated server. - The Edge Function writes the server details to the
lobbiestable. - Supabase Realtime fires an
UPDATEevent to all subscribers. - Every client in the lobby connects directly to the game server.
Key Integration Point
The only GameFlow-specific code in your backend is the server allocation call in your lobbies-start function:
const res = await fetch(
`https://dev.api.gameflow.gg/v1/fleets/${gameId}/allocate`,
{
method: "POST",
headers: { "X-Api-Key": apiKey },
body: JSON.stringify({
region: "us-east",
payload: JSON.stringify({ players }),
}),
}
);
const { allocation } = await res.json();
// Write back to DB, this triggers Supabase Realtime for all clients
await supabase.from("lobbies").update({
status: "started",
server_port: allocation.port,
server_address: allocation.address,
}).eq("id", lobby_id);
Client-Side Realtime
On the client, subscribe to the lobbies table. When status changes to started, the server address and port are immediately available:
const event = {
event: "UPDATE",
schema: "public",
table: "lobbies",
filter: `id=eq.${lobbyId}`,
}
const handler = (payload) => {
if (payload.new.status === "started") {
connectToGameServer(payload.new.server_address, payload.new.server_port);
}
}
supabase
.channel("lobby-updates")
.on("postgres_changes", event, handler)
.subscribe();
Deployment
Local development
supabase start
supabase functions serve --env-file supabase/functions/.env.local
Set your GameFlow credentials in supabase/functions/.env.local:
GAMEFLOW_GAME_ID=your-game-id
GAMEFLOW_API_KEY=your-api-key
Production
supabase link --project-ref <your-project-ref>
supabase db push
supabase functions deploy
supabase secrets set GAMEFLOW_GAME_ID=your-game-id
supabase secrets set GAMEFLOW_API_KEY=your-api-key
SUPABASE_URLandSUPABASE_ANON_KEYare injected automatically into Edge Functions — do not set them manually.
Sample Project
See the Godot + Supabase sample project for a complete, working implementation of this integration:
👉 Godot + Supabase Sample Project
It includes the full database schema, all Edge Functions, Godot client code, Agones SDK integration, and step-by-step setup instructions for both local development and production.