A real-time multiplayer hangout game where you can explore, build, and hang out with friends. Built with HawkEngine and WebSockets.
Hawk is an online multiplayer game that lets you hang out with friends in a shared virtual world. You can move around, chat with nearby players, and create your own spaces. The party system allows you to create private instances where you and your friends can build and customize maps together.
Multiplayer
- Real-time interaction with other players using WebSocket connections
- See and chat with players in your view range
- Smooth movement synchronization with chunk-based rendering
Party System
- Create private parties with custom names and descriptions
- Invite friends via invite codes or direct invitations
- Separate party instances with isolated maps
- Customizable member permissions (editing maps, placing tiles, inviting others)
- Save up to 3 different maps per user
Map Building
- Place and modify terrain tiles
- Add, move, and delete objects on the map
- Changes sync in real-time to all party members
- Load and save custom maps
User System
- User registration and authentication
- Personal profiles with avatars and bios
- Last position saved separately for normal world and parties
- Moderation tools (ban, timeout, hide players)
Game World
- Dynamic day/night cycle
- Chunk-based world loading for performance
- Persistent world state
- Node.js 18.x or higher
- npm or pnpm
- Git
Clone the repository:
git clone https://github.com/zt3xdv/hawk.git
cd hawkInstall dependencies:
npm installConfigure your server:
cp config.example.json config.jsonEdit config.json with your settings:
{
"port": 3000,
"host": "127.0.0.1:3000",
"turnstile": {
"key": "YOUR_TURNSTILE_SITE_KEY",
"private": "YOUR_TURNSTILE_PRIVATE_KEY"
},
"https": {
"enabled": false,
"cert": "path/to/cert.pem",
"key": "path/to/key.pem"
}
}For development (faster builds, no minification):
npm run fast-build
npm run fast-build-engineFor production (optimized builds):
npm run build
npm run build-engineWatch mode (automatically rebuilds on file changes):
npm run watch
npm run watch-engineStart the server:
npm startThe game will be available at http://127.0.0.1:3000 (or your configured host).
hawk/
├── src/
│ ├── server/ # Backend logic
│ │ ├── Hawk.js # Main game server
│ │ ├── PartyManager.js # Party system management
│ │ ├── ChunkManager.js # World chunk handling
│ │ └── Socket.js # WebSocket routing
│ ├── game/ # Client game logic
│ ├── engine/ # Hawk engine code
│ ├── components/ # UI components
│ ├── models/ # Data models (User, Player, etc.)
│ ├── routes/ # Express HTTP routes
│ └── utils/ # Helper functions and constants
├── assets/ # Images, sprites, audio
├── data/ # Server data files (users, maps, parties)
├── public/ # Static public files
├── dist/ # Compiled output
├── config.json # Server configuration
└── index.js # Application entry point
Parties are private instances where you and your friends can build together. When you create or join a party, you're put into a separate world instance with its own map and objects.
Creating a party:
{ type: 'createParty', data: { name: 'My Party', description: 'Come hang out!' } }Joining via code:
{ type: 'joinPartyByCode', data: { code: 'ABC123' } }Inviting players:
{ type: 'inviteToParty', data: { playerId: 'player-id' } }The party owner can control permissions for each member. Members can have permission to edit the map, place tiles, or invite other players.
Party maps are saved separately for each user. You can save up to 3 different maps and load them later.
| Option | Description | Default |
|---|---|---|
port |
Port the server listens on | 3000 |
host |
Public hostname (used in WebSocket URLs) | 127.0.0.1:3000 |
turnstile.key |
Cloudflare Turnstile site key for bot protection | - |
turnstile.private |
Cloudflare Turnstile secret key | - |
https.enabled |
Whether to use HTTPS | false |
https.cert |
Path to SSL certificate file | - |
https.key |
Path to SSL key file | - |
You can customize game behavior by editing src/utils/Constants.js:
- Party name/description length limits
- Maximum elements per party map
- Player view ranges
- Development mode settings
Authentication
login- Log in with username and password
Movement & Interaction
playerMovement- Update your positionchat- Send a chat messagetyping- Notify others you're typing
Map Editing
createElement- Add an object to the mapdeleteElement- Remove an objectmoveElement- Move an objectsetTile- Place or modify a tile
Party Management
createParty- Create a new partyleaveParty- Leave current partyjoinPartyByCode- Join using invite codeinviteToParty- Invite another playeracceptPartyInvite- Accept an invitationsetPartyPermission- Change member permissions (owner only)kickPartyMember- Remove a member (owner only)
Map Persistence
savePartyMap- Save current party map to a slotloadPartyMap- Load a saved mapgetPartyMapSlots- Get list of saved maps
Connection
connected- Connection establishedloggedIn- Login successful
World State
chunks- Load map chunkstiles- Load tile datatime- Current in-game time
Players
addPlayer- A player entered your viewremovePlayer- A player left your viewplayerMoved- A player moved
Chat
chatmessage- Chat message from another playertyping- Someone is typing
Map Changes
createElement- Object addeddeleteElement- Object removedmoveElement- Object movedsetTile- Tile changed
Party Events
partyCreated- Party successfully createdpartyJoined- You joined a partypartyLeft- You left a partypartyMemberJoined- Someone joined your partypartyMemberLeft- Someone left your partypartyPermissionUpdated- Member permissions changedpartyMapSaved- Map saved successfullypartyMapLoaded- Map loaded successfullypartyMapSlots- Your saved map slots
Errors
loginError- Login failedpartyError- Party operation failed
For detailed event schemas, see PARTY_SYSTEM_BACKEND.md.
The project uses Rollup for bundling. There are two main build targets:
App Build (app.build.js)
- Bundles client-side code and UI components
- Output:
dist/bundle.js
Engine Build (engine.build.js)
- Bundles the Hawk game engine
- Output:
dist/engine.js
Build modes:
npm run build- Production build with minificationnpm run fast-build- Development build without minificationnpm run watch- Watch mode that rebuilds on changes
Server-side features:
Edit files in src/server/. The main server is in Hawk.js, which handles WebSocket connections and game logic.
Client-side features:
Edit files in src/game/ for game logic or src/engine/ for engine-level changes.
UI components:
Add new components in src/components/. They'll be automatically bundled.
HTTP routes:
Add Express routes in src/routes/.
User data, maps, and parties are stored as JSON files in the data/ directory:
data/users.json- User accountsdata/map.json- Main world mapdata/tiles.json- Main world tilesdata/party.json- Active partiesdata/parties/[user-id]/slots.json- User's saved party maps
Backend
- Node.js & Express for HTTP server
- WebSocket (ws) for real-time communication
- bcrypt for password hashing
- MessagePack for efficient binary serialization
Frontend
- HawkEngine for game rendering
- Vanilla JavaScript (no framework)
- Custom UI components
Build Tools
- Rollup for bundling
- Terser for minification
- Chokidar for file watching
Security
- Cloudflare Turnstile for bot protection
- bcrypt password hashing
- Input validation and sanitization
Contributions are welcome. If you want to help:
- Fork the repository
- Create a feature branch (
git checkout -b feature/new-feature) - Make your changes
- Commit (
git commit -m 'Add new feature') - Push to your fork (
git push origin feature/new-feature) - Open a Pull Request
Please make sure your code follows the existing style and test your changes before submitting.
This project is licensed under the Apache License 2.0. See LICENSE for details.
- Website: hawkg.xyz
- Repository: github.com/zt3xdv/hawk
- Issues: github.com/zt3xdv/hawk/issues
- Pull Requests: github.com/zt3xdv/hawk/pulls
Made by tsumugi_dev