Improbable Icon

[BEST PRACTICE?] Character's change effected by time and the system: how/where to store?

unity
win
v10-3-2
v10-3-3

#1

Hi everyone,

My player’s characters will have certain aspects that are effected by time and by the system. Ideally I would like to make the characters entities on SpatialOS while all the account information (payments for subscriptions, points, etc) are stored on the PlayFab system. I know normally everything account related would have to be stored on the PlayFab (or other services) systems. But I was wondering how I could best deal with things like this.
Examples of time and system effected things:

  • Skills will go down after a certain time if you don’t practice them enough.
  • Personality things can be influenced by things that happen in the system with NPC’s and other characters (each character will have it’s own personality a player can create at the beginning, a personality that later can be influenced but not be changed with sliders)
  • I have planned characters can “work” in their offline time (like Puzzle Pirates offered)

What would be the best way to do this?

Thanks for the help!


#2

I just read in the new Recipe “Client connection lifecycle” the following:

You could even make the player entity persist while the player is offline.

@rebecca @heather @dvanamst Does this also mean we can store player (or character) data like inventories, character’s attributes (like health, etc), pets, access to quests, etc in that entity?

Cause that would be amazing and an answer to my prayers!!! :heart_eyes: That would mean I could use PlayFab just for all the financial stuff and the account creation and authorization while I can keep my characters really in the game (have them sleep when the player is offline and more things like already mentioned above and a lot more :smile: )

./me keeping my fingers crossed


#3

@Sheriziya this is EXACTLY what we are planning to do with our game! We were already using UE4 multiplayer for replication and gameplay and have integrated PlayFab for user accounts, and their AWESOME catalog functions for sales. Unfortunately, it appears we have conflated the use of snapshots with a database.

While your plan seems the easiest in terms of the technology, from what I have read about snapshots, their exact purpose is to recreate the state of the world when workers die, rather than to function as a data store. You’ll also want to consider how much using a snapshot as a datastore would increase the size you have to send around. Not to mention the tooling you’ll need if you want to make admin changes (name change, add money, etc)

For these reasons, we added an additional PlayFab worker that is solely responsible for synchronizing game data to the PF backend.


#4

You may be right. I understand that snapshots can also be used to do things like maintenance (like the weekly maintenance that’s often done in games) so perhaps the data storage isn’t that big of a problem. Can someone shed a bit more light on that?


#5

In the Discord channel I just learned this, with thanks to @Tom316 (Tom, I hope you don’t mind me quoting you on this?):

I use a mixture of both. (I’m using Unreal btw) PlayFab as a means of a more permanent backup and I use snapshots as a more volatile style backup. So I can temp store inventory or any character data I want within my entities (players, npcs or otherwise) and then just push that at intervals into a database for safe keeping incase things go belly up.
You kind of need the info in two places because as you move from one worker to another worker in SpatialOS anything not within your entity doesn’t get moved with it. So you have to keep a working copy of information within your entities.

I have my entities do database updates to playfab about every 5 mins depending on how important that information is / isnt.
But thats the beauty of it is I have mine setup so that the simulation within SpatialOS can scale that number up or down as needed based on if / how often the data on the entity is changing.

So… keeping the entity persistent with the data is possible and then have the system back it up to PlayFab (or another system) :slight_smile:


#6

@Sheriziya Np, As far as I am aware there is no right or wrong way to do things. There are downside to storing things inside your snapshot. It’s going to take longer for workers to load in all the info when they spin up. Like I said there is always that chance of data corruption (though it shouldn’t happen).

In my case (Mines a VR game without much / very little UI) so all of my players inventory is visible in the game world. That and players are generally not carrying around / have really large inventories. You are limited to what can physically fit into a chest and what you can physically put / carry on your character.

So there are things to take into account no matter what approach you take. For me the benefits of the approach above just outweighed the other options that came to mind. And it just made sense, sense the info was already inside the entity and held on the worker for when a entity moves from one worker to the next or when a worker crashes.


#7

Just came across this topic and thought I might give some perspective with a previously written response:

It certainly does not provide all the answers but it should give you some extra ideas about what would work and what would not.

Duco


#8

Okay, I’ve read through the linked post again. A warning ahead: It’s a long post :slight_smile:
Just to clarify I’ve understood things correctly in regards to Characters/NPC’s etc.

  1. Temporary everything can be saved in SpatialOS
  2. For a more permanent back-up we should use an on-disk cloud-based transactional database like PlayFab or another service (or your own database)
  3. For offline players it’s not wise to keep storing everything in SpatialOS as this will increase the size of the snapshots unnecessarily. Instead it’s better to store the data in option two and pull everything from there once the player logs in again.
  4. If I understood your explanation correctly, this statement in “Client lifecycle Connection” can perhaps be done, but looking at the size of the snapshots shouldn’t be done.:

You could even make the player entity persist while the player is offline.

Am I correct with the above conclusions?

