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.
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://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, GameFlow SDK integration, and step-by-step setup instructions for both local development and production.