Creating a roguelike MMO for your web browser!


Hi all! For the past few months, I’ve been working on a game called Gastrotale, a multiplayer roguelike (i.e. Risk of Rain or Hades) that runs in a standard web browser. I’ve always been a big believer in the web platform, and I think web technologies (like WebGL, WebRTC, and WebAssembly) are finally mature enough for a project like this.

I have some grand ideas of an overarching story and zany gameplay mechanics, but I’ll keep it brief for now. The project is just too early in development, and I don’t want to waste your time with baseless promises of what may be. I’ll update this post as I implement more features, so stay tuned! In the meantime, enjoy this devlog for a first look at the game!

Features
Over the past few months, I’ve implemented a lot of the core networking stack, game loop, and rendering. As of today, multiple people can connect to the server and move around in the same map:


Also, I’ve spent a lot of time working on a map editor:

Tech
I’ve incorporated a lot of really cool tech in Gastrotale so far.

I use a client-server networking model via an approach that’s well-documented on the internet. For those of you unfamiliar with game networking, the gist is that clients are untrustworthy and all actual game logic should happen on the server. Clients broadcast their input state (e.g. keypresses, mouse position) every tick, the server acts on this information, and the server updates all clients with the authoritative game state every tick. Of course, this introduces additional latency (the client won’t see the results of a button press until a full roundtrip to the server), so most games attempt to hide the lag with client-side prediction and reconciliation.

Client-side prediction lets the client preemptively act on local inputs before the server responds. If the client and server are running the same game loop, there should be no difference between the final game state on either the client or the server in the vast majority of scenarios.

Of course, this requires that the client and server run the exact same game loop as differences in implementation will result in bugs. In many networked games, this is not an issue- both the client and the server are written in the same language, so we can just share a library. In Gastrotale, however, I want to implement the server in C++ for performance, but the client needs to run JavaScript. To solve this, I implement the game loop in C++ and use WebAssembly  to export a module. I can then invoke this module on the client to advance the game loop using the local game state.

Also, most networked games use UDP instead of TCP for networking. Unfortunately, the easiest way to set up a bidirectional connection in the browser is with the TCP-based WebSockets. If you want unreliable and unordered packets, your only tool is WebRTC, an API for peer-to-peer connections between multiple web browsers. WebRTC was designed for P2P media sharing (i.e. video calls), but you can fake a client-server model by just running a WebRTC client on your server and have it connect to all clients. To do this in C++, I compile Chromium’s WebRTC implementation into my game server.

Thanks for reading!

Comments

Log in with itch.io to leave a comment.

It  look's great, i really like the cartoon style

Thanks! :)