Advertisement

Server Handling of Game Objects

Started by January 24, 2014 01:14 PM
2 comments, last by hplus0603 10 years, 10 months ago

Ok so I've been interested in building an online game for quite some time, mainly as a learning experience, but also as a fun project. Now don't go all anti-mmo, not good enough without 50,000 people on my team, whatever on me. This is a simple question to gain new knowledge.

So I've been studying various articles and posts and basically anything I could get my hands on, but one... well several questions keep popping into my head, but one major one in particular. And I can never seem to find a concrete answer just a lot of theory and discussion.

Server Objects...

How does the server and database interact? For instance, when the server starts up, does it create a list/array of all the game objects (i.e. Mobs, Props, etc...) And store them as a simple unique id reference and then pull the data from the database when necessary, or does it create a new object based on a class, give it a unique id and then store all the data about that object that's necessary in it from the database and add it to the list/array? Or is it some sort of hybrid system that uses the best performance features of both systems?

Basically how does the server store the game world objects? I mean we're talking like... 10K+ objects just for a basic online game right? That's a lot... then considering having to sort through all of those when you need to get information on a specific one.... Is it just a giant list of all the objects or are they separated into several list/arrays, like one that holds all the mobs, one that holds all the items laying on the ground from the last plio-platipus monster you kicked the crap out of.... Then based on the interaction (method call) you sift through the list/array you need...?

I could think of a million ways to do this but I'm sure there is a best performance method that is commonly followed.... Any thoughts?

Most of MMOs seem to simplify this aspect to save on amount of objects. You can't drop items, mobs are spawned when server is running, not saved on shutdown and restored. What persists is a state of player mostly (inventory, stats) and probably a lot of event/action/state logging for further reference (I bet that stat collecting takes way more resources than actual player data in such games).

