Monday, November 16, 2015

Dev Update #18 Ready for Release, Fixed Slow/Drunken Movement Bug, Found New Bug in Saving/Loading


Fixed Slow/Drunken Movement Bug


I finally fixed the Slow/Drunken movement Bug that has been plaguing me for weeks.  As near as I can tell there wasn't any bugs in my code, but there was some buggy weirdness in the project itself.  So, I created a new project.  Exported all of the assets with dependencies from my old project, copied over the tagmanager.asset from the projectsettings folder, and everything was fixed.  This created a new issue with horizontal lines on the edges of the tiles of the board, but this doesn't seem to show up in builds so it's not really an issue.  With this issue resolved, I should have been ready to release today except I did some more testing and...

Fixed Saving and Loading Bug


During testing for release I noticed that saving and loading was working correctly.  I was pretty certain it had been working right, but after examining the code, I noticed that I had missed some crucial lines of code.  Random.seed was being saved when the program began, but not when a new level was loaded.  When the new level was loaded, Random.seed had a different value, but that value wasn't being saved so restarting the level would give you a different level layout.

I added the needed code, which should have resolved the issue, but it did not.  In order to debug, I decided to use the unmodified version of the Roguelike tutorial.  I made the necessary changes and saving and loading still wasn't working correctly.

Each time a Random value is called, the Random.Seed changes.  As long as all of those calls are in exactly the same order, and you start with the same value for Random.Seed you should get the same Random values every time.  But for some reason, this wasn't happening.

In order to fix it I added this line:
Random.seed = Random.seed;
Let that sink in for a moment...
Yes, I am aware that it makes no sense.  Yes, it really does fix the issue with the Random values being different every time.

So, after making that change in the unmodified project, I made that change in my modified project, and lo and behold it did not work.  I realized that this was being caused by my use of coroutines instead of functions.  In code, the first function has to finish before the rest of the code runs.  With coroutines, the code starts the coroutine and then continues execution.  Each coroutine was making a call to Random.Range at it's beginning.  When the level is loading, those calls to Random.Range are in order, and then the other calls to Random.Range happen when a todo is clicked. Since, when the level is loaded, it skips the while loops that wait for each todo to be checked, that caused the order to be different.

So, I created some bools and added some more while wait loops between the running of the coroutines that setup the level.  After the level is loaded, the finished bool is set to true so that the next coroutine is run and this solved the execution order issue so that levels should finally load exactly the same whether they are being loaded sequentially after each todo or whether they are loading all at once.

Then I realized that I could have just used "yield return StartCoroutine" to call each coroutine, and that would make code execution wait for the coroutine to finish before continuing.

I feel kind of silly for not doing that from the beginning.  Live and learn, I guess.

Ready for Release


And with those last bug fixes, I feel confident in releasing the prototype.   I would like to do a little work on the website and might get a new domain as well.   Stay tuned. 





No comments:

Post a Comment