ZombiesWithGuns.io (https://zombieswithguns.io/)


ZombiesWithGuns.io is a multiplayer first person shooter made with Babylon v4 (NullEngine) and nengi.js (a recently open sourced network engine). Hopefully there are some players in there when you try it!

Players can change their keybinds in-game, but the defaults are:

  • WASD: move
  • mouse: look around
  • left click: shoot
  • right click: aim down sights (reduces recoil/bloom, zooms if sniper)
  • shift: sprint
  • spacebar: jump

You may also sign in with google/facebook to have the game save long term stats and add your scores to the daily/weekly leaderboards.

Technical details for you devs:

  • the game map is 9 large meshes, made in MagicaVoxel
  • server is a Vultr VC2 8192 ($40), and runs 24 instances of the game
  • each game instance holds up to 10 players (for design reasons…actual max is way higher)
  • runs on some (many?) chromebooks/low-end devices
  • server is 20 ticks per second
  • client uses predictive netcode, and flexible rates (30-250 fps all are playable)
  • netcode allows shooting right at the target at a variety of latencies
  • all shots are calculated on the server, not the client!!
  • collisions are regular babylon raycasts + a homemade voxel engine
  • webpage and in-game hud, ui, and menus are Vuex+VueJS
  • every player body part is a separate mesh, programmatically animated
  • each body part has its own hitbox…but i’m in the process of changing that (hands and forearms are immune/weird at the moment)

I’ve been obsessed with network programming for several years (I love multiplayer) and I had been developing nengi.js, primarily pairing it with Pixi. Nengi could hypothetically network anything from an mmorpg to a first person shooter – but that latter one hadn’t been proven. There is a game that is kinda close, Bruh.io. It has the type of netcode you’d find in a first person shooter (predicted movement, compensated shots, etc) but ultimately it was still a top down 2D game.

So as you could imagine I was excited to hear about NullEngine. I write server-authoritative games. That’s a programming model where the game client is heavily distrusted due to hacks and cheats. The technique to reduce cheating involves being able to perform an action on the client (such as moving or shooting) and being able to deterministically replicate that exact same thing on the server. The client version of this action is somewhat fake and might not be accepted by the server – it exists to provide visual feedback to the player and make the game feel like it has no latency. But the action that actually affects the game world as seen by everyone else is the version that occurs on the server. NullEngine makes this determinism much more obtainable… We can fire a shot on a game client… and then calculate two identical rays one on the client and one on the server. What does the client ray do…? Well for ZWG it just draws that tracer/smoke trail thing and eventually I’ll add a blood effect. Meanwhile an identical server ray is used to actually deal damage. This core technique is the basis of so much!

I did run into some issues with collisions and animations for which I made some very questionable decisions. Since nengi is now open source, and babylon was always open source, I imagine some people would like to see some game templates showing the two working together. This game makes it look like the two get along fantastically…and for the most part that is true. However I wrote a collision system that uses voxels. I also performed every animation programmatically! These are kinda large problems that need solved. I should probably write about these in the forum and try to come to some solutions, esp. if there is particular interest in nengi+babylon integration. I mean why not, right? :smiley:

Edit: here’s a game play vid:


This is a great game. :+1:

1 Like

Awesome game! Lots of fun and very playable.

1 Like

Great game! 'Hope there will be someone online next time I’ll try. I like the feeling and the reactivity for now. If I have to make a criticism it will be just about the fov which is a little too narrow IMO when not aiming.

And thanks for the technical details you’re talking about, it’s a nice summary.

1 Like

GG on the game, I love it !!! We were at some point 6 on the map and it is incredible fun.

1 Like

This reminds me of games I used to play years ago. Excellent!

1 Like

Will you make tutorials about nengi.js?

You were talked about here: Theory on how to make a multiplayer game

1 Like

Man, please add it here:

repo: Website/config.json at master · BabylonJS/Website · GitHub

1 Like

Thanks everyone!

@Deltakosh added!

@Givo I’ll try and work on some tutorials

Yeah that fov does feel a bit zoomed in now that you mention it, I’ll experiment more.


Very fun, I love the trend of the .io games popping up where you can jump right into the game.


I’m making an fps, and I’ve had some criticism about a specific game mechanic, and because the game is called NYNS, (Not Your Normal Shooter) I thought I could make another version of it called IJYNS (It’s just Your Normal Shooter) and have both playable on yns.io (I have to see if it is available)

1 Like

Fun game. Was up against 4 other players and absolutely dominated them :stuck_out_tongue:
I have an FPS project myself, with prediction, reconciliation and compensation(and working decently even with rigid bodies), but I’ll make sure to have a look at nengi.js.
But for the time being I’m actually rewriting my networking code of a racing game to be client-authoritative.
I’m doing this mainly to save money. Running Bullet/AmmoJS isn’t cheap, so One low-ish VPS per game server gets expensive.

Agree, I thought QuickPlay was a defining feature also.

1 Like

I love the breakdown, def ‘want to know more’

Hey what’s a “20 tick server” in AWS terms? Obviously it’s also usage dependent.

1 Like

“20 tick” is the number of times the game logic is called per second on the server
I’d say it is sort of a measure of how realtime something is. Most first person shooters will do 20 tick, though some will do more. I believe modern cs:go does 33 tick on match servers (though was also 20 tick for like a decade). It isn’t strictly visible to the players because the game clients will smoothly add frames in between the ticks (interpolation).

    setInterval(() => {
        gameInstance.update(1/20, tick++, Date.now())
    }, 50)

As far as the relationship between tick rate and hardware goes, (such as AWS) one can attempt to run any tick rate on any hardware. The problem is that 40 tick, for example, really is twice the CPU and bandwidth usage of 20 tick.

Increasing tick rates reduces latency, but it has pretty steep diminishing returns on the latency improvement, and a linear increase in CPU+bandwidth
10 tick - 100 ms
20 tick - 50 ms (2x CPU & bandwidth)
30 tick - 33 ms (3x CPU & bandwidth)
60 tick - 16 ms (6x CPU & bandwidth)

In practical terms this would mean that my $40/mo server which can do 240 players at 20 tick, would instead do <120 players at 40 tick. I would guesstimate that this $40 server is the equivalent of roughly $200 worth of hardware from the big cloud providers running their “compute” style machines.


I had a lot of issues with my game mechanics (still do TBH). And I’m going to take this opportunity to rant about them.

If one were to wrap these games and ship 'em on steam or something maybe the audience would differ… but the reality for my game is that a huge chunk of the players are on chromebooks-esque devices sneaking a few minutes of gaming at school or work. They’re not playing with positional audio, or any audio sometimes. They will will actually use track pads. They won’t right click to aim down sights, and even given a keybind to aim down sights I’m not sure that the implications are understood.

The first version of the game had wild and unique recoil mechanics that involved continuously pulling the gun down or firing really short bursts. As a long time PC gamer and former competitive CS player I thought this was fun and unique. But the first couple thousand game sessions were under 2 minutes – which to me meant the audience was not having a good time. It wasn’t the ideal use of my first traffic, and first votes on the portal sites (I guess something had to change my mind somehow…).

I reduced recoil and bloom drastically, and added the conventional system of the gun dropping back down on its own as the player stays off the trigger. I introduced more delay in between deaths, and also tried to draw more attention to the ability to rebind keys, change mouse sensitivity, and switch weapons. The game session length has more than doubled.

I suspect reducing recoil even more, removing sprint, and making the advantage of ADS even less would continue to align the game more with its players.

So wrt conventional or not conventional…I’ve started to think like this

  • many io gamers have limited controls (limits some options…)
  • io gamers are eclectic, and are probably several distinct groups
  • these portal sites rely on votes and algorithmicly judge a game in the first 2-7 days (whoops…)
  • If something looks like a conventional member of its genre (i.e. FPS) it carries both the benefits and the detriments of the collective assumptions. People can understand how the play the game more quickly (assumptions!) but they will likely also be more put off by large deviations from the norm. They will literally tell you the game is broken, and hand you a bug report if the deviation is off by too much.
  • products that resonate with large audiences are extremely similar (zzzZZz…) to something they already know. Attempts to study this suggest that an exciting amount of novelty is like 5% (such an esoteric concept, which i take to mean that things need to be non-identical but pretty similar)
  • genre mixtures are a way of sneaking in uniqueness while maintaining familiarity. I just say this b/c a lot of games that feel unique seem to just rely on mashing two non-novel ideas together, and the novelty is in the mixture.
1 Like

True, true. Shellshock.io, an fps game made with babylon.js, was notorious at my school for being played. There was a google doc shared with over 50 people (I think close to that at one point) where people could post links to games. It was soon shut down by the IT. Shell Shocker’s default control style involves shift as aim down sights, which is helpful to Chromebook players. I, too, play games on a Chromebook, as our school gives us one. (not to keep) I frequently play krunker.io and with recent updates the game is getting harder to run.

Krunker.io is movement based, while shellshock.io is rng based. The reason is that in krunker when you aim, you gun is accurate with no spread at all. Hardly any recoil for that matter, either. But in krunker you can bhop (you play CS, so you know what I mean, right?) and a technique called b-slides. I’m not going to explain it, but after jumping you can slide by crouching in midair. combined with bhoping, it can help you go fast.

Shellshock.io is rng based because even when aiming your gun still has a bit of spread. It takes a while to kill someone at range, but up close you can see just how much it affects the game because the time to kill is much shorter.

My game probably shouldn’t be a browser game, because of the mechanic that makes it unique. It is explained here: Presenting: NYNS!

I can officaly say that my forum post: Theory on how to make a multiplayer game
is the fisrt link to come up after your videos when googling “babylon.js nengi” :slightly_smiling_face:


You should make a simple barebones example of client+server using BabylonJS, NengiJS and NodeJS or whatever as backend. No animations or fancy stuff, just simple boxes as a template to get the BabylonJS people going using NengiJS.

When you say 20 ticks, do you mean that you queue inputs in a buffer, and then apply these inputs in 50ms intervals? And if yes, is it wrong to assume that you use positions to update the players, something like: player.position.z += controls.w*input.dt (simplyfied, not taking rotation into account)?

1 Like

Re: nyns, that’s a fun idea. I always like teleporting characters or strange mobility.
I think if something feels really different immediately, people will be more receptive to the change. It was just that my game really looked like bread n butter FPS, so going all weird on recoil had ppl sending me bug reports.

Sounds like I really need some more work if someone just mentioning nengi in passing on this forum wins the the search engines lol…

This is a favorite project and thread.

How do you do interpolation? Of everything? Rotation and Position, (scale)? : )

I use an unusual jQuery syntax: $({from}).animate({to},complete(){}); for now.

1 Like