Also 10K+ objects is not too many for a single MMO server, a single player can have hundreds of objects stuffed in vault, on his character etc. Even considering what I said earlier (that usually only players are persisted, and game world state isn't really saved much) thats still way less than average MMO has in its database.

I'm by no means expert on this, its just observation of many MMOs I played. All of them avoid saving game world state as much as possible - probably due their "massive" nature. Thats also why I think we're plagued by massively bad games, but thats another topic smile.png

And just a tip for the future - try to avoid using "M", its usually better looked upon by people. Its not like there can't be an online game that hosts up to several hundreds of concurrent players and don't have million dollar budgets. We can also talk about such projects, and using term MMO in there usually screws a discussion that could otherwise be quite nice and informative. People tend to dislike hearing that someone "tries to make MMO" but if you try something less massive (not thousands of players online and hundreds of players accounts) it usually brings way warmer discussions.


Where are we and when are we and who are we?
How many people in how many places at how many times?
Advertisement

Yes I figured that players are basically the only persistent data, or data that dynamically changes as far as the database goes. Monsters are obviously going to spawn at runtime. And I know that we're talking more like 100K+ objects not 10K+, as far as an MMO goes. I've actually operated and worked as a dev for private mmo servers for more than 5 years, so I have a pretty substantial understanding of how they operate. It's simply the actual code and how the application itself operates that I'm a little hazy on....

The way I see it there are 3 options:

1. The server creates a list/array of every game object that is necessary at runtime (Mobs, Porps, etc...) and assigns each entity a unique ID, then when some form of interaction is initiated (AI Movement, Combat, etc...) the server simply acts as a medium and may do calculations within the query to the database, or something.... Problem: How would each unique ID understand what it represents, not to mention you would have to store even temporary values within the database. The server would be making a ton of connections to the database over and over so long as the server is running. For every little detail the client would make a connection to the server then the server would make a connection to the database. Obviously this would be a hug resource hog and WAY too many connection states. You'd need like 3-4 times as many connections as the number of players logged in.

In this case I would say the database is authoritative over the server, and the server is authoritative over the client.

2. The server has various classes that store both data and methods. When the server is launched it creates every game object, calls the database to set the values of each piece of data within each object then adds the object to a list/array. In this case, most interactions happen between the client and the server, very little interaction would be needed with the database, aside from saving the player's current state every now and again. Basically the database is used as nothing more than a reference for the server's assets. Problem: Runtime would suck! The server would be making a crap ton of queries to set each and every object, not to mention that the server would then be "beefed up" with a ton of data. Obviously you could minimize this by only updating objects that are within a players view, but it would still be a memory hog. In which case you would do just fine using a SQL CE Compact database file to store your actual game data, and then could minimize the player states to it's own higher end database. I believe Perfect World uses this type of design, both their client and server use a simple database file similar to a SQL CE file to store and load their game data, but have a MySQL database that stores both account and player data.

Here the server is authoritative over both the client and the database.

3. A Hybrid System: This of course would blend both options 1 & 2 into a more complex operating system. But seeing as I've never really seen one in action I couldn't say for certain how it would work unless I designed one myself.

Obviously I've thought a lot about this but ultimately haven't come to a concrete conclusion as to what the best design would be. I would say 2 sounds great, but I'm not so sure if the resource hogging is really the best thing.

Then of course I was talking about how the server actually stores this data... is it a list, an array, some sort of custom container? And would there be a single container to hold all of the game objects, players included? Or would I create multiple containers and simply access the one that I need when necessary. I would think the later option, but I've been wrong before which is why I'm asking.

Also, there was one other thing I was curious about... I assume that the server is nothing more than an application that responds to events triggered by a client connection. The client however is a game application that is running a tick rate and updating itself every tick. From what I understand a client is getting updated from the server somewhere around 20 times per second, although it would be more in line with ticks.... so if 60 ticks = 1 second then the client would be updated once every 3 ticks??? Would a connection be sent and response received in that amount of time? I doubt it....

But anyway, so what if say... an admin sends out a message to the entire server? Obviously the admin's client would take the message send it to the server for processing but then how would it be distributed to the clients? Wouldn't the server require the network information for each client currently connected in order to send something to it? In which case when a client logs into the server, is it also sending it's local network information to the server for temporary storage and then the server is iterating through every connected client and using it's connection information to distribute a mass text message?

In which case, when a client logs in is it creating a new client/player object and assigning it values like say the client's network information, it's unique key, the characters current hp value, etc... then acting upon that object when new actions are called, like distributing a message or when a monster attacks, etc? Or is all player related information only stored and accessed through the database, and only non-player data is stored within the server temporarily during it's active state?

In which case, is the client sending a request to the server for an update of the current state within the player's surroundings 20 times per second and then receiving that data and updating the client, or is the server sending data 20 times every second for the client to update itself?

How to structure the objects, rules, and interactions, actually varies. The main driver is gameplay -- what are the needs of your game? A MMOFPS with continuous streaming has very different requirements than a space-based "hyperspace jump" MMO trading game, which in turn has different requirements from a limited-travel-speed RPG.

It is typical that objects and rules are enforced in a persistent process that runs the game simulation. The authority for an object lives in that process, which means it lives in RAM in some particular server hardware. To not lose "too much" state if that process crashes, the objects will checkpoint their state back to a database at some interval. Typically, these simulation servers will be geographically based; area X maps to server 1, area Y maps to server 2. If you support continuous movement (no zones) then the servers need to talk to each other to keep the simulation running, and allow interaction between objects that live on different servers. Personally, I think the gameplay "win" is not big enough to warrant the significant implementation and maintenance "cost" of that feature -- "zoning" between areas (or hyperspace jumping between stars, or whatever,) makes everything so much simpler.

Some rules may not live in RAM on simulation servers. For example, trading and inventory might be implemented as a more traditional web/database service. This gives you a better defense against "object cloning" or other kinds of hacks/attacks, and object loss if a server dies. A database gives you ACID guarantees :-) But it's not fast enough for things that change every simulation frame, like object position or health or whatever.

enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement