All projects
HAChimmy Accelerator logo
Production

HAChimmy Accelerator 2025

An active, community-run accelerator for a game with separate global and China releases, serving 100+ customers. Built and operated the custom protocol, edge network, routing, billing, and Flutter client end to end.

Role
Lead DeveloperProtocol, edge, billing & client
Timeline
2025 — Present
Customers
100+
01 · Context

Context & problem

The game i enjoyed had two separate releases: a global version and a China version. The global version was less active, while the China servers were where the community was. The problem was getting there. Connections to the China servers were gated behind the firewall and often took indirect routes through high-latency choke points in the United States or Japan. For a game, that is not a minor inconvenience, its the difference between playing and not playing.

Players who wanted to play the China servers could use commercial boosters such as UU Booster or ExitLag. They worked, but they were expensive for what many people wanted: a way to play with the community without a large monthly fee. I stepped up as a member of the community to offer a cheaper service specifically for this game.

That decision turned into a lesson in international networking. Providing low-latency, low-loss access to China is not just a matter of renting a server. It depends on peering and IP transit relationships between networks, and those relationships are difficult to arrange for this kind of traffic. Many providers did not allow the service to run on their networks at all. The workable options were lower-bandwidth links, which were cheaper but more exposed to attacks and blackholing. Those constraints shaped the product from the beginning.

02 · Role

Role & scope

I was the lead developer. I designed, built, and operated the entire service: the custom protocol, the edge infrastructure, session routing, billing, and the Flutter client with its backend. The project is still active and I continue to update it and serve users, so this is a description of a running system rather than a finished archive.

I worked with a product manager who shared the community and customer-support work. We split the project along product and engineering lines, but the service was small enough that both of us stayed close to the users. On the engineering side, the trade-offs like protocol design, node placement, route selection, billing logic, and client behaviour were made by me.

I did not build the game. My job was to build the network service around it: capture the game's traffic, carry it over a better path, and make the result reliable enough that players could forget about the network.

03 · Architecture

How the system fits together

The data path carries game traffic: WinDivert captures only the game on the player's machine, the client encapsulates it in a custom UDP protocol, and it travels through an entry node, a private backbone, and an exit node before reaching the game server.

Architecture diagram: game client traffic is captured by the accelerator client through windivert, encapsulated by the tunnel protocol, sent over UDP to an entry node, carried across a private backbone to an exit node, decapsulated, and delivered to the game server. A separate backend API handles session and route requests.
The data path and the control path: local capture, the custom tunnel, an entry node, a private backbone, an exit node, and the game server. The backend allocates and reroutes the session. Open full size

The client is kept from being authorative. It asks the backend for a session, which keeps routing policy server-side and prevents arbitrary node selection. Entry nodes perform ingress and session checks; exit nodes decapsulate and send clean traffic to the game, and the return path mirrors the same route. The topology stays simple at the edges because the hard part is choosing the right pair and keeping the path healthy.

The backend runs on two public cloud instances across two availability zones behind a load balancer, so an instance or zone failure does not take session allocation down.

The first version wrapped WireGuard. That validated demand but limited routing, session setup, and how traffic looked on the wire. The custom protocol and Go dataplane replaced that dependency; WinDivert captured game traffic without asking players to reconfigure their network, and Flutter gave the service a real client instead of a wrapper around some app.

04 · Deep dives

The parts that took real expertise

Custom protocol & Go dataplane

The custom protocol is a UDP transport with encapsulation and obfuscation, backed by a Go dataplane and WinDivert capture on Windows. The hard part was making proper routing decisions, certain paths are not always healthy 99% of the time, resulting in latency jumps or packet loss. By utilizing Redundancy and duplicating the nodes, we can ensure that packets are sent at least through one healthy path, then deduplicated at the exit. Giving us the best latency of the 2.

Edge routing & the private backbone

The edge is not a single tunnel endpoint. Traffic enters at an entry node, crosses a private backbone of optimized hops, and leaves through an exit node close to the game. Splitting the path this way is what lets the service avoid the public choke points that made the direct connection slow in the first place.

Route quality is the product. A path that looks fine on paper can be unusable in practice, especially when it depends on peering and transit relationships that are outside your control. The backend owns the entry/exit decision, so a route can be changed centrally when a path degrades instead of asking every player to edit a configuration. That separation between the data path and the routing decision is the core design idea.

Session orchestration & the backend

The desktop app can never allocate its own path. It asks the backend for a session and a route. Keeping the client dumb and the control plane strict makes the system easier to operate: routing policy, capacity decisions, and abuse controls live in one place.

That choice also makes failure handling more predictable. A node going away is a backend problem, not a player problem. The session can be reallocated without shipping a new build or walking a user through a manual fix, which matters for a service whose users are trying to play a game, not manage their route.

Windows capture with WinDivert

On Windows, the client has to capture only the game's traffic without breaking the rest of the machine. WinDivert provides packet-level interception, and the local tunnel service captures the game traffic and passes it to the protocol layer. The filter has to be precise: the wrong rule can catch traffic that has nothing to do with the game, or miss the traffic that does.

The hard parts are driver compatibility, filter correctness, and predictable failure. Testing for the broad playerbase is difficult: The different Operating systems, network driver compatibility and others.

The Flutter client

The Flutter app is the control surface: sign-in, route choice, session status, and the state of the tunnel. It talks to the backend, not directly to nodes, which keeps the client small and the routing logic server-side. The app is also where a network service becomes a product.

Building it in Flutter gave the project room to grow beyond the original wrapper. The client could present a coherent interface for authentication, route selection, and connection state while the protocol and backend evolved underneath it.

Billing & abuse control

Billing is built in-house and kept intentionally high-level: the backend records the billable event and owns entitlement, while the client only displays state. The client cannot grant itself service, and a session can be cut off centrally without the client. The aim was a system accurate enough to trust and simple enough to operate as a small team.

Abuse is the other half of the same problem. A small service like this is prone to "attackers" who want them free. Accounts, session allocation, and route choice therefore live on the server, where capacity and abuse decisions can be made together rather than patched in the client.

05 · Problems

Hard problems & trade-offs

Provider and peering constraints. The network was the supply chain, and it was the hardest part to secure. Low-latency, low-loss access to China depends on peering and IP transit relationships.

WinDivert and client compatibility. Capturing game traffic on Windows is a driver-level problem, and the client has to work on machines with different Windows versions, security software, and network setups. The filter has to select the game's traffic precisely, the tunnel service has to coexist with everything else on the machine, and the client has to fail predictably when the tunnel is unavailable. This makes it difficult as the code can be correct and still fail on a user's machine because of the environment around it.

Billing and abuse. A small service has to be accurate about who is entitled to what, and resilient to people who want to abuse the capacity. Keeping billing and session allocation server-side solves both problems at once: the backend is the source of truth for usage and entitlement, and it can refuse or reroute a session without relying on the client. The trade-off is that the control plane becomes a single point of policy, which is exactly where you want that responsibility, but it also means the backend has to be available and correct.

06 · Results

Results & impact

The service is still active and serves 100+ customers. The latency improvement is up to 250ms, depending on the ISP's routing to the game; that figure is the higher average of what we have seen, not a promise for every player. Uptime is currently 99.5%, and raising it is ongoing work.

The numbers matter less than what they replaced. For a community that wanted to play together on the China servers, the alternative was an expensive commercial booster or not playing at all. A cheaper, game-specific service made the community accessible to people who would otherwise have been priced out and it gave me a reason to learn how international networks actually fit together.

07 · Reflection

What I would do differently

The WireGuard wrapper was the right first version. It validated demand without committing to a protocol. The mistake would have been to keep it. A wrapper means living with someone else's protocol and someone else's decisions; once the product depended on route selection, session control, and the way traffic looked on the wire, the custom protocol and Go dataplane became necessary rather than aspirational.

The bigger lesson is that the network is a supply chain. The best route is not a code problem; it is a peering and transit problem. I would treat provider relationships and route measurement as first-class parts of the product from day one, not as infrastructure details to solve later. Low-bandwidth links looked cheaper until they were attacked or blackholed, and that false economy is easy to miss when you are optimizing the bill.

At ten times the customers, the constraint would not be the Flutter client. It would be transit capacity, peering, abuse, and support. I would design the control plane and the billing/abuse path for that scale earlier, and keep the client as boring as possible. The client should report state and get out of the way; the interesting decisions belong on the server.

08 · Expertise

Expertise demonstrated