Assuming my above understanding is correct, I wonder if the workflow for the following examples would be the way to go:
1. Player Personalities
Players can create personalities for their characters during character creation. The personalities, once created, cannot be adjust with sliders anymore (like during creation), but instead will be influenced by their actions, by interactions with other players and NPC’s and by things that happen in the world. These changes can happen while the player is online, but also when the player is offline. Should this workflow be what I’m supposed to use?:

  • While the player is logged in, her changes will be stored in SpatialOS.
  • Upon logging off, her data is send to PlayFab and removed from SpatialOS (with that decreasing the size of the snapshot)
  • Upon logging back in, the data is pulled from PlayFab, updated with input from the world where necessary and then presented to the player.

2. NPC Data
My NPC’s will “have a life” and thus work, roam around the universe, have chores, etc. AND Personalities that are influenced by interactions with players, things that happen in the world, interactions with other NPC’s, etc. In other games a NPC can be loaded from the default, but in my game the changes matter and have to be saved. NPC’s can’t return to the original state of the first deployment.
Would I do regular backups to a system like PlayFab for them and besides that have the snapshots for maintenance, etc.?

3. Housing
For housing I have two situations:

  1. Player lives in Slave house and has no house of her own yet.
    Slave houses are influenced by decay, maintenance and such. Slave houses are not instanced, but instead a part of the persistent world.
  2. In my game player houses will become a part of the persistent world as well, instead of in instanced neighborhoods with fixed locations. Players can rent or buy existing houses but they can also conquer land and build their own house there.
    The houses will be effected by things like weather, decay, etc. besides the changes a player makes to her house, like painting and such.
    How would I store the data in both situations?

4. Things like custom orders, tasks set by slavemasters, other work, etc.
In my game will craft in shops and will have a contract with shops. A shop will have a labor pool to pick from to fulfill (custom) orders. A custom order is an order that’s given to by a player to a specific player character in the shop’s labor pool. For a general order the system will pick the workers.
Players can get these orders and tasks while they’re online as well as offline. (will have to figure out how to send them an update about this when they’re offline).
How would I store this information?

5. Player access to the story line quests and new implemented quests and tasks
In my game the playerbase as a whole will open updates to the main storyline and accompanying side quests and tasks. Would the following workflow work?:

  • While online, all access to the storyline and other quests and tasks is stored in SpatialOS
  • When logging off the access data is stored in a database/service like PlayFab and removed from the player entity. (would have to look for a way to store info about the advancement of the playerbase in relation to the storyline)
  • Upon logging back in the character data is updated with the new access, if applicable, that has come live in the game.

6. Other changes like inventory, location (coordinates), quest logs, etc.
In my MMORPG players will have things like inventory, quest logs, etc and of course their location has to be saved. Can the following workflow work for those kind of things:

  • While online everything is saved in SpatialOS
  • Upon logging off, everything is saved into PlayFab and removed from the Player Entity (including the last location)
  • Upon logging back on, everything is pulled from the PlayFab database and put in in the player entity.

With the above for examples I assume I’ll send regular updates to PlayFab during the online time of a player.

Thanks for the feedback!


#9

Hello @Sheriziya,

That is a thorough list of questions I must say. But great to have it so that other developers can benefit from the answers! :smile:

Regarding your initial conclusions:

  1. True. Everything can be temporarily saved in SpatialOS.
  2. True in an overwhelming majority of cases. Unless your game does not rely on any strong semantics and guarantees for any of its operations you will want to use such a third-party service. You will probably use it anyway for storing player information but if your game has no character permanence for players between different connections (e.g an agar.io kind-of game) then you could potentially make it without a third-party service.
  3. True & False. If your player’s characters continue to live on (controlled by an AI) even when they are not playing then you will need to keep the data in SpatialOS anyway, and that is not an issue. Having a larger snapshot is certainly not a show-stopper. Just that if it makes sense it is probably better to keep them as small as possible.
  4. False. With my answer to the previous point you’ll see that this is actually something we definitely support and even encourage as it is part of some of the things that SpatialOS makes possible.

Now lets dive into your more specific game-design points.

1. Player personalities

This characteristic evolves in a manner that is completely independent from the connection state of the player and should thus be managed in a way that is not tied to whether the player is connected or not. The data will thus always be stored in SpatialOS but should be check-pointed into PlayFab at intervals that you define yourself. Depending on how frequent and big the changes are you can either sync them up directly when they occur in SpatialOS or you can make a batch-job out of it so it occurs every n minutes. The choice in the end will most likely depend on the generated load on PlayFab and the associated costs.

2. NPC Data

The personalities of NPCs behave in the same manner as those of player characters so they should be managed in the same way… unless of course if the continuity / non-regression constraint for NPCs is significantly lower in which case you can just rely on snapshots to save it and not use PlayFab here. Again associated costs will probably be the tie-breaker in your decision.

3. Housing

This is quite close to the personalities question. With respect to the state of the (slave or player) houses I suspect that evolution will be quite slow relatively to real world time. As such snapshots should be enough to save this as any rollback phenomena due to a failing deployment or maintenance should be minimal. The things you will want to store in PlayFab is the association between a house ID and a player’s character as this is kind-of a contractual / transactional datapoint.

4. Custom orders, tasks & co.

Orders seem like something really transactional (and there is probably a game-money cost associated with them) this means that in general you will want to back the SpatialOS information by PlayFab in a synchronised fashion. However in this case the roll-back costs would actually be quite low from a player perspective: as long as you program any monetary exchange to be atomically done together with the scheduling of the task / order then a snapshot will either store the state before paying and starting the work or the state afterwards.

5. Story-line quests and tasks

The main story-line access is something that you will probably only store within SpatialOS unless it is evolving so quickly that a roll-back between snapshots would cause serious regression. For player-specific story-line access this is in-line with player’s personalities and should be handled identically.

Your idea however sounds pretty reasonable as is.

6. Player inventory, etc.

Your idea sounds reasonable and you will be looking for the right load trade-offs previously identified with respect to the frequencies of updates to the PlayFab storage.


Duco


#10

Hi @dvanamst,

Thanks for the thorough answers! This helps me greatly in deciding how and where to store things :smile:

Yeah, I thought I’d better ask it all now since those would be issue I needed to solve anyway :smile:

Good that I understand most point correctly.

I understand your point of keeping the snapshot as small as possible. I’ll do my best. I might run it by you guys for feedback sometime to make sure everything will work as best as possible. I’m still thinking about the best way to use the offline hours of the characters. A few things I had in mind, were resting for energy restoring, using the offline hours for normal work orders (the character wouldn’t be visually for others to see working in the game) and perhaps a few other things, but not things like questing, or other things a player would like to do. I might get back to you about how to best implement those things when I get there in combination with the load of the snapshot :slight_smile:

1. Player Personalities:
Okay. The interval time for the backup to PlayFab will be a trial & error for a while, I think, but that’s okay. I don’t know yet how many changes per hour, for instance, to expect. It will be interesting to see that develop over time. I’ll probably start with a high interval time to see if that will work and gradually go down from there when there are too many changes with important effects during that high interval time.

2. NPC Data
Perfect! The interval time will be a trial & error here too, but that’s not a problem.

3. Housing
Ah, that sounds perfect! Evolution here will indeed be slow. Of course, when a player takes the required action to fix the house/room there will be a change, but the “decay” will be much slower.

4. Custom Orders and such
Your assumption about the transactional part of the orders is correct. I’m thinking about having the money in an escrow per shop until the order is done and the item is picked up by the player. At that moment the money would go into the shop’s account. Payment to workers would be instant when a player has finished the custom order. In case of normal orders that have been fulfilled in the offline hours, the payment would be done once a day.
Your proposal for handling this sounds good.

5. Story-line etc.
Okay. I don’t think a rollback in between would cause problems for the main storyline, but it is something to monitor. Good to know :slight_smile:

6. Player Inventory, etc.
Perfect! It will indeed be a trial & error for a while, but good to know this is how I can handle things :slight_smile:

Wow… This became a longer post than I thought it would be :smiley: And all of this from the original question on where to store player data :smile:

I’m very glad with your input and feedback! It makes the development easier knowing this!

Thanks again for your input and feedback! If I have anymore questions, I’ll be sure to ask them!

Regards,
Ilse


#11

@dvanamst

I’ve got one additional question, kinda related to everything above:

Leaderboards
In Never Ending Realms every month a player character can be chosen as the Apprentice of the month (with a max #winning of 3 times in total). This is based on a formula about the Custom Orders a Player character gets.
Is this something I can store in SpatialOS? It will be updated with each custom order process that is finished. I don’t think the regression between two snapshots would be big, so I think it’s doable to store it sec on SpatialOS, but I’d like to hear your opinion about this.

Thanks again for all your help!


#12

Hey @Sheriziya,

Finally got some time to come back to your additional question about the Leaderboards.
From my perspective it is indeed valid to store such things in snapshots, even more if the data is somewhat directly tied to custom orders. If you store their information in snapshots as well then everything will be tied together and synced-up nicely. And in the event of a roll-back you will also have the guarantee that you roll-back to a consistent state.

As an example:

  1. Player A completes custom order.
  2. Workshop receives result of custom order in store for player B to pick-up.
  3. Player A receives points for the leaderboard.
  4. Workshop removes money for order from escrow account.
  5. Player A receives money.

If you tie 1 to 5 together in an atomic fashion then you can make sure that a snapshot either will contain the pre-1. or the post-5. state and will be coherent (as opposed to containing the state between 4 and 5 which would be inconsistent).

Duco


#13

Thanks, @dvanamst

That is indeed precisely what I have in mind for process :slight_smile: Perfect!


#14

This is good information to know. Thanks for sharing! I was looking to store 4-5 in another system and had concerns about maintaining proper state in case of a rollback.