Access the pre-built web client at https://0xvector.me/mmo-rpg to try out the game without building it yourself!
The server communicates with clients by establishing WebSocket connections.
The clients automatically joins the game after interacting with the game screen. Inactive clients (eg. closed browser) are kicked. Each new instance (eg. browser tab) established a new connection and is considered as a new client.
For now, you can run around the map and kill the slimes spawning. PvP is not yet implemented.
WASD to move around the map<space> to attacknpm install -g bun.git clone https://github.com/0xVector/mmo-rpg.git, then cd mmo-rpgbun install --production herebun run buildbun run clientThe client is now running at http://localhost:8080/index.html.
You can also try the pre-built client served by github pages.
See the respective guide.
See server.
The client is written in TypeScript with Excalibur.js. It comes with a simple HTTP server that can be run with Bun or NodeJS to server the client page. It uses the native browser WebSocket implementation.
The client utilizes the common ExcaliburJS project structure. The main entrypoint is the game.ts file, where the engine and all dependencies are instantiated.
Actors are all the moving parts in ExcaliburJS. Here, they are in an inheritance structure resembling that of server, but with its own important distinctions.
There are the entities, with the CustomEntity base type, which defines the minimal properties of every entity (the main part is having an UUID, which is addressed as netId in client to distinguish it from the internal ExcaliburJS actor id). The most notable difference from the server implementation is that there are two different player classes. Player is the base player and by default represents other players on the map. PlayerOwn is the own, controllable player that inherits from Player.
The second kind of actors are items, which is just a basic type for objects on the map, such as rocks. This is an area of future interest.
Only a single World scene is used.
GameManager is the manager class responsible for most of the communication, as well as game logic. It seems to be responsible for too many parts of the client logic and should be separated in the future into a communication and pure game part.
One of its main responsibilities is providing handlers for WebSocket request events. These events are a sort of a merge between the server request DTOs and internal events. They define the shape for inbound requests from the server, but are also used internally.
Its second responsibility is holding the game client state and providing some low-level methods allowing the parts with the higher level game logic to make changes to the state.
WSManager is a class responsible for just the lowest-level communication on the WebSocket layer. It holds the WebSocket instance of the underlying browser WebSocket implementation representing the client's connection to the server in its state, processes incoming requests and provides a way to register handlers for them.
See the typedoc here.
See the respective package.json for now.
I used sprites from the free asset pack Mystic woods (thanks!).
Generated using TypeDoc