2
\$\begingroup\$

First of all I know about coroutines and how to use them (they're awesome).

A friend of mine was telling me about the way the he implemented his saving system in a game he was working on, after asking him what he was using I found out that he is using system.threading and not coroutines to save data.

I know that Unity isn't thread safe but apparently he has had no issues with saving which leads me to wonder if it is ok to use normal threads as long as you're only reading data and no pre-existing data is modified in the gameworld? would this affect the game at all (other than some moving objects being slightly ahead of where they should be because of the time it took to get to that object and save it)?

\$\endgroup\$
4
  • \$\begingroup\$ Look at this answers.unity3d.com/questions/908054/… \$\endgroup\$
    – Savlon
    Jan 19, 2016 at 12:14
  • \$\begingroup\$ I read that before asking this question and it only really talks about generating new terrain (manipulating data) what i want to know is if i can get away with just reading unity objects as long as i don't change any values from the other thread... \$\endgroup\$ Jan 19, 2016 at 12:21
  • \$\begingroup\$ What data types are you intending on using in these other threads? \$\endgroup\$
    – Savlon
    Jan 19, 2016 at 12:26
  • 3
    \$\begingroup\$ Possible duplicate of How to not freeze the main thread on unity? \$\endgroup\$
    – DMGregory
    Jan 19, 2016 at 18:07

1 Answer 1

1
\$\begingroup\$

Saving in another thread while the game keeps running is dangerous. When the gamestate changes while the savegame file gets written, you will write a mixed gamestate consisting partly of the old state and partly of the new state. This can cause all kinds of weird and impossible to reproduce bugs when that savegame is loaded.

For example, consider you have a script which destroys one game-object and instantiates another in its place. Now consider what happens if the saving takes place exactly between these two operations. There are two possible outcomes: Either both will exist when the savegame is loaded or neither will. Either case might break the game in a way that the player can not continue. You have created the worst nightmare of every gamer: a broken savegame.

The deviousness of such problems is that they will appear completely random. Your friend's savegame system might work perfectly fine in 1000 tests, but at the 1001st time it might run into such a race-condition and screw up. And then never again until after release when the user-reviews of your game are suddenly full of people whining about their corrupted savegames and your testers fall into despair trying to reproduce the problem.

If you want to save in a separate thread, you need to write the complete gamestate to an in-memory data structure first and then start the thread to save that structure while your game keeps running with the original gamestate.

\$\endgroup\$
5
  • \$\begingroup\$ I understand that this would happen (In my friends case the new thread is created when the game is basically idle) but what i want to know is what would the game itself crash as a result of running a read only threaded operation (such as saving), would it crash if the game is changing a variable and the other thread wants to read that variable at the same time? \$\endgroup\$ Jan 19, 2016 at 15:51
  • \$\begingroup\$ @user3797758 A crash of the main thread is unlikely, but the saving thread could crash under some conditions. Still, it's a very bad idea to have the saving-thread access the actively changed data, as I already explained. \$\endgroup\$
    – Philipp
    Jan 19, 2016 at 17:21
  • \$\begingroup\$ @Phillipp Under what conditions? \$\endgroup\$ Jan 19, 2016 at 18:01
  • \$\begingroup\$ @user3797758 For example, when a complex data-structure is changed while the thread is reading it, it might get a null reference where there used to be a proper reference before leading to a null reference exception. For example: if (foo.ref != null) { foo.ref.getBar() }. foo.ref might have a value during the check but then gets set to null by the main thread before foo.ref.getBar() gets called. \$\endgroup\$
    – Philipp
    Jan 19, 2016 at 18:04
  • \$\begingroup\$ @user3797758 And before you ask: yes, there are solutions for this, but they are easy to forget and also come with their own set of problems (like deadlocks). \$\endgroup\$
    – Philipp
    Jan 19, 2016 at 18:09

You must log in to answer this question.

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