Search Unity

DontDestroyOnLoad - Prefabs Data Persistence

Discussion in 'Editor & General Support' started by Jihaysse, May 1, 2021.

  1. Jihaysse

    Jihaysse

    Joined:
    Mar 29, 2020
    Posts:
    53
    Hello everyone,

    I'm working on a RPG game which is using PlayFab as a backend.

    The scene the player is currently in is saved during OnApplicationQuit(), and the scene is loaded when the user successfully logged in.

    So, I have my login scene, where the player enter its credentials and logs in. Upon clicking on the log in button, the game changes scene to go to the last scene the player was in.
    If it's the first time the player is connecting to game, he will go to the Character Customisation scene, where he can change hair, clothes, etc... Upon confirming, the mesh objects are serialized and sent to my Playfab database as JSON.

    It's working great except that I don't know which way I should go about "spawning" my customised Player.

    Should I spawn a dummy player, then get the mesh (hair, body etc) info from PlayFab, then swap them in Start()? It looks like overkill because the player can only change once its hair, body etc so updating this every time the player start a game feels counter-intuitive...

    Do you have any better idea?

    Thank you for your time!
     
    Last edited: May 1, 2021
  2. Do not trust the client's computer. Especially if it's a multi-player game. Since you're using a server I guess it is. Update every time from the database if it makes a difference (if it is important that you decide what the player wear and how the avatars look like).

    If it were a single-player and no money involved (paid accessories and whatnot) then I would say you can cache the modifications locally and you only need to refresh from the database if it's missing and once in a while.
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,697
    Also, don't do anything in that method. It is not reliably called under a wide range of circumstances.

    Instead, save when you end the current level, or perhaps once a minute or something like that.

    Otherwise we'll just have a new post from you some while after your game ships, with a title such as "some players losing all their data."

    Do not trust OnApplicationQuit() for important data... ever.
     
    Lurking-Ninja likes this.
  4. Jihaysse

    Jihaysse

    Joined:
    Mar 29, 2020
    Posts:
    53
    Indeed you’re right, I was going to use PlayFab cloud script after but I first wanted to find a way to make it work even directly from the client.

    The game itself is « solo player » but there are 1vs1 battles. Kind of like Pokémon, or animal crossing for example. You play 95% of the game alone, but you can connect to do some activities online.

    My main issue is: should I just have a player prefab, spawn it when player logins, call the function to check what items is on the player, and update the meshes?
    and actually do the same for everything else (that’d be like the Pokémon team, inventory, levels, etc in a case of a Pokémon game)?

    I’ve never worked on an online game so I’m sorry for the dumb questions!


    @Kurt-Dekker
    I thought it was reliable for most platforms (except iOS where I should use OnApplicationPause). I had some doubts though so thank you! I will only save on important events (buy something, level up, etc...).
     
    Kurt-Dekker likes this.
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,697
    This is always a better approach, especially if the user's computer crashes or their little brother kicks the power cable out of the wall.
     
  6. Since you're making a bigger game with lots of stuff in it, you probably want to use the Addressables system anyway. Which means you will spawn most things on-demand, so checking what the player has and spawning the stuff you need is the way to go IMHO.
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,697
    And if this is the case (OP), then please do use source control!

    Personally I use git because it is free and there are tons of tutorials out there to help you set it up.

    Here's how I use git in one of my games, Jetpack Kurt:

    https://forum.unity.com/threads/2-steps-backwards.965048/#post-6282497

    Using fine-grained source control as you work to refine your engineering:

    https://forum.unity.com/threads/whe...grammer-example-in-text.1048739/#post-6783740

    Share/Sharing source code between projects:

    https://forum.unity.com/threads/your-techniques-to-share-code-between-projects.575959/#post-3835837

    Setting up the right .gitignore file:

    https://forum.unity.com/threads/removing-il2cpp_cache-from-project.1084607/#post-6997067
     
  8. Jihaysse

    Jihaysse

    Joined:
    Mar 29, 2020
    Posts:
    53
    @Lurking-Ninja I didn’t know about Addressables, I will have a look at it thank you!

    @Kurt-Dekker I’m indeed using git but probably not as often as I should, thank you for all those links! I will have a look at it when I’m on my computer.

    I’m having a hard time understanding the server authoritative architecture as @Lurking-Ninja told me to use. I do understand that the client cannot be trusted, but in reality, how is it possible?

    Let’s say a classic RPG game with a player which kills a monster (calls OnMonsterKilled) and gains experience. I guess I need to update the player experience in the server (using Cloudscript for Playfab, for example). But how can I know the monster has indeed been killed on the client (as the monster is spawned in the client using a random function like Pokémon’s long grass encounters)? Wouldn’t a potential cheater be able to call OnMonsterKilled() several times from its client - thus gaining experience on the server? Else how would I implement a verification that the monster has been killed?

    Or am I wrong thinking the client can « modify » the source code and call OnMonsterKilled() several times and cheating is actually just modifying JSON files locally?


    Thank you for your time, I really appreciate it!
     
  9. Nope.

    - You are sending message to the server that the player is attempting to hurt the monster.
    - The server determinates based on the variables present at the moment if it is possible.
    - If it is possible, makes the player hurt the monster.
    - if the server finds that the player killed the monster messages to the clients to play the dead animation
    - the server removes the monster, add some XP to the player and give some loot if applies (also sends message to update the UI)

    Something like this. Server authoritative means every important decision is made on the server and the clients are there to accelerate the display and gather input.
     
  10. Jihaysse

    Jihaysse

    Joined:
    Mar 29, 2020
    Posts:
    53
    Thank you for your reply!

    So, an example of this would be, in a Pokémon-like game:
    1) player is walking in the grass on its client
    2) while player is in the grass, triggers the random encounter calculation on the server
    3) server tells client to start battle (update state, UI, etc...) when the random calculation actually triggers a battle

    Am I right?

    thanks again for your time!
     
  11. Yes, something like that. Obviously, you are sending input events to the server and the server moves the character according to the rules.

    Now, you can choose mixed authoritative mode if you think it is better for your game (when it is an always connected game, but not really a competitive multi-player). But to do that it is important that nothing serious happens if one player breaks the game.
    Good example is the friends-only co-op multiplayer. If one player cheats, it only affects their friends. Not a big deal. In this situation you can allow the client to make more decisions, the server only feeds data and store the results.

    But if strangers play together, even if only co-op, it's better to make it server-authoritative. One cheating player can leave very bad taste in your players' mouths.
     
    Jihaysse and Kurt-Dekker like this.
  12. Jihaysse

    Jihaysse

    Joined:
    Mar 29, 2020
    Posts:
    53
    Thank you for your explanation.

    Indeed mixed authoritative seems to fit me better as there is only a few things I care about, but I don't care about the player position for example (if a player wants to cheat on its position, he won't change anything for other players).

    I'm a bit confused about how I should spawn all of my prefabs containing the game logic (GameManager, BattleManager and so on) as the player will "spawn" in a different scene when he logs in (depending on its progression). I've thought about having a scene loaded additively upon logging in, which already contains all of my game-logic prefabs.
    This way, there will always be this "loader" scene + the current scene of the player (the index of the scene is saved in PlayFab).
    Is that the way to go? Is there a better solution?


    Thanks a lot!

    Kind regards
     
  13. Dapper Dino has great MP tutorials, including authentication and lobby, he's showcasing PlayFab as well:
    https://www.youtube.com/c/DapperDinoCodingTutorials/videos

    MP games are usually bigger than the average Unity games. So you don't want to load all your stuff at once, using stuff like Addressables will be a must, sooner or later. But the additive scene loading technique isn't that bad.