The Dink Network

Integral bugfix for anyone's dmod.

January 3rd 2021, 03:02 AM
Jester He/Him Australia
You feed the madness, and it feeds on you. 
I discovered a bug while testing my Dmod, this was confirmed with a fresh Dmod with 1 single sprite -

When loading a game from the title screen, in any engine version, every base script on the screen runs twice. Or more accurately, the screen is drawn twice. So every sprite with a script attached will run it's main procedure twice, and the screens base script will run twice.

This does not happen when starting a new game, or loading any other way (for instance, using the escape menu)

Here's a few(but certainly not all) bugs this can cause with your dmod when the player loads from the title screen:

1) If you have any global that increments on screen load, or are using the editor info trick as a variable and incrementing it, it can cause some havoc, because they will increment twice (I know this doesn't seem like something you'd do often, but I do for reasons of my own).

2) If you spawn a repeating, non dying sound and store the soundbank number in a global so you can access it and kill it off later (like an ambient sound based on the current environment) - since the base scripts run twice, it will play 2 instances of the sound, but you will only be storing and accessing one.

3) If you have a dedicated "load game detection" script that spawns from "main.c" it can play some serious havoc, especially if you have stuff in it that relies on the fact that the scripts on the loaded screen should only play once. In this situation, the "load game detection" script will run, all the base scripts will run, and then "draw_screen()" will run again - which means all the main procs and screen base script will re-run, but your "load game detection" script won't, because it has nothing to do with the screen if it's spawned from main.c. This made me want to tear my eyeballs out trying to figure out what was going on.

I'm sure there's other bugs this can cause, but that's just the 3 I'm noting.

What causes the double screen load when loading from the title screen ONLY?
It's just because both "set_mode(2)" and "load_game()" trigger a draw_screen.. now set_mode is run before the "load_game" command, but through testing, it is evident it doesnt do draw_screen straight away, it waits until the next "wait" line, then triggers a draw_screen. All base scripts on the screen that the player loads into, will then run twice. Basically it would be like if you did "draw_screen();" twice after the game is loaded.

Either way. This is not a bug with the engine, but with the original "start-2.c". Screen draw should NOT be run twice after load_game, because it is not the behaviour to be expected when developing a dmod and it will cause bugs in some situations.

Why to fix it, and why it might have been the cause of some "DinkC scripts randomly work and then don't" bugs in the past, which have haunted Dinkers.
It's probably a good idea to fix this. I'm just gonna go ahead and guess this could have been the reason for a lot of "how come this script is all of a sudden not working when it was working before?" bugs.
Here's a scenario to ponder over, and I know this has happened to me in the past.. your debugging your dmod, you "cheat-save" on the screen which contains your new fancy scripts your testing for convinience sake. Initially, your script works. Later on when you load your game from the title screen, it bugs out. I've seen people post some "wtf" scenarios where scripts suddenly don't work when they did before, this just might be one of the causes. "draw_screen()" rapidly running twice and loading every sprite and script (including the base script of the screen).. and unkown to the developer that it's happening? .. that causes havoc for sure in some situations.

The fix
The fix is simply to make the "wait" occur before the "load_game", so the extra "draw_screen" triggered by the "set_mode(2);" function runs on the title screen, rather than on the screen the player loads into. To do this, I added a "script_attach(1000)" to the "load" Procedure of start-2.c, since a "wait" line after set_mode(2); stops other things from executing due to the "draw_screen" it triggers. Then I simply ran a wait(0) directly before the "load_game" line.
That fixes the issue.

It's also worth noting here that there's a comment in the default "start-2.c", that leads you to believe that running "set_mode(2);", makes it so the script can't die when the load is performed. That's not true. It dies. Hence why I had to use the script_attach(1000);

The fixed start-2.c script is below, with the misleading comment also removed. I would recommend using it. It might prevent some horrible bugs in your dmod.

Download fixed start-2.c that fixes any potential bugs related to this:

January 4th 2021, 01:58 PM
Peasant He/Him
I disagree. 
I blame Seth...

On a more serious note, good investigation . So a dark anvil is in progress indeed (I still believe it's about anvil ).

On a side note, I blame Seth...

January 17th 2021, 10:16 PM
Good find Robj. I wonder how many people this has effected over the years...