Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: I Built Multiplayer Deathmatch Joust (joust.life)
257 points by jasonkester 23 days ago | hide | past | favorite | 103 comments



Most of this code dates back to 1998, when I built a little 2 player Joust game to push the bounds of what you could do with Div (and at the time Layer) tags in the latest browsers such as IE4 and Netscape 3. Surprisingly, most of it still worked when I thawed it out recently, provided your browser knew about document.all.

Over the weekend, I brought it up to date a bit and introduced it to Socket.io. Thus far it hasn't seen more than a dozen players at a time, so I'm curious to see what happens when a bunch of folks jump in at once.

I'll stick around to answer questions (and likely post-mortem the bits that catch on fire).


It's probably obvious for people who already played the game, but a quick note mentioning 'the highest one win' would make things easier for newcomers.

I was a bit confused about how to fight, before checking the wikipedia page


If you can figure out a way to only send inputs for each player instead of their full state, it should significantly reduce network traffic and lag for each player-- right now it's sending ~1KB/frame!


Yeah, 700b for 20 players, and normally at least somebody does something every tick, so that will go out 30 times per second. It still only works out to 24kbps, so you might not need to upgrade the modem you had back when the original was in the arcades.

I tried only sending updates every 3rd tick, but even there I could notice the difference.

You're right that it'd be worth experimenting with sending keystrokes instead, and backing off the full resync to once/second or so.


You'd have to resync fairly often to avoid desync especially for Joust where positioning during fighting is pretty important.


Desync is possible with UDP protocols, where a dropped packet would mean lost inputs, but this uses websockets, which are reliable TCP connections, so just the list of inputs combined with a deterministic engine is sufficient.


They can arrive out of order so you still have to deal with rewinding an re'simulating' the whole sequence of moves since the skipped packet then dealing with resolving the client vs server when they disagree.


The TCP connection is never closed with websockets.


That doesn't change that TCP packets can arrive out of order does it? (It's been a while since my college networking class and it's not something I come into contact with in my job)


Operational transformations (OTs).


I don't see "game" mentioned in the wiki at all. Is that something typically used for games or do they tend to use something else?


Collaborative text editing is what it’s traditionally used for.


It can also be used to mutate hard game state (I wouldn't try it with dynamic, interpolated values like object position, angle, acceleration, or velocity.)

There are many other methods, some are more precise and compressible than others:

Trailing State Synchronization

https://www.cs.ubc.ca/~krasic/cpsc538a/summaries/38/

Basic ideas

https://www.gafferongames.com/post/state_synchronization/

https://engineering.monstar-lab.com/2021/02/09/Game-server-S...

https://www.gabrielgambetta.com/client-side-prediction-serve...


This is superb, addicting as hell, and now I have to force myself to stop because I have real work to do.

The game gets increasingly jittery as it gets busier. It might be worth writing some tests to simulate lots of players moving around so it's easier to tune the performance.


Glancing at the code, it looks like he's rendering everything via DOM elements. I think player sprites are positioned using the top/left properties; could potentially optimize by keeping those props constant and just updating `transform: translate(x,y)` instead...


That's a holdout from 1998. Can't go changing things up after all that time, can we?

I imagine today I would have built the whole thing in canvas. But it's cool how quick you can get something up and running if you let the browser do most of the work.


I just joined for a quick session - just wanted to say that this is really fun and very well done (especially for someone who has played Joust before). Thanks for sharing!


I played Joust a lot as a kid, the character movement looks a really good reproduction of the original to me.


Which platform(s)?


Atari 400 (cartridge).


Fantastic :)

It would be nice if you could change the scaling to use nearest neighbour on the players so they don't look all smooged,


It's just vanilla javascript, html and css. Pull up dev tools and notice this in the css:

  img {
    image-rendering: pixelated;
  }
Lop that off (or uncheck it in dev tools) and you can have things as blurry as you please.


The modern way to implement this is with <canvas>, which lets you do that sort of thing pretty easily-- and is more performant to render.


I don't know what the obsession is with blocky graphics; they didn't look blocky back in the day, so maybe faux-nostalgia?


That's pretty awesome.

