# KinematicSoup: Full Content > Multiplayer engine and real-time collaboration tools for Unity. This file contains the full text of all KinematicSoup pages and blog posts. --- # Reactor Multiplayer Engine URL: https://www.kinematicsoup.com/reactor Reactor is a Unity multiplayer engine built around bandwidth efficiency. It moves 17x less transform data than Unity's Netcode for GameObjects and 9.5x less than Photon Fusion 2, and around 6x lower wire bandwidth overall. Key features: - Sync groups and interest management: spatially partition entities so each player only receives updates for what's nearby - Server-authoritative physics with raycasts, sweeps, and overlap queries - Input prediction and client-side interpolation - Component-based transform, animation, and ownership sync. Works with any Unity controller without a rewrite - Ship fast with client authority, then add server validation without rewriting - Local development server included; no cloud account needed to start - Free self-hosting for registered game titles: up to 32 CCU per room - Managed cloud hosting from $20/month with one-click deployment --- # Reactor Benchmarks URL: https://www.kinematicsoup.com/reactor/benchmarks Open benchmark comparing Reactor against five Unity multiplayer solutions. Reactor delivers 2 bytes per transform update vs 19 bytes for Photon Fusion 2 and 34 bytes for Netcode for GameObjects. Full methodology and source available on GitHub. --- # Scene Fusion URL: https://www.kinematicsoup.com/scene-fusion Scene Fusion syncs the Unity Editor in real-time so teams can work in the same scene simultaneously. No merge conflicts from scene files. How it works: 1. Install via Unity Package Manager 2. One team member hosts a session from the Scene Fusion panel 3. Others join; every change (moved objects, adjusted properties, new GameObjects) appears in everyone's editor as it happens Synced: transforms, built-in Unity component properties, GameObject hierarchy, terrain height maps, lighting, materials, prefab creation, custom MonoBehaviour serialized fields. Not synced: code changes, modifications to existing prefab assets, asset deletions/renames in the Project window. Free for teams of two. Paid tier is $25/seat/month (up to 10 seats) and adds terrain editing and additive scene loading (sublevels); enterprise licensing beyond 10 seats adds on-premises deployment and SLA support. Cloud versions collaborate remotely over the internet; LAN-only versions on the Unity Asset Store are restricted to local networks. Used by Synty Studios for nearly a decade across hundreds of asset packs. --- # Pricing URL: https://www.kinematicsoup.com/pricing Reactor: - Local development: free, full feature set, up to 32 CCU per room - Self-hosted: free for registered game titles up to 32 CCU per room; licensing removes the cap and covers non-game use - Reactor Cloud: from $20/month (Solo), $100/month (Indie), $500/month (Studio), Enterprise by arrangement - Every paid cloud tier includes a usage credit equal to the subscription cost - Rooms billed by the minute, from $0.02/hr (XS) to $0.50/hr (XL) - Bandwidth: $0.05/GB egress in N. America and Europe, $0.10/GB in S. America and Asia Scene Fusion: - Cloud free tier: up to 2 seats, 20,000 objects, remote collaboration, core sync (no terrain editing or sublevels) - Cloud paid: $25/seat/month up to 10 seats, unlimited in-scene objects, terrain editing, additive scene loading (sublevels) - Enterprise (10+ seats): on-premises deployment, SLA support, volume pricing (contact us) - LAN Free (Asset Store): 2-seat cap - LAN Indie (Asset Store): $190/seat, no cap Add-ons available: priority support, multiplayer development services, Scene Fusion plugin compatibility layers, self-hosting licenses. --- # About KinematicSoup URL: https://www.kinematicsoup.com/company KinematicSoup Technologies Inc. is a Canadian software company building multiplayer and collaboration tools for Unity game developers. Products: Reactor (multiplayer engine) and Scene Fusion (real-time scene collaboration). Epic MegaGrant recipient 2022. Unity Asset Store featured partner. --- # Blog Posts ## 2 years to build a game, 3 days to add multiplayer URL: https://www.kinematicsoup.com/blog/mutant-mayhem-single-player-to-multiplayer-in-three-days Date: 2026-08-26 Summary: Solo developer Matt Van Alstyne took Mutant Mayhem from single-player to a 4-player match in three days with Reactor, then began moving to server authority without a rewrite.

Mutant Mayhem, in development. Footage courtesy of KamJam Games.

