A real-time multiplayer game inspired by Agar.io, built with Node.js, Socket.IO, and HTML5 Canvas. Features advanced cell mechanics, a highly configurable client, cross-platform controls, and full Xbox controller support.
- Real-time Multiplayer: Play with others in a persistent world.
- Cell Mechanics: Grow by eating pellets, split your cells to attack or flee, and merge back together after a cooldown.
- Virus System: Spiky green cells that split larger players on consumption. Can be "fed" with ejected mass, causing them to duplicate in the direction of the mass.
- Mass Ejection: Strategically eject mass to feed other players, bait enemies, or feed viruses.
- Live Leaderboard: See the top players and your real-time ranking.
- Minimap & Coordinates: Navigate the world with a real-time minimap and on-screen coordinates.
- Spatial Hashing: Efficient server-side collision detection for high player counts.
- Interest-Based Updates: The server only sends data for objects within a player's "interest radius," dramatically reducing bandwidth.
- Configurable Update Rates: Separate server-side physics (60Hz) and network (30Hz) loops for smooth gameplay and efficient networking.
- Client-Side Prediction & Interpolation: Ensures smooth player movement, even with network latency.
- Render Caching: The leaderboard is cached and only re-rendered periodically to save client resources.
- Custom Appearance: Choose your cell color or upload a custom image (with automatic server-side resizing).
- In-Depth Settings Panel: Fine-tune your experience with a wide range of performance and visual settings.
- Persistent Score: An option to save your score upon disconnecting and resume with it in your next session.
- Collapsible Chat: In-game chat that can be minimized to reduce screen clutter.
- Detailed Debug Mode: An overlay showing cell merge cooldowns, client-server sync distance, zoom levels, and controller status.
- Desktop: Classic and responsive mouse and keyboard controls.
- Mobile: Intuitive touch controls with a virtual joystick and dedicated action buttons.
- Xbox Controller: Full plug-and-play support for Xbox 360/One controllers with aiming, haptic feedback, and configurable sensitivity.
- Custom Mobile Keyboard: An on-screen keyboard for chatting on mobile devices without relying on the native OS keyboard.
| Input | Action |
|---|---|
| Mouse | Move cell toward cursor |
| Space | Split cell |
| W | Eject mass |
| Enter | Open/focus chat input |
| Ctrl + C | Toggle chat visibility |
| Input | Action |
|---|---|
| Virtual Joystick (left) | Move cell |
| Split Button (right) | Split cell towards movement direction |
| Eject Button | Eject mass towards movement direction |
| Chat Input | Opens the custom on-screen virtual keyboard |
| Input | Action |
|---|---|
| Left Stick | Move cell |
| Right Stick | Aim for splitting/ejecting |
| A Button | Split cell |
| B Button | Eject mass |
| Y Button | Toggle chat visibility |
| Start Button | Open chat |
| Back Button | Toggle debug mode |
| LB/RB | Zoom out/in |
| LT/RT (Triggers) | Fine-tuned, gradual zoom control |
| D-Pad Up/Down | Adjust controller deadzone sensitivity |
| D-Pad Left/Right | Quick mass set (debug: 100/1000) |
| Command | Description | Example |
|---|---|---|
/help |
Shows all available commands and controls. | /help |
/debug |
Toggles the detailed debug information display. | /debug |
/mass <number> |
Sets your current mass (e.g., for testing). | /mass 500 |
/zoom <number> |
Sets a custom zoom multiplier (0.1-10). | /zoom 1.5 |
/controller |
Shows controller status and control mapping. | /controller |
/fps |
Displays current FPS and frame time in chat. | /fps |
Customize your game experience with the following options:
| Setting | Description |
|---|---|
| High Resolution | Toggles native device pixel ratio for sharper graphics on high-DPI screens. |
| High Quality Graphics | Enables advanced rendering effects like "squishy" cells. |
| Smooth Cell Animation | Toggles dynamic, wobbly cell animations for a more fluid look. |
| Particle Effects | Enables/disables miscellaneous visual effects. |
| Frame Rate Limit | Sets the maximum client-side FPS (30, 60, 120, 144) to match your monitor or save power. |
| Render Distance | Adjusts how far away objects are rendered to improve performance. |
| Show Nicknames | Toggles the visibility of player nicknames. |
| Show Player Images | Toggles the visibility of custom player images. |
| Remember My Score | Saves your score to browser storage on disconnect for your next session. |
- Node.js (v14 or higher)
- npm (comes with Node.js)
- Clone the repository:
git clone <repository-url> cd multiplayer-game
- Install dependencies:
npm install
- Start the server:
node server.js
- Open your browser and navigate to
http://localhost:3000.
{
"express": "^4.x.x",
"socket.io": "^4.x.x"
}multiplayer-game/
├── server.js # Main server file (Node.js, Express, Socket.IO)
├── public/
│ ├── index.html # Game client HTML structure
│ ├── game.js # Client-side game logic and rendering
│ └── style.css # Styling, responsive design, and UI
└── package.json # Project dependencies
- Server Simulation: Physics runs at a fixed 60Hz for consistency.
- Network Updates: Game state is broadcast at 30Hz to balance performance and real-time feel.
- Client-Side Prediction: Player movement feels instantaneous by predicting actions locally.
- Position Interpolation: Smooths out other players' movements to compensate for network jitter and lag.
- Spatial Hashing: Server uses a spatial hash grid to perform collision and consumption checks, avoiding O(n²) complexity.
- Interest Management: The server only sends updates for entities within a player's field of view, significantly reducing network traffic.
- Delta Updates: Only changed, new, or removed cells are sent to clients, not the entire game state on every tick.
- Image Compression: User-uploaded images are automatically resized and compressed on the client before being sent to the server.
Key server settings can be adjusted in server.js:
const WORLD_WIDTH = 4000;
const WORLD_HEIGHT = 4000;
const PELLET_COUNT = 1000;
const VIRUS_COUNT = 50;
const PLAYER_MERGE_TIME = 15000; // ms
const VIRUS_EJECTIONS_TO_SPLIT = 7; // Feeds to split a virusconst PHYSICS_UPDATE_RATE = 60; // Hz
const NETWORK_UPDATE_RATE = 30; // Hz
const INTEREST_RADIUS = 1500; // Player's view distance for updates
const SPATIAL_HASH_CELL_SIZE = 200;- Controller not detected?
- Ensure your browser supports the Gamepad API (most modern browsers do).
- Connect the controller before starting the game or refresh the page after connecting.
- High latency/lag?
- Check your internet connection.
- On the client, try lowering the Render Distance and Frame Rate Limit in the settings panel.
- Can't connect to the server?
- Verify the server is running with
node server.js. - Check for firewall or antivirus software that might be blocking the connection on the specified port.
- Verify the server is running with
- "Remember My Score" not working?
- This feature requires your browser to allow
localStorage. It may not work in private/incognito mode or if cookies/site data are blocked.
- This feature requires your browser to allow
🎮 Ready to play? Run node server.js and visit http://localhost:3000!