I remember making a CGI (that's an ancient, simple server backend for the young-ins) IM chat in 1996. It used the keep connection open trick present in HTTP 1.0 and a tiny bit of Netscape JS.


Holy volume warnings. My dog left the room.


Yeah my ears hurt. This should go in that thread of "injuries due to code."


You know I've been playing this for a week now, and until reading your comment it had never occurred to me to put a volumeNode in the middle of the webaudio path.

I just thought I had my speakers too loud :)


Wish I had read this comment before starting the game. I had my phone's volume maxed out.


I listen to my music with my speakers set to 40%.

I had to change them to 6% to comfortably play this game.


It's a little confusing when the name doesn't get dimmed or disappears when the player gets knocked off the bird. It's almost as if it's the name of the birds only, and the players are entirely nameless ;-)


I mean, how often do you hear the name of the jockey in horse racing?


I have no idea what's going on. I can't tell if that's intentional or if it's broken.


It's both, and it's glorious.


80's were a crazy time


I blame pastels, bad fashion, Saved by the Bell, and Trapper Keepers.


Are those Bugle Boy jeans you're wearing?


For the hardcore players you can switch teams while playing for optimal tactics.

You can also iterate between Space + Up + W keys to boost your jumps.


Awesome. I loved Joust as a kid and spent countless hours playing it. Unfortunately the physics don't work as well as in the original. When you hit another player, the bounce is missing (and the egg, but I guess that's not important).


Joust, Blaster Master, Jackal, Life Force, Raptor: Call of the Shadows, and Arkanoid II. :)

Found Tyrian a few years back.


Thank you, that was an awesome bit of 5 minutes of nostalgia. I know it must have taken you hours to build, and I could only get a few minutes to play, but it was worth your effort, and thank you for sharing it here.


All I get, no matter how many times I reload is,

Error

--

We encountered an error when trying to load your application and your page could not be served. Check the logs for your application in the App Platform dashboard.


Yeah, shame I wasn't around when this got popular (I actually submitted it on Tuesday, but HN must have automatically resurrected it for a second try).

The whole thing is running on a $5 Digital Ocean Apps server (well, two actually, one in New York, one in Frankfurt so that I can get low latency here in France), so it's amazing that it survived as long as it did.

Had I known it was going to get this much love, I would have spun up a dozen more servers.


I played only the coin-op version as a kid, so I never played competitively with other humans (the two-player version is more cooperative than competitive). It's a very different game against humans!

A suggestion: when you kill someone, you receive the points that they had (min 1). Have each player's point total hover around their sprite. This would set a higher bounty on the better/luckier players and balance the gameplay a little.


Thanks for the Friday fun.

Bug report: Me and another player happened to spawn on the same spot, locking us in place and producing a satanic screeching sound.

Other than that, great mechanics!


Yeah, I had to add a Suicide Button (q) for that. It does spawn checking for players and platforms, but there must be a bug there, since you can still get stuck.


See also: Killer Queen (and Killer Queen Black)


I remember when this came out. I had travel planned to NYC and made a stop at the install location to check it out. It was closed.

Fortunately, Portland got one at Ground Kontrol not long after. It was a lot of fun recruiting new people to try and fill in all 10 spots. It was pretty funny when a snail win got close and people started chanting “snail! Snail! Snail!”

I tried a tournament and had less fun. The game needed balancing and it took some time to get out there.

Still, very cool it evolved from a physical game.

Iirc, some valley-based startups bought some of the original cabinets. Anyone know which?


that was my immediate thought


Amazing work. Childhood vibes were seriously kicking in while playing this. Now if only I could get my brother here to constantly yell at me to stop cheating it would really bring me back.

I just played on my pc and the only issue I encountered was a noticeable amount of lag.


This reminds me of Ready Player One story mentioning Joust https://readyplayerone.fandom.com/wiki/Joust


Great work on the 'feel' of the movement. Would love to know how the gravity/jumping works.

I'm a little disappointed the sound effects of the feet are missing - that was one of my favorite things about Joust.


Gravity is just a constant acceleration downward, so nothing special there.

I have the footstep sounds ready to go, but I found that I really needed to limit what sounds I played because they get overwhelming pretty quickly. There's now a pretty tight radius to the player for what gets played.

First cut was to have all 200 players' flapping sounds audible to everybody. That was suboptimal...


For the footsteps, it’s probably fine to only play the fx for the one character the player is controlling.


Tried to toggle sound, now it's down.

