• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Handling mobs and their collisions in a multiplayer game with multiple rooms

nickhadder

Member
Howdy all,

I am creating a MMORPG game (like RotMG) where there are multiple rooms the player can go into. The server is like the client where you can see the game world, fly around and look at everything going on while handling the server stuff in the background. However, im at the part where I want to start spawning mobs in the game that all the players can attack together and I want to sync everything up between the clients such as movement, attacking, and colliding with solids in the room. There are a couple of ideas that came into my head, but each have their own drawback. I just wanted to know if anyone on here is experienced in this topic or knows how game companies manage this in the real world.

For reference, the client and server are integrated into the same project so the server has the same room as the client does. There's just a super-secret way to boot it up in server mode.

Scenario 1:
The client that wants to spawn mobs around them creates them on the client side, then each mobs sends a message to the server so that it can spawn it in the room with everyone else in it. When the player spawns the mob (obj_clientmob), that mob keeps track of the collisions around it in the same room as the player. The server will spawn a obj_othermob for everyone else linking together with a GUID to keep track of which mob is which.

Drawbacks:
When the player leaves the room into another, I will have to convert the obj_othermob for another player into a obj_clientmob so the mob just doesn't suddenly stop working after a player enters another room so that other players that may be fighting the mob can continue to do so. Having to pick another player to take this over might be a difficult one if there are multiple to choose from.

Scenario 2:
Make the server go into all of the rooms at the very start of booting up the server and make all the collision objects and mob objects persistent so that when the obj_god object (that flys around the game world to see everything) goes back to the first room, all of the mobs and collisions are there in the background. I can easily hide mobs and collisions and prevent them from working for god and the other players if they are not in the same room as I already track that for each player. Then, I can just have the server manage spawning mobs around the players and handle the mob movement and collisions server-side.

Drawbacks:
The idea of having the server go through each and every single room, to make all the collision objects in the background doesn't seem like a very clean solution and as this game grows, we may be talking about a very large number of objects and collisions to handle at one time. I understand servers are supposed to be processing heavy for reasons like this, but if I can have each client handle the mobs spawned around them like in scenario 1, that might ease the server processing and allow it to run faster and more optimized.

If you have another scenario that is better than what I listed or any information on this topic, please let me know. I've tried looking all of the internet for a solution but couldn't find anything useful especially when it comes to Game Maker Studio 2. If anyone needs to know anything more about my game or look at some code, I would be happy to share.

Thanks for your help,

Nick
 

nickhadder

Member
I think so far, my thoughts are leaning towards scenario 2 and I can try and optimize it as much as I can (despawning all mobs if no players are in the same room, despawing mobs if no players are near them, only spawn mobs if a player with the same room variable is near enough a "obj_spawner" with the same room variable. Also, the server will only send updates to the clients about mobs if those mobs are in the same room as the player we are sending the information to. The main concern is that the server will have instances of all enemies and all collision objects (during a create event, i can have the collision object detect what room it was created in and save its room variable that way so i dont have to make separate collision objects for each room). I'm going to start developing it this way, but if anyone has any better ideas, please let me know and I will refactor. I just want to maintain industry standards so I know I am doing it the right way.
 

TailBit

Member
When the player goes into a room, and if the room handler om the server for it isn't already opened(existing) or full, then create a new instance of a room handeler .. have it load the map in data form, so it know where to spawn things and collision check from it (like a 2D array if your game is grid based), and have it keep an array of instances it spawn in it .. that way you can ensure that one player's action don't have to be shared to millions of ppl, but instead limit it to the 1000nd that is in this instance of the map, while the overflood of ppl will just make another instance of the same map with its own instance list of NPCs

So at the start of the game you have the server fill an array with all the maps that the room handlers can copy from ..
 
Last edited:

nickhadder

Member
Every room is "global" (except for a few rooms like the player's house) where if any player enters that room, then they can see all the other players and objects in that same room. A room will never be "full". If too many players join the game for the server to handle, I will invest in dedicating another server hosted to another region of the world (US - WEST server vs US - EAST server for example) that the user can choose at the start of the game. The rooms that are not global such as the player's house can be handled with ease just by the client side and there is no need to send packets to and from the server to keep track of anything (except maybe the player's chest at his house to save his chest inventory). If no player exists in a room where enemies can spawn, then there wont be any enemies spawned in that room untill the first player joins. If the last player leaves the room, then I can destroy all the enemies. I do not care about saving enemy state if someone leaves the room and comes back. I just want to create the illusion of enemies "roaming" around the game world. I think i'm gunna spawn these server side with the help of some obj_spawner objects that when a server player gets too close to one, (just outside the player's view ofcourse), then they spawn more. They wont spawn more if it detects it already spawned enemies and they haven't been killed yet and probably on some timer. As for the collisions, they can be created server-side by the server just entering the room with those collision objects persistent and have the server back to the main room. Each collision object will have a room_start event where it saves self.myRoom = room so the server can keep track of what enemies should collide with what collision objects (players have a self.myRoom variable as well that can be compared). When a collision object has a room variable with no players or enemies along with it, then that instance can be "deactivated" to hopefully save some idle processing power. Having a room handler object would be a great idea if I need to spin multiple instances of the same room for different people, but I don't think that applies to my game. Also, saving the room data in an object sounds like a huge memory waste for the server if the room in game maker is already housing the same data. Like I said, the server and client are the same project so the server has access to the exact same rooms as the client does. I will keep that idea in mind when developing future multiplayer games where it applies, but I just don't think that's necessary for this one.

Thanks for the idea!
 
Top