How the multyplayer was implemented ? I didn't think out was possible to post multyplayer games on NG. Is it really hosted by ng, or is it on a private server from one of the dev ?
HO HO HOPE you become a Newgrounds Supporter this year!
We're working hard to give you the best site possible, but we have bills to pay and community support is vital to keep things going and growing. Thank you for considering!
How the multyplayer was implemented ? I didn't think out was possible to post multyplayer games on NG. Is it really hosted by ng, or is it on a private server from one of the dev ?
At 12/8/24 11:53 AM, AypS wrote:How the multyplayer was implemented ? I didn't think out was possible to post multyplayer games on NG. Is it really hosted by ng, or is it on a private server from one of the dev ?
as seen in the changelog at the bottom of the game description, it uses WebSockets, which is a full-duplex channel Web protocol that works on port 80 and 443, but is distinct from HTTP. I have no personal experience with WebSocket, but its API seems very simple, I suppose the callbacks are run in the JavaScript event loop just like most other APIs, so it might be safe to use without synchronization primitives.
there are older games that were multiplayer. I used to play these on Kongregate:
of course, they were made in Flash, so the Flash plugin bypassed the browser facilities and could communicate with game servers directly, somehow. I haven't looked further.
the server code is hosted in a server not controlled by Newgrounds. it is not viable for Newgrounds to host game code under any circumstances at all. the game seems to use Haxe. I don't know the technology used to make the game, but chances are it uses some framework that handles netcode automatically, however I wouldn't be surprised if the netcode was handmade, which I guess wouldn't be an enormous hurdle.
try this (instructions depend on Web browser):
I have no experience with multiplayer development, but it highly interests me.
At 12/8/24 04:14 PM, detergent1 wrote:At 12/8/24 11:53 AM, AypS wrote:How the multyplayer was implemented ? I didn't think out was possible to post multyplayer games on NG. Is it really hosted by ng, or is it on a private server from one of the dev ?
as seen in the changelog at the bottom of the game description, it uses WebSockets, which is a full-duplex channel Web protocol that works on port 80 and 443, but is distinct from HTTP. I have no personal experience with WebSocket, but its API seems very simple, I suppose the callbacks are run in the JavaScript event loop just like most other APIs, so it might be safe to use without synchronization primitives.
there are older games that were multiplayer. I used to play these on Kongregate:
https://www.newgrounds.com/portal/view/546677
https://www.newgrounds.com/portal/view/549091
https://www.newgrounds.com/portal/view/582433
https://www.newgrounds.com/portal/view/606437
https://www.newgrounds.com/portal/view/632070
https://www.newgrounds.com/portal/view/553689
https://www.newgrounds.com/portal/view/451163
of course, they were made in Flash, so the Flash plugin bypassed the browser facilities and could communicate with game servers directly, somehow. I haven't looked further.
the server code is hosted in a server not controlled by Newgrounds. it is not viable for Newgrounds to host game code under any circumstances at all. the game seems to use Haxe. I don't know the technology used to make the game, but chances are it uses some framework that handles netcode automatically, however I wouldn't be surprised if the netcode was handmade, which I guess wouldn't be an enormous hurdle.
try this (instructions depend on Web browser):
I have no experience with multiplayer development, but it highly interests me.
I'll check that out next weekend, but I think I understand how it works now. But to implement in this case seems to be very hard!
Thanks for your help!
At 12/8/24 11:53 AM, AypS wrote:How the multyplayer was implemented ? I didn't think out was possible to post multyplayer games on NG. Is it really hosted by ng, or is it on a private server from one of the dev ?
Doing the lightest of reverse engineering and building on what @detergent1 already said:
The game is hosted on NG but connects via HTTPS to an external server, tankmas.kornesjo.se, on a non-standard port, 25567. It then promotes that connection to a full-duplex WebSocket connection and proceeds to send and receive events in JSON format:
{"events":[{"type":3,"data":{"level":6},"name":"drop_marshmallow","timestamp":1733700813418,"username":"[censored]","room_id":1}]}
The netcode looks hand-rolled, though I could be wrong. The heavy lifting of synchronizing game objects seems to be handled by the OpenFl SharedObject library.
Saves (ie costumes and stickers) and time gating content (ie media only being available from a certain day forward) also seems to be handled by this external server. I'm not sure what the plan is long term. Maybe they'll upload an "archive" version? Also, I guess the non-standard port might be a problem for some (it explains why I can't play from my office).
kornesjo.se is obviously Swedish (Kornsjö?) and @jefvel is from Stockholm, so I assume he did the multiplayer. Maybe he can be enticed into this thread to give more details? I put forth honest flattery about how awesome Tankmas turned out, but maybe some has a more Swede specific bribe? Wax fish?
At 12/8/24 05:51 PM, AypS wrote:I'll check that out next weekend, but I think I understand how it works now. But to implement in this case seems to be very hard!
Thanks for your help!
I'm told this blog has some useful information about implementing multiplayer: https://gafferongames.com/
I've only ever read the "Fix Your Timestep!" poast
Hello!
Yeah, I wrote the websocket server and client for tankmas this year 🙂
It was actually the first time trying to do multiplayer for me, and it turned out to work surprisingly well. The server is written in typescript running on deno, but any language should work.
it works by clients sending their states to the server, and the server will send them back to all clients two times a second. The messages are just JSON strings, which works well enough.
It might be possible to up the update rate, but to me the game already feels very reactive.
To connect, the client sends their ng username and session id to the server, which then validates them using the NG api. This way it’s possible to ensure a user is who they claim to be.
At 12/10/24 05:03 AM, jefvel wrote:Yeah, I wrote the websocket server and client for tankmas this year 🙂
Dude! Pretty much everyone is saying this is one of--if not the best--Tankmaxen ever. A big part of that is the sense of community from your multiplayer. Thanks for goving this thread the celebrity treatment.
If you'll indulge in a few more questions, so we don't have to keep trolling through the source code:
1) With the updates being 2hz, are you doing any smoothing (ie between x,y positions)?
2) Are the events broadcast by the server passed directly from the clients or does the server do some of the game loop to "process" client input and broadcast the resulting events?
3) Related to #2, Is there any overlap between the client and server that had to be reimplemented in Typescript? I noticed the client is written in Haxe.
At 12/10/24 05:03 AM, jefvel wrote:Hello!
Yeah, I wrote the websocket server and client for tankmas this year 🙂
It was actually the first time trying to do multiplayer for me, and it turned out to work surprisingly well. The server is written in typescript running on deno, but any language should work.
it works by clients sending their states to the server, and the server will send them back to all clients two times a second. The messages are just JSON strings, which works well enough.
It might be possible to up the update rate, but to me the game already feels very reactive.
To connect, the client sends their ng username and session id to the server, which then validates them using the NG api. This way it’s possible to ensure a user is who they claim to be.
Thank you very much for talking some of your time to answer some of our question!
To add to alsoknowas1's questions, I was wondering on a security point of view:
(Web dev is not my speciality so it might have some obvious question)
At 12/8/24 08:53 PM, detergent1 wrote:At 12/8/24 05:51 PM, AypS wrote:I'll check that out next weekend, but I think I understand how it works now. But to implement in this case seems to be very hard!
Thanks for your help!
I'm told this blog has some useful information about implementing multiplayer: https://gafferongames.com/
I've only ever read the "Fix Your Timestep!" poast
This blog seems Indeed to hold a lot valuable information ! I'll keep that in m'y metaphoric pocket in case of future question!
At 12/11/24 03:06 PM, AypS wrote:[...]
Does newground accept any kind API request from within to an unknown server address ?
[...]
I'll let @jefvel answer regarding what his server does or doesn't do with your IP. There isn't really a need for it to pass that info along from one client to the next since all interaction is through the server and not peer to peer.
Regarding API requests, the short answer is basically "yes". Technically speaking, you can make any external request you want. I'm sure in practice there is some human oversight against abuse. On the tech side though, request between domains are controlled by two special HTTP headers (both of which have great articles on MDN):
and
These two headers somewhat redundantly (blessed web standards!) control how sites can access each other. The simplified rule of thumb is that by default a site can make any request it wants but that--also by default--sites will block all incoming requests. It's not quite so simple under the hood, but most people use CSP to limit the requests a site can make and CORS to lift restrictions on the requests a site will fulfill. You can thus think of the CSP as being used to restrict requests and the CORS to open them up.
A great example of this is the Newgrounds API itself. It's actually hosted on a different domain from Newgrounds games. If we use this CORS Tester to check if uploads.ungrounded.net (the Newgrounds game domain) can access https://www.newgrounds.io/ we see that it can't:
access-control-allow-origin: none
However, the API gateway at https://newgrounds.io/gateway_v3.php is special. It can be accessed, by anyone:
access-control-allow-origin: *
Regarding the CSP, if we use this secure header tester we can see that uploads.ungrounded.net doesn't even set the header. That means that by default it can call out to any site it wants.
So the default case is that Newgrounds games can make any requests they want, but the called sites have to allow the access as newgrounds.io does. To enable the needed headers usually requires high level server access. Most places that let you host HTML (or even scripts) won't let you do it.
And in case you're wondering, tankmas.kornesjo.se does allow anyone to access it:
access-control-allow-origin: *
Because of the need to serve ads, most sites aren't as locked down as you'd imagine. Montrose even did a performance art piece based on this. Here's a "Lights Out" clone running in this very forum thread:
At 12/10/24 04:08 PM, alsoknownas1 wrote:If you'll indulge in a few more questions, so we don't have to keep trolling through the source code:
1) With the updates being 2hz, are you doing any smoothing (ie between x,y positions)?
2) Are the events broadcast by the server passed directly from the clients or does the server do some of the game loop to "process" client input and broadcast the resulting events?
3) Related to #2, Is there any overlap between the client and server that had to be reimplemented in Typescript? I noticed the client is written in Haxe.
Hello! Thanks for the kind words, glad people are enjoying it!
At 12/11/24 03:06 PM, AypS wrote:At 12/10/24 05:03 AM, jefvel wrote:Hello!
Yeah, I wrote the websocket server and client for tankmas this year 🙂
It was actually the first time trying to do multiplayer for me, and it turned out to work surprisingly well. The server is written in typescript running on deno, but any language should work.
it works by clients sending their states to the server, and the server will send them back to all clients two times a second. The messages are just JSON strings, which works well enough.
It might be possible to up the update rate, but to me the game already feels very reactive.
To connect, the client sends their ng username and session id to the server, which then validates them using the NG api. This way it’s possible to ensure a user is who they claim to be.
Thank you very much for talking some of your time to answer some of our question!
To add to alsoknowas1's questions, I was wondering on a security point of view:
(Web dev is not my speciality so it might have some obvious question)
np!
The NG API allows you to make calls from anywhere, but some parts require you to be logged in. For that you can either play it directly on NG, it assigns you with a session ID that’s bound to your user. It’s also possible to sign in from anywhere using their Passport functionality, which launches a sign in page, and makes it possible to get a session ID that way.
So what I do is just pass the username and session id to the server, which work as sort of login credentials. I had it turned off until someone noticed they could spam login using any username 🙂
Every client is connected to the server, but they have no idea of the other players connections. The server just relays messages to other clients. So there’s no possibility for clients to see each others IP addresses
At 12/11/24 08:52 PM, alsoknownas1 wrote:Because of the need to serve ads, most sites aren't as locked down as you'd imagine. Montrose even did a performance art piece based on this. Here's a "Lights Out" clone running in this very forum thread:
That’s SO funny and awesome @kittyhawkmontrose :D
At 12/13/24 12:34 PM, jefvel wrote:At 12/11/24 03:06 PM, AypS wrote:At 12/10/24 05:03 AM, jefvel wrote:Hello!
Yeah, I wrote the websocket server and client for tankmas this year 🙂
It was actually the first time trying to do multiplayer for me, and it turned out to work surprisingly well. The server is written in typescript running on deno, but any language should work.
it works by clients sending their states to the server, and the server will send them back to all clients two times a second. The messages are just JSON strings, which works well enough.
It might be possible to up the update rate, but to me the game already feels very reactive.
To connect, the client sends their ng username and session id to the server, which then validates them using the NG api. This way it’s possible to ensure a user is who they claim to be.
Thank you very much for talking some of your time to answer some of our question!
To add to alsoknowas1's questions, I was wondering on a security point of view:
(Web dev is not my speciality so it might have some obvious question)
np!
The NG API allows you to make calls from anywhere, but some parts require you to be logged in. For that you can either play it directly on NG, it assigns you with a session ID that’s bound to your user. It’s also possible to sign in from anywhere using their Passport functionality, which launches a sign in page, and makes it possible to get a session ID that way.
So what I do is just pass the username and session id to the server, which work as sort of login credentials. I had it turned off until someone noticed they could spam login using any username 🙂
Every client is connected to the server, but they have no idea of the other players connections. The server just relays messages to other clients. So there’s no possibility for clients to see each others IP addresses
Thanks you for your answer and your time. And again tankmas this year is incredible!
At 12/13/24 12:54 PM, Dungeonation wrote:At 12/11/24 08:52 PM, alsoknownas1 wrote:Because of the need to serve ads, most sites aren't as locked down as you'd imagine. Montrose even did a performance art piece based on this. Here's a "Lights Out" clone running in this very forum thread:
That’s SO funny and awesome @kittyhawkmontrose :D
Hehe thank you. aka1 had the idea, and it was my time to shine with graphic design and fake ad copy. 😎 I just took a sample of what the current ads were and chose the themes based on the most common ones. "Titty" games and politics still rule the roost to this day.