Skip to content
← Portfolio
DarkLight
I · Roblox, Engine Systems and Network Transport

Keeping a connection alive when the network underneath it isn’t

Software Engineer Intern · June to September 2026 · San Mateo, CA

A phone switches from wifi to cellular. To the operating system, that’s routine. To a client mid-game session, it used to be fatal.

Every in-flight request died with the old interface. Players got dropped out of live games. The only recovery was restarting the app, which nobody does mid-game, so they just left instead.

That’s the problem I spent the summer on, and the fix ended up as shared infrastructure other systems could build on.

The problem

Raw network callbacks from the OS are noisy. A phone walking near the edge of a room can flap between wifi and cellular a dozen times a minute, and associating with a network is not the same as that network actually reaching the internet, especially behind a captive portal that intercepts everything until you accept its terms. Any fix had to survive both kinds of noise, and it had to work the same way whether the thing on the other end was an HTTP request, a QUIC stream, or Roblox’s own UDP game transport, each with different rules for what recovery even means.

What I built

I built Connectivity, a signal layer the rest of the engine can listen to. Per-platform monitors report OS-level changes into one shared, platform-agnostic core manager. That manager collapses the noise with debouncing, deduplication, and a generation counter that throws out stale or superseded events when two transitions race each other. On top of that sits a validation probe, a plain 204 no-content endpoint, picked because captive portals can’t fake a real response to it, so the system knows the difference between “connected to a network” and “connected to the internet.”

Two signals come out the other side: one carrying a snapshot of interface type and validation state, one for validation updates alone. What each consumer does with that signal depends on what it is. Regular HTTP connections get flushed and recreated cleanly on the new interface. QUIC connections migrate in place under RFC 9000, no re-handshake needed. Roblox’s own UDP game transport re-authenticates the client using a token issued ahead of time. That’s the part a player actually notices: switching from wifi to cellular mid-game no longer ends their session.

Rolling it out

The rollout started on iOS at a 15% bucket, and the first phase connected nothing to it at all. No consumer depended on the signal yet. It just logged what it saw, so we could compare what it reported against what was actually happening before a single line of production behavior relied on it being right. Only after that did HTTP migration, then the game transport, get wired in.

If you asked what I learned most from this project, it’s that rollout order. It was slower than shipping behind a flag and calling it done, but it’s why nothing broke when real traffic hit it.

Who ended up using it

I scoped this for HTTP and game-transport migration. Because it shipped as a general signal instead of a narrow fix, five other systems adopted it on their own, including voice chat’s connection migration and telemetry annotation, without me building either integration.

I’ve played Roblox since I was six. Getting to work on the engine underneath it still feels a little unreal.