A multiplayer browser-based Web3 2D shooter with an open economy, crafting, seasonal rankings, NFTs, and tokenomics.
My task was to create a distributed microservice system from scratch that could handle the real-time load of multiplayer, guarantee asset security, securely interact with the blockchain, and avoid turning the game into an endless wait for transaction confirmations.
Designing the architecture for a project of this type is a balancing act between security, speed, and resource costs. I needed to solve seven key problems:
In any client-server game, everything on the user's side can be hacked and substituted. Allowing the client to independently calculate its damage, position, or cooldowns will immediately invite cheaters: "immortal" players, teleporters, and infinite ammo. The main challenge was to make the server the source of truth without killing the game's dynamics.
When hundreds of bullets, enemies, and effects appear on the screen, the JS engine can be overwhelmed. We needed to find a way to render a huge number of objects so that the game delivers stable frame rates even on regular work laptops, not just on gaming PCs.
The server side must operate predictably under load. The main issue here is avoiding any stutters or micro-freezes that can be caused by incorrect memory management or heavy calculations. Any instability on one cluster node immediately ruins the experience for all connected users.
Game items have real value, so any technical error is a financial risk. The most dangerous situations are item loss and duplication.
This is the most challenging part of a hybrid economy. Doing everything on-chain is slow and prohibitively expensive for the player. (Yes, of course, there are, for example, XAI or SEI, but I didn't want to tie the project to a specific blockchain.) I had to separate the data: token ownership is recorded on the blockchain, and the state (modules, levels, upgrades) is in the database.
Another problem here is synchronization: how to quickly find out whether a player has bought or sold a ship on the marketplace, and how to provide up-to-date stats from the database to external platforms (OpenSea, etc.) without running into RPC request (CU) limits.
The main pitfall is writing a "monolith" that can't be further divided. I tried to make the system modular: break it into parts that can run on different machines and be independent of each other. This provides a foundation for the futureāif the load increases, we can simply add new game servers, a gateway, or a load balancer, without having to rewrite everything from scratch.
Public servers to which users connect are always under attack (DDoS, hacking attempts, etc.). Storing, for example, transaction signing keys on the same machine creates a huge security hole. It was necessary to design the architecture so that critical nodes were maximally protected from external threats.