**Mutant Mayhem** (in development) is a top-down sci-fi survival game by solo developer Matt Van Alstyne, known in his community as AiryShelf. Build a base, defend against evolving mutants, upgrade everything, and conquer 14 planets with unique challenges. It is his first Unity game. The first 4-player match ran on day three of the multiplayer conversion. ## Two versions, twenty years apart The first Mutant Mayhem was a GameMaker game Matt built in 2004, at fourteen, from a tutorial. "I enjoyed the game I made as a kid, and others did too." He stayed away from game development for years afterward, "out of fear it would consume my life. Well, now I'm ready for that fate!" In 2024 he finished Harvard's CS50x online while working his last rotation steering drills for pipeline crossings. Mutant Mayhem came back as his final project. After a month of Unity tutorials he started the full game with no design document. The scope grew: a building system, multiple planets, evolving enemies, controller and touchscreen support, a Steam goal. ## "Networking scares me" Multiplayer was not in the plan. "Networking scares me because I don't know it well, so multiplayer was never even an idea for most of the game's development." A friend asked for two players on one keyboard. Other players kept asking after that. This summer he built an online leaderboard in about a week, faster than he expected. He started the multiplayer conversion the same week. He had never built anything networked. ## Design in an evening, playable by day three Design took one evening. Implementation took about two and a half days, in this order: second player, enemies, damage dealers, upgrades, building system, turrets and drones, public lobby. He also got seven days' notice of exams after starting implementation; studying and cramming during development slightly slowed the process. Reactor's components handled transform and ownership sync. Matt worked from behavior rather than internals, describing what he saw to his AI coding assistant: "I would test and report what I saw. It would review the server and game logs, and I just told it how I wanted it to behave." The player and everything that communicates with it was reworked for multiple players. "The solo gameplay was mostly unaffected through the entire process, and only broke once when 'game over' wouldn't happen." Did he ever want to quit? "I don't remember feeling like giving up on multiplayer at all." ## The day-three stress test The first match had four players. Matt set it up as a stress test: the authoritative host was his Galaxy S22 Ultra on wifi, connected to a local server launched from the Unity editor on his laptop. Frames on the phone dropped from 60 to 20 at the busiest points. No network-entity pooling existed yet. The match stayed in sync. "It went really well. I don't think anyone did the tutorial, so it was frantic and disorganized, lol, but really fun regardless." A phone as authoritative host is the least reliable machine in the room. Production multiplayer runs on servers. That migration is the current work. ## Hardening without a rewrite Matt is moving the game from client authority to server authority: session tokens validated by a server authentication script, spawn validators, and server scripts that retain and reassign player entities across disconnects. Design is complete. Implementation is underway. Reactor supports this order of work: ship a client-authority build, add validation and authority where the game needs it, keep the codebase. Matt's questions during this phase led to new Reactor documentation, including the [Technical Overview](https://kinematicsoup.gitbook.io/reactor/architecture), [Handling Disconnects and Reconnecting](https://kinematicsoup.gitbook.io/reactor/tutorials/reconnecting), and [Validating Client Transform and Property Updates](https://kinematicsoup.gitbook.io/reactor/examples/validators). "Don't hesitate to reach out to the staff at Kinematic Soup, they are great and always willing to help out." ## The tools Matt used AI coding assistants for the conversion, with no AGENTS.md or special instructions. The design and the game are his; the AI assistant wired everything up under his direction while he ran the loop: test, observe, report, direct. His advice to other solo developers: "Do some tutorials first to get a basic grasp of things, to catch hallucinations and design flaws. Test often and make sure the AI is surgical." ## What's next Server authority, network-entity pooling, other optimizations, and Reactor's experimental UDP client frame syncing ("There is so much real-time data that I don't see the point in waiting for missed packets"). Then Steam and Google Play. Mutant Mayhem is in development by KamJam Games. Follow it on itch.io: [kamjamgames.itch.io/mutant-mayhem](https://kamjamgames.itch.io/mutant-mayhem) KamJam Games --- ## Multiplayer Network Topologies: How to Choose URL: https://www.kinematicsoup.com/blog/multiplayer-network-topologies-how-to-choose Date: 2026-07-09 Summary: Dedicated server, listen server, peer-to-peer, relay, or a plain web backend: how each multiplayer topology works, which games they fit, and the constraints that make the choice for you. Every multiplayer game has a network topology: an answer to the question of whose machine runs the simulation and how everyone else's machine hears about it. If you have never chosen one deliberately, you still chose one. It was the default of whatever framework you started with, and defaults are decisions someone else made without knowing your game. A wrong choice costs more than most technical decisions because it surfaces late. A topology is a decision about where authority lives, and every system built afterwards, movement, combat, spawning, persistence, assumes that answer. Teams usually find the mismatch at one of three moments: the first playtest with strangers, when host advantage or cheating stops being theoretical; the port to a platform the topology cannot support, which for client-hosted games is mobile; or launch, when the server bill or the session-size ceiling arrives. By then the fix is not a setting but a rewrite of the layer everything else was built on, at the point in the project with the least time for it. The good news is that choosing well is less about taste than it looks. Most of the option space gets eliminated by constraints your game already has, before preference enters into it. This guide walks through the topologies in use today, how each one works, and then the constraints that do the choosing. ## Dedicated server A server process owned by the game's developer runs the simulation. Every client connects to it, sends inputs, and receives state updates. The server is the single source of truth: it validates what clients claim, resolves conflicts, and decides the outcome of every interaction. Clients render that state, usually with prediction layered on top to hide the round trip. Dedicated server: four clients connected to a developer-run server that holds authority This is the strongest position on cheating and fairness. No player's machine holds authority, so no player has a latency or information advantage built into the architecture, and claims like "I hit you" are checked by hardware nobody in the match controls. Performance is predictable because the simulation runs on known hardware rather than whatever laptop the host happens to own. Dedicated comes with an operational cost: someone has to run and pay for the servers for as long as the game is alive. We wrote about what that costs, self-run and managed, in the [multiplayer cost series](/blog/how-much-does-it-cost-to-build-and-run-a-multiplayer-game/). Two variations are worth knowing about. Large or persistent worlds are usually built as clusters of dedicated servers, with the world sharded across rooms or regions and players handed between them; that is an architecture built on top of this topology rather than a different topology. And some games run a dedicated server but grant clients authority over their own movement to save server CPU, accepting the potential cheat surface in exchange. You will meet that hybrid in the wild, usually in games that later wish they had not shipped it in ranked modes, but sometimes in games where the compromise was deemed acceptable for another benefit. You will find dedicated servers under most competitive shooters, MMOs, battle royales, and physics-heavy games. Tools in this space include Reactor (our engine), Photon Fusion 2 in server mode, Unity's Netcode for GameObjects or Mirror deployed to dedicated hosts, and coherence with its cloud simulators. We compared several of these in [our engines guide](/blog/best-unity-multiplayer-engine/). ### Games that fit Should use it: competitive shooters and battle royales, MMOs and any persistent world, physics-heavy games where the simulation must be shared, and anything where ranking, money, or an economy rides on the outcome. Also any real-time game shipping on mobile, where client hosting is not an option. Could use it: co-op games that want drop-in sessions that outlive the host, or a platform mix that includes mobile or consoles with strict networking rules. Where it competes: against a listen server for small co-op, choose dedicated when mobile is a target, when sessions must survive the host leaving, or when you can budget for servers; choose the listen server when hosting cost has to be zero and the players are friends. Against lockstep for strategy games, choose dedicated when you cannot guarantee determinism or when maphacks matter; lockstep wins when unit counts are in the thousands and command delay is acceptable. ## Listen server (client-hosted) One player's machine runs both the game and the server; the other players connect to it. Authority works like the dedicated case, except the authority lives on a player's hardware and shares resources with their frame rate. Listen server: one player hosts and the other players connect to that machine That grants the host an inherent advantage, since their inputs reach the authority with zero latency, and it makes the session host-dependent: when the host quits, crashes, or loses connectivity, the session dies with them unless the game implements host migration. Migration is genuinely hard to do well, because it means promoting another peer to host mid-session, handing off authoritative state, resolving actions that were in flight, and hoping the new host's connection can carry the room. Many games that advertise host migration ship a version that works in the demo and disappoints in the wild. The binding resource is the host's upload bandwidth. Residential connections are built for downloading, and the host must upload state to every other player, so the session size ceiling is set by the worst upstream connection in the lobby, not by anyone's download speed. This sets a lower limit on both the amount of data the game cause use per connection as well as the number of players a single host can accomodate. The reward for accepting all of this is that hosting costs the developer nothing, which is why the topology carries co-op games, small-lobby games, and most games where cheating is a social problem rather than an economic one. Tools here include Netcode for GameObjects and Mirror in their default host modes, Photon Fusion 2 in host or shared mode, Reactor in client-authority mode (ours), which works much like Fusion 2's shared mode with clients driving the objects they own while the server brokers ownership, and the session APIs in Steamworks and Epic Online Services. ### Games that fit Should use it: co-op games for up to about eight players on PC and console, party games played among friends, and prototypes or playtests where standing up servers is premature. Could use it: casual competitive games where the host's latency advantage is tolerable, and games with a small budget that still need a public lobby. Where it competes: against a dedicated server, the listen server loses as soon as cheating has economic stakes, the game ships on mobile, or sessions need to outlive the host. Against a relay, there is no contest: a listen server shipping today should run over a relay, since the relay solves the NAT and privacy problems without moving authority. ## Peer-to-peer with deterministic lockstep No server at all. Every player runs the full simulation locally and exchanges only inputs with every other player. For this to work, the simulation must be bit-for-bit deterministic: the same inputs must produce the same state on every machine, every time, across hardware and platforms. Each tick waits until every player's input for that tick has arrived, so the game advances in lockstep and feels as responsive as the slowest client in the session. Peer-to-peer lockstep: four peers in a full mesh exchanging inputs, each running the same simulation The bandwidth profile is remarkable, which is why real-time strategy invented the technique: a thousand units cost no more to network than ten, because only the players' commands cross the wire. The liabilities are equally structural. A single divergence between simulations is unrecoverable without resync machinery, determinism rules out most off-the-shelf physics engines, and every client holds the complete game state, so maphacks are an architectural property rather than a bug to patch. RTS games are the home genre, and the approach persists anywhere unit counts are enormous and inputs are small. Photon Quantum is the notable engine offering determinism as a product; the classic implementations are custom, and the RTS community's postmortems on them are some of the best networking literature there is. ### Games that fit Should use it: real-time strategy with large unit counts, tower defense and auto-battlers with many entities, and simulations where every player must see the same world and input latency can hide behind a command delay. Could use it: sports and fighting games, which used lockstep historically; most have since moved to rollback. Where it competes: against rollback, lockstep wins when unit counts are huge and a few frames of input delay are acceptable; rollback wins when feel matters and player counts are small. Against a dedicated server, lockstep wins on bandwidth for large entity counts, and loses when determinism cannot be guaranteed, when maphacks matter, or when the platform mix makes peer connections unreliable. ## Peer-to-peer with rollback The same input-exchange idea, with the waiting removed. Instead of stalling until remote inputs arrive, each client predicts them, usually by assuming the other player repeated their last input, and keeps simulating. When the real input arrives and disagrees, the client rewinds to the last confirmed state, applies what really happened, and re-simulates forward to the present, all inside one frame. Peer-to-peer rollback: a tick timeline with predicted remote input, rewound and replayed when the real input arrives Done well, local inputs feel instant and the corrections are invisible, which is why fighting games consider rollback the gold standard for online play. The cost is engineering discipline: the simulation must be deterministic like lockstep, and additionally serializable and fast enough to re-run several frames in a single frame's budget. That constrains scope in practice to games with small player counts and lean simulations. GGPO made the technique famous and open source; its descendants power most modern fighting games, and Photon Quantum brings the same rollback-on-determinism model to Unity teams that do not want to build it from scratch. ### Games that fit Should use it: fighting games, platform fighters, and other one-on-one or two-on-two games where instant input response is the product. Could use it: small co-op action games with lean, deterministic simulations, and sports games with a handful of controlled entities. Where it competes: against lockstep, rollback wins on feel and loses on scale, since re-simulating several frames per frame is affordable only for small simulations. Against a dedicated server, rollback wins on latency for two players and loses when the game has more than a few players, when the physics engine is not deterministic, or when the platform mix includes mobile. ## Relay-assisted sessions A relay is less a topology than a modifier on one. A lightweight server in the middle forwards packets between players but runs no game logic, which solves the two problems that kill direct connections: NAT traversal, since everyone connects outward to the relay instead of accepting inbound traffic through a home router, and IP privacy, since players never learn each other's addresses. Authority stays wherever the base topology put it, on a player host or spread across peers. Relay-assisted session: players connect outward to a relay that forwards packets; the host keeps authority The cost profile sits between free and dedicated. Relays only move bytes, so they are cheap to operate per player, and platform vendors now provide them as a service: Steam Datagram Relay, Unity Relay, Epic Online Services, and the console platforms' equivalents. The latency cost of the detour through the relay is usually modest and often negative against a bad direct route, since relay networks tend to run on better backbones than consumer ISPs peer over. In practice, most games described as client-hosted today are client-hosted over a relay. If you are shipping a listen-server game in the 2020s, this is almost certainly the form it should take. ### Games that fit Should use it: any client-hosted game shipping to the public, since a relay removes port forwarding and hides players' addresses, and any peer-to-peer game (lockstep or rollback) that needs reliable connectivity between strangers. Could use it: shared-authority models where each client owns its objects and the relay carries everything, and mobile games where a phone hosts through the relay, with the caveat that the host is still the least reliable machine in the session. Where it competes: against a dedicated server, the relay wins on cost, since it runs no game logic, and loses when authority needs to be neutral, when sessions must outlive the host, or when the game is real-time on mobile, where a dedicated server is the reliable choice. ## Asynchronous backend Not real-time at all. Clients talk to an ordinary web backend over HTTPS; the backend stores moves, resolves turns, and notifies opponents, often through a push notification. There are no persistent connections, no tick rate, and no NAT concerns, because nothing about the architecture differs from any other online application. Asynchronous backend: clients make HTTPS requests to a web backend that stores turns and pushes notifications This is the correct topology for a whole class of games, and it is included here because choosing a real-time stack for a turn-based game is a common and expensive mistake. If your game's pace is measured in "your turn" moments rather than milliseconds, a real-time topology buys you permanent infrastructure cost and complexity for nothing. Word games, board games, and most social and idle games live here happily. Purpose-built backends like Nakama and PlayFab cover the game-shaped parts, and a plain web stack works fine too. ### Games that fit Should use it: turn-based strategy, word and board games, gacha and idle games, social simulations, and asynchronous competition such as ghost races and leaderboards. Could use it: slow real-time games, such as some 4X titles, where a turn or a tick takes seconds and a request per action is fine. Where it competes: against every real-time topology, the backend wins whenever outcomes resolve in turns rather than ticks. Many games need both: a real-time topology for the match and a backend for the meta layer around it, such as accounts, progression, and matchmaking. That is a pairing, not a choice. ## How to choose: elimination first Run these checks in order, and strike topologies as they fail. What survives is your real option space; the "games that fit" notes above cover the overlaps. 1. **Is the game real-time at all?** If outcomes resolve in turns rather than ticks, use an asynchronous backend and stop reading. Everything else on this list is overkill. 2. **Does it ship on mobile?** If yes, client-hosted topologies are out. A host's address must stay stable for the whole session, and mobile networks do not offer that: devices hop between Wi-Fi and cellular as players move, and carrier-grade NAT reassigns addresses without notice. A real-time mobile game connects to something with a stable address, which means a dedicated server or a relay. This single constraint eliminates half the option space for a large share of games, and it is far cheaper to learn before building than during the port. 3. **Can you commit to determinism?** Lockstep and rollback require bit-identical simulation everywhere, which rules out most off-the-shelf physics engines and any codebase that treats floating point casually. If you cannot make that commitment, both peer-to-peer models are out. 4. **Does money or ranking ride on outcomes?** Competitive integrity requires authority on hardware players do not control. Host advantage and peer-to-peer's open state are architectural properties; they cannot be patched out after launch. Ranked, wagered, or economy-bearing games point at dedicated servers. 5. **How many players per session, and how big is the world?** Host upload bandwidth caps listen servers, and input exchange scales poorly past a handful of peers. Large sessions and persistent worlds push toward dedicated servers, sharded when one machine stops being enough. 6. **Who pays for infrastructure?** If the answer must be nobody, you are choosing among listen servers, relays, and peer-to-peer, and accepting their limits knowingly. That is a legitimate choice for a great many games; the failure mode is making it by accident. ## The mistakes worth avoiding Each of these is a rule from the checklist, learned in production instead: - **Building a turn-based game on a real-time stack.** The infrastructure bill arrives monthly forever, purchasing nothing the game needed. - **Shipping client-hosted on PC and then porting to mobile.** The game ports; the topology does not. Games have re-architected their networking mid-life over this. - **Prototyping with client authority in a competitive game.** Server authority is not a feature you bolt on later; it changes where the simulation lives. If the endgame is ranked play, build toward authority from the start. - **Sizing a listen server by download speed.** The host uploads to everyone. Upstream is the limit, and residential upstream is usually a tenth of the number on the ISP's ad. Choose by elimination, and the topology decision mostly makes itself. The engineering that follows is substantial in any direction, but it is far better spent building on the right foundation than migrating off the wrong one. *Reactor, our multiplayer engine for Unity, ships with managed dedicated hosting behind it. If your elimination pass landed on dedicated servers, the [engine tour](/reactor/) is the place to start.* --- ## How We Synced 5,000 Enemies in a Multiplayer Survivors Game URL: https://www.kinematicsoup.com/blog/multiplayer-survivors-5000-enemies Date: 2026-06-24 Summary: A multiplayer survivors-like with 5,000 to 6,000 networked enemies, built in a week on Reactor. The numbers behind syncing that many server-authoritative entities at 50 to 70 KB/s with no network LOD. We build games on Reactor as a way to dogfood our own engine, and the latest one is a multiplayer survivors-like. The genre had a recent hit in Megabonk, and the appeal is familiar: you stand in a rising tide of enemies and cut them down in swaths. Our twist is that it is multiplayer, and there are far more enemies. A typical match has 5,000 to 6,000 of them on the field at once, and clearing a crowd that size has a particular cathartic pull to it. The gameplay loop was never the hard part. The question we cared about was whether we could keep 5,000-plus server-authoritative enemies synced to every player without the bandwidth or the frame rate falling apart. Here is how it held up.
A typical match: 5,000 to 6,000 server-simulated enemies, synced to every player.
## A week of greybox The first playable version took about a week, built with Reactor and our in-development DOTS extension. None of that week went into networking. There was no art either: the world was a flat plane ringed by a wall, players and enemies were capsules, and projectiles were spheres, with no sound or music. It was as greybox as greybox gets. The time went into the game concept and the enemy behavior, because the sync layer was already handled. That is the whole point of dogfooding the engine: we get to spend the week on the game instead of on serialization and state replication. The game targets 2 to 4 players in co-op, a choice driven by the design rather than any limit in the engine. ## Boids on the server Every enemy is server-authoritative. The flocking is a boids algorithm running on the Reactor server, so the simulation is consistent for all players and there is nothing for a client to fake. Each enemy is an entity with an `Update` function that only operates on itself, which lets us use Reactor's parallel updates: the engine runs those `Update` calls across multiple threads. For this game we used two threads. We did not reach for Reactor's virtual-player system, where each entity drives itself through the server-authoritative controller; the self-contained boids approach was simpler for what we needed. To keep the CPU in check, the boids run on a schedule rather than every tick. An enemy far from any player updates once every 8 frames, about 3.75 times per second, and an enemy near a player updates 15 times per second. This is simulation level of detail, applied to compute. It is worth being clear that it is separate from network level of detail, which we will come back to, because we are not using any. With all of this in place, the server holds at roughly one hardware thread most of the time. A few subsystems push it past a single vcore in bursts, and those are an optimization target rather than a wall. Simulating 5,000 to 6,000 flocking enemies on about one core is the kind of headroom that makes a crowd this size practical to host. The ceiling sits well above what the game needs. Early in that first week, before we settled on the 5,000 to 6,000 range, the greybox was syncing 10,000 entities, around 11,000 networked objects in total, to every client at once, on four server cores. We brought the count down because the game plays better there, not because the engine ran out of room. Between the smaller count and the scheduled updates, that four-core load came down to roughly one. ## The network numbers The server runs at a 30 Hz tick rate and sends a network frame every second tick, for a 15 Hz send rate. At those settings, with 5,000 to 6,000 entities in the play area and no network level of detail, server bandwidth sits between 50 and 70 KB/s per player. The compression behind that number: - A transform delta compresses to 7 bits. - A full object sync, sent when an object spawns, compresses to about 4 bytes. None of that was hand-tuned. We set the fidelity we wanted and the rest is innate to the netcode. Two details show how automatic it is. Enemies spawn at random positions and carry a full 3D transform, but the game never uses their rotation. Reactor notices that the rotation never changes and compresses it down to near zero bits on its own. Bullets are a second case: they spawn from the player's avatar, so their positions cluster near a known point, and Reactor takes advantage of that proximity to compress them, again with no instruction from us. Spawning and destroying is a larger share of the traffic than people usually expect. In later levels players fire hundreds of bullets per second, each of which spawns an object, and enemies are destroyed continuously as their health reaches zero. Replacement enemies spawn once per second, batched into a single update, while bullets and deaths happen on any frame. Together, this object churn accounts for about 20 percent of the total bandwidth. High spawn and destroy rates are where a lot of engines get expensive, so it is a part of the budget worth watching, and at 4 bytes per spawn it stayed cheap here. ## Why no network LOD The obvious next optimization is network level of detail: send updates for distant objects less often. We are not doing it, for a simple reason. The compression already performs well enough that we do not need it. The 50 to 70 KB/s figure is what the game costs before any culling at all. Network LOD would still help. It would cut distant-object updates by around 30 percent and reduce encoding time. The catch is that it adds a cost at the boundary: when an object crosses from far to near, it needs extra correction data, which is an inherent side effect of using delta coding for position. When your overall compression ratio is already strong, that tradeoff is not always worth making. We have it filed as a future option, but for now the effort is going into game design and gameplay, not squeezing a bandwidth line that is already comfortable. ## Choosing the rates The 30 Hz simulation rate and 15 Hz network rate were deliberate, one for server performance and one for bandwidth. Dropping the simulation from 60 Hz to 30 Hz halves how often the server runs its per-tick work: input handling, world-state checks, network status, and the rest. It also gives the simulation more room. At 30 Hz, each tick has roughly a 30 ms window to finish, and while it rarely needs all of it, the budget is there when a heavy frame comes along. The 15 Hz send rate suits the game. Players auto-attack, so their moment-to-moment input is light, and the two active abilities, a special attack and a dash, stay responsive at this rate. A twitch shooter would want more; a survivors game does not. One last detail we like: if encoding or simulation runs long in real time, Reactor automatically reduces the network sync rate to hold a steady cadence and keep server simulation time aligned with the wall clock. The send rate is a target, not a guarantee, and the engine protects the cadence on its own. ## The client side Rendering 5,000 enemies is its own problem, separate from networking them. On the client we use DOTS to handle the entity count, and the result is a steady 60 frames per second on moderate hardware, GPU-limited rather than CPU-limited. The simulation is on the server and the rendering scales on the client, and the two meet in the middle at a crowd that would be impractical to push through a conventional setup. ## What it adds up to A multiplayer survivors-like with 5,000 to 6,000 server-authoritative enemies, one server core, 50 to 70 KB/s per player, a steady 60 FPS client, and no network LOD, built to a playable greybox in a week. The part we want to underline is that the efficiency was not the work. We set a fidelity target and the netcode did the rest, from the 7-bit transform deltas to the dropped rotation to the proximity-compressed bullets. That is what lets a small team spend its week on the game instead of the plumbing. That automatic efficiency is the core of what Reactor does. If you are building something that needs to put a lot on the wire, [see what Reactor can do](/reactor/). --- ## Why Multiplayer Physics Breaks at Scale URL: https://www.kinematicsoup.com/blog/why-multiplayer-physics-breaks-at-scale Date: 2026-06-10 Summary: Syncing ten players is easy. Syncing thousands of physics objects is a different problem, and underneath it is a bandwidth problem. Here is where the cost comes from and what brings it down. Networking a multiplayer game is really two separate problems, and they have almost nothing in common. The first is moving ten players around a map, and it is effectively solved: position and rotation, a little interpolation, and server authority over who is where. Every engine and framework ships something that handles it well enough to get you a playable prototype in an afternoon. The second is moving thousands of active physics objects: rigid bodies, destructible props, dense crowds, persistent world state, all colliding and reacting every tick. This is the one that feels fine in a prototype and falls apart in production. Online multiplayer is now the most-adopted feature in Unity games, named by 83% of developers in the [2026 Unity Game Development Report](https://unity.com/resources/gaming-report), and as more of those games reach for physics depth and persistent worlds, more teams meet this second problem for the first time. When it falls apart, it is almost always for the same reason. ## It is a bandwidth problem before it is anything else A physics object on the wire is its transform plus its motion: position, rotation, and velocity. After the compression every serious engine already applies, a transform update lands somewhere around 12 to 20 bytes. Physics adds the velocity state on top of that. Then multiply it out. With 1,000 active physics objects at 30 Hz, a client that needs to see all of them receives roughly 1,000 * 18 bytes = 18,000 bytes per tick, which at 30 Hz works out to about 540 KB per second, per client, for movement alone. Push the scene to 10,000 objects and the same client is trying to receive 5.4 MB per second, which is no longer a number you can tune your way out of; it is a hard ceiling on what the scene can hold. This is why the jump from "it works" to "it ships" is so steep for physics-heavy games. Player count, tick rate, and object count all multiply each other, and physics is the term that grows fastest, which is how a prototype with 50 objects turns into a shipping game with 5,000. ## The limits of interest management The first thing studios reach for is relevancy, which means not sending what the player cannot perceive. Objects that are not moving get flagged as static and dropped from the stream, distant objects update less often, and anything outside the player's area of interest is culled. This works, and you should do it, but it reduces the object count rather than the cost per object. For genuinely dense scenes the count you are left with is still large, because the objects that stay relevant are the expensive ones: a crowd is relevant precisely because it is near the player, and a destruction event is relevant precisely when dozens of pieces are moving at once. Interest management thins the easy cases and leaves you holding the hard ones, which are the cases that made the game worth building in the first place. ## The durable lever is bytes per object Once you have culled what you can, the only variable left is how many bytes each remaining object costs. That is the number that decides your ceiling, and it is the one most projects never touch, because touching it means writing custom serialization. Going below the 12 to 20 byte baseline means building data models tuned to your exact game state, testing them against edge cases, and maintaining them as the game changes. It is some of the least glamorous engineering there is. The bugs show up in production as desync, jitter, or visual corruption, and the root cause is bytes that do not mean what the deserializer expected. Studios that go down this road spend real months on it. ([We have written about why the baseline is what it is.](/blog/why-is-my-multiplayer-bandwidth-cost-so-high/)) ## A note on the other approach There is a way to avoid sending state at all: deterministic lockstep, where every client runs the same simulation from the same inputs. It is elegant, and for dense physics it is treacherous. Floating-point arithmetic diverges across CPU architectures, and one rounding difference cascades into a full desync. It punishes late joiners, who have to be brought up to the current state before they can play. And cross-play makes it worse, because the platforms you want to share a match are exactly the ones whose float behavior differs. That is not a shrinking concern: the same report has 72% of studios prioritizing cross-play. Most large-scale physics games end up on server-authoritative state sync instead, which puts you right back at the bandwidth problem above. ## What Reactor does about it Reactor attacks the byte count directly, and without making it your job. Instead of asking you to write serialization, it builds the data model from your game's state and optimizes it automatically, observing what is in the scene, what is changing, and the range of each value, then generating the tightest representation it can. That process is ongoing, so the wire format keeps adapting as the game does. The result is the kind of thing that sounds unlikely until you measure it: - **Kazap.io:** about 0.5 bytes per transform. - **Braains2:** under 1 byte per transform, running 100 players and 150 physics objects at 30 Hz, with each player streaming roughly 35 KB/s at full load. ([Full case study.](/blog/braains2-case-study-reactor-scene-fusion/)) - **Ruins demo:** frequently under 1 byte per transform through continuous physics destruction. In a controlled comparison on identical scenes, Reactor moved 9.5 times less transform data than Photon Fusion 2 and 17 times less than Netcode for GameObjects. ([The benchmark is public](https://github.com/KinematicSoup/benchmarks/tree/main/UnityNetworkTransformBenchmark) if you want to run it yourself.) Put the 540 KB/s scene from earlier on that footing and it stops being a wall. The authority side is built in rather than assembled. Reactor runs PhysX on the server: raycasts, sweeps, overlap queries, and rigid-body simulation all happen server-side, with the server holding authority over entity state. Client updates are treated as inputs to validate, not state to trust. Prediction and reconciliation are included, so interactions stay responsive without giving up that authority. Doing this for dense physics, not just character movement, is the part that is genuinely hard to build yourself, and it is the part Reactor exists to handle. ## Decide this before you write gameplay If your game has meaningful physics complexity, the decisions you make in the first months set your ceiling. The studios that ship in this space tend to share a few habits: - They treat maximum networked object count as a hard spec, not a "we will optimize later." - They put a bandwidth budget in the design doc, next to the polygon budget and the memory budget. - They choose state sync or lockstep based on game type before writing a line of gameplay code. - They build on tooling made for dense physics sync rather than stretching a general-purpose networking layer to a job it was not designed for. The tooling for getting to a prototype has never been better, so the gap is no longer time-to-first-playable; it is whether the architecture under that prototype can carry the object count you eventually have to design around. Reactor is built for the second problem: thousands of networked physics objects, server-authoritative, with the wire format optimized for you. It is free to develop locally. Free self-hosting for registered game titles: up to 32 CCU per room. [Get started here.](/reactor/install/) --- ## How Much Does It Cost to Build and Run an Online Multiplayer Game? Part 2: Build vs Buy URL: https://www.kinematicsoup.com/blog/self-hosted-vs-managed-multiplayer-cost Date: 2026-06-02 Summary: Taking the roll-your-own cost from part one and comparing it to managed multiplayer services, Photon, Coherence, and Reactor: where buying wins, where building does, and why labor decides it for most teams. Disclosure first: we make [Reactor](/reactor/), one of the services compared below, so this part has a stake in the outcome. The method in [part one](/blog/how-much-does-it-cost-to-build-and-run-a-multiplayer-game/) does not, and you can re-run all of this with your own numbers using the [calculator in part one](/blog/how-much-does-it-cost-to-build-and-run-a-multiplayer-game/#estimate-your-own). Treat the figures here as a worked argument with its assumptions shown, not as neutral fact. In [part one](/blog/how-much-does-it-cost-to-build-and-run-a-multiplayer-game/) we costed out building and running a multiplayer backend yourself. For a 32-player 3D shooter at 300 MACCU (1,000 peak), the recurring infrastructure came to about $1,465 a month, and the labor to build and maintain a custom stack came to about $8,650 a month amortized: about $10,100 all in, dominated by labor. The short answer for this worked example: rolling your own costs about $10,100 a month all in, Photon Fusion with server authority about $1,715 a month plus most of the build labor, Coherence about $5,500 to $6,500 a month, and Reactor about $820 a month. Labor dominates until scale makes bandwidth dominate. The rest of this post shows the assumptions behind each number. Now the build-versus-buy question. Buying a managed service changes two things, and they pull in opposite directions. ## What buying changes **It removes the labor lines.** A fully managed engine ships the netcode, serialization, hosting, and scaling already built and operated. The ~$8,650 a month of build-and-maintain in our example drops to near zero. For most teams that is the entire decision, because it dwarfs everything else. **It reprices the infrastructure.** In exchange you pay the service's rates for bandwidth and compute, which can run much higher or much lower than your own depending on how the service is built. This is where the options diverge. ## The pricing models Three shapes, and knowing which one you are buying matters more than the sticker: - **Per-CCU relay** (Photon): you pay for connected-user-time. The relay moves messages, it does not run your game logic, so for server authority you run your own dedicated servers on top. - **Credits across CCU, compute, and bandwidth** (Coherence): you pay for connected users, simulator compute, and egress, all metered as credits. - **Per-room compute, metered by the minute** (Reactor): you pay for the compute a room uses, plus bandwidth, and capacity tracks MACCU rather than peak. Per-CCU and credit models bill against connected-user-time, so they map to MACCU. Per-room compute maps to MACCU only when the service scales rooms to demand, which metered billing does. ## The same game, four ways Our 32-player shooter at 300 MACCU, run through each option. Infrastructure is monthly; labor is build amortized plus maintenance. The assumptions are stated because they are what move the numbers. | Option | Infrastructure | Build + maintain | Still on the hook for | |---|---|---|---| | Roll your own | ~$1,465 | ~$8,650 | everything | | Photon Fusion (relay only) | ~$250 | most of it | building and running server authority yourself | | Photon Fusion (server-authoritative) | ~$1,715 | partial | building and operating your own authoritative servers | | Coherence | ~$5,500 to $6,500 | ~$0 | a dev-tools fee if you are funded | | Reactor | ~$820 | ~$0 | nothing | **Photon Fusion**, in pure relay mode, is the cheapest line in the table at ~$250 a month, but that buys the lowest capability: the relay moves messages between clients, with no server authority and no cheat protection. The moment you need an authoritative server, which our example does, the relay fee stays but you add back most of the roll-your-own costs it does not cover. You build the authoritative server layer (Fusion gives you a netcode framework, so this is reduced, not removed). You stand up and operate dedicated server instances (~$310 of compute), and their egress is your cloud bill (~$1,005 of bandwidth). You carry the ops to keep them running. So Photon for an authoritative game is about the roll-your-own infrastructure plus a per-CCU relay fee, with build-and-maintain reduced but not removed. The value is the netcode framework and ecosystem; the bill is not smaller. **Coherence** is fully managed, so the labor goes away. Assume it compresses about as well as any competent engine, the same ~67 GB per CCU-month as the baseline. The cost is the rate, not the volume: Coherence bills bandwidth at $0.20 to $0.32 per GB, four to six times a typical egress rate, which puts bandwidth alone near $5,000 a month for this game. Per-CCU connection charges add about $216, and simulator compute adds more, though how much is hard to pin down because Coherence does not publish clear simulator pricing. That uncertainty is what the $5,500 to $6,500 range absorbs. On top of that, studios over $200k in revenue or funding pay a $1,000 a month developer-tools fee. The exact credit math is in their [pricing docs](https://docs.coherence.io/support/credit-cost-and-pricing). **Reactor** is fully managed, and the bandwidth line is where it departs from the baseline. In our deployments a 3D transform compresses to two bytes or less, against the 12-byte general figure from part one, and that transform line is the single biggest input to the bandwidth number. At two bytes the per-player rate falls to about 6,900 bytes a second, and bandwidth drops to ~$270 a month. Compute is metered by the minute and tracks usage rather than peak: the ~9.4 rooms this game averages at 300 MACCU come to ~$550 at Reactor Cloud's per-room rate. Together that puts infrastructure near $820. This is our engine, so verify it against your own game with the [calculator in part one](/blog/how-much-does-it-cost-to-build-and-run-a-multiplayer-game/#estimate-your-own) rather than taking our word, and see the per-unit detail in our [Reactor versus Coherence comparison](/blog/reactor-vs-coherence-unity-multiplayer/). ## So, build or buy? Two things fall out of the table: **Labor decides it more often than infrastructure does.** At the scale of the worked example, the ~$8,650 a month of build-and-maintain in rolling your own is larger than any infrastructure difference between the services. A fully managed engine (Coherence or Reactor) removes that line; Photon only reduces it, because you still build and run the authoritative servers. Unless you have netcode expertise in-house and a reason to own the stack, buying a fully managed engine wins on cost before the per-unit rates come up. **Among managed services, bandwidth is the swing, and it grows with scale.** Compute and per-CCU fees land in a similar range; egress does not. A service with no compression, on a data-heavy 3D game, can cost several times one that compresses well. Because bandwidth scales with usage while the labor savings stay flat, this gap widens as the game grows and, at sufficient scale, overtakes labor as the deciding cost. Model that number for your specific game; it is the one that varies most. Roll your own if you need to own the stack and can afford to: full control, data residency, or a scale that justifies amortizing the build. Buy if you want to ship multiplayer instead of building infrastructure, which is most teams. Either way, run [the method from part one](/blog/how-much-does-it-cost-to-build-and-run-a-multiplayer-game/) on your own numbers before you commit. The [calculator in part one](/blog/how-much-does-it-cost-to-build-and-run-a-multiplayer-game/#estimate-your-own) makes it a five-minute exercise. --- ## How Much Does It Cost to Build and Run an Online Multiplayer Game? Part 1: Rolling Your Own URL: https://www.kinematicsoup.com/blog/how-much-does-it-cost-to-build-and-run-a-multiplayer-game Date: 2026-06-01 Summary: A practical, vendor-neutral method to estimate the real monthly cost of building and running your own multiplayer backend: bandwidth, compute, backend services, and the labor to build and maintain it. The worst time to find out about multiplayer hosting costs is after shipping, when the bill arrives. If online multiplayer is a key part of your project, you need to figure out how much it's going to cost you to run and adjust your business plan accordingly. This article gives you a model to predict those costs before you commit to a path or a technology. The formulas apply whether you self-host on bare metal, rent cloud instances, or buy a managed service, and there is an interactive calculator at the end so you can plug in your own game. This is part one of two and covers just the method for working out what it costs to build and run a multiplayer backend yourself. [Part two](/blog/self-hosted-vs-managed-multiplayer-cost/) takes these numbers and compares rolling your own against managed services, including our own [Reactor](/reactor/). That comparison is where our bias comes in, so it stays in part two; the method here does not depend on any of it. ## The five costs Every multiplayer game's running cost reduces to five things: 1. **Bandwidth** (egress): the bytes your servers send to players. 2. **Compute**: the CPU and memory running the simulation or relay. 3. **Backend services**: matchmaking, accounts, persistence, analytics. 4. **Cost to build it**: the engineering time to get it working. 5. **Cost to maintain it**: the ongoing time to keep it running. The first three are recurring infrastructure. The last two are labor, which for most teams is the larger number. The cost to build it is unique, as the entirety of that cost is paid prior to release. It is still an added cost and is amortized over a period of time. You can always separate that line item out and just include it in your game development budget if you want. We will compute each, then total them with a worked example. ## Concurrency: MACCU, CCU-months, and how they relate to MAU Hosting cost scales with concurrent users, but "concurrent users" is a moving target. Getting it wrong throws estimates off by an order of magnitude. Player counts rise and fall on a daily cycle: a trough in the local pre-dawn hours, a climb through the day, an evening peak. You can watch this in public data. [SteamDB](https://steamdb.info/) charts concurrent players for individual games, and [Steam's own stats page](https://store.steampowered.com/stats/) shows the platform-wide curve. They all have the same general shape. ![A typical day of concurrent users: a deep overnight trough, a climb through the day, and an evening peak. The dashed line is the monthly average, MACCU, which here sits near 46% of the peak.](/blog-images/ccu-daily-curve.svg) Two distinct numbers come off that curve, and they must not be conflated: - **Peak CCU**: the height of the curve, the most players connected at once. You **size** your servers for this. - **MACCU** (Monthly Average Concurrently Connected User): the average height across the month, which is the area under the curve divided by the hours in the month. You **pay** for this. It is a metric we defined in our [kazap.io economics writeup](/blog/the-economics-of-web-based-multiplayer-games/); measure it by sampling CCU at a fixed interval (we used every 5 seconds) and averaging. **Estimating MACCU from peak.** Before you have live data, you can estimate. The ratio of average to peak depends mostly on geography. A game concentrated in one region has a sharp evening spike and a deep overnight trough, so its average lands around 30 to 50% of peak. A game spread across the globe has staggered regional peaks that flatten the curve, pushing the average toward 50 to 65% of peak. The chart above is a single-region example at about 46%. Pick a ratio for your situation, then replace it with a measured number the moment you have one. **The billing unit: the CCU-month.** To turn an average concurrency into something you can multiply by a price, use a CCU-month: one concurrent user, served for one full month. It is a usage unit, like a kilowatt-hour. The conversion is the cleanest part of this whole article: > Over one month, the CCU-months you consume equals your MACCU. An average concurrency of 300 is 300 CCU-months that month, or 3,600 over a year at that level. The unit earns its keep by separating the two cost behaviors: bandwidth and metered compute scale with CCU-months, while capacity you provision up front scales with peak CCU. A game that peaks at 2,000 but averages 300 pays for 300 if its hosting is usage-metered, and closer to 2,000 if it runs fixed servers sized for the peak. That gap is often the single biggest lever on the bill. Per-CCU pricing models, used by relay services like [Photon](https://www.photonengine.com/fusion/pricing) and in part by [Coherence](https://docs.coherence.io/support/credit-cost-and-pricing), bill against connected-user-time, which maps to CCU-months directly. Per-vCPU hosting bills compute time, which only maps to CCU-months if you scale capacity to match demand. **Where MAU comes in.** [Monthly active users](https://en.wikipedia.org/wiki/Active_users) is the number most teams quote, and on its own it is nearly useless for hosting estimates, because it says nothing about how long those users stay connected. Playtime is the link: ``` MACCU = MAU × (avg hours played per user per month) / 730 ``` The 730 is hours in a month. This is just the user-hours your players generate, averaged over the month. Our kazap.io data shows how wide the gap can be: in its peak month, roughly [150,000 monthly active users](/blog/the-economics-of-web-based-multiplayer-games/) produced an average concurrency of about 100, which is only about half an hour of play per user per month. That is normal for a casual .io game most people try once. A session-based competitive game or an MMO, where engaged players log dozens of hours a month, can have a MACCU-to-MAU ratio ten or twenty times higher. Two games with identical MAU can have hosting bills an order of magnitude apart, purely because of engagement. Reason from concurrency, not from MAU. ## Line 1: Bandwidth Bandwidth is usually the cost that scales hardest, and the one most often underestimated, because people count the game data and forget the wrapper around it. Build it up per player, per second, from four contributions: **Transforms.** For each entity a player receives updates for, the position and rotation being synced. Uncompressed, a 3D transform is large, well over 30 bytes. Quantization plus a compact rotation encoding (the smallest-three quaternion trick) bring a **general 3D transform to roughly 10 to 12 bytes** on the wire: about 6 bytes for position at 16 bits per axis, about 4 for rotation, plus framing. A **2D game is smaller, around 3 to 4 bytes**, because position is two axes and rotation is a single angle. From there, delta encoding and further compression push the *average* below the quantized size when motion is slow or predictable, sometimes under a byte, which is how dense crowds and .io games stay cheap. The figure is set by how much the motion varies, so use 10 to 12 bytes for a general 3D game and treat anything lower as a property of your game or your engine, not a given. See Glenn Fiedler's [snapshot compression writeup](https://gafferongames.com/post/snapshot_compression/) for the mechanics. ``` transform bytes/sec = entities_seen × bytes_per_transform × tick_rate ``` **RPCs / events.** Discrete events (a shot fired, a door opened). Count them per second and multiply by their serialized size. These are usually small relative to transforms unless your game is event-heavy. **NetVars / replicated properties.** State that changes occasionally (health, ammo, score). Count the changes per second, not the variables: a value that does not change costs nothing on a delta-based system. **Protocol overhead.** The part that gets forgotten. Every packet carries headers regardless of payload. Over UDP that is a 20-byte [IPv4 header](https://en.wikipedia.org/wiki/IPv4#Header) plus an 8-byte [UDP header](https://en.wikipedia.org/wiki/User_Datagram_Protocol#UDP_datagram_structure), and a reliability layer such as [KCP](https://github.com/skywind3000/kcp) adds about 24 bytes. So roughly 50 bytes per packet, and if you send one packet per tick per player, that overhead is paid every tick: ``` overhead bytes/sec = ~50 × packets_per_second (≈ network tick rate) ``` At 30 Hz that is about 1.5 KB/s of pure header per player, before any game data. For a low-data game it can be most of the bill. TCP, websocket, and other reliable transports carry their own, often larger, overhead. **Putting it together.** Sum the four into bytes per second per player, convert to a monthly figure per CCU-month, and multiply by your egress rate: ``` GB per CCU-month = (total bytes/sec) × 2,628,000 sec / 1,000,000,000 monthly bandwidth = GB_per_CCU_month × MACCU × egress_rate ``` Egress rates vary wildly by provider. Hyperscalers price egress as a profit center: AWS starts at [$0.09/GB](https://aws.amazon.com/ec2/pricing/on-demand/) for the first 10 TB out of US-East. Developer-focused hosts are far cheaper, with [Vultr at $0.01/GB](https://www.vultr.com/pricing/) overage and bare-metal providers often bundling a large transfer pool. A 10x difference in egress rate is normal, so this input matters as much as your byte count. The trend is toward cheaper egress, and in some cases free. AWS GameLift, for example, removed egress charges on certain instance types in mid-2026. The method handles this directly: set the egress rate to near zero for those hosts and the bandwidth line collapses. It is worth being clear about what that does and does not change. A zero egress rate removes the server-side cost of bandwidth, but it does not make the data free to deliver. Every byte still has to travel the player's own connection and be decoded on their device, so byte count still sets your ceiling on player counts, entity density, and mobile reach. When egress is cheap or free, the value of efficiency shifts from saving money to enabling games that would otherwise saturate the network, which is the more durable reason to care about it. **The trap that breaks the model: interest management.** If every player sees every other player, `entities_seen` grows with the room, and per-player bandwidth scales with room size. A 16-player match is fine; a 200-player one is not, unless you cull what each player receives (only sync nearby entities). Decide early whether your game needs everyone to see everyone, because it changes the bandwidth line by an order of magnitude. ## Line 2: Compute Compute splits into two regimes: **Relay or light-authority games.** The server mostly forwards messages and validates a little. CPU per player is low, so one modest instance serves hundreds of players. Compute is a minor line; bandwidth dominates. **Physics-heavy or fully authoritative games.** The server runs the simulation: physics, AI, hit detection. CPU per player is high, so a single core might handle tens of players, not hundreds. Compute can rival or exceed bandwidth. The honest way to price compute is per vCPU-hour, because that is the underlying resource whether you rent it or a managed service resells it. A current reference point: an AWS [c7i.xlarge](https://aws.amazon.com/ec2/pricing/on-demand/) (compute-optimized, 4 vCPU) is $0.1785/hr on-demand in US-East, about **$0.045 per vCPU-hour**, and reserved or spot pricing cuts that substantially. Bare metal is cheaper per core if you keep it busy; managed services charge a premium for the operations they handle for you. ``` vCPU needed (at peak) = peak_CCU / players_per_core monthly compute = vCPU_needed × $/vCPU-hour × hours_billed ``` The `hours_billed` term is where the peak-versus-MACCU distinction returns. Fixed servers sized for peak bill 730 hours a month whether full or empty. Autoscaled or per-minute capacity bills closer to your MACCU. The same game can have a 5x difference in compute cost based purely on whether capacity tracks demand. ## Line 3: Backend services Multiplayer is more than a game server. Budget for: - **Matchmaking / lobbies**: often a small always-on service, or a managed feature. - **Accounts and auth**: a managed identity provider, or your own. Many have generous free tiers below a threshold of monthly active users. - **Persistence**: a database or key-value store for progression, inventory, leaderboards. Cost scales with reads/writes and storage. - **Analytics and telemetry**: event ingestion and storage. - **Relay / NAT traversal** (for peer or client-hosted topologies): STUN is cheap, TURN relays traffic and is billed like bandwidth. For a small-to-mid game these often land in the tens to low hundreds of dollars a month, dominated by whichever service you have outgrown its free tier on. The point is to enumerate them, because they are easy to omit and then find on the bill. ## Line 4: The cost to build it This is usually the largest number, and the most overlooked, because it is labor rather than infrastructure. Anchor it in a defensible rate. The U.S. [Bureau of Labor Statistics](https://www.bls.gov/ooh/computer-and-information-technology/software-developers.htm) puts the median software developer wage at $133,080 (May 2024), with the 10th-to-90th percentile spanning roughly $80,000 to $211,000. Loaded cost (benefits, overhead) typically runs 1.25 to 1.4x salary, so call it roughly $50 to $150 per hour depending on seniority and region. Now estimate the hours. Rolling your own authoritative netcode, with prediction, reconciliation, a serialization layer, and the backend services above, is a multi-month effort for an experienced engineer, and longer if it is the team's first time. A conservative range for a production-grade custom stack is several hundred to a few thousand engineering hours. This can be reduced by employing a framework like Netcode for GameObjects/Entities, Mirror, or FishNet on Unity, but there is still some customization required to dial in the harder problems like prediction and bandwidth optimization. AI coding assistants change this materially but not magically. GitHub's [controlled study](https://github.blog/news-insights/research/research-quantifying-github-copilots-impact-on-developer-productivity-and-happiness/) found developers completed a specific task about 55% faster with Copilot, and real-world gains on novel systems work are usually smaller. A reasonable planning assumption is a 20 to 40% reduction in hours on the parts that are boilerplate-heavy (serialization, plumbing, tooling), and little speedup on the genuinely hard parts (netcode correctness, edge cases). Model it as a discount on your hour estimate, not a different category. ``` build cost = engineering_hours × (1 − ai_discount) × loaded_hourly_rate ``` Amortize this over the months you expect the game to run to compare it against the recurring lines. ## Line 5: The cost to maintain it Live multiplayer is never finished. Even with maximum automation (infrastructure as code, autoscaling, automated deploys, alerting), budget for: - **On-call and incident response**: someone has to be reachable when a server falls over at peak. - **Updates**: engine versions, dependency patches, security fixes, content updates that touch the netcode. - **Capacity tuning**: as the player base grows and shifts regions. Automation reduces the hours but does not zero them. A realistic figure for a stable, automated live game is a recurring fraction of an engineer: anywhere from a few hours a month for a small, quiet title to a substantial share of a full-time role for a busy one. Price it the same way, at the loaded hourly rate, and add it to the monthly total. ## Worked example: a 32-player competitive shooter Server-authoritative, 60 Hz network tick, hosted on metered cloud capacity. Peak 1,000 CCU, MACCU 300 (players come and go). Egress at a developer-host rate of $0.05/GB. **Bandwidth, per player.** It is a 3D game, so a transform is about 12 bytes after quantization and rotation compression. (A 2D game would be nearer 3 to 4.) | Contribution | Calculation | Bytes/sec | |---|---|---| | Transforms | 31 others × 12 B × 60 Hz | 22,320 | | RPCs / events | ~15/sec × 8 B | 120 | | NetVars | ~10 changes/sec × 6 B | 60 | | Overhead | 50 B × 60 packets/sec | 3,000 | | **Total** | | **~25,500 B/s** | That is 25,500 × 2,628,000 / 1e9 ≈ **67 GB per CCU-month**. Across 300 MACCU: 20,100 GB × $0.05 = **~$1,005/month** in bandwidth. (On AWS egress at $0.09 it would be ~$1,800; on a bare-metal transfer pool, close to zero.) Strong delta compression on predictable motion cuts the transform line well below 12 bytes, which is the lever an efficient engine pulls. **Compute:** a 1-vCPU room holds the 32-player match, so peak needs ~31 vCPU; metered to MACCU it averages ~9 vCPU. At $0.045/vCPU-hour × 730 hours: **~$310/month** (autoscaled). Fixed-for-peak would be closer to $1,000. **Backend:** matchmaking, accounts, a small database, analytics: call it **~$150/month** at this scale. **Recurring subtotal: ~$1,465/month** at 300 MACCU. **Build:** say 800 engineering hours for a custom stack, a 30% AI discount, at $130/hour loaded: 800 × 0.7 × $130 = **~$72,800 one-time.** Over a two-year run that is ~$3,050/month amortized, several times the recurring infrastructure. **Maintain:** a quarter of an engineer at $130/hour loaded ≈ **~$5,600/month.** The lesson the worked example makes obvious: for most teams the infrastructure (~$1,465) is the small number. The labor to build and maintain a custom stack (~$8,650/month amortized here) dwarfs it. That is the real decision, and it is why "build versus buy" is a cost question, not just an engineering one. One caveat keeps that from being a universal rule: the two costs scale differently. Build is one-time. Maintenance is a roughly fixed fraction of an engineer whether you run 300 players or 30,000, because a stable, automated system needs about the same attention either way. Infrastructure does not behave that way. Bandwidth and metered compute scale with usage, so as your game grows they climb while the labor line stays roughly flat. Past a certain scale the bill flips and infrastructure becomes the dominant cost. So the honest version is two-sided: at the scale most teams operate, labor dominates and build-versus-buy is about buying back engineering time; at scale, infrastructure dominates and the question becomes per-unit efficiency, which is where bandwidth and compression earn their keep. ## Next: is buying cheaper? Those labor lines are exactly what a managed service removes, in exchange for pricing the infrastructure its own way, sometimes far higher. [Part two](/blog/self-hosted-vs-managed-multiplayer-cost/) runs this same example through Photon, Coherence, and our own Reactor, so you can see where buying wins and where rolling your own does. --- ## Reactor vs Photon Fusion 2 vs Coherence: A Unity Multiplayer Comparison URL: https://www.kinematicsoup.com/blog/reactor-vs-coherence-unity-multiplayer Date: 2026-05-24 Summary: A technical comparison of Reactor, Photon Fusion 2, and Coherence for Unity multiplayer development: server authority, bandwidth efficiency, hosting costs, and complexity at scale. Reactor, Photon Fusion 2, and Coherence are three of the options developers evaluate for Unity multiplayer with managed hosting. They differ in architecture, pricing model, and design philosophy. The short answer: Reactor runs game logic and physics on a built-in authoritative server and bills for compute time ($0.02 to $0.50 per room-hour by size) plus bandwidth at $0.05 to $0.10 per GB. Photon Fusion 2 is a relay billed per CCU, and server authority means running your own dedicated servers on top of the relay fee. Coherence bills CCU time, simulator compute, and bandwidth through a credit system, with bandwidth at $0.20 to $0.32 per GB. In a controlled benchmark syncing 250 physics objects at 30 Hz, Reactor used about 15 kB/s per client and Photon Fusion 2 about 112 kB/s; Coherence does not publish bandwidth numbers. ## At a glance | | Reactor | Photon Fusion 2 | Coherence | |---|---|---|---| | Server authority | Built-in | Requires separate dedicated server | Requires headless Unity instance | | Server-side physics | Yes (PhysX) | No | No | | Max tick rate | 120 Hz | No platform limit | 30 Hz cap | | Compute billing | CPU-time ($/hr per vcore) | Per CCU relay fee | Per CCU + CPU-time (via credits) | | Bandwidth rate | $0.05-$0.10/GB | $0.05-$0.10/GB | $0.20-$0.32/GB | | Bandwidth per client (250 objects, 30 Hz) | ~15 kB/s | ~112 kB/s | Not published | | Multi-room player connections | Yes | No | N/A (simulator model) | *Prices verified May 2026. Pricing pages: [Reactor](/pricing/), [Photon Fusion 2](https://www.photonengine.com/fusion/pricing), [Coherence](https://coherence.io/hosting/cloud).* *Disclosure: KinematicSoup makes Reactor. This comparison is written by the Reactor team. It draws on public information from all three vendors. Verify claims against each vendor's documentation before making a purchasing decision.* ## Reputation and community Photon has a long track record. It has been the default recommendation for Unity multiplayer for years, and the community reflects that: extensive documentation, a large pool of developers who have used it, and many public examples to learn from. For developers entering multiplayer for the first time, that ecosystem lowers the learning curve. Coherence is newer. Its onboarding requires little setup, its community is smaller, and its track record is shorter. Reactor has been in development since 2015 and has shipped in commercial games. The community is smaller than Photon's, and public documentation is less extensive. Developers who choose Reactor tend to do so for technical reasons rather than ecosystem size. ## Developer experience Coherence puts the most work of the three into the first-run experience; setup is short and the tooling is approachable. Photon Fusion 2 is well documented and the API is straightforward to start with. Shared mode requires little setup to sync objects across clients. Reactor's structure differs. It uses a local development server and a server-side scripting model. That structure is familiar to anyone who has done backend or dedicated-server work, and it separates client and server code, defines what is shared between them, and shortens build times by decoupling client builds from server builds. With Photon, state synchronization code grows with the codebase; Reactor generates and maintains the data model from game state. ## Server authority All three solutions support server-authoritative multiplayer, but the implementations differ. **Photon Fusion 2** offers two modes. Shared mode assigns authority over objects to different clients: each client owns and drives its own objects, and Photon relays state to others. This is fast to build, but the server holds no authority over the objects. For real server authority, Photon requires the developer to run a dedicated headless Unity server build, manage hosting and orchestration for it, and pay those infrastructure costs separately on top of Photon's per-CCU fees. **Coherence** uses the same pattern. Shared mode assigns object authority to clients. For server authority, a headless Unity instance runs alongside Coherence and handles authoritative logic. Coherence manages some of the synchronization, but the authority layer is something the developer constructs. **Reactor's room is itself the authoritative server.** It runs PhysX physics simulation server-side, handles raycasts, sweeps, and overlap queries, and can be configured with complete authority over all entity state. Client updates are validated before they change state. Reactor also supports a shared authority model where the server assigns ownership of entities to Unity clients or headless instances, providing flexibility for games that do not need full server-side physics. The distinction from Photon and Coherence is that Reactor's server authority is built in rather than constructed from a headless Unity process running alongside a sync layer. ## Bandwidth efficiency Reactor publishes its bandwidth numbers. In a [head-to-head comparison](/reactor/benchmarks/) against Photon Fusion 2, Netcode for GameObjects, FishNet, Mirror, PurrNet, and SFS2X, Reactor used about 15 kB/s per client syncing 250 physics objects at 30 Hz. Photon Fusion 2 used about 112 kB/s under the same conditions. The full methodology, scene configuration, and source are available on GitHub. Photon applies compression and delta updates. Coherence does not publish bandwidth benchmarks. Reactor's bandwidth efficiency comes from data models generated from game state. The developer does not write serialization code. Real deployments have achieved under 1 byte per transform update in games with 100 players and 150 physics objects at 30 Hz. ## Hosting costs Four inputs set the monthly bill: how compute is charged (per CCU or per CPU-hour), how bandwidth is metered, how much bandwidth the framework uses, and whether server authority requires separate infrastructure. A framework that is cheap at 50 players can become the dominant cost at 500. The three solutions charge for different things. **Photon Fusion 2** charges per CCU for its cloud relay service ([pricing](https://www.photonengine.com/fusion/pricing)). A CCU in Photon's model is a player slot connected to the relay infrastructure: it covers message passing between clients but not server-side computation, since Photon's relay does not execute game logic. Plans are structured as CCU tiers (500 CCU, 1,000 CCU, 2,000 CCU), and each tier includes 3 GB of bandwidth per CCU per month. At Photon's overage rate of $0.05 per GB in standard regions, that bundled bandwidth represents $0.15 of included value per CCU. In premium regions (Asia, Middle East, South America) at $0.10 per GB, it represents $0.30. Unused fees are credited back. Monthly plans include burst capacity with a 48-hour window to upgrade before throttling. The annual 100 CCU plan does not include burst. For server authority, the developer runs their own dedicated Unity server build on their own infrastructure, paying those hosting costs separately and on top of Photon's CCU fees. **Coherence** charges via a credit system that covers relay and compute ([pricing](https://coherence.io/hosting/cloud)). Unlike Photon, which charges only for CCU relay slots, or Reactor, which charges only for CPU time, Coherence charges for both: CCU connections to the relay and CPU time consumed by simulators, in addition to bandwidth. CCU time is billed at $0.01 per 10 hours, which works out to $0.72 per CCU per month for a player connected around the clock. Bandwidth is priced at 200 credits per GB, with credits costing $0.99 to $1.60 per 1000, working out to $0.20 to $0.32 per GB. The credit abstraction bundles these costs together, which makes the monthly cost of a given player count difficult to estimate in advance. **Reactor Cloud** charges for CPU time: rooms are billed by the minute based on the compute size you choose, from $0.02 per hour for a 0.25 vcore room to $0.50 per hour for a 4 vcore room. There is no per-CCU cost as there is for Coherence or Photon. You are paying for actual server-side computation running your game logic and physics simulation, not for player slots connected to a relay. Every paid Reactor tier includes a usage credit equal to the monthly subscription cost, so the fixed fee covers the first equivalent amount of room and bandwidth usage each month. Bandwidth is $0.05 per GB in North America and Europe, $0.10 per GB elsewhere. For small games, developers can use Reactor's sync groups and Unity ownership components to divide a connected playerbase into isolated subsets within a single room, creating virtual sub-rooms. Each sync group controls which state is visible to which clients, and ownership components handle data replication between them. The smallest room size supports 100 or more CCU, so a single room instance can carry multiple concurrent game sessions during early growth before scale justifies dedicated rooms per match. The bandwidth rate gap between Reactor and Coherence is 4 to 6 times. For simple games with few dynamic objects, that rate difference is the main factor. For action games with hundreds of dynamic objects, bandwidth usage scales with entity count, and without an efficiency story Coherence has no mechanism to contain that growth. The rate gap and the volume gap compound: the total bandwidth bill on Coherence for an entity-heavy game can be an order of magnitude higher than the same game on Reactor. Photon and Reactor charge similar bandwidth rates. At the same object count and tick rate, Reactor's egress volume is about 7x lower. The 3 GB per CCU inclusion softens Photon's bandwidth bill for games with low average playtime, but at 112 kB/s per client it covers about 7.5 hours of play per CCU per month before overage. For any game with regular engagement, the inclusion covers only a fraction of actual usage. And for Photon in server authority mode, the dedicated server infrastructure costs are separate from and in addition to the CCU fees. ## Room customization and game types Photon Fusion 2 and Coherence are well-suited to a defined range of game types: action games, social games, casual multiplayer. Both become harder to work with as the game's requirements move toward physics simulation, large entity counts, or demanding server-side logic. Coherence's documentation does not state what compute resources a simulator provides, whether processing is shared or dedicated, or how to capacity-plan against it. Coherence also caps simulator frame rates at 30 Hz, which limits physics simulation fidelity and rules the platform out for competitive games where tick rate affects hit registration and input responsiveness. Reactor rooms are a full processing timeslice: dedicated, predictable compute with defined CPU and memory allocations. The developer knows what the room runs on and can tune for it. Reactor supports tick rates up to 120 Hz, giving developers control over the tradeoff between server load and latency. A card game runs at a low tick rate to minimize cost; a competitive shooter runs at a high tick rate for tight input responsiveness. The same room infrastructure handles both. Reactor rooms are open to the developer in other respects as well. The server supports physics simulation, scene queries, scripted game logic, and room-to-room communication via the Cluster API. The framework does not limit what the server code can run. In Photon, a player occupies one room at a time. In Reactor, a player can hold connections to any number of rooms at once. This enables server topologies that are not practical with a single-room model. A large world can be sharded across multiple zone instances, with players connected to the zones around them. Zones can be replicated to distribute concurrent players across instances for load balancing. Separate rooms can run dedicated microservices (global chat, matchmaking, leaderboards, guild systems) that any connected client can interact with independently of their game room. These patterns require the multi-room connection model. ## Which to use **Photon Fusion 2** is the right starting point if community size, documentation quality, and ecosystem familiarity are your top priorities. For games of low to moderate complexity where server authority is not critical, the shared mode is quick to build on. The cost structure becomes complicated if you need true server authority, since you are then paying for both Photon and your own dedicated server infrastructure. **Coherence** suits developers for whom developer experience and speed to a working prototype are the primary concern, and whose game type does not require bandwidth efficiency or physics simulation. The bandwidth cost structure is the main tradeoff. **Reactor** is the choice when technical requirements are the binding constraint: server-authoritative physics, large crowds, high entity counts, competitive games, or persistent online worlds. The result is lower bandwidth cost at scale and server capabilities the other two provide only with separate infrastructure. Reactor is free to develop locally. Free self-hosting for registered game titles: up to 32 CCU per room. Cloud hosting starts at $20 a month. [Get started here.](/reactor/install/) --- ## Why Is My Multiplayer Bandwidth Cost So High? URL: https://www.kinematicsoup.com/blog/why-is-my-multiplayer-bandwidth-cost-so-high Date: 2026-05-16 Summary: Your engine is already compressing your transforms. The 12-20 bytes you are paying per networked entity is the floor, not a misconfiguration. Here is where the cost comes from and how to go lower. Your multiplayer game is not leaking bandwidth. The costs you are seeing are the correct costs for what your engine is doing. Understanding why they are high is the first step to changing them. ## Bandwidth is a hard limit, not a performance metric Most game performance problems have a fix: optimize the shader, cull the draw calls, pool the allocations. Bandwidth works differently. It is not a variable that responds to an optimization pass. It is a hard constraint on what you can simulate and what your business model can support. Every networked entity, every additional player, every physics object consumes a fixed slice of your budget. When you hit the ceiling, you cannot add complexity without a larger bill, a smaller player count, or both. ## What you are paying for A 3D transform is position, rotation, and scale: nine floats at four bytes each. Uncompressed, that is 36 bytes per entity per update. Almost nobody ships a game with raw transforms, and no networking framework or engine does either. Every serious multiplayer system applies compression before data touches the wire. Bit packing reduces float precision to what the game actually requires. Delta compression sends only what changed since the last tick. Quantization represents values in fewer bits. Batching amortizes header costs across multiple updates. These are well-understood techniques, and Photon Fusion, Netcode for GameObjects, Mirror, and Coherence all implement some version of them. After compression, a 3D transform update costs roughly between 12 and 20 bytes. Game structure can allow this to be optimized further, but that requires more time and effort that is not going into the core game. Many developers just stick with the baseline. If you are using a standard multiplayer engine or framework and wondering why your bandwidth bill is high, you are most likely not misconfigured. You are paying the industry baseline, and the industry baseline is expensive at scale. ## How player count multiplies the cost Bandwidth scales with three variables: players, tick rate, and the number of entities each player needs to track. Those variables multiply each other. For a dedicated server model, take 50 players in a zone at 20 Hz. Each player receives position updates for the other 49 players. At 20 bytes per transform, each player receives 49 * 20 bytes = 980 bytes per tick. At 20 Hz, that is 19,600 bytes per second. Across all 50 players, the server is sending roughly 960 KB per second for movement alone. Run that 24/7 and it adds up fast. For client-hosted or peer-to-peer topologies, the situation is worse. Each client sends to every other client, so connections scale with n*(n-1). Four players require 12 update streams per tick. Eight players require 56: a 4.67x increase for a 2x increase in players. P2P does not eliminate bandwidth costs. It redistributes them to your players and imposes a hard ceiling on viable player counts. ## The monthly math for a persistent online game For a mid-scale game averaging 500 MACCU (the Monthly Average Concurrently Connected User metric from [our kazap.io analysis](/blog/the-economics-of-web-based-multiplayer-games/)): each MACCU at standard compression uses roughly 36 GB of egress per month. Across 500 MACCU, that is 18 TB of outbound transfer per month. On AWS, data transfer out from US East starts at $0.09/GB for the first 10 TB and $0.085/GB for the next 40 TB. The bandwidth bill for that workload is approximately $1,580 per month. Five game servers running 24/7 add another $600. Total: roughly $2,180 per month. Compute costs are relatively stable. They scale with what your CPU is doing. Bandwidth costs scale directly with players times bytes per player per second times seconds per month. If your game doubles in size, the bandwidth line doubles. If your tick rate doubles, so does the bandwidth line. Compute does not behave the same way. ## Going below the baseline If 12-20 bytes per transform is what standard engines deliver, going lower means building custom data models. You write serialization code tuned to your specific game state. You test it against edge cases. You maintain it as the game evolves. Custom serialization is a category of bugs that is particularly hard to diagnose in production: the symptoms show up as desync, jitter, or visual corruption, and the root cause is bytes that do not mean what the deserializer expects. For competitive games running at 60 Hz or higher, the baseline multiplies with tick rate. For persistent online worlds, the baseline accumulates with server uptime. In both cases, getting below the baseline matters enough that studios invest significant engineering time to do it. Most of that time is not glamorous: it is protocol debugging in production, edge case handling, and keeping serialization code in sync with a changing game. ## What Reactor does differently Reactor builds data models from the actual state of your game and optimizes automatically. The developer does not write serialization code. Reactor observes what is in the scene, what is changing, and what the range of values is, and generates the most efficient representation it can. That process is ongoing: the model updates as the game state changes. Real results from games built on Reactor: - **Kazap.io:** approximately 0.5 bytes per transform - **Braains2:** under 1 byte per transform, running 100 players and 150 physics objects at 30 Hz, with each player streaming about 35 KB/s at full load. [The full case study is here.](/blog/braains2-case-study-reactor-scene-fusion/) - **Ruins demo:** frequently under 1 byte per transform despite active physics destruction throughout the session In a controlled comparison, Reactor moved 9.5 times less transform data than Photon Fusion 2 and 17 times less than Netcode for GameObjects. The full methodology and scene configuration are [available on GitHub](https://github.com/KinematicSoup/benchmarks/tree/main/UnityNetworkTransformBenchmark) if you want to run it yourself. Applied to the monthly cost example above: at 6x wire bandwidth reduction across a full game session (accounting for protocol overhead), the $1,580 AWS egress line drops to about $263. Compute stays the same. Total falls from $2,180 to $863 per month, or about $15,800 per year. Bandwidth is a problem at scale. The real decision is whether you keep investing engineering time in custom serialization or build on a foundation that handles it for you. Reactor is free to develop locally. Free self-hosting for registered game titles: up to 32 CCU per room. [Get started here.](/reactor/install/) --- ## Why We Built Reactor: What Unity Multiplayer Was Missing URL: https://www.kinematicsoup.com/blog/unity-multiplayer-engine-history Date: 2026-05-13 Summary: Ten years of building a Unity multiplayer engine for physics simulation, large crowds, and games other tools can't handle. How Reactor compares to Photon, NGO, and Mirror. We started building Reactor in 2015. The first release came in 2016. We built it because the tool we needed did not exist, and we think it still fills a gap that a lot of developers do not realize is there until they run into it. ## What the options looked like in 2015 Unity developers had two realistic choices at the time. The first was Photon. Photon was popular for good reason: a developer could sync data between clients with a few API calls and never think about a server. That is genuinely fast to get started with. The problem is that Photon was a relay. It had no context about your game world. It just moved messages between clients. The server did not know what was in the scene, what the rules were, or what state was authoritative. That works for simple games where clients can be trusted and latency is forgiving. It breaks down when you need physics simulation, large numbers of entities, or any situation where client authority is exploitable. Pricing added friction too. You had to estimate your peak concurrency and buy CCUs upfront. Guess wrong and you were either overpaying or scrambling. The other option was Unity's own networking solution, or taking the Unreal approach. These were more capable. They were built around real server authority and had the track record to prove it. The cost was significant backend engineering. Deploying and managing dedicated servers requires infrastructure expertise: provisioning, monitoring, security, scaling under load. That is a full discipline on its own. For a team building a game, it is usually a discipline nobody on the team has. Even if they did, it would consume time that could have gone into the game itself. ## The gap We wanted a system that could handle the full range of game types: turn-based, action, physics simulation, MMO, MMOFPS. We wanted developers to never have to touch a server. No DevOps. No backend engineering. Full server authority. That combination did not exist. Our first attempt was, in hindsight, a useful mistake. We built something closer to Photon but with a richer API. Clients could place objects in a world, describe how they should behave, and the server would simulate and sync them. It made more complex games possible than a plain relay could. But the client-side API kept growing to cover every case we wanted to support. Too many calls from client to server. We had built a more capable relay, not what we were actually after. ## Starting over We scrapped the approach and started from the server side. We had already built a lightweight simulation server using Bullet physics, and switched to PhysX shortly after to take advantage of its debug tooling. We expanded it to include a scripting engine, built a server-authoritative controller system, and added a Unity integration layer on top so the Unity workflow could be used for server scripting. Developers write game logic in the Unity environment they already know. The server runs it. Unity was a natural choice at the time. It was an up-and-coming engine that performed well and was easy to work with. We chose it and we have not had reason to regret it. This foundation became the basis for [Scene Fusion](/scene-fusion/) as well, our real-time collaborative scene editing tool for Unity. Scene Fusion and Reactor share the same underlying synchronization system. Building Scene Fusion pushed the backend infrastructure hard in ways a game alone would not have, and several components that ended up in Reactor came directly from that work. We also built games ourselves and with partners. Repulsor was an early demo from 2016: an asteroid field with hundreds of physics objects, a destructible base, and players fighting each other in the environment. It was a useful stress test for the engine at the time. ![Repulsor, a 2016 multiplayer demo built on Reactor featuring hundreds of physics objects and destructible environments.](/blog-images/repulsor.png) [Kazap.io](/blog/the-economics-of-web-based-multiplayer-games/) was one of the first commercial games we shipped. A later collaboration gave us a direct side-by-side comparison: the same game concept, built twice, once without Reactor and once with it. Same developer, same audience. The [results are documented](/blog/braains2-case-study-reactor-scene-fusion/). ## Bandwidth Bandwidth is the constraint that determines what is possible in a multiplayer game. More bandwidth per player means smaller player counts, higher hosting costs, and harder limits on what you can simulate. We focused on reducing it with as little developer input as needed, because better efficiency means bigger games or a lower bill, and ideally both. Our first implementation was a bit-packing solution built for speed. It evolved into what we have now: complex data models that are automatically generated and synchronized to minimize bytes on the wire. The developer does not configure compression. It happens by default. ![A large crowd simulation running on Reactor. Each character is a fully networked physics entity.](/blog-images/bigcrowdscreenshot.png) We benchmarked it against Photon Fusion 2 and Unity Netcode for GameObjects using a standard scene. Same entities, same update rate, measured directly. Reactor moved 9.5 times less transform data than Fusion 2, and 17 times less than Netcode for GameObjects. The benchmark is [available on GitHub](https://github.com/KinematicSoup/benchmarks/tree/main/UnityNetworkTransformBenchmark) if you want to run it yourself. ## Where things stand now The managed hosting question, the one that pushed us to build this in the first place, is handled by Reactor Cloud. Developers deploy to our infrastructure with one click. There are no servers to provision, nothing to monitor, and no scaling decisions to make. The free tier covers development and small deployments. On authority, we added shared authority between Unity and the server. The server can assign authority over all or part of an entity to any connected Unity client or headless server. It gives back some of the flexibility of the original client-driven approach without giving up the correctness guarantees of a server-authoritative foundation. The thing we are most excited about right now is our DOTS plugin, currently in beta. Client-side prediction is still being finished, but the core integration is working. Reactor hooked up to a DOTS-based Unity game is a combination we think will open up game types that have not been practical to build before. The bandwidth advantage we have built over ten years matters most at the scale that DOTS makes possible. If you are building a multiplayer game in Unity, see what Reactor can do. --- ## Case Study: Synty Studios Builds Every Asset Pack with Scene Fusion URL: https://www.kinematicsoup.com/blog/synty-studios-case-study Date: 2026-05-07 Summary: Nearly a decade of remote level collaboration at one of the Unity Asset Store's most prolific studios. We asked Synty how they work, what changed, and what they'd tell other studios. Synty Studios builds some of the most recognizable Unity asset packs on the market. Their POLYGON series covers medieval fantasy, sci-fi horror, post-apocalyptic wastelands, and dozens of genres in between. Every pack ships with a polished demo scene, and for nearly a decade, those scenes have been assembled using Scene Fusion. We sat down with the Synty team to ask how they work, what changed when they adopted real-time collaboration, and what they would tell other studios considering it. ## Before Scene Fusion Before Scene Fusion became part of their workflow, building a demo scene meant either routing everything through one person or passing the file back and forth sequentially. > "Before that it was the tedious back and forth of either one person in charge of the scene and just getting notes on it, or handing off the scene to each other to work on one at a time." The Synty team is fully remote, which made that kind of handoff especially costly. Feedback that could have happened in context, in the scene, had to be communicated through notes and reviews after the fact. ## A Tool for Every Stage Synty does not use Scene Fusion for one specific task. It runs through the entire production arc. > "Almost everything, from start to finish. We start out any pack in Scene Fusion to greybox out the demo scene, then use it to build out areas while being able to have instant feedback and/or just working together to build something quickly. Later we can then use it to QC the scene or make tweaks with more people in the room to give feedback. And finally we can use it for training or as an easier way to work something out together." The most common session is the two environment artists sitting in the same session all day, building in parallel and reacting to each other's work. Broader reviews bring in up to six more people from the Polygon team and typically run an hour or two. ## The Turning Point Synty noticed the shift most clearly around the time of their POLYGON Pirates pack. > "You can almost see exactly where our demo production got an instant efficiency boost, because our demos became more detailed and expansive as we have been able to have multiple artists collaborating on a scene at once, meaning our scenes got better without any increase in time spent working on them." Speed was only part of it. With several artists in the scene at once, better ideas surfaced earlier, hard areas got solved faster, and sections that used to take multiple rounds of revision came together in a single session. POLYGON Sci-Fi Horror is another example the team points to. Multiple sessions had everyone flying through the scene adding story-telling details and world-building touches. > "We had a few sessions of everyone flying around and adding little story-telling easter eggs and world building throughout the scene which was really fun. But really every single pack we do benefits so much from having more people in the scene together, talking about it in context." ## Sessions at Scale Most Synty sessions stay under five people, but the tool has been put to larger tests. For their 10th anniversary, the entire company of 25 people joined a single scene for an internal contest. > "Having the whole company in there at once doesn't happen too often, though we have done a few sessions where we either wanted everyone's feedback or just wanted to do something fun with everyone." Scene Fusion also appears regularly on Synty's public Twitch and YouTube livestreams, where viewers routinely ask how the team is working together in real time inside Unity. ## Adding Reactor for Game-Scale Review More recently, Synty has added Reactor to their process, using it to walk through finished scenes at actual game scale before shipping. > "Reactor has been great to get a proper sense of scale. We always have scale characters in the scene for reference, but seeing it at eye-level with other characters running around gives a whole new appreciation for the size of everything." This has proven especially useful for their map packs, which are designed to be used as complete shipped environments rather than just asset showcases. Navigating a scene with other characters moving around surfaces layout and proportion issues that a static Editor view does not catch. > "It's been especially helpful for our maps we've been releasing recently where they're specifically created to be used as-is rather than just a demo scene showing off all the assets in context. It's meant that we can get a better idea of how it will actually be used and can make adjustments accordingly." ## The Outcome When asked to quantify the time savings, the Synty team put quality first. > "For us the major benefit is in quality. The fact that we can all be contributing ideas in real time means iteration happens much faster and we can come to a better result. That being said, because we can get in there and figure things out it also means it has potential to save about a day per week of back and forth and reworks." On recommending it to other studios: > "100%. I don't know why it's not a standard feature in Unity." --- ## Unity Multiplayer Engines Compared: Reactor, Photon Fusion, NGO, Mirror, and Coherence URL: https://www.kinematicsoup.com/blog/best-unity-multiplayer-engine Date: 2025-11-01 Summary: A practical comparison of Unity multiplayer networking solutions in 2026. Which engine fits your game type, team size, and hosting situation, and where each one falls short. The best Unity multiplayer engine is the one that fits your game. A physics-heavy game syncing thousands of entities has different needs than a turn-based card game, and the right pick shifts with how much infrastructure you want to run and what bandwidth costs you can absorb. This is a practical breakdown of the main options and where each one fits. ## Quick reference | Solution | Best for | Hosting | Cost to start | |---|---|---|---| | Photon Fusion 2 | Competitive games, FPS | Managed (Photon) | Free tier, CCU pricing | | Unity NGO | Unity-native server logic | Self-hosted | Free | | Mirror | Indie, self-hosted, budget | Self-hosted | Free | | Coherence | Standard game types, good workflow | Managed | Free tier | | Reactor | Physics simulation, large crowds, bandwidth-critical | Managed (Reactor Cloud) or self-hosted | Free to 32 CCU per room (registered game titles) | --- ## Photon Fusion 2 Photon Fusion 2 has the largest ecosystem of the solutions here: tutorials, community answers, and third-party integrations for most needs. Common problems have been solved and written about. Fusion has good client-side prediction and rollback, which makes it a solid choice for competitive games where latency compensation matters. Photon manages the relay infrastructure, so you do not need to run your own servers. The downsides are cost and bandwidth. Photon prices on CCUs, which means you pay for peak concurrent users rather than usage. Bandwidth is not a focus. In a controlled benchmark against Reactor using identical scenes, Fusion moved about 9.5 times more transform data per player. That gap matters at scale, but for most games at moderate player counts it is manageable. **Use Photon Fusion 2 if:** you want the largest community and ecosystem, your game is a competitive or action game, and you are comfortable with CCU pricing. --- ## Unity Netcode for GameObjects (NGO) NGO is Unity's official multiplayer solution. It is free, open source, and integrated with the Unity editor. The documentation is good and it follows Unity conventions, which lowers the learning curve for teams that know Unity. NGO works best when you need Unity functionality running on the server. If your game logic is coupled to Unity components and you want a headless Unity server instance handling game state, NGO is a natural fit. Individual server instances with Unity running the full simulation are where NGO is at its strongest. The trade-off is infrastructure. NGO does not include managed hosting. You run your own servers, which means provisioning, monitoring, and scaling are your responsibility. For teams with backend experience this is fine. For teams without it, the operational overhead adds up. **Use NGO if:** you need a lot of Unity-native server-side functionality, your architecture calls for individual Unity server instances, and you have backend engineering capacity on your team. --- ## Mirror Mirror is free, open source, and has been around long enough to have a large community and a lot of answers on forums and Discord. The API is familiar to anyone who worked with Unity's old UNET system. It is a good choice for indie developers or small teams on a tight budget. You run your own servers, so infrastructure is your problem, but the cost floor is low. Community support is solid. Mirror is not built for extreme scale or physics-heavy simulations. It works well for games with moderate player counts and straightforward synchronization requirements. **Use Mirror if:** you are an indie developer, self-hosting is fine, and budget is a priority. --- ## Coherence Coherence is one of the newer entrants and has gained traction on the strength of its developer workflow. Developers who have used it tend to find the experience well-designed and approachable. Coherence packs network data the way most solutions do; it has no bandwidth or physics advantage. It is a competent solution for standard game types where the development experience matters more than performance. **Use Coherence if:** you are building a standard multiplayer game and want a modern, well-designed workflow. --- ## Reactor Reactor centers on server authority, physics simulation, and bandwidth efficiency. Compression is automatic. In a controlled benchmark against Photon Fusion 2 and NGO using identical scenes, Reactor used 2 billion bits where the others used 19 and 34 billion respectively. [The benchmark is public](https://github.com/KinematicSoup/benchmarks/tree/main/UnityNetworkTransformBenchmark) if you want to run it yourself. That benchmark represents a specific controlled case. Real games tend to do better. Reactor builds data models from your game state and keeps optimizing them, so compression improves with the patterns in your data. In [Kazap.io](/blog/the-economics-of-web-based-multiplayer-games/), a 2D browser multiplayer game, Reactor compressed transforms down to about half a byte each. [Braains2](/blog/braains2-case-study-reactor-scene-fusion/), a 3D top-down physics game with 100 players and 150 physics objects, came in at under a byte per transform. [Ruins](https://ruins.kinematicsoup.com), a 3D physics destruction FPS demo we built to test the engine, frequently runs below a byte per transform despite the complexity of the simulation. The managed hosting question is handled by Reactor Cloud. One-click deployment, no servers to provision, no infrastructure to monitor. Development is free, and the server runtime is free to self-host for registered game titles up to 32 CCU per room. Cloud plans start at $20 a month and scale from there without requiring any DevOps work. Reactor is the right choice when bandwidth and physics are the constraint, which in practice means large crowds, dense physics simulations, open worlds with thousands of entities, or games where bandwidth is a real cost concern. The Braains2 case study shows what this looks like in practice: 100 players at 30Hz with 150 physics objects, at 35 kbps per server. The server runtime is small. It contains only what is needed to run scripts, simulation, and networking: no editor overhead, no rendering subsystems, nothing that does not affect game state. It is concurrent and scales across server cores. Memory overhead is in the tens of megabytes, which means you can run more server instances on the same hardware compared to solutions that require a full Unity headless build. Reactor has two control system models depending on the game type. The server-authoritative controller takes client inputs and replicates them to the server and to the client-side prediction system at once. The developer provides the motion code (assigning velocities, sweeping movement) and that same code runs in both contexts. On the client, a predictor uses it to generate instant feedback. On the server, it drives the simulation directly. The two states are then converged by the predictor. Reactor ships with several predictors out of the box and supports custom implementations. This is the right model for physics-based games with a low tolerance for desyncs, where authoritative physics and responsive controls both matter. The shared mode lets the server assign ownership of entities to any connected Unity instance, whether that is a game client or a headless authoritative build. Developers can write a standard single-player controller and Reactor replicates the key state to all other connected clients. This model works well for simpler games with minimal physics, and for MMOs where offloading logic like pathfinding or animation to separate processes helps the server scale. It is also the easier path for converting an existing single-player game to multiplayer. The runtime compiles separately from Unity. A change to client code does not trigger a server recompile and a change to server code does not trigger a Unity recompile. On larger projects this keeps iteration times short in both directions. The trade-offs: the community is smaller than Photon's, public documentation is less extensive, and Reactor's workflow is Unity-oriented. The engine itself can be adapted to other C# game clients (we have used MonoGame on the client side), but the tooling and integration layer are built around Unity. If ecosystem size and community support are your top priorities, Photon Fusion is a better fit. **Use Reactor if:** you want server authority and managed hosting without DevOps work, or your game involves physics simulation, large crowds, or high entity counts where bandwidth efficiency matters. --- ## How to choose If you are not sure where to start, a few questions narrow it down. **Do you need physics simulation, large crowds, or high entity counts?** Reactor is the clearest choice here. The bandwidth advantage compounds as your simulation grows. **Do you need Unity-native logic running directly on the server?** NGO is worth a look if you want individual Unity server instances and have backend engineering capacity. **Is budget the primary constraint?** Mirror is free and has a large community. NGO is also free if you are comfortable managing infrastructure. **Do you want managed hosting with no infrastructure work?** Reactor Cloud or Photon both handle this. Reactor is stronger on bandwidth and physics; Photon is stronger on ecosystem and community. **Are you building a competitive game where prediction and rollback matter most?** Photon Fusion 2 has the most mature implementation of this and the largest community around it. If you want to try Reactor, [it is free to get started](/reactor/install/). Development is free. Free self-hosting for registered game titles: up to 32 CCU per room. --- ## Synty Studios on Scene Fusion: Days of Work Compressed to Hours URL: https://www.kinematicsoup.com/blog/synty-studios-scene-fusion-blog Date: 2024-09-19 Summary: Synty Studios published a walkthrough of how they use Scene Fusion for remote collaboration across every stage of asset pack production. Synty Studios, one of the most prolific Unity asset publishers on the Asset Store, published a post last week walking their community through how their team uses Scene Fusion in production. Written by Kris from the Synty team, it covers their day-to-day workflow, how a fully remote team stays in sync, and the moment they noticed their demo scenes getting noticeably better. The line that stands out: > "Days worth of work can be compressed to hours when a team is iterating and problem solving together." Synty traces their adoption back to around the time of their POLYGON Pirates pack. From the post: > "You can almost see exactly where our demo production got an instant efficiency boost, because our demos became more detailed and expansive as we have been able to have multiple artists collaborating on a scene at once, meaning our scenes got better without any increase in time spent working on them." The post also mentions their 10th anniversary session, where 25 team members joined a single scene at once for an internal contest. And they note that Scene Fusion has become a regular feature of their public Twitch and YouTube livestreams, where viewers frequently ask "how are you working together like that?" On why it matters for a remote studio: > "We find this is much more efficient, and allows us to get more creative together." If you are evaluating Scene Fusion for your own team, the Synty post is worth reading in full. It gives a candid look at how a professional studio integrates Scene Fusion across every stage of production. [Read the full post on the Synty Store blog.](https://syntystore.com/blogs/blog/tips-and-tools-scene-fusion) --- ## Reactor 1.0 URL: https://www.kinematicsoup.com/blog/reactor-1-0 Date: 2023-12-29 Summary: After six years powering our own games and partner projects, Reactor is available for general release. Reactor 1.0 is available today. We have been running Reactor in production since 2017. The first game it powered was [kazap.io](/blog/the-economics-of-web-based-multiplayer-games/), a browser-based multiplayer brawler we built ourselves to test the engine and study the economics of web games. It is still running. In 2019, we partnered with modd.io to build Braains2. The sequel to the popular browser game braains.io, Braains2 pushed 100 players into the same server at 30 Hz with 150 physics objects. Total bandwidth was 35 kbps per server. The original game ran at 300. Reactor's compression is what made that possible. Scene Fusion, our real-time collaboration tool for Unity, also runs on Reactor. The same synchronization system that handles multiplayer physics in a live game handles multi-user scene edits in the editor. We spent the years since those launches refining the API, hardening the tooling, and closing the gaps that come up when you move from internal use to something you hand to other teams. We are proud to make it available to everyone. If you are building a multiplayer game, [get started for free](/reactor/install/). --- ## Case Study: Braains2, 10x the Data, 8x Less Bandwidth URL: https://www.kinematicsoup.com/blog/braains2-case-study-reactor-scene-fusion Date: 2023-06-15 Summary: How braains.io developer Jayun Noe used Reactor and Scene Fusion to double the player count, double the update rate, and cut bandwidth costs to 1/10th of the original game. Jayun Noe, known online as m0dE, is the founder of Braains.io Inc. He built braains.io, a web-based multiplayer zombie tag game where up to 50 players fight to survive an outbreak. It took him about 3 months to build, and when he launched it, players loved it. That was also the problem. ## Bandwidth was eating the profits Like a lot of successful .io game developers, Jayun found that most of what the game earned went straight back out the door in bandwidth costs. His team spent months grinding through optimizations just to get it into the black. By the time the game was profitable, the peak had passed. Optimization is hard, and easy to get wrong, even on a game that already shipped and did well. A lot of braains.io's bandwidth came down to an encoding problem: its binary network payloads were base64-encoded into JSON by the libraries it used, then sent without compression. That inflated every update, and the cause was not obvious. Finding it cost the team months. He had a clear idea for a second game. This time, he wanted to get the economics right from the beginning. ## Building braains2 with Reactor and Scene Fusion Jayun found out about Reactor and Scene Fusion through us. He knew we had built [kazap.io](/blog/the-economics-of-web-based-multiplayer-games/) ourselves, so he reached out to ask how it was done. What he was trying to do with braains2 was a real step up from the original: 100 players instead of 50, twice as many physics objects, double the server update rate, and a move from 2D to 3D. That is a lot more data to push every frame. The only way to pull it off at a reasonable cost was to let Reactor handle the compression and real-time optimization. We partnered with him on the build. His team used Scene Fusion to collaborate on level design, which kept things moving fast on the 3D environments. Reactor took care of the multiplayer side: state synchronization, physics, bandwidth compression, server infrastructure, all of it. ![braains2 gameplay](/blog-images/braains2-cap.png) Four weeks later, braains2 had a playable release candidate. The original braains.io took 15 weeks to get there. ## The numbers | | braains.io | braains2 (Reactor) | |---|---|---| | Players per room | 50 | 100 | | Update rate (Hz) | 15 | 30 | | Inanimate physics objects | 70 | 150 | | Bits per object per update (uncompressed) | 96 (2D) | 194 (3D) | | Bandwidth per player at full load | ~300 KB/s | ~35 KB/s | | Cost per MAU (AWS bandwidth) | $0.024 | $0.0027 | | Time to release candidate | 15 weeks | 4 weeks | Braains2 has to move 10x as much data per frame as the original game, between the move to 3D, twice the players, and double the update rate. Even so, total bandwidth came down by a factor of 8, and the cost per monthly active user dropped to about 1/10th of what it was. Nobody hand-tuned the serialization for it. Reactor builds and optimizes the wire format on its own, so the encoding problem that hurt braains.io is off the table. That made something possible that was not viable before: running servers in South America, close to where most braains players actually are. Lower latency, better experience. ## What we learned from this Braains2 did not go viral the way the original did. That moment had already passed. But what it gave us was a controlled, side-by-side comparison of two versions of the same game, same developer, same concept, same audience, one built without Reactor and one built with it. At the traffic levels braains2 sees today, Reactor's bandwidth savings are what keep the game from losing money. At the traffic levels a hit game sees, the same savings become a significant business advantage: lower costs from launch, more players per server, and the freedom to run servers where your players actually are. Jayun built a better game faster than the first one, and it costs a fraction of what the first one did to operate. That is exactly what Reactor is supposed to do. --- ## The Economics of Web-based Multiplayer Games URL: https://www.kinematicsoup.com/blog/the-economics-of-web-based-multiplayer-games Date: 2019-09-08 Summary: We built kazap.io alongside Reactor to understand the economics of .io games. Here's what we learned about bandwidth costs, ad revenue, and why only the most viral games win. Kazap was our project. We made the first working version in about 2 days, and put another few weeks into it. This trailer was made several months after release. It made about $7k to date. When Agar.io took the world by storm and kicked off the .io games genre, we found it quite surprising. We knew there was no technological hurdles: Browser-based technology has improved in leaps and bounds in recent years, and with the advent of websockets and WebGL, games were definitely an attainable target. What surprised us was that it could make any money. To understand the process, we created our own game, kazap.io along side our own multiplayer system, the [Reactor Multiplayer Engine](/reactor/). ## Get paid by your free game Agar.io provides ads on the landing page. A player sees those ads simply by navigating to the game, and they are removed once the player starts playing. Once a player dies, he is sent back to the landing page, where the ads are visible once more. Web-based ads pay on a cost per thousand impressions (revenue per mille impressions, or RPMI). The common earning rate is between $1 and $5 RPMI. Before you go out and create your own .io game managing costs will be critical. You make very little money on a per-MAU basis and at the very least it must cover its own costs. ## Predict the costs If you don't know what you're selling, you probably won't make money. Worse yet, you might end up owing money. Online multiplayer online games have costs associated with them, and you will need to make sure those costs are covered. For that, you need to a metric to measure your costs. We started with the concurrent connected users (CCU) who are playing at any given time. A CCU is not actually an individual player, it is a "player slot" that requires processing and bandwidth to provide. There is a problem: While CCUs are directly related to your costs, they are not constant and are not useful for estimating your costs on their own. To solve this, we created a metric called the Monthly Average Concurrently Connected User (MACCU). ![CCU is a constantly varying number, so it needs to be averaged.](/blog-images/economics-ccu.png) The MACCU is easy to measure. Simply record your CCUs at fixed time intervals, such as 30 seconds, over the course of the month and average them. You can get a good estimate for your MACCU by doing the average over a shorter time period, though if you go shorter than a week you will likely not get an accurate estimate as your player population varies by day of the week. ## How much does the MACCU cost? If a MACCU is effectively a player slot that people occupy when playing your game, you need to figure how much it is going to cost you. To calculate the cost we have to make some assumptions. The first is that we will need an online server. Many people will look to Amazon AWS, Google Cloud, or Azure for solutions that are proven to scale. Granted, these are not the cheapest solutions, but if you need a lot of extra machines in a pinch, they will scale faster and larger than smaller vendors can manage if you need it. If we start with a small but capable server from one of these providers, we are looking at a cost of about $5 per month, if it is running 24/7. A server like this can handle 200 CCU max - more if your server is very efficient. For this, you can just assume a minimum cost $0.025 per CCU. In reality, it could be a bit higher or a bit lower, depending on the number of players you get during a given hour, but this is a good ballpark estimate. As you will see shortly, it is the least of your concerns anyway. Bandwidth will vary widely from game to game, but we will take a rule-of-thumb: A 64-player FPS will need about 110,000 bits per second of bandwidth - 13,750 bytes per second - for a fluid experience. Providers typically charge you for total bytes transferred each month. Each MACCU will use 13,750 bytes per second, each second of each day for the entire month. Each month is about 2,635,200 seconds long. That means the total amount of data an MACCU uses is about 36 Gigabytes. The price per gigabyte varies significantly by region. In North America the cost is generally below $0.10, while in South America it can be as much as $0.25. North America generally has cheaper bandwidth than most of the world, so let's assume that your average cost comes our around $0.12 per GB, so your MACCU costs about $4 per month - significantly more than the computational cost! In practice, we've seen many .io games out there use significantly more bandwidth than the 'rule of thumb', with many reaching into the 300-400kbps range, well over $10 per month! Clearly, reducing bandwidth costs is your highest priority. That said, most web games don't use AWS. They use smaller outfits like Linode. These small shops provide a lot of value but have limited abilities to scale. The majority of games are unlikely to require much scale, and can therefore operate significantly cheaper. At the time of this writing, it is possible to get a single-CPU server with 1 TB of transfer for $5 per month. Such as system can easily handle 100s of CCUs. Bandwidth overage costs between $0.06 and $0.12 per GB, which is comparable to the large cloud providers, especially since ingress is free on AWS, and not always free elsewhere. No matter how you slice it, bandwidth optimization is key to making decent money and your players will appreciate these games not eating into their bandwidth cap so much. In our case, Reactor already optimizes bandwidth aggressively automatically. Our actual bandwidth per MACCU was only a few GB per month. ## The "Other" Cost Another cost that adds up is content delivery. It can be significant, especially when you have high player turnover or push frequent updates. In an ideal world, most of your players would be coming back again and again. We used the Unity game engine to build our game. It is well-known that Unity generates a particularly large runtime, especially if you include features like PhysX client-side. The result is a runtime a few megabytes in size just for the code. Your runtime size can be reduced a myriad of ways - just use another engine that is built for web that only has the features you need. You will quickly run into another issue: Your assets can easily take up more space than your runtime, if you're not careful. For kazap, we had this problem. Our assets were simply bitmaps, however they were large and high-resolution. Unity was helpful and automatically generated mipmaps at build time. Our web footprint was 22 megabytes. We reduced our asset sizes, turned off mipmapping, and were careful about other aspect we included, and dropped the runtime with assets down to 8 MB. Still large, but manageable. Being good AWS customers, we hosted our package on S3, and used Cloudfront to ensure global fast delivery. It was a far cry from the cheapest option. Even at 8 MB, our cost to deliver the runtime was upwards of $5 per MACCU at first, and dropped to $3 per MACCU as players came back and were able to use cached copies. Any time we posted a game update, everyone would re-request the game client which would create a slight uptick on the average delivery cost. ## Where's the Money? When it comes to monetization, ad revenue is the least effective. In order to turn a profit you will need a large number of impressions served. The cool thing about the MACCU value is that determining how to monetize it is relatively easy. All you need to do is determine how many individual ad impressions need to happen over the course of the month. If we assume the $4 MACCU cost, with a conservative $1.50 RPMI, you can see that a single MACCU will need to serve just under 3500 impressions to break even over the course of the month. This means that every 12.5 minutes, you have to display an ad to every active player. Increasing the frequency of the ads increases revenue. When we made kazap.io, we designed to show an ad every 4 to 5 minutes. We estimated our revenue to be around $12/MACCU. ## Our Real-world Example ![Our adsense earnings for the first few months after launch. Not exactly a smash hit, but we learned a lot!](/blog-images/economics-adsense.png) We assembled our game and launched it. We tracked several metrics using Google Analytics events such as how many players successfully loaded the game. We logged the number of CCU every 5 seconds across all servers. During our peak month, our determined our MACCU number was about 100. Our earnings for the month were $1128.47. It was a little below our estimate. We set up events using Google Analytics to detect various conditions. One of those conditions was the use of ad-block software. We would still allow people to play the game using adblock, we would just present them with a message instead of an ad that took even longer to dismiss. 8% of players used ad blockers - a number that seemed smaller than we expected. Another thing we noticed, even with our relatively large runtime, our bounce rate was below 20%. This suggests that you can get away with downloads that are a bit larger without too much impact. For comparison, games that have 15MB+ runtimes have bounce rates 4x higher. Generally, people don't seem to mind a bit of a load time, however once you go over 10MB it will definitely start to take too long. When we tested with another web game that had a 17 MB download, the bounce rate skyrocketed to 80%. ## Conclusion All in all, our game made around $7k over its lifetime. It didn't go viral, dashing our hopes of making $50k-$200k per month, but it paid its own bills and we learned a lot. I suspect that if we had released now, it would not fare as well. The multiplayer web games space is getting relatively crowded, with a new game or two released almost every day. It's a great way to prove a concept and maybe find a seed player base, but not really a good place to make money unless you're very lucky. At its peak, our game had 150k MAU. Gross revenue around $1130 means we made $0.007 per MAU! Pretty terrible, so clearly web-based MAU have nothing on mobile, PC, or console, at least not in the .io space. about 60% of our gross revenue went to expenses - about $100 for servers, the rest was bandwidth. So, our experiment paid for its usage, but not much else. Only the most viral games win. Thanks for reading! ## 2026 Update: How Bandwidth Pricing Has Changed This article was written in 2019. The core analysis still holds, but bandwidth pricing at smaller providers has dropped substantially since then and is worth revisiting. At the time of writing, overage bandwidth from providers like Linode ran $0.06–$0.12 per GB. Today, Vultr charges [$0.01 per GB](https://www.vultr.com/pricing/) for bandwidth overage, a 6x reduction from the low end of that range. At that rate, the 36 GB per MACCU figure works out to roughly $0.36 in bandwidth costs per MACCU per month, down from the $4 figure in the original calculation. The compute cost is now the bigger line item, not the bandwidth. AWS has not followed suit. [Data transfer out from US East starts at $0.09 per GB](https://aws.amazon.com/ec2/pricing/on-demand/) for the first 10 TB, dropping to $0.085 for the next 40 TB and lower at higher volumes. Pricing is higher in other regions: South America (São Paulo) starts at $0.15 per GB. The gap between AWS and smaller providers has widened, not closed. The reason for the disparity is structural. AWS prices egress as a profit center: their enterprise customers accept it as a cost of the ecosystem, and high egress fees make it expensive to leave. Smaller providers use cheap bandwidth to compete for developer workloads. Bare-metal providers like OVH take a different approach entirely: bandwidth is often bundled into the server price as a large monthly transfer pool or an unmetered connection at a fixed port speed, because their business model is selling hardware capacity rather than cloud services. The conclusion from 2019 still stands: bandwidth optimization is critical, and Reactor's compression advantage compounds as your player count grows. But if you are self-hosting, the economics are meaningfully more forgiving today than they were when this was written, provided you choose your infrastructure carefully. The bandwidth math in this post is the exact problem we build for. Reactor compresses your network traffic automatically, with no serialization code to write, which is how games on it run well under a byte per transform. In a controlled benchmark it moved 17x less transform data than Unity's Netcode for GameObjects and 9.5x less than Photon Fusion 2. See what Reactor does. --- ## Epic Announces $1M in Developer Grants. Scene Fusion Included! URL: https://www.kinematicsoup.com/blog/epic-announces-1m-in-developer-grants-scene-fusion-in-included Date: 2018-06-28 Summary: Epic Games recognized KinematicSoup as a winner of developer grants, supporting Scene Fusion's development including a new C++ core that can power any engine. Epic Games has recognized KinematicSoup as a winner of approximately $1M in developer grants distributed among 37 teams. The company has invested nearly eight months developing Scene Fusion for Unreal Engine. A significant upgrade, Scene Fusion 2, features a C++ core rewrite with substantially improved APIs, enabling deployment across multiple game engines rather than Unreal exclusively. The development roadmap prioritizes stability and extensibility initially, with subsequent work targeting support for Unreal's comprehensive feature set. Scene Fusion for Unreal remains in closed alpha testing. Interested developers can join a sign-up list for announcements and closed testing opportunities. Recognition from Epic is... well, Epic! --- ## Data Compression: Crushing Data Using Entropy URL: https://www.kinematicsoup.com/blog/data-compression-crushing-data-using-entropy Date: 2017-08-17 Summary: How arithmetic coding compresses data into fractional bits using entropy, and why accurate probability predictions are everything. It has been quite some time since our first installment on simple data compression. This second installment is long overdue! Compression is ubiquitous in our everyday lives. Our OSes handle .zip files natively, we watch high-quality compressed video on our cell phones, we browse the web and see dozens or hundreds of compressed images every day, and even under the hood websites like this one are compressed for faster delivery. If you are a game developer, you have probably encountered a need to use compression in one form or another. Game engines like Unity and Unreal provide built-in methods of compressing game and texture data as engine features that are transparent to use. In other situations, such as if you have to create networked multiplayer code, you likely would have to spend a lot of time reducing the size of the data you are sending over the network in order to ensure the best possible experience. Every method of bit-packing has the effect of representing some number of input bits as fewer output bits. In our previous blog on this subject, we represented 32-bit integers as smaller, variable-length integers. We accomplished this by merely injecting a 5-bit length field and making the first 1-bit of each integer implicit. The result was a reasonably efficient bit-packer. However, the smallest individual symbol a bit packer can use is 1 bit in size. It is possible to store those symbols in fractions of a bit by using an entropy coder like Arithmetic Coding. Arithmetic coding is very simple. They work by encoding the probability of a symbol into a range on the number line [0...1). Each time a symbol is encoded, it defines an ever-shrinking part of the number line as the next range. The output is a real number of finite length. Here is a simple example: ![Here is how you encode the first few symbols of a string of bits. At each stage, a symbol gets encoded by tracking the resulting probability. At the first stage, the output is 0.75. We then 'zoom in' on the 0...0.75 range and repeat the process with the probability model. The 0 occupies the upper .25 of the probability space, so we zoom in on the 0.5625...0.75 range. The process repeats until the last symbol is encoded, and the output of the process is 0.66796875.](/blog-images/entropy-encoding.png) Here is how the decoding process works: ![The decoding process uses the same math to compute the progression of probability ranges. The encoded number will always fall in the correct probability range for the given symbol at each stage, allowing the original data to be decoded. Here we test the encoded message 0.66796875 against each iteration of the probability ranges and emits the symbol associated with the sub-range the value sits in. In this case, 0.6679... sits below 0.75 in the first iteration, so the first symbol is a 1. We then rescale the ranges in the same way as when we encoded and test again. We find that 0.6679... is larger than 0.5625, which sits in the probability range for 0, so we emit a 0. After rescaling the third time, we find that 0.6679... sits below 0.703125, which again puts it in the probability range for 1, and so on.](/blog-images/entropy-decoding.png) What is even more interesting is that at each stage you can change the probability distribution of your symbols, and it still works, and will still decode as long as you switch to the same probability distributions at the same stages as the encoder did. Now, computers don't store things as arbitrarily-long real numbers, and types like float or double will run out of precision after only a small number of symbols. This is overcome in a very simple way: Just multiply everything by 0x7FFFFFFFh. You came here for code, so let's get started. We are using a binary arithmetic coder. There are many implementations out there, such as the one is LibLZMA, however for this blog we are using a port of the coder implemented by Fabian Giesen. His coder is written in C++, however given that most our audience uses C# in Unity, I have ported his encoder and placed in our examples repository, licensed under MIT. Here is the implementation of the binary arithmetic encoder: ```csharp public class BinaryCoder { private UInt32 m_high = ~0u, m_low = 0; private Stream m_output; public BinaryCoder(Stream outputStream) { m_output = outputStream; } public void Encode(int bit, UInt32 probability) { UInt32 x = m_low + (UInt32)(((UInt64)(m_high - m_low) * probability) >> CoderConstants.PROB_BITS); if (bit != 0) m_high = x; else m_low = x + 1; // this is renormalization - shift out topmost bits that match while ((m_low ^ m_high) < 0x01000000) { m_output.WriteByte((byte)(m_low >> 24)); m_low <<= 8; m_high = (m_high << 8) | 0x000000ff; } } public void Flush() { UInt32 roundUp = 0x00ffffffu; while (roundUp != 0) { if ((m_low | roundUp) != 0xffffffffu) { UInt32 rounded = (m_low + roundUp) & ~roundUp; if (rounded <= m_high) { m_low = rounded; break; } } roundUp >>= 8; } while (m_low != 0) { m_output.WriteByte((byte)(m_low >> 24)); m_low <<= 8; } m_output.Flush(); } } ``` The binary arithmetic coder looks confusing at first. They have been around for quite some time, and contain various approximations and optimizations, so the math they employ is not immediately familiar. There is a good explanation on how these various optimizations came to be and what they do here. It is very simple to use, just encode a bit with a probability prediction using the Encode() function. The parameters are the value of the bit, and the probability of the bit being 1. The coder itself is just a way to tracking and emitting encoded bytes, it will not magically make your data smaller until you have a good prediction model. Our example code contains a set of models that can be used to attain compression. The simplest one, the SimpleStaticModel, uses a static probability and encodes a given bit using that probability. Let's look at our example code. We have cooked up some data for the purposes to showing off compression. This is representative of the type of data that is easier to analyze and build a compression scheme for: ```csharp byte[] simpleSampleData = { 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xe0, 0x0c, 0xf0 }; ``` An efficient way to encode this is using a run-length (or dgap) scheme to code run-lengths of bits. We encode a series of values to give us the starting state followed by the lengths of the runs, which would encode to {28, 16, 15, 41, 3, 4, 9, 2, 2, 4, 4}, where the first 0 representing the bit starting state, and the remaining bits represting the runs of the alternating states, therefore there are 28 zeros, followed by 16 ones, followed by 19 zeros, etc. This is efficiently encoded using 1 bit for the initial state, and 6 bits for each subsequent value, giving a grand total of 67 bits ~ about 8.375 bytes! 8.375 bytes/16 bytes = a compressed size of 52%! However, it will encode to 9 bytes because everything must be, at a minimum, byte-aligned. You will also need two other pieces of information: The initial bit state, and the number of encoded dgaps, which in this case can all be done using a 5-bit header, bringing the total output size to 9 bytes. That's pretty efficient. Now Let's see what happens when we use a simple binary coder fed by a simple adaptive probability model. ```csharp { System.IO.MemoryStream output = new System.IO.MemoryStream(); BinaryCoder coder = new BinaryCoder((Stream)output); BinShiftModel adaptiveModel = new BinShiftModel(); // the lower the number, the faster it adapts adaptiveModel.Inertia = 1; foreach (byte b in simpleSampleData) { for (int bitpos = 7; bitpos >= 0; --bitpos) { int bit = (int)(b >> bitpos) & 1; // NB: Skipping try/catch here! adaptiveModel.Encode(coder, bit); } } coder.Flush(); Console.WriteLine("Adaptive Output size is " + output.Length); } ``` The result reduces the data by just a few bytes. Not nearly as good as our tailored bit-packing result. This an important lesson: Using entropy alone for packing bits is NOT a silver bullet. In fact, with real-world data, entropy is probably going to make your data bigger. Why? Entropy works based on accurate predictions. Guess correctly, you get a little benefit. Get it wrong by the same amount, get punished much more. The number of bits required to encode a given symbol can be calculated using -log2(Psym). Let's lay you figure you have a 70% chance of encoding a 1 bit, but when you read the next bit you want to encode it comes up a 0. That bit is going to encode to 1.74 (-log2(1-.70)) bits in the output stream - you lost almost 1 whole bit! Had you been lucky and actually read a 1 bit instead, you would have encoded it with 0.51 bits (-log2(.70)), you would have saved .49 bits of space, whereas the mis-prediction costs you an additional .74 bits. Think of it this way, the better you can predict the future, the better entropy works. Let's try another way to compress our data. This time, rather than be adaptive, we'll come up with some fixed probabilities that work well. We can compute this ahead of time. For the above dataset, we have 128 bits. 10 of these bits 'transition', that is, they are the last of a series of 1 or 0, and the proceeding bit will be in the opposite state. The means that the probability of the next bit being the same state as the current bit is about 92%. The implementation works as such: We encode 0 bits with a 8% probability of being 1, and we encode 1 bits with 92% probability of being one. We can implement this using two static models: One of the models is used when encoding runs of 0's. This model has a low probability of 1 because while you're encoding 0's there is little chance that they will encounter a 1. The other model is the opposite, it encodes with a high probability of 1 because you are unlikely to encounter a zero. Another important step is that you encode the current bit with the last model you used, regardless of the bit's value. So if you are encoding 0's, and then you suddenly encounter a 1, you will encode the 1 with the same model as the previous 0's, then you will switch to the 1-biased model. The reason for this is that when decoding, you won't know ahead of time what the next decoded symbol will be, and you need to follow the same rules. This switching of models during encoding/decoding is called a "context switch". What is very interesting here is that, as long as you preserve the encoder state, you can dynamically switch out the probability models as you go. The only requirement is that whatever you do during encoding, you are able to duplicate during decoding. For this example, we are going to set aside our adaptive probability model for now and just use the simpler static probability model with context switching: ```csharp { // encode System.IO.MemoryStream output2 = new System.IO.MemoryStream(); BinaryCoder coder2 = new BinaryCoder((Stream)output2); SimpleStaticModel model0 = new SimpleStaticModel(); SimpleStaticModel model1 = new SimpleStaticModel(); model0.SetProb(10f / 128f); model1.SetProb(1f - (10f / 128f)); bool use0Context = true; // 0 bits come first, use the correct model! foreach (byte b in simpleSampleData) { for (int bitpos = 7; bitpos >= 0; --bitpos) { int bit = (int)(b >> bitpos) & 1; // encode using the correct context // NB: Skipping try/catch here! if (use0Context) model0.Encode(coder2, bit); else model1.Encode(coder2, bit); // switch context AFTER the bit state changes use0Context = (bit == 0 ? true : false); } } coder2.Flush(); Console.WriteLine("Ideal static model with context switch size is " + output2.Length); /* The decoder looks much like the encoder. Notice how the context switch occurs only after a symbol is decoded, exactly as the encoder does it. */ output2.Seek(0, SeekOrigin.Begin); // decode BinaryDecoder decoder2 = new BinaryDecoder((Stream)output2); SimpleStaticModel staticModel0dec = new SimpleStaticModel(); SimpleStaticModel staticModel1dec = new SimpleStaticModel(); staticModel0dec.SetProb(10f/128f); staticModel1dec.SetProb(1f - (10f/128f)); bool use0ContextDec = true; // 0 bits come first, use the correct model! foreach (byte b in simpleSampleData) { for (int bitpos = 7; bitpos >= 0; --bitpos) { int bit = (int)(b >> bitpos) & 1; int decBit; // decode using the correct context! // NB: Skipping try/catch here! if (use0ContextDec) decBit = staticModel0dec.Decode(decoder2); else decBit = staticModel1dec.Decode(decoder2); /* the decoded bit should match the source bit for the decoder to have worked*/ if (decBit != bit) { Console.WriteLine("Error, static example 1 did not decode properly!"); } // switch context when the bit state changes use0ContextDec = (decBit == 0 ? true : false); } } } ``` And just like that, it encodes to 6 bytes. In theory, it should encode to 6.3 bytes, however binary range coders aren't 100% efficient, mostly because they have to flush extra bits to renormalize. For this (obviously) cooked data set, this is probably the most ideal representation of its compressibility in it's raw form. One last note: Entropy coding with an arithmetic encoder is time consuming, though it is actually fast enough for many applications, especially if you can reduce the amount of input data bits you have to encode beforehand. Encoders like gzip can also be useful in many situations, as they perform well and are general-purpose. However, a specific-purpose entropy coder will beat out a general-purpose one, all else being equal, in both CPU performance and compression ratio. I hope you enjoyed this follow-up installment. Time permitting, I may follow up with another in the future with a more complicated application of entropy encoding. Until then, I hope you have learned enough in this post to be able to dig into some of the common general-purpose compressors out there. Happy coding! --- ## We Powered Unity at SIGGRAPH VR Village 2017 URL: https://www.kinematicsoup.com/blog/we-powered-unity-at-siggraph-vr-village-2017 Date: 2017-08-01 Summary: Scene Fusion powered Unity's live EditorVR demo at SIGGRAPH VR Village 2017, real-time collaboration in VR on a live production system. Real-time collaboration is a great way to work and be productive. It is especially powerful when you are looking at VR development. We have been working with EditorVR from Unity Labs since they released it, ensuring that Scene Fusion enables real-time collaboration on the platform. We are happy with the results! Unity actually used our live production system for the demo. It worked well, despite an iffy internet connection. Check out the video of how it went! [Watch on YouTube](https://www.youtube.com/watch?v=hpuEdXn_M0Q&t=4388s) Real-Times Live!: An interactive extravaganza that celebrates real-time achievements. Real-Time Live! showcases the latest trends and techniques for pushing the boundaries of interactive visuals. --- ## Scene Fusion + EditorVR Featured at Unity Europe 2017! URL: https://www.kinematicsoup.com/blog/scene-fusion-editorvr-featured-at-unite-eu17 Date: 2017-07-10 Summary: Scene Fusion was featured in Unity's presentation at Unite Europe 2017, highlighting how EditorVR and real-time collaboration work together. Give some love, get some love! Scene Fusion has supported EditorVR since its release last year. EditorVR has evolved so much in that time, and continues to get even better! Most notably, the tool operates as open-source software with community-driven development. Unity returned the love by giving Scene Fusion some screen time! EditorVR allows VR authors to create VR inside of VR. To maximize productivity for artists and designers working on VR projects, custom tools may be necessary. The Unite EU17 presentation demonstrated the process for building custom tools using the EditorVR framework and explored the design principles underlying the system's architecture. --- ## KinematicSoup and ProCore3D join together to massively accelerate level creation! URL: https://www.kinematicsoup.com/blog/kinematicsoup-and-procore3d-level-up-together Date: 2017-06-27 Summary: Scene Fusion now supports ProBuilder3D, combining real-time collaboration with powerful in-engine geometry creation for the fastest level creation workflow available. Tools for game developers have entered a new era. Scene Fusion, the most powerful level design collaboration tool available, has teamed up with the most powerful in-Unity asset Probuilder3D to become the fastest in-engine asset creation solution available! KinematicSoup Technologies, the company behind Scene Fusion, is working to support the most powerful and popular tools used by game developers. Scene Fusion 1.0 was launched in November 2016, and has expanded in capability ever since. Scene Fusion has direct support for VR as well as a growing number of plug-ins for Unity3D. Scene Fusion is currently available for Unity3D, and provides level designers with the ability to collaborate in real-time. Hundreds of studios have discovered the benefits of Scene Fusion, which reduces months of work to mere weeks, and enables studios to create and ship their games up to 33% faster. ProBuilder3D provides a fast and easy mechanism to generate 3D content directly within Unity, without the need for external tools. It enables extremely rapid prototyping as well as completed model design, with powerful geometry generation and texturing tools. "ProBuilder3D is one of the most pre-eminent tools available for game developers to use to accelerate their content creation process. We are excited to be bringing direct support for ProBuilder to Scene Fusion. We believe that tools like Scene Fusion and ProBuilder are the future of the game development process. We look forward to working with the folks at Procore3D to extend Scene Fusion support to their entire toolset." **Justin McMichael, CEO, KinematicSoup Technologies Inc.** "We are excited to be included in KinematicSoup's efforts for Scene Fusion. We believe that ProBuilder combined with superior collaboration will provide studios with a significant advantage in terms of development timelines. We share a vision where better tools make game developers' lives easier, enabling them to make even better games!" **Gabriel W., ProCore3D** Starting with Scene Fusion 1.5, ProBuilder is now supported! --- ## Client-side Prediction for Smooth Multiplayer Gameplay URL: https://www.kinematicsoup.com/blog/multiplayerprediction Date: 2017-05-30 Summary: How to implement client-side prediction and smoothing for responsive server-authoritative multiplayer games, with the algorithm we used in kazap.io. Multiplayer games present complexities absent from single-player development, making them more time-consuming and expensive to create. For server-authoritative online games, developers must implement client-side prediction and smoothing to ensure responsive player movement across varying latency conditions. The fundamental approach involves clients responding to player input by moving characters locally before server confirmation arrives. This creates potential divergence between client and server positions. The basic challenge: preventing these states from drifting too far apart while maintaining gameplay responsiveness. Multiple implementation variants exist, each suited to different game types. The article demonstrates the approach used in Kazap.io, a 2D space-shooter multiplayer game. ## Key Technical Considerations The implementation requires running identical player controller code on both client and server. However, several factors cause divergence: - Differing game state awareness - Timestep differences between systems - Floating-point non-determinism across hardware The solution involves maintaining position and input history spanning the round-trip latency period. When server updates arrive, clients compare predicted positions against actual server data. Exceeding tolerance triggers position correction through input replay using updated server state. Rather than instantly snapping to corrected positions, smooth interpolation prevents jarring visual discontinuities. ## The Kazap.io Algorithm ![An overlay of the client ship (orange) and server 'ghost' (white) showing divergence](/blog-images/multiplayer-prediction-demo.gif) The article introduces a specific technique reducing client-server position separation. Instead of clients perpetually leading servers, this method gradually converges toward server positions during movement. Key variables tracked: position, rotation, velocity, input history, and time deltas. Upon receiving server updates, the system removes historical frames until the remaining history duration equals round-trip latency. Position and rotation deltas are summed and added to server state, producing predicted position. Velocity divergence exceeding tolerance triggers input replay, recalculating deltas using actual server velocity. Each client frame executes the player controller, generating position deltas added to history. The predicted position extrapolates using adjusted velocity multiplied by latency and convergence constant (0.05 in Kazap.io). Client position then interpolates toward the extrapolated position, controlled by latency and convergence parameters. ![Server and client position over time for two prediction methods](/blog-images/multiplayer-prediction-graph.png) ![Frame-by-frame comparison of both prediction methods (server updates every 2 client frames)](/blog-images/multiplayer-prediction-animation.gif) ![Key variable positions: S (server), C (client), P (predicted), E (extrapolated), R (rendered)](/blog-images/multiplayer-prediction-vars.png) ## Pseudo Code Implementation ```csharp // Called when we receive a player state update from the server. function OnServerFrame(serverFrame) { // Remove frames from history until its duration is equal to the latency. dt = Max(0, historyDuration - latency); historyDuration -= dt; while (history.Count > 0 && dt > 0) { if (dt >= history[0].DeltaTime) { dt -= history[0].DeltaTime; history.RemoveAt(0); } else { t = 1 - dt / history[0].DeltaTime; history[0].DeltaTime -= dt; history[0].DeltaPosition *= t; history[0].DeltaRotation *= t; break; } } serverState = serverFrame; // If predicted and server velocity difference exceeds the tolerance, // replay inputs. if ((serverState.Velocity - history[0].Velocity).Magnitude > velocityTolerance) { predictedState = serverState; foreach (frame in history) { newState = playerController.Update(predictedState, frame.DeltaTime, frame.Input); frame.DeltaPosition = newState.Position - predictedState.Position; frame.DeltaRotation = newState.Rotation - predictedState.Rotation; frame.Velocity = newState.Velocity; predictedState = newState; } } else { // Add deltas from history to server state to get predicted state. predictedState.Position = serverState.Position; predictedState.Rotation = serverState.Rotation; foreach (frame in history) { predictedState.Position += history.DeltaPosition; predictedState.Rotation += history.DeltaRotation; } } } // Called every client frame. function Update(deltaTime, input) { // Run player controller to get new prediction and add to history newState = playerController.Update(predictedState, deltaTime, input); frame = new Frame(deltaTime, input); frame.DeltaPosition = newState.Position - predictedState.Position; frame.DeltaRotation = newState.Rotation - predictedState.Rotation; frame.Velocity = newState.Velocity; history.Add(frame); historyDuration += deltaTime; // Extrapolate predicted position // CONVERGE_MULTIPLIER is a constant. Lower values make the client // converge with the server more aggressively. We chose 0.05. rotationalVelocity = (newState.Rotation - predictedState.Rotation) / deltaTime; extrapolatedPosition = predictedState.Position + newState.Velocity * latency * CONVERGE_MULTIPLIER; extrapolatedRotation = predictedState.Rotation + rotationalVelocity * latency * CONVERGE_MULTIPLIER; // Interpolate client position towards extrapolated position t = deltaTime / (latency * (1 + CONVERGE_MULTIPLIER)); clientState.Position = clientState.Position + (extrapolatedPosition - clientState.Position) * t; clientState.Rotation = clientState.Rotation + (extrapolatedRotation - clientState.Rotation) * t; predictedState = newState; } ``` ## Conclusion Client-side prediction represents one latency compensation technique among several. For additional strategies particularly relevant to first-person shooters, Valve's documentation on latency compensation techniques is an excellent resource. The algorithm above is the one we shipped in Kazap.io, and getting it right (the history buffer, the replay on divergence, the convergence tuning, holding up across latency and floating-point differences between machines) is most of the hard part of server-authoritative multiplayer. We productized that work: our Unity multiplayer engine Reactor provides prediction and reconciliation out of the box, so you write the controller once and it runs on both client and server. [How that compares to the other Unity engines.](/blog/best-unity-multiplayer-engine/) *Written by Alyosha Pushak, Senior Developer at KinematicSoup.* --- ## KinematicSoup Technologies Launches VR Support for Scene Fusion URL: https://www.kinematicsoup.com/blog/kinematicsoup-announces-scene-fusion-vr-support Date: 2017-03-13 Summary: Scene Fusion now officially supports EditorVR, giving VR game developers real-time collaborative scene editing inside Unity's experimental VR editor. **March 13, 2017** – VR game development on the Unity platform just received a massive productivity boost. Today, KinematicSoup Technologies announced that Scene Fusion now officially supports EditorVR. The announcement was in response to Unity Technologies' latest update to the platform, released on March 11th, 2017. Scene Fusion is a Unity plug-in that adds real-time collaboration for level design to the Unity engine, which reduces the amount of time it takes to build and ship a game by up to 33%. With the growing popularity of VR, the decision to support it in Scene Fusion was an easy decision for Justin McMichael, CEO of KinematicSoup. Unity launched the first publicly available experimental build of EditorVR for Unity, on December 15, 2016. Since this launch, the team at KinematicSoup has made efforts to ensure Scene Fusion builds have supported the continuous development of EditorVR, and plans to continue this trend. "Our goal is to provide complete interactivity to game developers so that they can bring games to market sooner and work more efficiently. We see VR as a natural next step to the evolving landscape of game development. The benefits of real-time collaboration have never been greater than they are in VR. Being able to have people in and out of VR interact together on a single scene creates a very fast and efficient workflow that results in faster game development." Justin McMichael, CEO, KinematicSoup Scene Fusion has been in development since 2015 and has since become popular among many Unity-based game studios. --- ## How to Effectively Collaborate with Your Team in Unity URL: https://www.kinematicsoup.com/blog/how-to-effectively-collaborate-in-unity Date: 2017-01-15 Summary: How Unity teams work on the same project in 2026: source control setup, what replaced Unity Collaborate, asset management, and the options for editing the same scene at the same time. *Updated September 2026. The original 2017 article predates the retirement of Unity Collaborate and several changes to how Unity teams work; this version reflects the current tooling.* Working on a Unity project as a team raises two separate problems: how to share the project files, and how to work in the same scenes without destroying each other's changes. Source control solves the first. The second has no complete built-in solution in Unity, and teams handle it with a mix of project structure, locking conventions, and real-time editing tools. This guide covers both. ## What happened to Unity Collaborate? Unity Collaborate was retired. Unity acquired Codice Software, the developer of Plastic SCM, in 2020, and began migrating Collaborate projects to Plastic SCM in late 2021. The product is now called [Unity Version Control](https://unity.com/features/version-control) and is part of Unity DevOps, which absorbed the old Unity Teams plans. DevOps includes three free seats, and Unity has [announced](https://unity.com/products/pricing-updates) the removal of seat charges for cloud-hosted Unity Version Control starting in 2026. If you are searching for Collaborate today, the practical answer is: pick a source control system from the next section. Unity Version Control is the direct successor, and Git is the most common choice. ## How multiple people work on the same Unity project Source control is the foundation. A shared repository holds the project; each person pulls the latest revision, makes changes, and merges them back. Revision history lets you inspect and revert changes, and text files (code, and Unity's YAML-serialized assets) merge between contributors. The common choices for Unity projects: - **Git**, with GitHub or GitLab. The most common option. Needs setup for Unity (below). - **Unity Version Control** (the former Plastic SCM). Handles large binary files without extensions, supports file locking, and integrates with the editor. - **Perforce Helix Core**. The standard at larger studios; strong with large binaries and exclusive checkouts. - **Subversion (SVN)**. Still in use; simpler model, weaker branching. A Unity project needs three pieces of setup regardless of which you pick, and Git needs all of them: 1. **Text serialization.** Keep Asset Serialization set to Force Text (the default) in Editor settings, so scenes and prefabs are diffable and mergeable YAML rather than opaque binaries. 2. **A Unity-specific ignore file.** `Library/`, `Temp/`, `Logs/`, and build output are machine-generated and must stay out of the repository. 3. **Large-file handling.** Textures, models, and audio do not diff or merge. On Git, that means Git LFS; Unity Version Control and Perforce handle large binaries natively. Unity also ships **UnityYAMLMerge** (Smart Merge), a merge tool that understands scene and prefab structure. Wiring it into your source control tool resolves many scene merges that a text merger would fail. ![Git branch diagram](/blog-images/collaborate-git-branch.png) ## Art assets and asset management Art files are stored in source control but cannot be merged, and generic diff views say little about what changed in a texture or a model. Digital asset management tools track revisions of art assets with visual comparisons and annotations. The current names: Autodesk **Flow Production Tracking** (called Shotgun until 2021 and ShotGrid until 2024) and **ftrack**. Both read files from the common art applications (Maya, 3ds Max, Blender, Photoshop). For game teams without a film-style pipeline, Perforce or Unity Version Control with file locking covers the practical need: one person edits a binary asset at a time. ## How teams work in the same scene Scenes are where Unity collaboration breaks down. A scene file is one large YAML document describing every object in a level, and Unity offers no built-in way for two people to edit it at the same time. Teams use four approaches, in rough order of sophistication: ### Scene merging Two people edit copies of the scene and merge afterward, with UnityYAMLMerge resolving the structure. This works when the changes do not touch the same objects. When they conflict, the resolution is manual and tedious, and neither person saw the other's work until the merge. Merging is a fallback, not a workflow. ### Scene locking (the "conch" method) One person owns the scene at a time, enforced socially or by exclusive checkout in Perforce or Unity Version Control. This prevents conflicts by preventing parallelism: one person works while the others wait. ### Splitting the scene: prefabs and additive scenes Since Unity 2018.3, nested prefabs let teams break a level into pieces that are edited as separate files, which shrinks the surface where conflicts can happen. Additive scene loading does the same at a larger grain: a level built from several scenes lets each person lock a smaller piece. Both reduce contention; neither lets two people build the same area together. ### Real-time multi-user scene editing The remaining option is to make the scene itself multi-user. We build [Scene Fusion](/scene-fusion/), a Unity editor plugin that connects multiple editors to one scene session: everyone places, moves, and edits objects in the same scene, and sees each other's changes as they happen. There is nothing to merge afterward, because there is only one live version of the scene. ![Scene Fusion multi-user plugin in the Unity editor](/blog-images/collaborate-plugin.jpg) ![A scene that 8 users assembled at once with Scene Fusion](/blog-images/collaborate-dungeon.jpg) This changes the shape of level work. Greyboxing, review, and set dressing happen in one session instead of a lock-edit-merge cycle, and problems are visible while the other person is still working rather than at merge time. [Synty Studios uses Scene Fusion](/blog/synty-studios-case-study/) to build levels in parallel and, in their words, saves about a day per week of production time. The [workflow guide](/scene-fusion/workflow/) covers how sessions run day to day, including how Scene Fusion coexists with source control: the scene still lives in your repository; the session replaces the merge. Scene Fusion is [free for two collaborators](/scene-fusion/install/), and supports Unity 2022.3 LTS and Unity 6.0 through 6.5. ## Summary Use source control for the project: Git with LFS and UnityYAMLMerge, Unity Version Control, or Perforce. Keep scenes and prefabs in text serialization. Track binary art with file locking or a DAM tool. For scenes, split levels into prefabs and additive scenes to reduce contention, and use real-time multi-user editing when the team needs to build the same space together. --- ## Game Development Workflow Part 2: Production and Post-Production URL: https://www.kinematicsoup.com/blog/game-development-workflow-part2 Date: 2016-11-10 Summary: How production teams shift from prototyping to shipping: world building, testing, and the bottlenecks that slow down content creation. ## Production During production, teams establish more standardized workflows. While prototyping continues for lower-priority items, most of your high priority and critical items will have already completed those stages by this point. Production focuses on generating sufficient content for a complete game, with art teams developing assets, developers implementing gameplay code, and level designers transforming greyboxed levels into final versions. As digital assets multiply, version control becomes essential. Tools like Perforce and PlasticSCM manage game assets differently than source code. Digital assets are usually modified in their entirety, whereas code can be modified and merged together. Digital asset management tools integrated with source control enable early-stage versioning and team access. ### World Building World building brings level design to life through asset implementation. Multiple disciplines collaborate: programmers test for edge cases and performance targets, playttesters identify design flaws, and creative directors ensure aesthetic alignment. This coordination-intensive process often faces bottlenecks. Traditional solutions like level sectioning have limitations. KinematicSoup created Scene Fusion to enable a team to work within a single level in real-time, supporting instantaneous feedback across disciplines. ## The Importance of Testing Testing encompasses both code-level and playtest evaluation. Unit testing frameworks like nUnit, CppUnit, and Unreal's UFE tool help developers write testable code and generate automated reports. Playtesting occurs in two stages: Quality Assurance tests for internal bugs and functionality, while User Acceptance Testing evaluates player reception. The critical thing to remember with testing is that it needs to occur early and it needs to happen often. ## The End of Production ![Generalized Gamedev Workflow Timeline](/blog-images/workflow-part2-timeline.png) As production concludes, development enters post-production, the final polishing phase addressing remaining bugs through small tweaks to the design or aesthetic of the game such as adding clutter or non-critical props, final lighting passes, performance optimization, and non-critical bug fixes. --- ## KinematicSoup Technologies Launches Scene Fusion URL: https://www.kinematicsoup.com/blog/kinematicsoup-technologies-launches-scene-fusion Date: 2016-11-01 Summary: Scene Fusion officially launches after an open beta since March 2016. Real-time multi-user scene collaboration for Unity developers. **November 1, 2016** – KinematicSoup Technologies Inc. officially released Scene Fusion, their real-time multi-user collaboration tool for Unity game development. The service had been in open beta since March 2016. Scene Fusion enables game developers to create richer content more efficiently through cooperative iteration. The platform addresses common Unity workflow challenges, particularly scene merging, by allowing developers, artists, and designers to connect to scenes through a cloud environment where changes sync instantly. The service operates on a tiered monthly subscription model accommodating different studio sizes, from indie to enterprise, plus educational licenses. CEO Justin McMichael emphasized their commitment to accessibility: "studios of all sizes have an affordable way to use Scene Fusion." New subscribers receive a complimentary trial month. McMichael credited beta testers for their contributions, noting that user feedback proved extremely valuable in refining the final product. --- ## Game Development Workflow URL: https://www.kinematicsoup.com/blog/game-development-workflow Date: 2016-10-26 Summary: A practical introduction to game development workflows: from design and prototyping to the vertical slice, and how to structure your team's pipeline. Note: This blog will be continued over the course of the next few weeks. Although posted by me, it is a combined work from several employees at KinematicSoup. These are our own conclusions based on personal experience in the industry. This blog is meant to give a very high level and generalized introduction into the workflow behind creating games. It is not meant to be a strict guide as teams will adapt their development methods to suit their needs. ## What is a Workflow? Never bite off more you than you can chew, or at least so my various elders have told me while growing up. In my younger days, building games was in some ways harder and in other ways easier than it is today. Back then there were no AAA titles and every game was an indie game. With some decent pixel art and clever programming you could define, and then redefine, entire gaming categories. Things have changed. We now have a concept of blockbuster games with hundred-million-dollar development budgets and revenues in the billions. This changes a fan's perception, and should he or she decide to build a game, they may be tempted to set their expectations a little too high. Before you start, remember, baby steps. Don't go out thinking you'll make the next Call of Duty or League of Legends. Start small, do something simple, and get your bearings. Once you have a simple idea that you can imagine yourself putting the work into, you're ready to get into the nitty gritty of actually building it. These days, building games is more popular than ever. Tools and services for making them are getting better, cheaper, and more accessible. However, if you are new to the trade it can be very daunting. You need a mix of artistic and technical talents to pull it off. First of all, it requires a mix of disciplines such as audio and visual art, programming, and game design all working together. Many new studios are starting without the benefit of experience, and the various challenges of game development can make that first project difficult to ship. The key is to adopt a series of steps and the discipline to follow them that helps mitigate potential problems. This is called a workflow. In your travels, you will also hear the word "pipeline", which I will use interchangeably with workflow for the purpose of this blog. ![Level Building Production Pipeline](/blog-images/workflow-pipeline.png) ## So then, where do you start? ## Design and Prototyping The initial stages of game development are design and prototyping, also known as the concept and pre-production phases. Design is where you define the game rules, gameplay, theme, art style, and control schemes. This stage is dominated by activities such as creating concept art, defining pacing and mechanics, story-boarding and level mapping. Design is really meant to give the team an understanding of the project goals, theme, and what gameplay should look and feel like. Prototyping is where you make a minimal mock-up of the gameplay and game rules to make sure they fundamentally work. Many larger studios use minimal art assets to build the initial prototype. They use stock or previously used models. Very few, if any, textures and placeholder sounds are used as needed. This stage of development has several names: white boxing, grey boxing, blue boxing – they all refer to the same activity: performing a rough sketch of your game. You will spend some time writing rough core mechanic code, seeing if the basics of the game's design are fun, playing through your prototype, and using what you learn to refine your design. ![Greyboxed Level](/blog-images/workflow-greybox.jpg) The idea behind prototyping is not to make a polished product, to have every game feature, or to have something shippable. Its purpose is to 'find the fun' as Clinton Keith would say in his book "Agile Game Development with Scrum". You want to make sure that concepts set out in the design phase make sense and come together to make a truly fun and playable game. You want to discover this early on in development so that you can iterate early rather than being forced to refactor major pieces of your game to fix fundamental design issues. There are tools that can speed up the prototyping phase. We mentioned several of these in our other blog. However, in a lot of cases you may not need to use extra paid tools. Often the basic shapes and default assets that ship with game engines suffice. Again, at this point it is more about identifying the core aspects of the game than making something polished. It's likely your team will want to continue to use and refine some of the code generated during the prototyping phase. Source code tools such as Git and Perforce are critical to tracking these changes and ensuring you keep a historical account of all your changes as they are made. These tools allow you to try different algorithms and implementations with the safety of being able to roll back to previous working versions should you decide that a change does not work out. It is a good idea to start using these tools as soon as you start programming in your project. In game development, tools like Perforce have a distinct advantage in that they have the capability of storing and versioning game assets as well as source code. More on why that is important later. Prototyping is a task primarily left to programmers and game designers but communication with the art team is also very important. As prototyping progresses, the design team will start to gather critical prerequisites for specific gameplay mechanics and level design features. It is critical to involve the art team in the process early so that look-and-feel can be discussed and an understanding of the scope of art can begin to form. While the look-and-feel is fine-tuned, artists will continue to create concept art and work with level designers to understand the visual flow of the game. Sound and music artists may be involved at this point, though often sound can come in at a later stage of development. Just like in programming, it is good to have a record of art assets and a good system to track revisions. The team will likely generate a lot of concept art and you will want to experiment with different looks, compositions, and color palettes. Many larger studios will use digital asset management tools (DAM) like Shotgun to track these assets. The creative director and lead artists use facilities within DAMs to provide feedback on which art should be pursued, changed, or cut. Full-feature DAM software can be expensive, and many small studios will opt for a cheaper solution. Free, open-source alternatives such as ResourceSpace could be adapted to your needs, though they often require some set-up and maintenance, and would likely be lacking in features. As prototyping progresses, you will eventually reach a point where you are happy with gameplay and your current level designs. In many cases this doesn't occur on a game-wide scale, but instead for chunks of your game such as a few of the first levels or your core gameplay mechanics. Once you reach this point you can now enter production and the main phase of your project: Building your game. ## The Vertical Slice Sometimes when nearing the mid to end point of pre-production, something called a 'vertical slice' will be created. The vertical slice is essentially a small part of the game that is taken through an accelerated development cycle from beginning to end. The purpose of building a vertical slice is to have a better grasp of everything that needs to be considered throughout the entire production pipeline. It helps identify potential technical issues up front, gives the team and potential stakeholders a preview into what their final game will look like, and also greatly helps with task estimation. A later part of this blog will cover task estimation in more depth, but for now just remember that because the vertical slice is more or less representative of the ongoing production process, it gives producers and project managers a way to understand how long things will take. Creating a vertical slice doesn't always make sense, but for games with a high level of complexity and scope, it can make a lot of sense. Ideally the vertical slice should be a piece of the game that will be repeatedly created throughout production. This could mean it's a level, or a location, or some other small piece of the game that there will be many of. If it's not a part of the game that will need to be repeatedly created throughout production, then the vertical slice will not provide as much useful information. In this case it becomes more of a rush to complete a feature than it is to understand the production process further. This blog will continue in part 2, where we will cover production and post-production workflows. --- ## Data Compression: Bit-Packing 101 URL: https://www.kinematicsoup.com/blog/data-compression-bit-packing-101 Date: 2016-09-06 Summary: The simplest data compression technique explained: bit-packing. How to minimize the bits needed to store each value and reduce data size by 30%+ with a few lines of C#. Data compression is fundamental to modern computing, though poorly understood by most users. We utilize compression tools like 7-zip and gzip routinely, often reducing file sizes to 30% or less of their originals. Gaming heavily relies on compression for images, textures, geometry, and video assets. This ensures rapid loading and efficient storage, while enabling game state serialization into UDP packets for multiplayer networking. Sophisticated compression also powers collaborative tools like Scene Fusion, supporting features such as shared terrain editing with minimal bandwidth. The fundamental compression principle is: Don't store bits of data unless you absolutely need them. Bit-packing represents the simplest compression form developers have employed for decades. The concept is straightforward: utilize minimal bits for storing data. When executed properly, significant size reductions occur. The dataset demonstrates that 68.8% of values can be stored using 16 bits or less. While separating values by size is possible when order is irrelevant, preserving sequence requires alternative strategies. ## BitStreamReader and BitStreamWriter Implementation The foundation requires classes enabling bit-level stream operations. Here is the C# implementation: ```csharp using System.IO; namespace BitPackingExamples { class BitStreamWriter { private int bitsInBuffer = 0; private byte[] buffer = new byte[1]; public BitStreamWriter() { // clear the buffer buffer[0] = 0x00; } public int WriteBits(uint inputBits, int numBits, Stream outputStream) { if (numBits > 32) numBits = 32; int bitsWritten = 0; for (int i = 0; i < numBits; i++) { uint bit = (inputBits >> i) & 0x00000001; WriteToBuffer(bit, outputStream); bitsWritten++; } return bitsWritten; } public void WriteFlush(Stream outputStream) { if (bitsInBuffer != 0) { outputStream.Write(buffer, 0, 1); } buffer[0] = 0; bitsInBuffer = 0; } private void WriteToBuffer(uint bit, Stream outputStream) { if (bitsInBuffer == 8) WriteFlush(outputStream); if (bit != 0) // only write 1 bits. buffer is initialized to 0 buffer[0] |= (byte)(bit << bitsInBuffer); bitsInBuffer++; } } class BitStreamReader { private int bitsInBuffer = 0; private byte[] buffer = new byte[1]; public uint ReadBits(int numBits, Stream inputStream) { uint bits = 0; for (int i = 0; i 0) { uint value = (uint)(buffer[0] >> (8 -bitsInBuffer)) & 1; bitsInBuffer--; return value; } return 0; } } } ``` These classes enable reading and writing individual bits to streams like FileStream or MemoryStream, providing essential tools for compact data encoding. ## Simple Single-Bit Header Approach The simplest method employs a 1-bit header preceding a fixed number of value bits. The header functions as follows: a set bit (1) indicates 16-bit encoding, while an unset bit (0) indicates 32-bit encoding. This expands 32-bit values to 33 bits but reduces smaller values by 15 bits. For the sample dataset: 4×33 + 11×17 = 319 bits (approximately 40 bytes), achieving 33% compression. ```csharp // here are the values we want to compress static uint[] values = { 0x0000FDEE, 0x000000A1, 0x0000EF2F, 0x02A3120E, 0x00001147, 0x000000F1, 0x00000907, 0x000013F7, 0x000003A3, 0x00000407, 0x00000067, 0x0000F25A, 0x0041FB7E, 0x075B1C78, 0x0CCC20D6 }; // simple 1-bit header for a single division static void Example1_SimplePack() { const int MAX_BITS = 28; const int MIN_BITS = 16; MemoryStream packedData = new MemoryStream(); BitStreamWriter bitWriter = new BitStreamWriter(); // bit packing the values: // bit header 1, then value bits = 16, bit header 0, value bits = 32 foreach (uint v in values) { uint size = CountBits(v); // if there are 16 bits or fewer, write only 16+1 bits if (size <= MIN_BITS) { bitWriter.WriteBits(1, 1, packedData); bitWriter.WriteBits(v, MIN_BITS, packedData); } else { bitWriter.WriteBits(0, 1, packedData); bitWriter.WriteBits(v, MAX_BITS, packedData); } } bitWriter.WriteFlush(packedData); Console.WriteLine("Original size = {0}, packed size = {1}", values.Length * sizeof(uint), packedData.Length); // now read the data back // // rewind our stream so we can read it back packedData.Seek(0, SeekOrigin.Begin); BitStreamReader bitReader = new BitStreamReader(); uint[] output = new uint[values.Length]; for (int i = 0; i < output.Length; ++i) { uint header = bitReader.ReadBits(1, packedData); switch (header) { case 1: output[i] = bitReader.ReadBits(MIN_BITS, packedData); break; case 0: output[i] = bitReader.ReadBits(MAX_BITS, packedData); break; } if (output[i] == values[i]) Console.WriteLine("Position {0} matches!", i); } } ``` Single-bit headers work effectively when compression gains exceed the 1-bit overhead added per value. Division point selection significantly impacts results. ![Bit representation before packing](/blog-images/bit-packing-1.png) ## Multi-Level Variable-Length Headers More aggressive compression employs variable-length headers supporting multiple value sizes: - 1-bit value (1) indicates smallest size - 2-bit value (01) indicates medium size - 2-bit value (00) indicates largest size This "escapement" scheme uses the initial bit as a flag for additional information. Testing with 32-bit, 16-bit, and 13-bit divisions yields 38-byte compression while supporting full 32-bit values. ```csharp // length range where bits <= 16 static void Example2_2Divisions() { MemoryStream packedData = new MemoryStream(); BitStreamWriter bitWriter = new BitStreamWriter(); const int MAX_BITS = 32; const int MED_BITS = 16; const int MIN_BITS = 13; // let's pack them into a stream! foreach (uint v in values) { uint size = CountBits(v); // if there are 16 bits or fewer, write only 16+1 bits if (size <= MED_BITS) { if (size <= MIN_BITS) { bitWriter.WriteBits(1, 1, packedData); bitWriter.WriteBits(v, MIN_BITS, packedData); } else { bitWriter.WriteBits(2, 2, packedData); bitWriter.WriteBits(v, MED_BITS, packedData); } } else { bitWriter.WriteBits(0, 2, packedData); bitWriter.WriteBits(v, MAX_BITS, packedData); } } bitWriter.WriteFlush(packedData); Console.WriteLine("Original size = {0}, packed size = {1}", values.Length * sizeof(uint), packedData.Length); // now read the data back // // rewind our stream so we can read it back packedData.Seek(0, SeekOrigin.Begin); BitStreamReader bitReader = new BitStreamReader(); uint[] output = new uint[values.Length]; for (int i = 0; i < output.Length; ++i) { uint header = bitReader.ReadBits(1, packedData); switch (header) { case 1: output[i] = bitReader.ReadBits(MIN_BITS, packedData); break; // if the bit is 0, there is a second bit with length subsections case 0: uint secondBit = bitReader.ReadBits(1, packedData); if (secondBit == 0) output[i] = bitReader.ReadBits(MAX_BITS, packedData); else output[i] = bitReader.ReadBits(MED_BITS, packedData); break; } if (output[i] == values[i]) Console.WriteLine("Position {0} matches!", i); } } ``` ## Explicit Bit-Count Headers An alternative approach encodes a 5-bit header specifying the exact bit count, followed by that many value bits. While less efficient for this particular dataset (39 bytes), this method offers flexibility for datasets with numerous small values. ```csharp // We could just explicitly write the total number of bits prior to each value, so each header is 5 bits, // but then the value is perfectly packed every time static void Example3_ExplicitHeaders() { MemoryStream packedData = new MemoryStream(); BitStreamWriter bitWriter = new BitStreamWriter(); // packing foreach (uint v in values) { uint header = CountBits(v); bitWriter.WriteBits(header, 5, packedData); bitWriter.WriteBits(v, (int)header, packedData); } bitWriter.WriteFlush(packedData); Console.WriteLine("Original size = {0}, packed size = {1}", values.Length * sizeof(uint), packedData.Length); // now read the data back // // rewind our stream so we can read it back packedData.Seek(0, SeekOrigin.Begin); BitStreamReader bitReader = new BitStreamReader(); uint[] output = new uint[values.Length]; for (int i = 0; i < output.Length; ++i) { uint header = bitReader.ReadBits(5, packedData); output[i] = bitReader.ReadBits((int)header, packedData); if (output[i] == values[i]) Console.WriteLine("Position {0} matches!", i); } } ``` ## Further Optimization Additional refinement involves making the most significant bit implicit rather than encoded. By storing remaining bits after the 5-bit length header, the example dataset compresses to 37 bytes (36.75 exactly). ![Memory layout comparison after packing](/blog-images/bit-packing-2.png) ## Conclusion Basic bit-packing requires tailoring encoding rules to your specific data distribution for optimal compression. Complete source and project files are available at https://github.com/ks-examples/BitPacking101. In the next post in this series, we look at entropy coding, a more advanced technique for achieving even greater compression ratios, with the possibility of packing 1 bit of data in less than 1 bit of memory. These are the same building blocks, bit-packing and the techniques layered on top of it, that our server-authoritative Unity multiplayer engine Reactor uses to keep per-object network updates small. The difference is that you do not write any of it. Reactor builds the data model from your game state and tunes the encoding automatically, which is how games on it run at [under a byte per transform](/blog/why-is-my-multiplayer-bandwidth-cost-so-high/). --- ## Timesteps and Achieving Smooth Motion in Unity URL: https://www.kinematicsoup.com/blog/timesteps-smooth-motion-unity Date: 2016-08-09 Summary: Why objects stutter in Unity and how to fix it: the relationship between Update and FixedUpdate, and how interpolation eliminates jitter. > **Editor's note (May 2026):** This article was published in August 2016. The conceptual explanation of Unity's semi-fixed timestep, the cause of motion stutter, and the interpolation-based remedy are all still accurate. However, Unity has shipped several features since publication that solve the common cases more directly than the custom scripts below. Before implementing the asset package, consider: > > - **[`Rigidbody.interpolation`](https://docs.unity3d.com/ScriptReference/Rigidbody-interpolation.html) / [`Rigidbody2D.interpolation`](https://docs.unity3d.com/ScriptReference/Rigidbody2D-interpolation.html).** Set to `Interpolate` (or `Extrapolate`) in the Inspector and Unity handles per-frame interpolation between physics steps automatically. This resolves stutter for most Rigidbody-driven objects without any of the scripts below. > - **[`LateUpdate`](https://docs.unity3d.com/ScriptReference/MonoBehaviour.LateUpdate.html).** For cameras following a moving target, moving the follow logic into `LateUpdate` (combined with an interpolated Rigidbody on the target) eliminates the camera/target stutter shown in the GIFs above. > - **[Cinemachine](https://docs.unity3d.com/Packages/com.unity.cinemachine@latest)** (released 2017). The modern Unity camera system exposes an `UpdateMethod` ([`FixedUpdate` / `LateUpdate` / `SmartUpdate`](https://docs.unity3d.com/Packages/com.unity.cinemachine@2.10/manual/CinemachineBrainProperties.html)) and a separate `BlendUpdateMethod`, designed specifically for this problem. > - **[Input System package](https://docs.unity3d.com/Manual/com.unity.inputsystem.html).** The old [`Input`](https://docs.unity3d.com/ScriptReference/Input.html) manager referenced in the input-buffering discussion has been superseded by the Input System, which uses event-based [Action callbacks](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.8/manual/Actions.html); buffering needs are different. > - **Standard Assets.** The first-person controller used as the reproduction example has been deprecated and removed from Unity. The current equivalents are the [**Starter Assets**](https://assetstore.unity.com/packages/essentials/starter-assets-character-controllers-urp-267961) (First Person / Third Person Controller) packages on the Asset Store. > > The custom interpolation scripts below are still useful for **non-Rigidbody objects you move manually in `FixedUpdate`** and for **deterministic / networked simulations** where you need explicit control. The asset package was built for an older Unity version and may need light updating for [Unity 6 LTS](https://unity.com/releases/unity-6). One of the most intensely debated topics in the Unity community is how to go about removing jerky movement from games, and rightfully so. The issue is universal to all engines, and is directly derived from what timesteps your engine uses. There is no single solution that works for every situation, but there are certainly sub-optimal practices. Many developers have encountered the issue of motion stutter at one point or another, but getting help can prove difficult. There is a surprising amount of misinformation out there regarding timesteps in Unity. Many answers on the Unity forums, while correct, aren't comprehensive and leave gaps in understanding needed to fully resolve the issue. This article aims to tackle the issue in more depth by explaining timesteps in Unity, where and why they can lead to stutter, and presenting a solution that helps resolve the issue. An asset package is provided, along with a demonstration of the solution. ![Eww! Is this type of stutter familiar?](/blog-images/timesteps-stutter.gif) The above image is a simple example of motion stutter in action. Clearly this is not behavior we want in our games. This is very easy to replicate yourself: 1. Create a new project 2. Import the default first person character controller and put it in a fresh scene 3. Place some objects and circle one of them. Removing the head bobbing and using a gamepad makes this effect easier to observe. In general, you should notice particularly bad stutter when moving while looking around. Now look at this case, where I've applied the techniques we will discuss later. Comparing the first example to the second, and you should see a significant difference in the smoothness. Prior to tackling the issue, it is important to understand Unity's update cycle. In particular, we need to examine the logic behind the Update and FixedUpdate methods. Below is a small excerpt from Unity's documentation on execution order found here: https://docs.unity3d.com/Manual/ExecutionOrder.html In particular, you'll want to examine the Update Order segment carefully if you have not before, as it is highly relevant for the remainder of this article. ![Unity Update Order](/blog-images/timesteps-update-order.jpg) This chart outlines the order that methods are called during a single frame in Unity. The parts we will focus on are the FixedUpdate and Update methods, highlighted in green and red respectively. Unity implements what is known as a semi-fixed timestep. That means the main game loop can run at any frame rate using a variable timestep, called deltaTime in Unity, and that manages an internal loop which uses fixed timesteps. This has some advantages; primarily, being able to run visual updates as fast as hardware permits, while locking the core game simulation to a constant rate. There are disadvantages though, including being prone to the aforementioned stutter. The following is a simplified representation of what Unity's update loop is probably structured like: ``` float currentSimulationTime = 0; float lastUpdateTime = 0; while (!quit) // variable steps { while (currentSimulationTime < Time.time) // fixed steps { FixedUpdate(); Physics.SimulationStep(currentState, Time.fixedDeltaTime); currentSimulationTime += Time.fixedDeltaTime; } Time.deltaTime = Time.time - lastUpdateTime; Update(); Render(); lastUpdateTime = Time.time; } ``` The Update method is likely familiar to you already. It is called on Monobehaviors every frame just after inputs are processed by Unity and before the screen is rendered. If VSync is disabled, when one frame is completed, Unity will immediately start on the next one, therefore attaining the highest possible framerate. Since hardware and the complexity of each frame varies, the frame rate is never constant. Even with VSync enabled, causing Unity to try to match a specific frame rate, it is not truly constant. Because of this, Update can be called any number of times per second. FixedUpdate is called on Monobehaviors each time the physics simulation is progressed. Unity treats these calls as if they are a fixed time apart, even though in actual time multiple simulation steps are not calculated at even time intervals. This is done because game physics, in particular accelerated motion, is most accurate and stable given even delta times. That fixed timestep is known as fixedDeltaTime within Unity. By default it has a value of 0.02, meaning there are always 50 physics steps and FixedUpdate calls for every second of the game. In this way, one can think of FixedUpdate as frame rate independent as it is called the same number of times per second, even if the rendering frame rate is very low or high. It is necessary to stress that the FixedUpdate and physics loop is synchronous, and does not occur on a separate thread. At this point, let's observe some examples of update timings. ![Update Timings](/blog-images/timesteps-update-timings.png) Above is what the timings might look with 50 FixedUpdates and 60 frames per second. However, this is not perfectly achievable since frame rate varies, so a more realistic, though exaggerated, timeline is below. Notice how some frames are close together with no physics steps between them, which typically occurs when there is low rendering complexity. On the other hand, other updates have long pauses between them with numerous physics steps computed between each frame, which often happens when loading assets. This means that even if you try to match frame rate with the number of fixed steps, they are not guaranteed to be aligned. Using our knowledge of Unity's timesteps, we can now understand the case presented below. In this scene, there is a sphere and camera both orbiting a pivot. The sphere's transform is set in the Update loop, while the camera's transform is set in the FixedUpdate loop on the left, and Update on the right. The left side has obvious stuttering, while the right remains smooth. ![Camera moves in FixedUpdate on the left, Update on the right.](/blog-images/timesteps-fixedupdate-vs-update.gif) Because Update is called at a different rate than FixedUpdate, the sphere often moves while the camera remains still. This causes the sphere to move inconsistently relative to the camera, creating the stutter. Slowing things down, that behavior can be observed. ![Same example as above, 5% speed.](/blog-images/timesteps-2.gif) So, we can see the root cause of this stutter is moving some objects in Update and others in FixedUpdate. The simple fix is indeed to move all transforms in either Update or FixedUpdate. However, this is where things get tricky. The common answer found among Unity developers is to put most game and movement logic in Update and use FixedUpdate only for the occasional physics task. While this has merits, including simplicity of use, it is problematic for many reasons. Perhaps most important is that your gameplay is frame rate dependent. This opens the door for plenty of gameplay affecting bugs and inconsistent behavior. Furthermore, it prevents determinism, which almost the entire real time strategy genre, for example, depends on. It also introduces problems when you need accelerated motion for an object, such as a character controller's gravity. For those objects FixedUpdate should be used, but since other objects are moved in Update you'll get stutter (see the standard assets first person character controller to observe this exact issue). Therefore, a common and sometimes necessary alternative is to put all state and gameplay logic in a fixed timestep like FixedUpdate and strictly handle visuals and input logic in Update. This is not without its own challenges however. First off, you may want your physics steps to occur at a different rate from game logic ticks depending on your game. That can be resolved by implementing your own fixed timestep loop independent of FixedUpdate that ticks at whatever rate you wish. This is fairly simple to do and can give you a lot of control, allowing for fine tuned optimization. Next, inputs can be missed when read only in FixedUpdate, since multiple frames could occur between FixedUpdates, and only the last frame's input survives to the following FixedUpdate. This particularly affects button up and down events, as they are only active for a single frame. The solution to this issue is buffering inputs by storing them each frame until they are all processed during the next FixedUpdate. Integrating this behaviour into whatever input controller you use is a fairly seamless way to do this and keeps the buffering in one place. One larger issue, however, is that FixedUpdate is typically called less than the client frame rate, so moving objects don't update their position as frequently as the screen is rendered. This makes the game somewhat choppy, though consistent. There are various ways to resolve this centering around using interpolation and extrapolation to fill the frames between FixedUpdates, smoothing the movement out. Interpolation, moving an object smoothly from one game state to the following state, is convenient in that it can be applied to most objects and work easily, but does introduce a fixedDeltaTime worth of latency. This latency is generally accepted however, and plenty of games, even twitch shooters and such, allow for this delay to gain smoothness. Extrapolation, predicting where an object will be next fixed step, avoids latency, but is inherently more difficult to get working seamlessly and comes with a performance cost. ![Camera and sphere moving in FixedUpdate, using interpolation on the right side only.](/blog-images/timesteps-interpolation.gif) Above is another comparison to demonstrate interpolation. On the left side, both the camera and sphere have their transform set in FixedUpdate. The right side is the same, but with interpolation moving the transforms smoothly between FixedUpdate steps. Notice how both objects remain aligned in either case, but on the right side the more frequent transform updates reduce stutter. So, how might this interpolation be done within Unity? I've made an asset package containing a setup similar to what I've used in the past which you can get here. The setup works based on three scripts, found under the "Assets / Scripts / FixedInterpolation" directory after importing the package. Those scripts are fully commented, but more compact versions are provided here with a brief description below. **1. InterpolationController** - Stores the timestamps of the two most recent fixed steps, and by comparing them against the time during Update generates a global interpolation factor. The script must be attached to a single gameobject in the scene. ```csharp using UnityEngine; using System.Collections; public class InterpolationController : MonoBehaviour { private float[] m_lastFixedUpdateTimes; private int m_newTimeIndex; private static float m_interpolationFactor; public static float InterpolationFactor { get { return m_interpolationFactor; } } public void Start() { m_lastFixedUpdateTimes = new float[2]; m_newTimeIndex = 0; } public void FixedUpdate() { m_newTimeIndex = OldTimeIndex(); m_lastFixedUpdateTimes[m_newTimeIndex] = Time.fixedTime; } public void Update() { float newerTime = m_lastFixedUpdateTimes[m_newTimeIndex]; float olderTime = m_lastFixedUpdateTimes[OldTimeIndex()]; if (newerTime != olderTime) { m_interpolationFactor = (Time.time - newerTime) / (newerTime - olderTime); } else { m_interpolationFactor = 1; } } private int OldTimeIndex() { return (m_newTimeIndex == 0 ? 1 : 0); } } ``` **2. InterpolatedTransform** - Stores the transforms for an object after the two most recent fixed steps, and interpolates the object between them using the global interpolation factor. It also ensures that the object is placed back where it was last fixed step before the current fixed step executes, instead of where it was interpolated to last. This means that any scripts moving the transform are working from the correct state. If you teleport an object and want to prevent interpolation, call the ForgetPreviousTransforms method after moving the object. This script should be attached to any objects moved during a FixedUpdate. ```csharp using UnityEngine; using System.Collections; [RequireComponent(typeof(InterpolatedTransformUpdater))] public class InterpolatedTransform : MonoBehaviour { private TransformData[] m_lastTransforms; private int m_newTransformIndex; void OnEnable() { ForgetPreviousTransforms(); } public void ForgetPreviousTransforms() { m_lastTransforms = new TransformData[2]; TransformData t = new TransformData( transform.localPosition, transform.localRotation, transform.localScale); m_lastTransforms[0] = t; m_lastTransforms[1] = t; m_newTransformIndex = 0; } void FixedUpdate() { TransformData newestTransform = m_lastTransforms[m_newTransformIndex]; transform.localPosition = newestTransform.position; transform.localRotation = newestTransform.rotation; transform.localScale = newestTransform.scale; } public void LateFixedUpdate() { m_newTransformIndex = OldTransformIndex(); m_lastTransforms[m_newTransformIndex] = new TransformData( transform.localPosition, transform.localRotation, transform.localScale); } void Update() { TransformData newestTransform = m_lastTransforms[m_newTransformIndex]; TransformData olderTransform = m_lastTransforms[OldTransformIndex()]; transform.localPosition = Vector3.Lerp( olderTransform.position, newestTransform.position, InterpolationController.InterpolationFactor); transform.localRotation = Quaternion.Slerp( olderTransform.rotation, newestTransform.rotation, InterpolationController.InterpolationFactor); transform.localScale = Vector3.Lerp( olderTransform.scale, newestTransform.scale, InterpolationController.InterpolationFactor); } private int OldTransformIndex() { return (m_newTransformIndex == 0 ? 1 : 0); } private struct TransformData { public Vector3 position; public Quaternion rotation; public Vector3 scale; public TransformData(Vector3 position, Quaternion rotation, Vector3 scale) { this.position = position; this.rotation = rotation; this.scale = scale; } } } ``` **3. InterpolatedTransformUpdater** - Used to call a couple methods in InterpolatedTransform both before and after other script's FixedUpdates. Must be placed on objects that also have InterpolatedTransform attached. ```csharp using UnityEngine; using System.Collections; public class InterpolatedTransformUpdater : MonoBehaviour { private InterpolatedTransform m_interpolatedTransform; void Awake() { m_interpolatedTransform = GetComponent(); } void FixedUpdate() { m_interpolatedTransform.LateFixedUpdate(); } } ``` ![The required execution order.](/blog-images/timesteps-4.png) For these scripts to work, the execution order must be specified as above. As well, any objects with InterpolatedTransform attached must only be moved in a FixedUpdate, as any transformations made in Update will override the interpolation. Additionally, you should make sure that you buffer any inputs where necessary. While there are numerous ways you can do this, a good solution is to build input buffering into your own input controller, reducing complexity elsewhere. Finally, keep in mind that while this simple setup is surprisingly functional, there are many improvements that could be made for a production ready system, such as extrapolation. In conclusion, put all your game logic in either Update or FixedUpdate. Do not mix and match timesteps unless you are willing to bite the bullet and accept some stutter. Additionally, it is strongly worth considering putting all game state in FixedUpdate, using Update exclusively for user input, visual effects, and interpolation between game states. While this requires a change how you structure your games, it is a proven design structure with many advantages. ## When the same problem goes multiplayer Everything above is the local version of the problem: keeping motion smooth when your render rate and your simulation rate disagree. Put that same motion across a network and it gets harder. Now you are interpolating between state updates that arrive late, out of order, and less often than you render, while the authoritative copy of the game lives on a server. The techniques are from the same family (interpolation, prediction, reconciliation), just applied to networked state. If you get to that point, our Unity multiplayer engine Reactor has them built in, so you are not rebuilding this layer by hand on top of the network. ## Recommended Reading **More on variable, fixed, and semi-fixed timesteps:** * https://gafferongames.com/post/fix_your_timestep/ * http://www.koonsolo.com/news/dewitters-gameloop/ **A case where placing all game state information in fixed timesteps only is necessary:** * https://www.forrestthewoods.com/blog/synchronous-rts-engines-and-a-tale-of-desyncs/ **Unity docs:** * https://docs.unity3d.com/Manual/ExecutionOrder.html Written by Scott Sewell, developer at KinematicSoup --- ## An Alternative to Scene Merging URL: https://www.kinematicsoup.com/blog/an-alternative-to-scene-merging Date: 2016-07-22 Summary: Why traditional Unity scene merging is painful: conflicts, lost work, and limited collaboration, and how real-time multi-user editing solves all three. ## Problems with Traditional Scene Merging The article identifies three main issues with conventional scene merging using tools like UnityYAMLMerge: 1. **Technical limitations** - Conflicts between scenes can cause corruptions during merging, often requiring significant manual work. In worst cases, team members' work may be lost completely. 2. **Special source control considerations** - While not overly difficult, integrating Unity's scene merging tool requires platform changes and additional team training. 3. **Limited collaboration** - Real-time awareness of teammates' work is restricted. Reviews often get postponed until substantial progress is made, potentially leading to costly late-stage revisions. ## Scene Fusion as an Alternative Scene Fusion enables real-time collaborative editing by allowing multiple people to connect to a scene simultaneously and observe others' work as it happens. Once editing concludes, the scene is saved with everyone's changes and committed to source control. This approach addresses the previous issues by: eliminating the need for scene merging entirely, maintaining standard source control workflows without special considerations, and enabling immediate feedback and collaborative decision-making among team members regardless of location. --- ## Gamma and Linear Space - What They Are and How They Differ URL: https://www.kinematicsoup.com/blog/gamma-and-linear-space-what-they-are-how-they-differ Date: 2016-06-15 Summary: Linear space lighting explained for game developers: what gamma correction is, why it matters for physically based rendering, and how to configure it in Unity. ## Linear Space Linear color space means that numerical intensity values correspond proportionally to their perceived intensity. This enables proper color addition and multiplication. Non-linear spaces lack this property. The article illustrates this with an example: doubling intensity in linear space produces correct numerical values, but in non-linear space (gamma = 0.45), simple doubling fails to achieve the desired result. ![Doubling the intensity of a dark grey square in linear vs. non-linear space](/blog-images/gamma-linear-comparison.jpg) ## Gamma Space Gamma correction addresses two issues: screens have non-linear intensity responses, and human eyes distinguish dark shades better than light ones. The correction applies a power function to pixel intensity, with gamma representing the exponent value. ![A graph of pow(x, gamma)](/blog-images/gamma-power-graph.jpg) Most images store gamma of 0.45, compressing bright ranges while expanding dark ranges for better detail preservation. Neutral grey becomes 0.73 numerically rather than 0.5. CRT screens naturally apply gamma 2.2 (the reciprocal), which reverses the stored correction during display, showing properly adjusted images. ![Two common gamma values applied to an image](/blog-images/gamma-values.jpg) ## Color Spaces and Rendering Pipeline The gamma pipeline passes gamma-corrected textures through shaders for lighting calculation, then outputs to displays for gamma adjustment. However, this approach lacks physical accuracy since real light behaves linearly. Modern practice favors linear pipelines: textures undergo gamma removal before shading, calculations occur in linear space, post-effects process in linear space, then final output receives gamma correction for display. The linear approach produces brighter specular highlight and stronger falloff compared to gamma rendering, supporting photorealistic results. ![A comparison of gamma and linear rendering pipelines](/blog-images/gamma-pipeline.jpg) ## Color Spaces in Unity Unity defaults to gamma space on most platforms but supports linear rendering on PC, Xbox, and PlayStation. Users can switch via Edit → Project Settings → Player → Other Settings → Color Space. When linear space is enabled with HDR, Unity performs post-effects in full linear space automatically. Without HDR, Unity uses gamma framebuffers but automatically converts values during reads and writes. Mobile platforms require manual implementation using pow() functions in shaders to convert between spaces, though this increases computational cost. ## Conclusion Understanding gamma and linear space fundamentals prevents color management mistakes. Properly implemented linear rendering pipelines support immersive, realistic game worlds. --- ## Using the Command Line Toolset to Run Unity Tests URL: https://www.kinematicsoup.com/blog/using-the-command-line-toolset-to-run-unity-tests Date: 2016-06-08 Summary: How to use Unity's command line toolset to automate builds and unit tests, including custom method invocation and headless Linux setup with xvfb. In the game development cycle, Quality Assurance and testing can be tedious and time consuming. Because of this, these tasks are all too often delayed for small studios. Things like critical bug fixes or new features typically take a higher priority and time is not consistently spent on automated testing solutions. That said, every so often a bug gets leaked into a release or a mysterious compile error crops up in the main code repository, making the need for testing clear again. To mitigate these risks, teams will typically perform unit testing with tools like nUnit or Google Test. However, additional steps are required to execute Unity specific code and tests through an automated process. Having a programmatic way of integrating testing tools with Unity can benefit teams greatly by offloading repetitive tasks like build releases or running unit tests on an automated system. Luckily Unity has an often overlooked feature: its command line toolset. This is available on all supported Unity editor platforms, including the Unity Linux beta. By using the command line toolset, teams can automate events like builds and unit testing. For our team at KinematicSoup, we chose to use Unity's command line as it provided us with the flexibility we needed. In our case, when we learned that Unity for Linux supported the command line toolset, we wanted to be able to migrate our deployment and build systems to Linux. To do this, we needed the Windows deployment and asset bundle builder tools we built for our current system to work on Linux in the future. The command line toolset in Unity allowed us to do this, and here's how: ## Using Command Line methods The basic format of invoking Unity command line methods is to call the Unity editor application followed by the command line options: "/Unity.exe ". In order to do this you will need to know the paths of the installation locations for Unity. The default Unity install locations for Windows, Mac and Linux are as follows: - Windows: C:\Program Files\Unity\Editor\Unity.exe - OSX: /Applications/Unity/Unity.app/Contents/MacOS/Unity - Linux: /opt/Unity/Editor/Unity Before we discuss how to run custom classes and methods through the command line, let's briefly review the built in Unity command line options. The built in functions allow you to do things like build an asset package or build a targeted release. The following list is an excerpt from the full documentation. - `-batchmode` - this should always be present when calling Unity from the command line, it lets Unity know not to open pop ups. - `-nographics` - tells Unity to not load any GUI or windows. Unfortunately Unity will still load the Direct X frameworks which will throw errors on systems without graphics capabilities. For example, a headless Linux build machine. We will discuss a work around for this later in the blog. - `-projectPath ` - opens the Unity project at the specified path. This will likely also be used every time. - `-logFile ` - Unity will redirect the log output to this file. This is really useful for builds and debugging. - `-buildWindows64Player ` - builds a win64 version of your project. - `-importPackage ` - imports the package at the given location. - `-exportPackage ` - exports the assets at into an asset bundle at the location and name of . ## Invoking Custom Methods The Unity command line functions are often not enough to complete required tasks, which is where the ability to invoke custom methods becomes very helpful. The syntax to call a custom Unity method is as follows: `/unity.exe ... -projectPath -exit -batchmode -executeMethod ` Where parameter1 through parameterN are strings to pass into your Unity method. This can be used to call a public static method where the script is saved in an "Editor" folder (resides in a folder in the assets directory with the name "Editor"). Below is an example of a generic C# class that could be called from the command line. ```csharp using UnityEngine; using UnityEditor; using System; Namespace myNameSpace { class myClass { Public static void myMethod() { string[] params; params = Environment.GetCommandLineArgs(); //DO SOMETHING EditorApplication.Exit(0); } } } ``` In order to parse the command line parameters that are passed in, the Unity class will need to use the query Environment.GetCommandLineArgs(), which will return a string array of arguments. From here you can do whatever is needed, whether making a web request or incrementing a build. ## Special Notes on building with Headless Systems When running Unity on a headless system you will need some sort of virtual frame buffer. As previously mentioned, the -nographics option will prevent any windows from loading but still loads the DX11 environment. On Linux the fix is quite simple, just use the xvfb package (on Ubuntu open a console and run "sudo apt-get install xvfb") then append xvfb-run in front of your Unity command. For example: `xvfb-run ../unity/Editor/unity…` This should give you a basic idea of how to use the Unity command line interface and how it can be used integrate automated tests with Unity. As your team grows, more rigorous testing will be a vital part of ensuring smooth production. Utilizing automated testing can greatly decrease the time it takes to test your software, and provides a tool that can be used consistently throughout development. Interfacing these tests with the Unity platform takes this one step further and gives your tests the flexibility and adaptability required for modern game development. Written by Bob Cao, developer at KinematicSoup. --- ## Unity Development Tools that Help Create Games Faster URL: https://www.kinematicsoup.com/blog/unity-development-tools-that-help-create-games-faster Date: 2016-05-06 Summary: A roundup of Unity Asset Store tools across visual scripting, world creation, and audio that help studios reduce development time and ship faster. In an industry flooded with competition on every level from indie to AAA, creating better games and doing so quickly has become extremely important. Not only do developers need to concern themselves with the quality of their game, but in many cases company longevity can be based upon how quickly they can bring great games to market. There are some amazing tools for Unity that can give studios the speed and efficiency boost they need to reduce development time and remain competitive. Here at KinematicSoup, we decided to compile a list of must have tool types and provided some examples of each. We only picked a couple of tools from the Unity asset store for each category, but there are many other amazing tools that could be mentioned. Note that these tools are not mentioned in any particular order and we are not endorsing them over any other tools on the Asset store. Prices were all accurate at the time we wrote the article but may have changed since. ## Visual Scripting **Playmaker, Publisher: Hutong Games LLC** Playmaker is a visual scripting solution for Unity3d. The tool provides value to users throughout the development process by providing an easy to use alternative to coding. Using Playmaker, teams can prototype and iterate much faster at every stage of development. Price: $65 **Behavior Designer, Publisher: Opsive** Behavior Designer implements a highly efficient visual behavior tree system into Unity. It allows teams to build complex AI behavior without having to write much, if any, code. This tool has the potential to greatly reduce time spent on creating AI while still enabling highly complex functionality. Price: $75 **FlowCanvas Visual Scripting, Publisher: Paradox Notion** FlowCanvas is another visual scripting solution, employing a very intuitive and user friendly interface. Users coming over to Unity with prior Unreal Engine experience will feel very comfortable using this system. Price: $65 ## World Creation **Gaia, Publisher: Procedural Worlds** Gaia is a terrain creation tool that helps developers create beautiful landscapes, quickly. Supporting both procedural and manual generation helps teams build highly unique scenes quickly and easily. Landscape creation and population is typically a time consuming process, meaning development teams stand to greatly benefit from this tool. Price: $39.99 **ProBuilder Advanced, Publisher: ProCore** ProBuilder allows users to build geometry, directly in Unity. This is highly valuable from a prototyping standpoint as developers can change and playtest new geometry immediately. Not only does this reduce time from an asset creation standpoint, but also supports highly iterative design. Price: $95 (ProCore also offers a free version called ProBuilder Basic) **DunGen, Publisher: Aegon Games Ltd.** DunGen allows users to procedurally generate dungeon layouts by piecing together rooms they have created in Unity. The tool is very flexible, allowing customization of dungeon flow and object spawning to fit any game. Price: $75 ## World Building Efficiency **ProGrids 2, Publisher: ProCore** ProGrids displays a grid within the unity editor that snaps to all three axes. While the grid is enabled, users are able to snap objects to locations very easily and accurately, speeding up level creation workflow and design precision. The tool also includes many settings to let developers use the grid in a way that works best for their team. Price: $20 **Easy Scatter, Publisher: Hedgehog Team** Easy Scatter lets users paint mesh objects or prefabs to terrain instead of having to drag them into the scene and manually place them. The tool can paint on terrain and meshes and does so according to their colliders, enabling fast asset placement in a scene with minimal manual adjustments. Price: $10 **QuickDecals 2, Publisher: ProCore** QuickDecals is an easy to use decal placement system. This tool takes a lot of time out of adding decals to a scene and helps developers make their scenes come to life very quickly. The tool also supports Atlases and multi-decal randomizing to maximize usability. Price: $10 **Simple LOD, Publisher: Orbcreation** Simple LOD takes what is normally a difficult and complex task and makes it extremely easy. By reducing triangles, combining meshes and baking texture atlases, SimpleLOD can significantly reduce draw calls and make very efficient LODs. The adjustable compression level allows users to ensure their LODs are made to fit their game. Price: $30 ## Audio **Everloop, Publisher: Dustyroom** Everloop is a system that provides procedural generation of music from a base of 18 loop-able music layers. Because all of these tracks will play seamlessly regardless of their order, or how many of them are played at once, it becomes easy to create great music on the fly based on game events or areas. Price: $14.50 We hope that you found this article helpful. There are many tools for the Unity engine and this list only scratches the surface. At the end of the day our team's goal is to help game developers build better games, faster. --- ## KinematicSoup is named a Top 25 Up and Coming company URL: https://www.kinematicsoup.com/blog/kinematicsoup-is-named-a-top-25-up-and-coming-company Date: 2016-04-26 Summary: KinematicSoup has been named a Top 25 Up and Coming company in the annual Branham300 listing of tech companies in Canada. KinematicSoup has been named a Top 25 Up and Coming company in the annual Branham300 listing of tech companies in Canada. Founded in 2013, the company has since been at the forefront of tools development for game developers worldwide. KinematicSoup states that their goal is to make development more streamlined, flexible and accessible for game developers all over the world. Justin McMichael, CEO of KinematicSoup states: "Game developers are in need of tools and services that improve productivity. World building is the most significant activity in the game development cycle. Scene Fusion delivers real-time collaboration that significantly improves productivity for world building. Early adopters estimate that it is reducing their overall game development schedules by up to 33%." KinematicSoup is committed to creating tools and services for game developers that improves their productivity and enables them to deliver better experiences to their customers. "As we look ahead into this massively growing industry, we are excited to play a role in defining its success and enabling its developers." KinematicSoup Technologies Inc. aims to provide game developers with innovative tools to enhance collaboration, reduce development time and increase ROI. Their Scene Fusion platform is designed to deliver a high impact collaborative development environment within the Unity editor. --- ## Scene Fusion Interview with 80.lv URL: https://www.kinematicsoup.com/blog/scene-fusion-interview-with-80lv Date: 2016-04-26 Summary: KinematicSoup was interviewed by 80.lv about Scene Fusion's real-time collaboration capabilities for Unity developers. KinematicSoup was featured in an interview with [80.lv](https://80.lv), a leading resource for game development artists and developers, discussing Scene Fusion and real-time collaboration in Unity. *The original interview was published on 80.lv. Visit [80.lv](https://80.lv) to read the full feature.* --- ## Basic Level Creation Workflow with Scene Fusion URL: https://www.kinematicsoup.com/blog/basic-level-creation-workflow-with-scene-fusion Date: 2016-04-22 Summary: A walkthrough of the basic Scene Fusion workflow: hosting a session, collaborating in real-time, and committing back to source control. Scene Fusion is a tool that allows teams to collaboratively edit Unity scenes in real-time. This video gives an overview of the typical workflow when using the tool, regardless of which source control your team uses. The Scene Fusion beta is now available. Head over to SceneFusion.com to register and start building worlds faster. Scene Fusion operates as a scene sharing tool built for Unity. The system requires developers to create prefabs of elements they want to manage, as Scene Fusion replicates things in your scene that have Prefabs associated with them. The workflow begins with a developer hosting a scene after installing the asset package and logging in. Once hosted, teammates can join the session and populate scenes using the prefab list. You can do everything that you would normally do in scene editing. None of this will be unfamiliar. After collaborative editing concludes, the host can terminate the session by selecting leave, which removes the online session and disconnects teammates. The developer then saves and commits the scene normally. It's a very simple workflow and should work in with whatever workflow you have set up right now. --- ## Getting Started with Scene Fusion URL: https://www.kinematicsoup.com/blog/getting-started-with-scene-fusion Date: 2016-04-21 Summary: A step-by-step guide to setting up Scene Fusion and starting your first collaborative Unity session in about two minutes. Scene Fusion is a tool that we developed to help teams build worlds faster and more collaboratively. The system enables multiple users to edit a Unity scene simultaneously with real-time visibility of changes. We have put together a video to help guide you through this process: [Watch on YouTube](https://www.youtube.com/watch?v=JZh31_w1pPg) The setup process takes approximately two minutes. Here are the steps: 1. Visit scenefusion.com to sign up for the beta 2. Invite collaborators through the Scene Fusion Console (they must accept email invitations) 3. Download Scene Fusion from the console overview page 4. Install the package by double-clicking while Unity is open 5. Select Scene Fusion from the KS Reactor menu in Unity 6. Log in with your beta credentials 7. Start a Scene Fusion session within Unity 8. Collaborators must install and log in 9. Collaborators join the hosted session 10. Build scenes collaboratively 11. The host ends the session and saves normally --- ## Scene Fusion - Collaborative Unity Scene Editing URL: https://www.kinematicsoup.com/blog/scene-fusion-collaborative-unity-scene-editing Date: 2016-04-19 Summary: An introduction to Scene Fusion: real-time collaborative Unity scene editing that reduces world building times and lets teams work together from anywhere. Scene Fusion is a tool that allows teams to collaboratively edit scenes in real-time. With Scene Fusion, developers can work together on the same Unity scene regardless of location. This global and team oriented approach reduces world building times dramatically, allowing developers to launch their game sooner and with fewer resources. Teams don't need to worry about changing their current workflow or processes as Scene Fusion is an organic extension of Unity. This means that they can continue building worlds exactly as they did before, but faster, smarter and far more collaboratively. The Scene Fusion beta is now available. Head over to SceneFusion.com to register and start building worlds faster today. --- ## Using Scene Fusion Unity 3D Scene Collaboration Tool with Perforce - Tutorial URL: https://www.kinematicsoup.com/blog/scene-fusion-unity-3d-scene-collaboration-tool-perforce-workflow Date: 2016-04-12 Summary: A step-by-step tutorial for using Scene Fusion alongside Perforce: check out, collaborate in real-time, and submit your scene when done. Scene Fusion is a tool that allows teams to collaboratively edit Unity scenes in real-time. Scene Fusion is built to work with your existing source control solutions. In this video we show the typical workflow for using Perforce with Scene Fusion: Step 1: In Perforce, check out the Unity scene file that your team will be working on. Step 2: Start your Scene Fusion session in Unity. Step 3: Have your team join the Scene Fusion session. Step 4: Edit your Unity scene collaboratively. You can get new prefabs your team has created from Perforce while running Scene Fusion. To do this, ensure your team has pushed the prefabs to Perforce and then get the latest revision. These prefabs will now be added to your Unity scene. Step 5: Once your team has finished editing the scene, stop the Scene Fusion session. Step 6: Save your scene. Step 7: Submit your scene to the Perforce depot. Now, the next time a user gets the latest project revision from Perforce they will have the new scene. --- ## Tools are Changing the Landscape of Game Development URL: https://www.kinematicsoup.com/blog/tools-are-changing-the-landscape-of-game-development Date: 2016-04-06 Summary: How modern tools are enabling smaller studios to compete, and why speed to market and operational efficiency are now as important as the game itself. KinematicSoup began developing multiplayer systems but pivoted to creating production tools. Their mission centers on boosting team productivity through solutions like Scene Fusion, which facilitates real-time multi-user world building in Unity. The company recognized that game development requires diverse disciplines collaborating effectively. While programmers prefer minimal disruptions during work, artists and world builders benefit from simultaneous collaboration. Existing tools favor the former approach, prompting KinematicSoup to develop alternatives that integrate smoothly with current workflows. Game development presents unique challenges. New studios often lack formal processes and project management experience. Success requires either established intellectual property, studio reputation, or prior achievements, barriers that are lowering as development tools proliferate and more people enter the industry. This accessibility paradoxically intensifies competition for funding. Games demand substantial upfront investment before generating returns. Speed to market and operational efficiency have become critical for studio survival. Developers must produce investor-ready, polished products as quickly as possible. Contemporary tools democratize game development. General-purpose engines like Unreal and Unity are freely available. Cloud-based source control eliminates maintenance burdens. Communication platforms enable distributed teams. Digital storefronts provide global distribution at minimal cost. Small studios can now establish profitable market positions within the expanding gaming economy. Investors and publishers now prioritize studios maximizing existing tool ecosystems. Cloud services have become industry standards. Time-saving solutions drive significant value, enabling higher-quality games completed faster. Smaller studios increasingly produce acclaimed titles, demonstrating this efficiency advantage. Modern tools must be accessible, user-friendly, and require minimal maintenance alongside responsive support. Most providers offer free tiers for bootstrapping projects. High-quality examples set elevated industry expectations. Game development continues evolving rapidly. As digital entertainment matures, tools remain central to progress. Better tools enable developers creating superior games faster. Studios operate leaner, adapt more quickly, and experiment more extensively than previously possible. Production, release management, live operations, and analytics tools are becoming indispensable and increasingly effective. --- ## KinematicSoup Announces the Expansion of their Multi-User Unity Scene Collaboration Tool Beta URL: https://www.kinematicsoup.com/blog/kinematicsoup-announces-expansion-multiuser-unity-scene-collaboration-beta Date: 2016-03-17 Summary: Scene Fusion's beta expands globally. KinematicSoup opens their real-time multi-user Unity scene collaboration platform to game studios worldwide. March 17, 2016 – KinematicSoup Technologies Inc. has announced that they will be expanding the beta for their Scene Fusion platform, inviting additional game developers using the Unity3D engine to trial Scene Fusion in its current stage of development. This is the first expansion of the Beta that will be open to game studios worldwide as KinematicSoup focuses on delivering a tool viable for global teams. Scene Fusion is a revolutionary new service that adds real-time, collaborative world building to Unity, a feature the engine does not support natively. It enables developers to complete games faster and get to market sooner. Scene Fusion is a Platform as a Service (PaaS) that allows game developers to push games in development into a persistent, cloud-based environment where changes are shared between developers, artists, and world builders instantly and globally. Scene Fusion enables users to work within a single scene simultaneously, cutting down world building time and complementing highly iterative workflows. The platform's cloud-based environment makes it scalable to all studios of all sizes, regardless of the number of users or their locations. By using a proprietary compression technology, developed specifically for Scene Fusion, KinematicSoup can ensure that the platform is fast and reliable. Elaborating on the importance of collaboration tools in modern game development, Justin McMichael, CEO of KinematicSoup, states that "as game development has evolved, things like rapid prototyping, collaborative design, and iterative development have become increasingly important." Developers need not worry about integration time, workflow changes or learning periods; after only a few minutes of setup, developers will have full access to the platform. Scene Fusion uses the existing Unity interface, meaning developers can continue to use the editor exactly as they did before integrating the multi-user collaboration tool. Taunia Sabanski, CEO of Amnia Interactive, stated that she "would expect Scene Fusion to cut down development time by up to 36%." KinematicSoup Technologies Inc. aims to provide game developers with innovative tools to enhance collaboration, reduce development time and increase ROI. Their Scene Fusion platform is designed to deliver a high impact collaborative development environment within the Unity editor. ---