The Dink Network

Gamestopping bug near the beginning

Twins

January 13th 2007, 10:27 PM
girl.gif
DrFraud
Peasant She/Her
 
The old person a couple screens north of the southeastern save machine in the caves is *really* starting to annoy me. Twice now (I didn't find the machine the first time) I've paid the bonca, been misteleported, wandered around a fairly biggish chunk of the caves, gone up to the NPC in question, selected "Hello" from their conversation menu - and had the freakin' dmod freeze on me.
February 22nd 2007, 09:29 PM
anon.gif
ya no
Ghost They/Them
 
SAME exated thing happened to me, it was the old guy who wants the shelf right?
January 25th 2010, 08:02 PM
fish.gif
I know this is over 3 years old, but I've experienced the same thing. After looking into WinDinkEdit, I found out that the author of the D-mod simply made a mistake with the sprite code on where this symbol "}" is supposed to go. It looks like this-

{
say_stop("Hello!", 1);
wait(200);
say_stop("`5A good day to you to.", &current_sprite);
}
unfreeze(1);

When it should really look like this-

{
say_stop("Hello!", 1);
wait(200);
say_stop("`5A good day to you to.", &current_sprite);
unfreeze(1);
}

If you want to fix this dmod, just simply go to WinDinkEdit and put that symbol in the correct place.

Cheers.
January 25th 2010, 09:09 PM
spike.gif
That's not really the problem, the script should move straight on to the unfreeze line after the greeting chat is over. Moving unfreeze(1) will fix it (though it would still freeze with the other if checks in the script), but only because then unfreeze(1) is not the last line in the script anymore.

Apparently, the last line in a script doesn't run, and Binirit doesn't like to close procedures with }.

So, just adding an empty row after unfreeze(1) should be enough to fix it.
December 22nd 2015, 11:14 PM
dinkdead.gif
millimeter
Peasant He/Him Canada
Millimeter is Wee-Lamm, Recording Artist. :-) 
Seeing as this bug is still present in this file, as well as several others in both this DMod and others, I feel it is worth updating with my opinion for future Dinkers who will encounter this issue.

I believe, that the real issue is that the Choice function provides for 5 ifs, whereas there are only 4 thens with none being defined as the default or 'fall-through' path. By omitting the closing brace for the talk(void) function, the menu is only being dismissed visibly and not programmatically. This can be evidenced in V1.08HD by hitting escape for the menu which will have both the Map and Dink menu options, disabled because there is already a menu open.

While Scratcher's advice would indeed be a functional kludge by allowing the parser to see that there isn't anything following the "unfreeze(1);", I'm not convinced that this will allow the engine to handle housekeeping chores including purging the script from memory and invalidating any variables that may have been defined.

In my opinion, adding the closing brace is preferable to simply an empty line as it both provides a fall-through path for the 5th option, and informs the parser that any local variables can be removed from memory.

e.g.
...
unfreeze(1);
}

Mm
December 23rd 2015, 01:56 AM
anon.gif
ghost
Ghost They/Them
 
There is no 1.08HD. Did you mean 1.09?
December 23rd 2015, 08:22 AM
dinkdead.gif
millimeter
Peasant He/Him Canada
Millimeter is Wee-Lamm, Recording Artist. :-) 
Yes, I suppose I should have said 1.09HD.

I should try this game in 1.08 to see if it has the same issues, it freezes up for me all over the map.