> We encountered an error when trying to load your application and your page could not be served. Check the logs for your application in the App Platform dashboard.


Played 5mins, had a blast. Great job :)


Neat! It's definitely crashed right now. I think we hurt it.


So neat! Where are the left/right controls on iPad?


Why not implement some kind of chat feature as well? Maybe push enter to type something and it will appear above your head.


Unplayable for me. My character's movements are very rough and they're jittering all over the place.


That was awesome and brought me back to being a teenager in the 80s. Someone go build the same for Berzerk!


On Safari using an iPhone XR, the left and right movement buttons are obscured by the bottom navigation bar.


Yeah, mobile safari is annoying in that it doesn't allow fullscreen mode for anything except video. And that it doesn't always leave you in a consistent scroll state or with knowledge of how much screen is visible. So the left/right buttons drop off the screen unless you scroll it a bit before hitting start.


Came to say the same about the original iPhone SE. I thought it was because mine is a smaller model (most sites look weird on it these days). But now I guess that's not the reason.


Just use Chrome. It is the sane choice.


There is no choice on iPhone


Christ what a platform. I see, and stand corrected.


Very fun. My suggestion would be add sounds like "triple kill", "killing spree".


Wow, what a throwback. Haven't played it in 30+ years but was surprised to find myself trying old tactics immediately. (Too bad "ceiling" bouncing doesn't work, or maybe it's just the lag.)


Very cool! Bug: sometimes my ostrich would stop walking. I could even press the arrow key pointing the opposite direction. The sprite would change to face the new direction but keep moving in the old direction.


One of my favorite arcade games ever. It's unfortunate that it doesn't have the same cultural cachet as the likes of Pac-Man and its cohorts.

I'll have to link this to my Dad so that we can have a quick deathmatch!


Thank you! Joust was a sort of second-tier video game back in the day and I felt it never got quite the love it deserved. I bought the Sony PSP solely for its implementation. This is wonderful.


HN gentle hug of death.


On a tech site like this can we please bring 'slashdotted' as the verb to describe a non-malicious DDoS?

/. atleast earned the right to coin the term.


/.ed implies /.-originated. Hug of death is the HN equivalent. /.ed / HoD seem to also be used for popularity DDoSes generally.


One of my all-time favorite games, thanks! Brings back the days of kids hanging around Brother's Pizza and playing Joust on the consoles.


I had a lot of fun, but there's a big incentive to hit idle players. I would suggest making players intangible until receiving their first input on respawn.


I have a joust-esque game as well but never released it because of fear with copyrighted graphics. Is that a risk with something like this?


I played for a few minutes then clicked back, and I'm still hearing the sound effects. It's kinda weird

edit: after closing the tab they stopped.


On mobile, it's not obvious how to do anything other that fly up by tapping the screen.


I feel like it's a little less responsive to movement than the real game.


Loving that my decades-old arcade skills still work :) Great job!


Most fun i've had in a long time playing a game. Thanks!


Reminds me of good times playing Killer Queen in Chicago.


This was hilariously fun to play. Thank you! :)


I had to reload a few times for the page to load.


Thats awesome. Would love to see match statistics


You can see current leaderboard if you press Tab


Well done! Can you please do Robotron next?


Robotron got a fantastic port for the 2600 recently [0] (WIP). It supports twin-stick mode but that's pretty unusable on original Atari controllers without a special rig. Genesis controllers work on the 2600 and I've been trying to convince them to add a configuration like Smash TV did for NES (sideways controller in each hand, D-Pads only) but no one knows what I'm talking about. It was such a comfortable way to play twin-stick and with the Four Score you could even play 2 player.

[0] https://champ.games/downloads ("RobotWar 2684", Games in Progress section)


Well, I'm done working for the day. :)


It's unplayable on a 1366x768 screen.


Love the sounds!


That was extremely fun -- Go Team Blue!


I love it, thanks for sharing!


Hug of death'd!


This is magnificent.


So go. Thank you!


domain suspended


that was fun. nuff said.


How do I win in this game? You should include some instructions so that newcomers can enjoy the game instead of being confused. Also, I have a fast connection, yet I experience massive delays during the game. Great work though, thanks for making me try this game.


Browser vim plugin prevents me from playing.


Click on the extension, then "save changes". It'll add an exception for the site.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: