2
\$\begingroup\$

In mobile game development there are types of data that are not user save-data but are necessary for the game, we call it GM files. In my specific case, the GM files include text data such as "item name" and "item description", as well as things like monster parameters like attack point and defense point.

A very common thing to do that are employed in a lot of real life games, based on my research, is to store a local copy of the GM file and also a server copy of the GM file. The server version of the file is prioritized but the local copy is used to speed up game rendering.

My questions are,

(1) Are text info such as names and descriptions generally considered data that need to be pulled from server every request or something that can be accessed from the local file?

(2) When the local file for game rendering become out of sync with the server, when should it be synchronized? It does not seem likely for me one has to wait until the next version upgrade to fix these type of bugs.

Some side notes:

One problem I am considering is, storing the item names locally would reduce the amount of data transfered (and hence the cost) than when pulled from server every request. However I am not even sure whether this is considered a significant factor in real life games since the amount of data is tiny when compared to other resource files. (A programmer in my team is very keen on this method but I am pretty precarious as research I made suggests the other way. The main argument he makes is actually about the data transfer cost rather than the rendering speed)

On the other hand, I can't find a very good reason to defend the method that pulls the item names from server every time, since one would never achieve the effect of cheating via modifying "names". The only thing I can think of is it's more convenient to debug for the developing process. And most real life games I have researched seem to use this method.

\$\endgroup\$
3
  • 2
    \$\begingroup\$ I know it's tempting to believe that there should be one standard way to do this that's common across all/most/many games, but that's often not true to the degree we might hope. 😅 In this case, I think phrasing your question in terms of "typical mobile game development/a lot of real life games" actually unnecessarily obfuscates the question you're asking about "this specific game that I am making". I'd recommend deleting everything that's referencing games in general, and instead tell us about your game. What data needs to be stored in these files in your game, and when might it change? \$\endgroup\$
    – DMGregory
    Nov 29 '21 at 12:12
  • \$\begingroup\$ I have rephrased my problem more clearly and without reference to any specific game. I have also included the side notes that is the real struggle I am having, but I did not describe clearly in the original question. If anyone that is familiar with GM file handling in the industry and is kindly enough to answer my question I will appreciate. \$\endgroup\$
    – cr001
    Nov 29 '21 at 12:13
  • \$\begingroup\$ @DMGredory I modified tried to be as specific about my case as possible, but since the problem itself is hard to understand without introducing the general way used in games that I myself spent a lot of time researching, I will need to leave that part as least. \$\endgroup\$
    – cr001
    Nov 29 '21 at 12:22
2
\$\begingroup\$

(1) Are text info such as names and descriptions generally considered data that need to be pulled from server every request or something that can be accessed from the local file?

"General practice" will not save us from making our own decisions here. Every game makes its own idiosyncratic choices based on all kinds of factors - be they well-considered responses to the game's unique needs, or historical baggage from a tumultuous development process, or compromises forced upon it by budget, time, technology, or architectural (or sometimes legal) constraints.

The real question you need to ask yourself is "is this data in my game something that I want to synchronize from the server?" Things you might consider here include:

  • Is this data unnecessary for the initial experience of the game, and bulky? (So you might want to remove it from the initial app install to keep your download size small, and stream it later as needed - this is done for levels/maps beyond the starting area in some games)

  • Will I want to change this data frequently or with very little notice? (Say for urgent balancing updates, without pushing a whole new app update for users to install)

(2) When the local file for game rendering become out of sync with the server, when should it be synchronized? It does not seem likely for me one has to wait until the next version upgrade to fix these type of bugs.

One simple way you can handle this is to have a manifest file that lists these data files and their latest update version.

When the user connects to the server, they request the latest manifest file, and check the versions of all the data files it references. If they are missing a data file referenced in the manifest, or their local copy has a lower version number than what's listed in the manifest, then they request the fresh version of those needed files from the server.

That way, most connections transfer just a small manifest file, and the larger data files are sent only when needed.

That said, this approach has significant complexity: your game needs to support "hot-reloading" these data files when they change, all of the manifest transactions above, and you need a process for keeping your version numbers and server manifest correctly updated so that the whole process works. That could be a substantial investment of development time and opportunity for bugs to creep in. So, ask yourself if that complexity is truly necessary for your case.

One problem I am considering is, storing the item names locally would reduce the amount of data transfered (and hence the cost) than when pulled from server every request. However I am not even sure whether this is considered a significant factor in real life games since the amount of data is tiny when compared to other resource files.

Again, there's no such thing as "real games" or, to put it another way, your game is as "real" as any. To get a precise answer here, you need to ask about your game and get concrete: count the bytes of data involved in the specific data you want to send.

You can get a ballpark idea of the size of the data to be transferred per message, and multiply it by the number of concurrent users and the rate at which you need to send them these messages. That gives you the total added bandwidth of including these bits of data in each relevant exchange, rather than keeping a local cache in sync. Compare that to the rate you pay under your server hosting plan - is it within your budget? You may well find it's cheaper to pay that overhead than it is to pay a programming team for the extra weeks to develop the file caching/synching system. Instead, they can spend that time working on gameplay updates!

\$\endgroup\$
1
  • \$\begingroup\$ Just to explicitly call out the logic behind the last piece of this answer: Just because it may be a tiny amount of data for the user to pull down, it will still have a noticeable effect on the server side, because of the sheer number of users you (presumably) expect to get. The same logic can apply to any server vs client decision - it's always safer to do it on the server, but you are paying for that CPU/memory/bandwidth on a per-user basis, whereas anything done at the client is "free". \$\endgroup\$
    – Bobson
    Nov 29 '21 at 16:58
1
\$\begingroup\$

When you have data which changes very rarely, like the data for common inventory items in the game, then it's usually not a bad idea to just put them in a file in your favorite markup format (XML, JSON, CSV, whatever) and ship it with the game client.

Now there is of course the questions what happens if you release an update. This should happen rarely (perhaps weekly or monthly), but when it happens there might be players who are online.

One way to do this is to just restart the server and kick all online users in the process. A server restart might be required anyway because allowing such files to be hot-loaded on the server is also a nasty can of worms with a lot of pitfalls and edge-cases to handle. So taking the server down, changing the content file, and rebooting it can be the easiest and safest solution.

Then when the clients reconnect, have the client send their version number. When the version number is outdated, reject the login attempt and tell them to download the update first. This also prevents a ton of other problems which can occur when players try to play the game with an outdated client.

So if you can get away with a restart for all servers and clients for each update, you should do so. It's the easiest and cleanest way to ensure that all clients and servers play the same version of the game.

OK, but what if your managers and players really don't like getting kicked once per week and insist on six-sigma uptime? A rather costly request, but not a completely unreasonable one. In that case you need hot-reloading on both the client and the server. Which means you need to establish a protocol which allows these things:

  1. There needs to be some command on the server to reload a specific content file at runtime.
  2. The server then notifies the currently connected clients that a specific content file is outdated
  3. There needs to be a way to transfer the new version of the content file (incremental updates optional if you are extra-masochistic). This could happen via pull (the client does a request, via HTTPS, for example) or via push (the notification from the server already includes the new version of the file)
  4. The client needs to be able to hot-reload that file at runtime without restarting.

None of these points is trivial to do, but nothing about it is technically impossible.

\$\endgroup\$
1
\$\begingroup\$

the GM files include text data such as "item name" and "item description", as well as things like monster parameters like attack point and defense point

Those are potentially different categories of things.

Names and descriptions are often fine to modify. In fact, you may want to provide different versions of them for clients in different languages.

Yet, stats have a more direct impact on game play. For example, more or less attack points - presumably - means battles could last longer or shorter.

For those you are going to consider the online and multiplayer mechanics of the game. If every game is pretty much isolated from each other, there is little harm on these modifications. Yet if there are online rankings, or some other way in which players compete to each other, then you need to consider if modifying these stats can enable cheating. It can be far removed from the actual player-player interaction, for example changing the stats leads to defeating more offline enemies that lead to more resources that are used in a player-player interaction.

Addendum: The server should be in charge of player-player interactions. In general, don't let the client tell the server what it has (be it stats or inventory or rewards or whatever). But some of those changes made locally, if the game is entirely offline, or other players can't see and are unaffected by them are fine.


(1) Are text info such as names and descriptions generally considered data that need to be pulled from server every request or something that can be accessed from the local file?

No, not really. Unless it is something that changes often. Usually you would download them in case of an update.

I'll elaborate further below.


(2) When the local file for game rendering become out of sync with the server, when should it be synchronized? It does not seem likely for me one has to wait until the next version upgrade to fix these type of bugs.

Again, this depends on your game. On one extreme it could be that this is entirely irrelevant. On the other it could be that you need to tell the player that they have to update the game because a new version is available and they can't play with the old version.

Plus, I cannot hold it against you if you don't have a hot reload mechanism if isn't a problem, much less on an initial version. Yet, it cost you very little to publish the current version on the server, so the client can check if its version matches.


You seem to be worried that the players are going to see the wrong thing. And one part is to keep the data up to date. And another part is to prevent the data from being tampered with.

If the player tampered with the game in such way that they see a million times the damage or coins or whatever, but that is only local and the server register the correct value, is that really cheating? Also, are you worried they don't see the correct information when it is them who tampered with it? I don't think it is cheating, nor that you should be worried.


One problem I am considering is, storing the item names locally would reduce the amount of data transfered (and hence the cost) than when pulled from server every request. However I am not even sure whether this is considered a significant factor in real life games since the amount of data is tiny when compared to other resource files. (A programmer in my team is very keen on this method but I am pretty precarious as research I made suggests the other way. The main argument he makes is actually about the data transfer cost rather than the rendering speed)

It will be important for you and your servers to save transfer data. And it will be important for those players on a measured connection. You need to consider how many players are there, and how much data transfer per unit of time they need. Having a server and connection that can handle more will have a monetary cost for you.

If the player sees the wrong values because they tampered with them, it won't cost you.

Let us put this in terms of information security. There are three main properties of the information we want do defend:

  • Confidentiality. I believe there are no confidentiality concerns here.
  • Availability. The local files are available even when there isn't a network connection, or the network connection is of poor quality.
  • Integrity. The local files could be tampered with or corrupted. Also, sometimes they can become outdated.

This tells us that having local files is better. But we need some kind of integrity check and update check. And let me reiterate that you should not worry about the integrity check.

Thankfully, we can address both checks in a single one: when launching the game - or when you first need the data - ask the server for a checksum of the files. Compute it for the local files and compare it with the checksum from the server, and if they don't match, download them again. You may also add a timestamp so the client can bypass the check if the server is saying that it is a newer version of the files than the client has downloaded.

However, that is an extra request (one for asking for the checksum, and one to download). We can do better, let the client tell the server what it got (checksum and timestamp), so the server can simply reply "not modified" or reply with the file. Or perhaps just a timestamp, if we don't care about the integrity.

Ah, but that request could be faked… Look, if this is text data, this is fine. The players that tampered with it is only affecting themselves. If they got to the point when they bypassed the checksum so they can tamper with their own copy, let them.

It is when we talk about player-player interactions that you would have some concern. To prevent cheating you need to have the server decide all rewards, control the player stats and inventory, and have the server validate all interactions. The local copy is both to reduce data transfer and for performance. But your game logic should remain on the server.


I have been assuming we are talking only about text data. But you can imagine how you could start doing something like this for textures, models, and so on. Which have their own considerations (e.g. if the player can modify the textures, can the player make an x-ray mod?).

Also, as I was saying, stats and text are not necessarily on the same bucket. yet, that depends on how authoritative the server is.

You could also imagine how you could even have it update without closing the game. Or how you could have the server generate diff patches so the client does not have to download the whole files, only what changed. It can get quite complex. However I believe I gave an outline of something you can get working that address the issues at hand.

\$\endgroup\$
2
  • \$\begingroup\$ I'd argue that if player can earn resources in offline play, and those resources count toward online player-player interactions, then it no longer matters whether the data is synched from the server — the player can forge the data file while offline, or even skip a step and forge a save file saying they earned the resources while offline, and the server can't know the difference. So while this is an important vector of cheating to consider, I don't think the synching of stats from the server is a meaningful mitigation for it. \$\endgroup\$
    – DMGregory
    Nov 29 '21 at 13:44
  • \$\begingroup\$ @DMGregory Correct. There the game is letting the player handle its inventory without knowledge or validation from the server. That scenario shows that it is ok to let the text data go out of sync, but not other data. The server should be in charge of stats and inventory if there is any kind of player-player interaction at all. Edit: except - perhaps - non-tradable cosmetics? But again, assuming the change is local and other players don't see it. \$\endgroup\$
    – Theraot
    Nov 29 '21 at 13:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .