Turn your game on. Press CTRL + ALT + DEL, close your laptop lid, or wait for the Power Policy to shut off the screen. When you return, you realize your game just crashed.
This is a streamlined, no frills, no distractions demonstration of how to recover from the loss of a screen device. This is one of the fundamental problems people face when making a commercial game with DBP.
My purpose here is to help improve the overall quality of material the community is producing. If I could be so bold...
Previous Discussions On The Issue.
On the rare occasion this problem has been talked about before. I have noticed at times some incorrect or out of date information was allowed to linger. I want to try to iron some of that out. Other times workable demos were circulated, but were either unnecessarily complex, or not specifically purposed to this problem. There was fluff, and/or unresolved issues. I want to try to address this also.
Program Behavior During Screen Loss.
The problem here is when your game is running, and the screen device is lost, such as locking the computer at the Windows login screen, the program will crash. I've tested that the program will not crash and will continue to normally operate the entire time, until the moment the screen is restored. At this time all game assets like images/objects/sprites are deleted. If they aren't reloaded before your program code attempts to use them then the program will crash. However, you can sync the screen while they have been deleted. If you try to position/rotate/etc anything that got deleted that's when a crash occurs. So you can load an image and detect screen loss when it becomes deleted. Deletion actually occurs during first Sync command executed after the screen is restored. So we detect deletion after each sync, and reload the game assets if needed.
Problems with old forum demos and examples.
Some misconceptions have been to use a sprite for detection. All you need is an image. Commonly people have written demos thinking that the screen is lost as soon as the computer is locked or laptop shut, instead of when the screen is returned. So they make loops for the program to sit in for long periods of time that don't even get used. They don't realize the game is playing up until the time the screen comes back. Some people wrote mandatory key presses to begin reloading when the screen returns in their demo, but they should pause after reloading instead... if at all.
Screen Invalid() appears to be almost useless and doesn't operate as most people think, intuitively. I haven't seen anyone demonstrate code animating a loading screen, and protecting it against further screen loss, but did see 1 video. Many demos/examples require a rewrite to be capable of this, something every modern game has.
Demo Here - No Media Required
Rem ***** Main Source File *****
`Written by Mage Jan 2013
`This program demonstrates recovering after a lost screen device. And demonstrates how to reload content safely during additional screen loss.
`Setup Screen
Set Window on
Set Display Mode 800,600,32
backdrop on
sync on
sync rate 0
`Initilize Recovery Mode
RecoveryMode_Init()
`Demo Variables - Not Needed
Global CrashCounter as integer
`Load The Game
Game_LoadScene()
`---Game Loop---------------------------------------------|
Do
Sync
`Check If Screen Was Lost First Thing After Sync
If RecoveryMode_ScreenValid() = 0
`Handle Recovery Of Game Assets
RecoveryMode_Main()
`Increment Crash Counter For The Demo Purposes
INC CrashCounter
EndIf
`Operate The Game
YRotate Object 1, Object Angle Y(1) + 0.01
Text 10, 10, "Crashed " + Str$(CrashCounter) + " times."
Loop
End
`----------------------GAME LOADING FUNCTIONS---------------------|
`Loads All Game Assets, Exits Early If Screen Is Lost During Load
`The purpose is to demonstrate loading with an animated screen and aborting early if screen is lost again.
Function Game_LoadScene()
`Draw A Simple Load Screen
Game_DrawLoadScreen()
`Check If Screen Was Lost, Abort Load if lost
If RecoveryMode_ScreenValid() = 0 Then ExitFunction
`Add A delay Just to Make the Demo take longer and look better as an example.
Sleep 1000
`Reload Some of the game assets...
Make Object Cube 1, 1
Position Object 1, 0, 0, 1
Xrotate Object 1, 45
`Draw a simple Load Screen Again... will produce an animated effect.
Game_DrawLoadScreen()
`Again check if screen was lost and abort if lost
If RecoveryMode_ScreenValid() = 0 Then ExitFunction
`Sleep again just to make the load take longer for demo purposes...
Sleep 1000
`Create an image from memory so the demo doesnt need an image file with it.
Game_CreateImage(1)
Texture Object 1, 1
EndFunction
`Draws A simple Loading Screen, Randomizes ... length to make an animated effect.
Function Game_DrawLoadScreen()
CLS
Msg$ = "LOADING GAME CONTENT"
For i = 1 to rnd(5) + 1
Msg$ = Msg$ + "."
Next i
Text 10, 10, Msg$
Sync
EndFunction
`Creates a random color image from memory so the demo doesnt need an image supplied with it.
Function Game_CreateImage(imgNum)
Dot 0, 0, RGB(rnd(255), rnd(255), rnd(255))
Get Image imgNum, 0, 0, 1, 1
EndFunction
`-----------------RECOVERY MODE FUNCTIONS------------------|
`Handles recovery of game assets when screen is lost. The game will attempt to reload everything but this function will
`retry if the loading code aborts from being interupted by another lost screen.
function RecoveryMode_Main()
`Keep attempting recovery while the screen is lost.
While RecoveryMode_ScreenValid() = 0
`Init Recovery Mode Detection (try to create an image then below we will sync and see if it got deleted, if deleted the screen still isnt available)
RecoveryMode_Init()
`Sync To Test If Screen has been restored
Sync
`If Screen was restored, then begin reloading the game assets
If RecoveryMode_ScreenValid() = 1
`Load Game Assets
Game_LoadScene()
EndIf
EndWhile
endfunction
`Sets up Recovery Mode Detection Method, an image is created off screen. If the screen is lost, this image will be deleted.
`We can test for this image to detect if the screen was lost.
Function RecoveryMode_Init()
`Create an image from memory so the demo doesnt need extra files.
Get Image 10, 0, 0, 1, 1
EndFunction
`Tests whether Screen was lost, based on loaded image being deleted when screen is lost.
Function RecoveryMode_ScreenValid()
retVal = Image Exist(10)
EndFunction retVal
The Details.
In this demo I have attempted to cut the code down to just the basics. Some unnecessary things we saw before have been removed. No fluff. I've attempted to also include practical aspects. The content will reload through a simple function. Reloading supports an animated loading screen and will abort early if the screen is lost again. None of the base system requires any media. The intention here is a clean platform to expand on.
I didn't include any performance optimizations, like timer movement or frame limiters so I could keep the code as clear and clean as possible. I could have made this pretty, instead I'm showing the nuts and bolts in the most simplified terms. All business.
I hope this improves the quality of people's work across the community.
Any suggestions and improvements are welcome.
This work is improved and based upon this discussion:
http://forum.thegamecreators.com/?m=forum_view&t=200645&b=1&msg=2400136#m2400136
See my previous tip here...
http://forum.thegamecreators.com/?m=forum_view&t=202812&b=1