Jump to content


Using MySQL for a 2D MMORPG?


24 replies to this topic

#1 Ethanbot

    New Member

  • Members
  • PipPip
  • 23 posts

Posted 25 April 2006 - 06:23 PM

Hello everyone,

I'm writing a very simple 2D MMORPG game. Right now it consists of a single map, a single character sprite, and only the ability to walk around. I'm doing this to demonstrate how much easier having a ready and able database to use for the server-side end it is to get a 2D MMORPG up and running. I do, however, have one issue.

Though it seems to work pretty well as of now, at times it lags a little bit. I've only tested with two players, so I have absolutely no idea how it'll react with, say, twenty players on a single map, all buying things, fighting, chatting, etc.

I'm running the MySQL server off of this computer, my own personal one, and I'm still continuing my normal endeavors such as surfing the web, downloading things, etc. I do understand this will slow me down. My question, in the long run, is this: How can I beef up the speed of the MySQL server, and in turn, speed up the game? Can I somehow use the UDP protocol, wouldn't that help?

Any help from anyone would be greatly appreciated.

#2 Ed Mack

    Senior Member

  • Members
  • PipPipPipPip
  • 1239 posts

Posted 25 April 2006 - 06:55 PM

As much as you can try to optimise bits and pieces, I think having a beefy server capable of dealing with the load (or some sort of server cluster if things get that big) is pretty much the answer.

However, just don't worry till later :P Then you can beg faithful users ect..

#3 Ethanbot

    New Member

  • Members
  • PipPip
  • 23 posts

Posted 25 April 2006 - 07:17 PM

Ed Mack said:

As much as you can try to optimise bits and pieces, I think having a beefy server capable of dealing with the load (or some sort of server cluster if things get that big) is pretty much the answer.

However, just don't worry till later :P Then you can beg faithful users ect..

;) Mooching.. yes... good idea..

But seriously, if anyone has some optimization ideas, let me know. I'm very new to running my own server, but not much MySQL itself. Anyway, I heard UDP is better for games because the packets aren't verified like in TCP/IP. Is there a way to make MySQL use UDP?

#4 geon

    Senior Member

  • Members
  • PipPipPipPip
  • 812 posts

Posted 25 April 2006 - 08:07 PM

Eeeeh... You shouldn't let the clients connect to the database server (MySQL). The database should be used for data storage only, while your own server software communicates with MySQL. After processing the data can be sent to your clients via UDP.

The main reasons for this is:
* Security
* Modularity
* Simplicity

I also believe using MySQL for a project like this is a bit like shooting mosquitos with a minigun. I think a library like SQLite would perform better in such a scenario, since it is lightweight and you would skip the overhead of sockets.

#5 Ethanbot

    New Member

  • Members
  • PipPip
  • 23 posts

Posted 26 April 2006 - 03:48 PM

geon said:

Eeeeh... You shouldn't let the clients connect to the database server (MySQL). The database should be used for data storage only, while your own server software communicates with MySQL. After processing the data can be sent to your clients via UDP.

The main reasons for this is:
* Security
* Modularity
* Simplicity

I also believe using MySQL for a project like this is a bit like shooting mosquitos with a minigun. I think a library like SQLite would perform better in such a scenario, since it is lightweight and you would skip the overhead of sockets.

Thank you for your input.

At one point I had my own server programmed, and the game lagged much worse. It's actually faster than it was. I'm afraid writing a server to deal with everything may make it lag even worse than before. I'd also like to mention I'm using DXGame (Visual Basic 6.0), which I'm aware is not ideal for games, but knowing this may help everyone give me better feedback.

Is SQLite a database like MySQL, or something to access MySQL? As long as I can use it with VB6, I'll learn it. I do need to make this faster though, and I know it's possible, because I've seen people do it. I'm just doing something wrong.

Thanks again everyone for your help. Hopefully I can get some more feedback on this.

