Download

Database Connection

Hello, I was wondering if it was
A: a wise idea to have a single class that contacted the server database (of a multiplayer game) and then retrieve the desired information for other classes actually used within the levels to access (ie variables containing how much damage weapons do etc) rather than have every class make individual calls to the server database for that information.
B: If that is a wise choice and makes sense, how would I do it (assuming it is possible in UE4)?

Additionally, what are the best practices for game server databases and connecting to them?

If you require any additional information, please do not hesitate to ask.

Thank you for your time,
Markyroson

P.S.
I do have a go-between webserver and clients do not directly connect with the database.

Hello Markyroson,

Your approach with databases is indeed implementable in UE4, but I’ve been asking the same questions before, and I’ve got answers that it’s not really good practice, and insecure.

What I suggest doing is use HTTP requests for database managing. I’ve wrote a tutorial about C++ simple GET request on the wiki. You can check the link in my signature. It usually works for on the same principle, tho you would want to use proper VERBS like GET (for getting data) POST (creating something) PUT (updating record) DELETE (deleting). Usually it’s all the same code but different verbs.

I’m using PHP as it’s veryyy easy to setup, but modern solutions like ASP.NET Core WebAPI have builtin tools to help you. For example when you get your data from database it has some very cool method “return Json(myData);” will will return a serialized json string with your needed data, and you can read it in your game, and do whatever you wish.

But even if you wanted to write a direct connection between the game and the database server, make sure at least to keep the database client server only (since clients could hack and you anyway have to keep data replicated)

Best regards,
YoungWolf

True that, it’s bad practice to let the clients directly communicate with databases. In case of a database change, you have to update all the clients. Also the clients could stress the database more than necessary.

I would recommend a client <-> MasterServer <-> Database Server structure.

As many others have pointed out. Never ever ever have direct database interaction in your client application… that is asking to be hacked. Run a secure web environment that utilises things like OAuth etc… Since this is out of scope here I wont go into detail. It’s bad practice don’t do it.

If you have a dedicated server you can have that server run the database and then no problem just make sure there is ZERO interaction from client to DB. (Like in an example of how ARK could do it, they dont just saying they could)

Your tutorial I actually have used.

First off, thank you for your responses! My apologies for not stating this in my original post, I know not to directly connect to a database with a client and do have a PHP go-between in place and do know how to perform GET requests within unreal engine. (From here I am just repeating gist of first post) I was just asking if it made sense to do all the calls in one class and retrieve the stored information from that class for the sake of not having to make numerous calls to the web server (basically for efficiency) and how to implement it if that made sense.

Aaah got ya :wink: See that was much better. Now it is really up to you. PHP > 7.1 & Nginx would probably do for the beginning but to get even more performance I would suggest looking into the Net libraries of GOLang… its about 768 times faster than php and would be the fastest HTTP server if you were going to write one. And then it wouldn’t matter too much if you made numerous calls or just one, of course making one call gives you less overhead in terms of load you put on the web server and of course you might be running into trouble if you have thousands upon thousands of calls per second. (yes seconds not a typo)

So all in all it depends on your architecture. I am a professional web / backend developer and have been using PHP / C / GOLang right now. I started with BorlandC and then BorlandC++ back in the DOS days. Nowadays you have so many different ways on how to do something that I feel there is NO correct or right answer. There are several ways which all might be equally good.

I drifted off there sorry :slight_smile: so to tldr; If I was you I would profile and see what performance impacts I am getting and then take it from there. Write some test cases where you do it either way. Then it is your decision what makes you more happy in terms of performance :wink:

Well yeah, that would be the proper way. Making a HTTPManager class or whatever name, and do all the requesting and posting in it. Tho you would have to probably implement Singleton design pattern (easy) and make it multi threaded and asynchronous to make the most performance out of it (hard part).

You are on the right track, go for a single class manager.

Another suggestion (that I want to implement for my game) is to make that manager as actor component. That way I could anytime add it to any of my actors that I need and never worry about references and validity and stuff.

As other people stated there is no correct way to do this. It all depends on you.

Best regards,
YoungWolf

How would I access the info stored within it in the other classes though? Also, what is a singleton design pattern?

Well, first off, Singleton is making sure that you only have exact one instance of the same class and never having another one, and you can access it globally everywhere. Note that the HttpModule and OnlineSubsystems work the same way. You are doing HttpModule::Get(). Google it, it’s very popular and well documented in all programming languages.

Second, what do you mean how you would acess the data? I mean you would do inside your function


MyHttpManager* Manager = MyHttpManager::Get();

FString returnedData = "";
Manager->Post(urlToRequest, &returnedData);

//do something with returned data

//for example parse it as json string and get values that you need

I hope that clears some stuff for you :slight_smile:

Edit: You could even extend that even further by making Services. It’s a concept from the web development, where you make a class that you make all needed functions to pull data for you. For example you could have a service for the player character, that would pull his stats, his xp, level, health, armor from the database.

It did clear some stuff up, thank you.
I will definitely Google Singleton and look into it. What I mean is how to access the variables where the information would be stored from within another class.

Basically, you would have one class do the call and store the returned info and the others access what is stored within it, essentially minimizing actual calls to server required.

You would have to define Get() within MyHTTPManager I take it? If so, what would you put in it?

MyHTTPManager->Post would be where you would actually perform the HTTP call, right?

Correct.

Typical pseudo code would be:


if(_instance == null)
{
   _instance = new MyHttpManager();
   return _instance;
}
else{
   return _instance;
}

Basicly that’s singleton, but you would need to make it multi threaded, lock it when it’s used and unlock it when it’s free (I’ve done this only in C#);

It all depends on you. As I said you could make a model for the data to be hold. For example MyDataModel which will have Health, Stamina, Level, XP, and you POST a request to get that data for specific player, then return a json string and assing values from json to MyDataModel.

MyDataModel->Health = Json.GetIntValue(“Health_Var”);

Then pass that instance to anywhere you need it.

Thanks for the help so far! How would I make it multi threaded and lock/unlock a thread?

Well, that I struggle to find myself too. There are some wiki tutorials on multithreading but not sure if they will be useful.

Have to research in google.

Edit: It seems the wiki threading post has an example of multithreaded singleton class. I haven’t tested it out, but I will once I get to this stage of development. If you manage to test it before me, please do tell if it works.