Every game eventually asks its backend to do something the backend doesn't do out of the box. Loot box odds that read from a player's inventory tier. Matchmaking weighted by a skill model only your game understands. An entitlement granted the instant a season ends, server-side, so nobody can fake it from the client. The default behavior got you to that point. Now you need to customize, and the question is how.
There are three broad ways studios answer that, and inside each one there are specific platforms developers actually put on the shortlist. You can own the source and run the whole thing yourself. You can write logic inside a managed vendor's scripting environment. Or you can write your own services and hand the operations to a platform that keeps them separate from its core. Each is a real answer. Each has a tail you feel more around year two than on day one, and picking well means understanding that tail before you're living in it.
One thing to get straight up front, because it's a common mix-up: "can I see the source" and "how do I customize" are related but different questions. You can extend a platform's behavior deeply without ever forking its code, and you can have full source and still lean on a runtime module system for most of your changes. Keep those separate as we go.
Forking or self-hosting the backend gives you everything. Every subsystem, every service, every line of logic lives in your repository and runs on your infrastructure. Performance-sensitive paths like matchmaking and in-memory state can be tuned exactly to your requirements. There are no vendor API limits and no waiting for a feature to land on someone else's roadmap. For a studio with deep backend expertise and the headcount to sustain it, this is a genuinely powerful option, and it's the most literal answer to "no lock-in" there is.
Two platforms anchor this bucket, and they're not the same flavor of "own the source," so it's worth separating them.
Heroic Labs / Nakama is the open-source end. Nakama is Apache-2 licensed, free, and self-hostable forever on Postgres or CockroachDB, so fork-and-leave is a real option rather than a marketing line. Here's the nuance that matters, though: Nakama's intended way to customize is not editing the core and rebuilding it. It ships a server runtime where you write custom logic as Go, TypeScript, or Lua, all three running concurrently in the same server process, through RPC functions, before/after hooks, and authoritative match handlers. Heroic Labs explicitly recommends against modifying the source and rebuilding to change behavior; the runtime is the supported path. So for Nakama, "owning the source" mostly means you own and operate the whole server and its database, not that you're expected to hack on its internals. If you'd rather not run it, Heroic Cloud is the managed option. The genuine strength here is control with no licensing gate, and it's a strong fit for teams that want exactly that.
Pragma is the licensed end. It's a source-available "backend game engine," built in Kotlin, and it was designed from day one for source-level access rather than bolting source on later as a risk-mitigation step. You customize it by writing Kotlin plugins loaded through configuration, starting from prebuilt templates, and by authoring your own services inside the engine when nothing existing fits. Pragma offers both managed and self-hosted, and it's used by serious studios including People Can Fly and Frost Giant. The tradeoff is the one that comes with any licensed source fork you run yourself: every upstream release is a merge against your customizations, so you carry merge debt that grows with how much you've changed, and your team works in Kotlin and the JVM whether or not that's their strength.
Both flavors share the same underlying cost, and it's the part teams underestimate. Once you own the running system, you own the operational weight of it: autoscaling, failover, container orchestration, CI/CD, on-call rotations, database scaling, and cost optimization. You also build the observability stack yourself, log ingestion, metrics, distributed tracing, dashboards, alerting, and the pipelines behind them. That's not a one-time project; it's a standing commitment that never stops. And language rigidity is real in both cases: you work in the platform's language or you hire for it, which narrows who can contribute and slows iteration.
Who is this actually for? Studios with a real backend org, performance-critical systems that need hand-tuning, and requirements specific enough that no managed platform will ever meet them. For a lot of teams, that isn't the situation, and taking on an infrastructure organization to change loot box logic is a steep price.
Managed platforms let you attach custom logic without thinking about infrastructure. If you need to validate a receipt, adjust an inventory, or run a trigger when a game event fires, this is the fastest path from nothing to a working backend feature. For prototypes and early live-ops, it's often the right call and genuinely all you need.
Three platforms sit in this bucket, and they span a real range from "constrained script" to "hosted service," so they're worth taking individually.
PlayFab CloudScript has two forms. Classic CloudScript is a set of JavaScript functions compiled with V8 and hosted on PlayFab's servers, which is quick to start but JavaScript-only and bounded by PlayFab's execution model. The newer path runs CloudScript on Azure Functions, which gets you C# and other languages plus local debugging, but now you're standing up and operating a separate Azure Functions application with its own billing, deployment, and observability surface, and calls into it carry timeout limits that will shape what you can do in a single request.
Unity Gaming Services Cloud Code also comes in two shapes: JavaScript scripts you author in the dashboard, and C# modules you write and deploy from the Unity Editor, which Unity recommends as the way to get the most out of it. Both run in Unity's hosted environment and let you change game logic without shipping a new client build. It's a natural fit if you're already a Unity shop, and less so if you aren't.
Beamable takes it furthest: you write C# microservices that live in your Unity project alongside your client code, and Beamable hosts and scales them for you. Of the three, this is the closest to a real service model rather than a script, and its logic runs server-side and safe from client tampering. The constraint is that it's built around Unity and C#.
The shared tradeoff across this bucket is the execution model. You run inside what the vendor exposes, which means concurrency, autoscaling, and low-latency tuning are decisions the platform makes, not you. Observability tends to be shallow: logs are often delayed, tracing is thin or absent, and debugging distributed behavior turns into reasoning from symptoms rather than root causes. And you're more tightly coupled to vendor health; if a module gets deprecated or a behavior changes, your game inherits that without much warning. None of this makes cloud scripting wrong. It makes it a fast on-ramp with a ceiling, and the question is whether your game stays under it.
Notice the gradient, though. Classic CloudScript sits at the constrained end, and Beamable's hosted C# microservices sit close to the other, where "scripting" starts to look like running actual services. That upper end is the bridge to the third approach.
There's a third path that sits between the two: you write the custom logic your game needs as services, and the platform runs, scales, and observes them for you, while keeping them separate from its own core. AccelByte Extend is that path, so it's a useful concrete example of how the model works in practice. You get much of the flexibility of a source fork without taking on the operational weight of running the infrastructure.
Mechanically, Extend apps are gRPC servers, and there are a few kinds:
An Extend Override is a gRPC server holding custom functions that AccelByte Gaming Services (AGS) calls instead of its own defaults, which is how you replace matchmaking logic or change how loot box odds resolve.
An Extend Event Handler is a gRPC server that receives AGS events through Kafka Connect and runs your logic in response, which is how you grant an entitlement automatically when a season ends.
There are also Service Extensions for adding entirely new endpoints and App UI for embedding custom admin screens. You write them in Go, C#, Java, or Python (TypeScript is in development), package them as Docker containers, and deploy them with the extend-helper-cli tool.
If you'd rather not start from an empty repo, the Extend Apps Directory is a public collection of open-source apps, custom matchmaking functions, MMR services, rotating shop handlers, voice integrations, that you fork, modify, and deploy.
What this model does about the two tradeoffs from the other buckets:
Customization without the ops burden.
Extend uses well-defined gRPC interfaces that stay stable when the core platform updates, because your logic lives separately from it. Your services deploy independently, so you can ship, iterate, and roll back one without touching the others; a change to your ranked matchmaking service doesn't put your economy logic at risk. The core evolves on its schedule and your services evolve on yours, which is what keeps it maintainable over years rather than months. That separation is the thing a source fork has to fight against with every merge.
Observability you don't have to build.
With a fork, the logging, metrics, tracing, dashboards, and alerting are all yours to stand up and maintain. With cloud scripting, you usually get shallow logs and thin visibility. Extend includes structured logs with context, metrics for latency, throughput, and queue depth, distributed tracing across your custom services and the platform's, unified dashboards, and alerting, out of the box.
Not locked to a full-AGS stack.
Extend apps can call external APIs and third-party services and act as a bridge in a mixed backend. That's also how the EOS case from earlier resolves in practice: you can use Extend to write the custom logic that wires EOS into the rest of your backend without hosting that logic yourself. There's a deeper architecture writeup if you want the internals.
Now the honest tradeoff, because this bucket has one too. Writing production Extend services has a real learning curve but the ramp can be a lot shorter with AccelByte’s AI capabilities.
AccelByte ships two MCP (Model Context Protocol) servers that lets AI assistants in tools like Cursor, VS Code, and Claude Code connect to external services and use them directly in the editor.
The ags-api-mcp-server bridges your assistant to the full AGS API surface through OpenAPI, so from inside the editor you can search API operations, inspect endpoint schemas, and run real requests against your live environment with your own auth token.
The ags-extend-sdk-mcp-server exposes the Extend SDK itself as structured context across Go, C#, Java, and Python, so the assistant generates code against the actual SDK signatures instead of hallucinating ones that don't exist.
With a source fork, your custom logic is opaque to an AI agent. With cloud scripting, the vendor doesn't publish the interfaces an agent needs. AccelByte is the only managed backend that ships dedicated MCP servers for both its platform APIs and its customization SDK, which is checkable and, as of now, holds.
Here's what that changes in practice. A developer opens Cursor to build a ranked matchmaking service that weights skill by gacha tier pulled from the player's inventory. Without the MCP servers, they're switching between the AGS docs, the Extend SDK reference, and the editor, breaking focus on every lookup. With them connected, they describe what they want; the Extend SDK MCP surfaces the right symbols and signatures for the matchmaking override interface, the AGS API MCP validates against the live matchmaking and inventory endpoints, and the assistant produces a gRPC stub that compiles and conforms to the real SDK. The developer reviews, adjusts the logic, and ships.
Two examples, both real and worth the specifics.
Ascent Rivals by Genun Games is a racing-shooter hybrid from a four-person indie studio that's already won at DreamHack and PAX. For a team that small shipping a cross-platform competitive game, building and maintaining custom backend logic in-house wasn't realistic. They used Extend to dynamically load sponsorships and in-game advertisements, the kind of game-specific logic that doesn't belong in a default backend and would otherwise have needed infrastructure they didn't have the headcount to run.
Ten Trillion Triangles used Extend for the security-sensitive microservices in Revolution, specifically draft pool generation and cosmetic exchanges, functions that carry real risk if they run client-side. The team estimates that building the equivalent infrastructure themselves would have cost roughly two additional years, two engineering hires, and $350,000. That's their estimate, not ours, but it's the shape of the operational bill the hosted model is meant to remove.
It's worth saying where Epic Online Services lands, because it comes up in these conversations and it genuinely doesn't fit any of the three cleanly. EOS is free identity, social, voice, anti-cheat, and connectivity plumbing, not a full backend, and its "customization" isn't a scripting runtime you write into or a platform core you fork. You integrate its C SDK or web APIs into your own client and server, and if you need authoritative custom logic, EOS supports a trusted-server client policy, but you host that trusted server yourself. There's no vendor-run script environment and no core to extend. So the honest place for EOS is alongside a backend rather than inside a customization bucket: you bring your own custom-logic layer, self-run or hosted, and wire EOS in for the parts it's good at. We get into where that line sits in the piece on server-authoritative versus client-authoritative architecture.
| Criteria |
Own the Source
Pragma · Nakama |
Cloud Scripting
PlayFab · UGS · Beamable |
Hosted Extension
AccelByte Extend |
|---|---|---|---|
| Control | Maximum, down to the core | Moderate, within limits | Fork-level on the logic |
| Operational burden | High, you run everything | Low, no infra to manage | Low, platform runs it |
| Language flexibility | Platform language (Kotlin, Go) | Vendor-defined (JS, C#) | Go, C#, Java, Python |
| Observability | Build it all yourself | Usually shallow | Built in, full-stack |
| Upgrade / merge risk | Merge debt on every update | Vendor changes hit you | Stable interfaces hold |
| Vendor coupling | Low, you own it | High, tied to vendor health | Low, bridges external too |
| AI tooling | Limited, code is opaque | Limited, interfaces closed | MCP servers, both API + SDK |
Backend customization is a decision every studio faces eventually, and none of these three is the right answer for everyone. Owning the source gives you total control and turns your team into an infrastructure org to get it, which pays off when you have the org already and a performance need nothing managed can meet. Cloud scripting is the fastest way to your first custom feature and runs out of road at a ceiling you may or may not hit. Hosted extension sits in between: you write the logic your game actually needs, the platform runs everything behind it, and the interfaces stay stable while both sides evolve.
The real question isn't which approach is best. It's how much of your backend you want to operate, how much custom logic your game genuinely needs, and whether you can live inside someone else's execution model. Answer those honestly and the choice is usually obvious.
Pick the one that matches the team you have, not the team you wish you had.