NOTE: The old server simply relayed data to the other clients, there was no storage, nothing. It was sent as a normal text string, such as ("MOVECHAR!CharNum,X,Y,Dir,AnimFrame"). I will not be using this system even if I implement a new server, I will still be using some type of database (preferably accessible using PHP as well). So instead of simply relaying, I presume the client would send something along the lines of my MOVECHAR command to the server, and the server would then query the database. This is obviously going to take more time, and in turn, cause more lag. My only option is to speed up my database and server, so once again, any ideas or tips you have will be greatly appreciated.

#6 geon

    Senior Member

  • Members
  • PipPipPipPip
  • 812 posts

Posted 26 April 2006 - 05:18 PM

Quote

It was sent as a normal text string, such as ("MOVECHAR!CharNum,X,Y,Dir,AnimFrame")

This would be the first place I would look for improvements. Switch to a binary protocol, instead of the text based. Normally, game protocols like these are heavily optimized to fit in as small space as possibly.

Count your commands. If they are less than 256, you can use a single byte to store it. Depending on the command, the following data would have a different meaning and different length. Doing it binary will also let you get away without a single string compare, wich could help.

SQLite is a database library, instead of a stand alone server. It means the SQL-engine will be directly integrated into the main application. To use it for networking, you need a server that can handle the connections to the clients.

#7 TheNut

    Senior Member

  • Moderators
  • 1397 posts
  • LocationThornhill, ON

Posted 27 April 2006 - 11:41 AM

It would help to know more about how you setup the DB and communicate with it. Typically you can use any database you want for any purpose. Just make sure you can create an infinite number of records (last time I checked MySQL had an upper limit) and stored procedures (supported in the latest MySQL?). Stored procedures make a big difference in performance when you need to access content frequently.

Secondly, you should minimize the amount of information you check from your database during runtime. You should copy meaningful content from the database over into server memory and access content via a fast algorithm like a hash/session (every player logged in should have a session ID). You should notice a significant performance improvement with this setup. You should also separate your DB server from your game server if possible.

As geon suggested, you should use a binary protocol over ASCII. In my engine I use XML, which I dispatch to a parser that converts the contents over to a binary network message with a header for the server to process (best of both worlds). It works very well with clients and with no noticeable performance penalty. The code is clean and easy to debug. For the server side, if performance is not an issue I follow the same format; otherwise I create an object for each message and dump the binary data directly into them.
http://www.nutty.ca - Being a nut has its advantages.

#8 Ethanbot

    New Member

  • Members
  • PipPip
  • 23 posts

Posted 27 April 2006 - 05:05 PM

TheNut said:

You should copy meaningful content from the database over into server memory and access content via a fast algorithm like a hash/session (every player logged in should have a session ID).

Are there any documents explaining some fast algorithms for this purpose? I'm still pretty new to anything networking. This is my first real multiplayer game. Any websites or tips from yourself or others would be greatly appreciated, as I'm still not too sure as to what you're saying.

Thanks for your reply.

#9 SmokingRope

    Valued Member

  • Members
  • PipPipPip
  • 210 posts

Posted 29 April 2006 - 02:52 AM

Ethanbot said:

Are there any documents explaining some fast algorithms for this purpose?

He's referring to a "Hashtable" which can generally be used to access data using an index of an arbitrary type. If each of your clients is referred to with a unique id you could then store data in your "Hashtable" for each client regardless of the value used as the id. When a client connects to your server you should then access your database and put whatever data is relevant to the client into said hashtable. This way you can 'quickly' access the data which is normally stored in the database by using the hashtable and the 'unique id'.

VB.Net has a built-in 'Hashtable' which you could probably put to use right away. Once you start using the hashtable you'll need to remember to save whatever data you have put into it back into the database when each client quits.

#10 Ethanbot

    New Member

  • Members
  • PipPip
  • 23 posts

Posted 29 April 2006 - 04:22 AM

SmokingRope said:

He's referring to a "Hashtable" which can generally be used to access data using an index of an arbitrary type. If each of your clients is referred to with a unique id you could then store data in your "Hashtable" for each client regardless of the value used as the id. When a client connects to your server you should then access your database and put whatever data is relevant to the client into said hashtable. This way you can 'quickly' access the data which is normally stored in the database by using the hashtable and the 'unique id'.

VB.Net has a built-in 'Hashtable' which you could probably put to use right away. Once you start using the hashtable you'll need to remember to save whatever data you have put into it back into the database when each client quits.

Two questions.

Can you give me a very simple 2D MMORPG example of using a hashtable (what info am I retrieving, etc)?

How can I utilize hashtables in VB6?

Thank you for your reply and hopefully your answer to my last questions. =)

#11 SmokingRope

    Valued Member

  • Members
  • PipPipPip
  • 210 posts

Posted 29 April 2006 - 06:26 AM

First to clarify, at least in VB.Net it's "Hashtable" or


dim myHash as new Hashtable() ' Create a hashtable


myHash.add(playerId, new Player()) ' Add a player into the hash

somefunc( myHash.Item(playerid) ) ' Call a function passing the player as a parameter


Anyway, a simple example of some data you might put into your hashtable would be your players coordinates or maybe their hitpoints.


Public Class Player

    Private hitpoints as integer

    Private maxhitpoints as integer

' Place Other Variables Here

End Class


You would then load a copy of this class into the hashtable for every player when they log in. Each time you make a copy of the class you would load the information from the database.

The real goal is to avoid repeated queries into your database when you're trying to achieve high performance. Each query into the database requires numerous instructions as the data is pulled from the filesystem, passed through the databases query mechanism and eventually cast into the proper data type in your program.

Using the hashtable and the class above you can achieve a huge speed increase in exchange for additional memory being consumed by your program. It's the classic speed/size trade off that plagues the world of program writing.

If you concern yourself with where you place your database queries and try to minimize the number of queries you make you can significantly speed up your program!

#12 Ethanbot

    New Member

  • Members
  • PipPip
  • 23 posts

Posted 29 April 2006 - 05:04 PM

SmokingRope said:

First to clarify, at least in VB.Net it's "Hashtable" or


dim myHash as new Hashtable() ' Create a hashtable


myHash.add(playerId, new Player()) ' Add a player into the hash

somefunc( myHash.Item(playerid) ) ' Call a function passing the player as a parameter


Anyway, a simple example of some data you might put into your hashtable would be your players coordinates or maybe their hitpoints.


Public Class Player

    Private hitpoints as integer

    Private maxhitpoints as integer

' Place Other Variables Here

End Class


You would then load a copy of this class into the hashtable for every player when they log in. Each time you make a copy of the class you would load the information from the database.

The real goal is to avoid repeated queries into your database when you're trying to achieve high performance. Each query into the database requires numerous instructions as the data is pulled from the filesystem, passed through the databases query mechanism and eventually cast into the proper data type in your program.

Using the hashtable and the class above you can achieve a huge speed increase in exchange for additional memory being consumed by your program. It's the classic speed/size trade off that plagues the world of program writing.

If you concern yourself with where you place your database queries and try to minimize the number of queries you make you can significantly speed up your program!

Well right now the only place I run queries is in every loop to retrieve the other players' positions. Isn't this the fastest and pretty much only way to do it, or are you saying to retrieve ALL the info and then pull it out locally? Is that truly faster?

Sorry for my ignorance and thank you for your help.

#13 SmokingRope

    Valued Member

  • Members
  • PipPipPip
  • 210 posts

Posted 30 April 2006 - 02:29 AM

The idea of the database is persistent storage.

I'm not being entirely accurate with this, but the amount of time you spend reading/writing with a database is going to be at least as slow as if you were to load the data from a file on the hard drive. If you're unsure of the speed implications of this i would definitley reccomend trying out writing a some functions to load/save data to file. Now replace your database queries with those functions. You'll quickly realize this isn't very efficient. Just because the query can be accomplished in a few lines of code does not make the database queries fast.

What you should really do in this case is keep all the data in RAM. Accessing data from RAM is much faster than reading from file or from a database.

#14 Ethanbot

    New Member

  • Members
  • PipPip
  • 23 posts

Posted 30 April 2006 - 04:15 PM

SmokingRope said:

The idea of the database is persistent storage.

I'm not being entirely accurate with this, but the amount of time you spend reading/writing with a database is going to be at least as slow as if you were to load the data from a file on the hard drive. If you're unsure of the speed implications of this i would definitley reccomend trying out writing a some functions to load/save data to file. Now replace your database queries with those functions. You'll quickly realize this isn't very efficient. Just because the query can be accomplished in a few lines of code does not make the database queries fast.

What you should really do in this case is keep all the data in RAM. Accessing data from RAM is much faster than reading from file or from a database.

Do you know of any sites that can explain storing in RAM using VB?

#15 SmokingRope

    Valued Member

  • Members
  • PipPipPip
  • 210 posts

Posted 01 May 2006 - 01:33 AM

Here you go... - Clicky

#16 Ethanbot

    New Member

  • Members
  • PipPip
  • 23 posts

Posted 01 May 2006 - 04:52 PM

SmokingRope said:

Here you go... - Clicky

=) Nice try, but I saw the URL before clicking it.

Other than that, I wasn't asking for general information, but personal preferred and personally suggested sites from you, as you seemed knowledgable on the subjects we've been discussing. Apparently I was mistaken. Next time, I'll make sure to check Google before asking someone what they prefer out of respect for that person.

#17 Reedbeta

    DevMaster Staff

  • Administrators
  • 4782 posts
  • LocationBellevue, WA

Posted 01 May 2006 - 06:31 PM

Don't take it personally Ethanbot. Just FYI, what you are asking about is something that's quite basic and it's not likely that there ARE any web pages devoted specifically to this topic. Since it seems that (no offense) you are a relatively inexperienced programmer, you'll need to do some brainwork in order to figure out how to make this happen.
reedbeta.com - developer blog, OpenGL demos, and other projects

#18 Ethanbot

    New Member

  • Members
  • PipPip
  • 23 posts

Posted 01 May 2006 - 09:27 PM

Reedbeta said:

Don't take it personally Ethanbot. Just FYI, what you are asking about is something that's quite basic and it's not likely that there ARE any web pages devoted specifically to this topic. Since it seems that (no offense) you are a relatively inexperienced programmer, you'll need to do some brainwork in order to figure out how to make this happen.

I'm relatively new to net coding, yeah. Other than that, I'm a pretty well versed coder. No offense taken =)

#19 SmokingRope

    Valued Member

  • Members
  • PipPipPip
  • 210 posts

Posted 02 May 2006 - 10:17 AM

Alright, well after leaving you in suspense ...

Duh Duh Duh ....

Dim x as integer
x = 20;

In the code fragment above, we have created a variable x which is initialized in RAM and contains a value of 20.

#20 Ethanbot

    New Member

  • Members
  • PipPip
  • 23 posts

Posted 02 May 2006 - 04:07 PM

SmokingRope said:

Alright, well after leaving you in suspense ...

Duh Duh Duh ....

Dim x as integer
x = 20;

In the code fragment above, we have created a variable x which is initialized in RAM and contains a value of 20.

*slaps forehead*

My mistake, I just misunderstood. That's one of those extremely common things that you just don't really consider.

Other than that, there's no reason to be rude. It was only a misunderstanding.

Also, you don't use semi-colons in VB. Just thought I'd point that out so you don't run into any compilation errors and have people tell you to go fucking google it. =)





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users