Thank you for keeping me honest.
December 23rd 2015, 09:35 AM
spike.gif
Since we're discussing it, here's the whole script (lookey.c):
void talk(void)
{

freeze(1);
 choice_start();
(&cave == 0) "What's for sale?"
 "Hello!"
(&cave == 1) "How do I get out of these caves?"
(&boncaa == 13) "I've got you a shelf" 
 "Leave"
 choice_end();

if (&result == 4)
 {
say_stop("`5That's just great! Here's the key to the Dark Caves.", &current_sprite);
wait(200);
say_stop("How do I use it?", 1);
wait(200);
say_stop("`5Just go to the entrance. Another entrance will show.", &current_sprite);
say_stop("`5But remember that the Dark Caves are real dark.", &current_sprite);
say_stop("`5You'll have trouble seeing the edges, but they are there for sure.", &current_sprite);
 &boncaa = 14;
}

if (&result == 3)
 {
say_stop("`5Just ask my daughter for the magic key.", &current_sprite);
wait(200);
say_stop("And where is she?", 1);
wait(200);
say_stop("`5She went to the toilet.", &current_sprite);
 &cave = 2;
}

if (&result == 1)
 {
say_stop("`5Invisible keys.", &current_sprite);
wait(200);
say_stop("What would someone do with such a key?", 1);
wait(200);
say_stop("`5Go the Dark Caves.", &current_sprite);
wait(200);
say_stop("And what's there?", 1);
wait(200);
say_stop("`5I don't know, but some want to go there.", &current_sprite);
wait(200);
say_stop("*looks at table*", 1);
wait(200);
say_stop("`5You can't steal them, so don't even think about it.", &current_sprite);
wait(200);
say_stop("How can I? I can't even see them!", 1);
wait(200);
say_stop("`5If you want one you have to give me a shelf.", &current_sprite);
wait(200);
say_stop("A shelf?", 1);
wait(200);
say_stop("`5Very rare around here.", &current_sprite);

 &cave = 1;
}

if (&result == 2)
 {
say_stop("Hello!", 1);
wait(200);
say_stop("`5A good day to you to.", &current_sprite);
 }

unfreeze(1);

My proposed fix was this:
...

unfreeze(1);
(just a line break)


I just tried it out on DinkHD, and had a pretty weird experience: the choice menu graphics weren't there when I talked to her (vines, arrows, etc), only the actual choices were displayed. However, this problem only occurred once, when I tried talking to her again everything was normal, I couldn't reproduce it even by exiting and relaunching DinkHD, nor deleting and adding the dmod again. I dunno what to say, except "Oh, DinkHD." =)

I believe, that the real issue is that the Choice function provides for 5 ifs, whereas there are only 4 thens with none being defined as the default or 'fall-through' path. By omitting the closing brace for the talk(void) function, the menu is only being dismissed visibly and not programmatically. This can be evidenced in V1.08HD by hitting escape for the menu which will have both the Map and Dink menu options, disabled because there is already a menu open.

I think the the 'view map' and 'dink menu' options are only not being displayed because Dink is frozen - the same as if you press escape while in a conversation. I don't disagree that adding a closing bracket is preferable to an empty space, though, even if disregarding any programmatical considerations; it's better just for the sake of clarity, as it's easier to notice if you forgot to add a bracket at the end of a script, than it is to notice if you forgot to add a line break.

I did also notice a difference between FreeDink and DinkHD in how they behave with a line break at the end. It seems that a line break is always not enough in DinkHD, while it works every time in FreeDink (and regular v1.08). This is the test script I used:
void main
int &bananas = 999
void talk
say("I have &bananas wonderful wonderful bananas",&current_sprite)
(just a line break)

^ that doesn't work in DinkHD.

void main
int &bananas = 999
void talk
say("I have &bananas wonderful wonderful bananas",&current_sprite)
 (one single empty space)

^ This does work in DinkHD

EDIT: Stupid code tags don't display line breaks and empty spaces. (just a line break) and (one single empty space) aren't in the actual scripts, obviously.
December 23rd 2015, 10:04 AM
dinkdead.gif
millimeter
Peasant He/Him Canada
Millimeter is Wee-Lamm, Recording Artist. :-) 
Just for clarity, in HD I can use the [TAB] key to speed up the engine. Is this merely a part of the HD interface that reduces the number of wait states between executing each parsed action? I ask because, even when Dink seems frozen in this situation, I can hold [TAB] which speeds up his swaying in Idle animation.

I also noticed in a couple other script files that there are extra closing braces, though these would be in scripts that haven't been actioned yet as they apply later in the game. I presume that none of the scripts would be known to exist to the engine except during the period between being created and killed?

I also wonder, if HD is properly looking after it's house-keeping chores. It seems that it holds onto some bits even after loading a completely different DMod, in that sprites are not visibly drawn though they are there. Things such as invisible walls and monsters that can still attack, which is cleared by closing HD but not by simply reloading the Module.

This same issue occurs in slayer1.c.

void talk(void)
{
freeze(1);

choice_start();
"Hello!"
"I see the former owner was a knight."
"Do you like it here?"
"Have you been here long?"
"Leave"
choice_end();

if (&result == 4)
{ snip }

if (&result == 3)
{ snip }

if (&result == 2)
{ snip }

if (&result == 1)
{ snip }

unfreeze(1);
--------------------------------------------

*Note: I snipped the series of...
say_stop("`5Yes, it's allright.", &current_sprite);
wait(200);
say_stop("At least you've got plenty of food.", 1);
wait(200);

As they all seem to appear as they should.

When I first tried adding just the empty line (I used 2 for added measure), I noticed it did exit nicely from the first option but still seized if choosing 2 - 4, but the "Leave" seemed to work okay. Then, just for curiosity, I completely exited HD and restarted, and it seemed to work a few times, but I then visited next door to where "housebonca" is connected 'in the editor' to one of the boncas there, though the script does not exist, then going back to the slayers and the shelf-guy again failed.