How to Make Multiplayer Online Games

Поділитися
Вставка
  • Опубліковано 20 сер 2024

КОМЕНТАРІ • 100

  • @idkncc
    @idkncc Місяць тому +222

    Finally new video from my favorite web developer!

    • @ABCABC-sw8mh
      @ABCABC-sw8mh Місяць тому +14

      Vid From fav web, game, c, c++, python, programming language, ...., game engine, ... all developer

    • @Eldarlll
      @Eldarlll Місяць тому +20

      My favorite JavaScript influencer!

    • @weekipi5813
      @weekipi5813 Місяць тому +5

      💀

    • @nonefvnfvnjnjnjevjenjvonej3384
      @nonefvnfvnjnjnjevjenjvonej3384 Місяць тому +4

      can your python do that?

    • @Labib2003
      @Labib2003 Місяць тому

      ​@@nonefvnfvnjnjnjevjenjvonej3384why are you interested on what peoples "python"s can do? 😏

  • @cryptonative
    @cryptonative Місяць тому +30

    Bro: I don’t have any experience with networking
    Also bro: Written a web server in assembly

  • @rebokfleetfoot
    @rebokfleetfoot Місяць тому +42

    sync of the multiplayer was an issue, we blamed it on Einstein and his time dilatation theory :)

  • @BboyKeny
    @BboyKeny Місяць тому +16

    As response to the question at 20:00. I've been using vanilla JavaScript with Esmodules and Jsdoc comments. Typescript LSP can parse the doc comments from .js files. That way I'm not using any dependencies or build system while having types and an LSP.

    • @dealloc
      @dealloc Місяць тому +7

      Delivering ES Modules without any bundling will make it more difficult for you to deliver a good user experience and avoid waterfalls, especially as you add more and more code and internal dependencies.
      Instead of bundling the necessary parts, and minifying them for higher compression ratios, you are delivering a dependency graph for the client to resolve through network boundaries. Sure you could try to manually structure your project such a way that the code necessary for a given page is delivered in the least amount of network boundaries, but you now have to make decisions of where place your code in which modules to prevent waterfalls.
      Great for hobby projects and small apps with very few modules, but not ideal for user experience-and your servers-if you want to scale beyond that. There is no such thing as "no dependencies" when you rely on ES Modules; each import statement creates a network-bound dependency in the browser.

  • @mthia
    @mthia Місяць тому +2

    the twitch chat as subtitles is the best things i've ever seen

  • @greyshopleskin2315
    @greyshopleskin2315 Місяць тому +30

    Thanks for all your videos.
    Nowadays people just act as consumers of high level, messy abstractions without understanding the basics.
    Complex solutions are invading each area and people think it is cool and the right way.
    I’m so, so sick.
    I enjoy your recreational programming videos. They help me learn about different topics and understand a little bit better the basics.

  • @im-anomalies
    @im-anomalies Місяць тому +3

    I just have finished to watch the previous yesterday after work and here we are again! My fav content on yt

  • @sanjaux
    @sanjaux Місяць тому +17

    These thumbnails are so good lol

  • @Hazanko83
    @Hazanko83 Місяць тому +6

    I'm building a game/engine and have written all of the networking stuff in pure UDP. There is a ton of stuff you can get away/be lazier with in a single player game; put simply you can be lazier with your data and overall layout.
    In a single player game you can make a ton of assumptions, and/or rely on work that's already been done elsewhere.
    A good example is, on the server application(or in single player mode), every character has a ton of values associated with stats and bonuses and what not. For the client to properly simulate what's on the server, you'd need to either send a massive chunk of data from the server every single time a new character was visible, or find a way to detach various actions from their full simulation and send a tiny packet and expand upon it client-side. Do you send a damage value with the projectile_add packet? what if the damage isn't calculated until hit and there are crits/resists/etc?
    Then, obviously the nightmare that can be async, combined with the network layer and things like latency, dropped or re-ordered packets, etc. If a thread keeps getting blocked and goes to sleep, in my experiences the debugger isn't going to help, so it's print-to-console-debugging and other logging systems built into the program itself that you need to rely on. Sending some packets back and forth is incredibly easy and you could get something working in a couple hours probably, the bigger hurdle is the layout of your program being compatible with callbacks and simplifiying/minimizing interaction points between threads. Most of the system could be ''working'', until you put it under any load and realize it's constantly hanging waiting on main or networking thread... WHO KNOWS !?
    The 'plus-side' is though, doing the work to align things for networking usually means any sort of future feature-extending becomes easier. Certain abstractions or gains that you might think pointless for a single player game or might not even think of until you'd explicitly need it, can actually end up being a gain regardless. Something like allowing a player to save their game is really easy when you already have data accessible and formatted for network messages.
    Being that I decided to go with full UDP, I had to build the packet handling system for things like confirmation and resending for missed replies, connection/time-out/etc. TCP would be much easier I'd imagine in many ways, and would likely be the way to go for anything not intending to work on a larger scale(or maybe period lol).

    • @StevenMartinGuitar
      @StevenMartinGuitar Місяць тому

      If you need reliable network comms, which you hinted at with confirmation and resends, then TCP likely would have been more appropriate

    • @Hazanko83
      @Hazanko83 Місяць тому

      @@StevenMartinGuitar Part of it was obviously learning, as this was my first networking system I've built. Unless you need confirmation/resends/etc on every single message going out, I think you'd technically be able to build a more performant and scalable system going with UDP.
      I don't like that TCP handles the connection and timeout stuff, and that's really easy to implement on top of UDP. A good portion of the fast -flying messages could technically get dropped without issue and I wouldn't want to potentially halt communication on required packets for TCP to catch-up(I do have systems in place for package sequencing to prevent out-of-order messages).
      To be honestly I'm not entirely sure how TCP handles confirmation, but I'm assuming it uses some sort of hashing function + sequence, but on the entire outgoing packet and not individual messages within? Currently certain things are easier, or even possible at all, because I can build my own confirmation packets for certain situations.
      There's also the fact that TCP headers are at least 2.5x larger than UDP packet headers, and since not every message can get bundled into a larger packet it can add up quick.

    • @borstenpinsel
      @borstenpinsel Місяць тому

      The trick is, you don't need to send a ton of data. Only the bare minimum. Basically location and direction and some visual queues like of they're holding a pistol or a bazooka, crouch/jump status. That's a handful of bytes.
      Everything else is client side or doesn't need to be updated as often. Location, you need every game frame. Their health, maybe every 10 or more seldom and only if you want to display it to the player. Otherwise bool alive/dead is sufficient.
      Same for every other stat/visual, like making them glow when they have a power up or rendering ice on them when they're frozen in some magic rpg game.

    • @borstenpinsel
      @borstenpinsel Місяць тому

      ​@@Hazanko83about the UDP/TCP. Ever since Google invented QUIC and managed to emulate TCP while using UDP, essentially rebuilding TCP from scratch and making it better and faster with less overhead, without the annoying slow start mechanic that was created 30+ years ago when 128kb/s was considered fast Internet. I think for most applications, it's better to not use TCP anymore, if you can use QUIC or something like it.

    • @Hazanko83
      @Hazanko83 Місяць тому

      @@borstenpinsel Yes exactly. Client-side, all network characters regardless of whether they are a player or NPC don't use the full Player/NPC class but instead a network variant that only requires the bare minimum: things like movement, location, health/mana/etc, flags for combat and what skills are active, and then basically all the other stuff can be tied to uniqueIDs for what character to show and their weapon and what not.
      Location and velocity I send at a variable update rate depending on if they are moving at all, on a normal path, or if the path is congested with a lot of obstacles and/or there are collisions. Pretty much everything other message for things like health updates or flag changes are handled on events and obviously don't need to be sent regularly, or only needs to be sent upon the initial 'server-add-character' message

  • @aredrih6723
    @aredrih6723 Місяць тому +1

    (just some general feedback/through on the project. Not meant to be feature request; just take on the way you're going so feel free to ignore them)
    So, a problem with having the entire state of the game to the client is that the client has the entire state of the game.
    So wallhacks are hard to prevent with that design.
    Another point is that you have a full server round trip every time a player tries to move (and the final position is decided by the server).
    Not the worst on low latency but effectively not having direct control over your character can jarring.
    Giving players control over their position does open up room for abuse but nothing a "trust but verify" approach can't prevent.
    But if you allow player to decide were they are, there are "fun" desync that can happen with 1 player stopping before a corner an another one shooting the server prediction going past the corner. One think they shoot the other, the other thinks they didn't get exposed.
    How you deal with that has to be decided by what feels right. You can make slowing down be slugish to reduce the size of the server misprediction.
    The most complex games engines I've seen had timestamp in client message and rollbacked the server state to process event sequentially.
    Even then, the issue had to be decided based on what felt right to avoid being biases toward player lagging and because you kinda want to reward head shots.

  • @SuperDarkBoss
    @SuperDarkBoss Місяць тому +5

    Love seeing your videos, man !

  • @lengors7327
    @lengors7327 Місяць тому

    1:07:50 While it doesn't generate the function, but with the newest version, it does infer the return type (`arg is Test`) if you follow some rules (which helps reduce code bugs). There's also some libraries out there for it

  • @byterbrodTV
    @byterbrodTV Місяць тому

    Can't wait for continue.
    Thank you for all your content!

  • @antonpieper
    @antonpieper Місяць тому

    2:10:09 the difference is that interfaces get merged, so if you declare an interface Vector2, you can later redefine the interface and it won't replace it but rather merge it.

  • @ronaldninhoooooo
    @ronaldninhoooooo Місяць тому

    Did I just watch whole vod on my holidays with gf? Of course, first things first

  • @bbq1423
    @bbq1423 22 дні тому

    3:00:06 If you change from interface to type you’ll force the users of the type to initialize all fields, solving the problem

  • @TheEyeOfBrows
    @TheEyeOfBrows Місяць тому +1

    On BSON: I used it quite a bit, and found it lacking for my purposes. I wanted smaller network messages, but the BSON serialized messages wound up being about the same size as the equivalent JSON. We switched to protobufs where we don't need readable strings.

    • @dealloc
      @dealloc Місяць тому

      Haven't used BSON much, but used to use MessagePack back in the day. And while it was not terrible for its time, it wasn't great for real-time either, and still very heavy. If I had to choose a format for delivering packets in real-time, it would not be either of those, that's for sure.
      I'd rather bite the bad apple and then either use protobufs (which has its own downsides; recommend reading "Protobuffers Are Wrong" by Sandy Maguire), or "just" manually define protocols and figure out a plan for compatibility with the team.
      It's a bit easier if you control the client and force people to update in case of protocol changes so you don't need to think about backwards-compatibility. But in cases where you can't, protobuf may be a safer choice, or flatbuffers depending on your needs.

  • @snarkyboojum
    @snarkyboojum Місяць тому +1

    Crazy that Doom was usually getting about 35 fps on then current hardware when it launched in 1993 ;)

  • @realcristir
    @realcristir Місяць тому +1

    If you want to make it even fancier, add proximity voice chat

  • @SeishukuS12
    @SeishukuS12 Місяць тому +1

    Not too far off from how I did multiplayer in my engine, though I'm still kind of stuck trying to figure out getting physics objects synched without blowing up the simulation or needing insane amounts of bandwidth.
    I also added networking pretty late in my engine's design, it wasn't *that* bad adding it in... Not saying it's pretty, it's still pretty much hacked in still, but wouldn't take much to clean it up. lol
    It's something that's fairly low priority.

  • @muhammadmustafa3158
    @muhammadmustafa3158 Місяць тому +1

    Awesome stream zozin :)

  • @taba1950
    @taba1950 Місяць тому

    You happened to be in the lucky situation where your .mts and .mjs are in the same place so you can just switch to .mjs.
    Usually the correct way to import typescript files .ts .mts .tsx you just omit the extension and in the case of index.ts you can also omit the file name (just specify the directory containing the file)

  • @jackzugna5830
    @jackzugna5830 Місяць тому +2

    7:16 It's literally Xorg 👀

  • @glowiak3430
    @glowiak3430 Місяць тому +2

    51:08 NBT also exists

  • @kirillvoloshin2065
    @kirillvoloshin2065 Місяць тому +2

    you are a legend!
    p.s. как же я ору с чата на твиче 😀

  • @cariyaputta
    @cariyaputta Місяць тому

    Amazing playlist. Thanks.

  • @antropod
    @antropod 27 днів тому

    Never realized subtitles are chat messages

  • @egoat-xyz
    @egoat-xyz Місяць тому

    Awesome episode, Im grateful

  • @mikejohneviota9293
    @mikejohneviota9293 Місяць тому

    new follower of this genius dude

  • @RandomGeometryDashStuff
    @RandomGeometryDashStuff Місяць тому

    02:07:22 valid directions: __defineGetter__, __defineSetter__, __lookupGetter__, __lookupSetter__, __proto__, constructor, down, hasOwnProperty, isPrototypeOf, left, propertyIsEnumerable, right, toLocaleString, toString, up, valueOf

  • @EliasOjeda-mv6cg
    @EliasOjeda-mv6cg Місяць тому +1

    why is the twitch chat showing up on the subtitles owo
    edit: i just realized now lol

  • @umapessoa6051
    @umapessoa6051 Місяць тому +8

    Sorry for being 30 seconds late :(

    • @munto7410
      @munto7410 Місяць тому +1

      I was a whole minute late 😔

  • @hedlund
    @hedlund Місяць тому +1

    God damn I love yasnippet. Such a massive (potential) time saver it's sort of ridiculous.

  • @Sourcer3r
    @Sourcer3r 24 дні тому

    At 46:32 (extension on import) I like the way you think 🙃
    Probably deno and bun will serve you better 😉

  • @doodocina
    @doodocina Місяць тому +1

    tsoding is real sus when it comes to explanation, he really shows the path from dumb to "let`s try that, sounds cool"

  • @kevinkkirimii
    @kevinkkirimii Місяць тому

    enjoyed this episode.

  • @btarg1
    @btarg1 14 днів тому

    Tsoding trying godot 4 would be fun to watch

  • @vxcute0
    @vxcute0 Місяць тому +1

    I am glad I lived until I saw tsoding turning into a web developer

  • @rebokfleetfoot
    @rebokfleetfoot Місяць тому +1

    plus we were dealing with like 96K bits per second

  • @texodus_et6313
    @texodus_et6313 Місяць тому

    My ultimate hatred for JS grew exponentially ... Stay Up G and keep em coming!

  • @lucyper8921
    @lucyper8921 Місяць тому

    3:03:45 Forgot to consider the player size when you hit the boundaries

  • @11WicToR11
    @11WicToR11 Місяць тому

    1:05:15 ...these typeguards are going away in next version of typescript, it will assume it automatically (not sure to which extend tho)

  • @RandomGeometryDashStuff
    @RandomGeometryDashStuff Місяць тому +1

    12:35 yes, there is from gpu to cpu
    how else would screen recorders like obs work?

  • @alexnik1181
    @alexnik1181 Місяць тому +1

    Hello mr Tsoding, have you ever done a NES emulator?

  • @IgneousGorilla
    @IgneousGorilla Місяць тому +1

    This mf does in 3 hours what would take me 30

  • @rormah
    @rormah Місяць тому

    @TsodingDaily Would using protobufs be a good alternative to JSON?

  • @antran1686
    @antran1686 25 днів тому

    What is the problem with using something like zod to define the types for the payload and using zod parse instead of this custom function

  • @affanyunas7693
    @affanyunas7693 Місяць тому

    it was like he was using js on purpose and wanted to mock him. lol

  • @shrddr
    @shrddr Місяць тому

    data is pronounced data unless you're The Cherno

  • @justfly1984
    @justfly1984 Місяць тому

    Type guards automatically works in TS 5.5.3+

  • @Chukilled
    @Chukilled Місяць тому

    My porn folder is much greater than 53GB...

  • @user-ez6dn5do9p
    @user-ez6dn5do9p 24 дні тому

    Hello Tsoding / whoever it my interest. Could you please share your emacs else vim plugins/configurations?.New fan here and am amazed at how you immediately find docs for functions. e.g At timestamp 53:02

  • @RandomGeometryDashStuff
    @RandomGeometryDashStuff Місяць тому

    01:12:00 what if server sends bogus-amogus message that is not valid json and JSON.parse throws error?

  • @bekirkagankaraahmetoglu4343
    @bekirkagankaraahmetoglu4343 Місяць тому

    I want to know how you did that at 40:00

  • @blackhaze3856
    @blackhaze3856 Місяць тому

    Waiting for moving this project to urmom vps.

  • @belskun
    @belskun 22 дні тому

    Why is it called properMod, can anyone explain?

  • @rebokfleetfoot
    @rebokfleetfoot Місяць тому

    it's corncob 3D :)

  • @nathanpotter1334
    @nathanpotter1334 Місяць тому

    1:52:26

  • @user-nx8pg3gw8d
    @user-nx8pg3gw8d Місяць тому +1

    What is text editor?

  • @dimadem
    @dimadem Місяць тому +1

    лучший

  • @MemeConnoisseur
    @MemeConnoisseur Місяць тому

    2:21:22 📑

  • @_jam1eK
    @_jam1eK Місяць тому

    btw, why tsoding use ts even he doesnt turn any linter option.

  • @nullternative
    @nullternative Місяць тому

    56:59 fkin LOL

  • @frostheavenangel
    @frostheavenangel Місяць тому

    Found a BUG !!!!! When i throw multiple bombs, i only hear exploding sound when the last one explodes. And also sometimes if i throw a bomb 45deg at the corner of a block, it goes inside, like ignoring collisions.

  • @nyyakko
    @nyyakko Місяць тому

    Pog

  • @umapessoa6051
    @umapessoa6051 Місяць тому +3

    30 seconds and 2 views, tsoding really fell down.

  • @nevork7578
    @nevork7578 Місяць тому

    Твои видосы отличные, но мне, как русскоговорящему, тяжело слушать русский акцент) Если тебе не похуй на мой совет, то изучи правильное произношение звуков в английском. Например звук "т" в англе совершенно другой (и при этом не сложный бтв)

    • @Tezla0
      @Tezla0 Місяць тому +5

      Видимо ты единственный, кого акцент не устраивает. Все спокойно смотрят

    • @nevork7578
      @nevork7578 Місяць тому

      @@Tezla0 завидую

    • @rubyciide5542
      @rubyciide5542 Місяць тому

      You are a sooka babushka then , (don't heck me bliss)

  • @hamyncheese
    @hamyncheese Місяць тому

    I am hoping that I stop watching political hacks and that I start learning from a master here

  • @girlswithgames
    @girlswithgames 25 днів тому

    lowkey does feel like mr tsoding is writing JS like it's C. I would at least try to process events in their callback to have more event driven architecture. it could complicate the sequence of events but i think you can account for that. it would flow better with the nature of JS imo