The Dink Network

'script_attach()' isn't what it says it is.

April 27th 2021, 03:58 PM
custom_robj.png
Robj
Jester He/Him Australia
You feed the madness, and it feeds on you. 
script_attach is not what it says it is (unless you are reading my revised version of the DinkC reference available online).

I did some more testing and basically this:

"script_attach will attach the current script to the active_sprite."

Is bullsh#t. All it does is update which sprite "&current_sprite" refers to, but the script is actually still attached to the old sprite.

Part 1: the evidential test and demonstration
The simplest way to see this is to attach a script to a sprite and do this:
//This script is attached to editor sprite 2, a fence sprite.
//save &current_sprite in a local variable
int &hold = &current_sprite;

//store sp(3), which on the screen I'm running this on, is another editor placed pillbug sprite
int &getsp = sp(3);

//attach this script to &getsp (the pillbug sprite)
script_attach(&getsp);
wait(1);

//now check the script attached to both sprites using is_script_attached()
int &script1 = is_script_attached(&getsp);
say("&script1", &getsp);
int &script2 = is_script_attached(&hold);
say("&script2", &hold);

if (&getsp == &current_sprite)
{
 //this will run, even though is_script_attached shows that no script is attached to &getsp.
}


&getsp (the pillbug) says 0.
&hold (the fence) says the script number of the script.

However the last if statement will run, showing that &current_sprite updated to the sprite designated in script_attach.

Further evidence that the script is still attached to the old sprite, is that even though &current_sprite updated, to trigger any sprite-specific procedures(such as hit, talk, push), you have to do so on the old sprite (e.g: to trigger the hit procedure, you have to hit the old sprite). This means if inside the hit procedure you include a say("blah", &current_sprite);, you have to hit the old sprite to trigger it, but the new sprite will say the line.

Part 2: The point
The point I'm making is that the description of script_attach is wrong, and the name of it is misleading. Although this is not explained in the DinkC reference very well, there is a difference between a script number being attached to an active sprite, and an active sprite number being attached to a current script, and yes they are both a thing, which is why under pseudo variables in the DinkC Reference, &current_sprite is described as followed:
"The active sprite number attached to the current script."

An accurate description of the function "script_attach" is:
"script_attach will attach the active sprite number to the current script"

Part 3: The misleading descriptions of script_attach, sprite 1000, and sprite 0 in the DinkC Reference
The previous findings leave the following 100% confirmed fact:
script_attach(int active sprite), does not attach the current script to the active sprite, but rather attaches the active sprite number to the current script.

This also means, there is a discrepancy in the DinkC Reference of how special variables actually work, not that it changes how you use them, but incorrect information, is still incorrect.

From the DinkC Reference:
"The active sprite number 1000 can only be used with script_attach. Active sprite 1000 isn't a real sprite, but the Dink engine will make any scripts attached to it survive when the player changes screens."

How it actually works, which is evident from the prior findings:
The active sprite number 1000 can only be used with script_attach. Active sprite 1000 isn't a real sprite, but attaching the active sprite number 1000 to a script, will make the script survive when the player changes screens.

It's a small discrepancy, but a big difference, technically. Because the scripts never get attached to the active sprite number 1000 or 0, but rather the active sprite numbers get attached to the scripts.

Also:
You can have multiple scripts with the same active sprite number attached to them, but you cannot easily have multiple sprites with the same script number attached to them. I say "not easily", because it is possible with a strange work around I found, and there's no real benefit to it anyway... 2 sprites would be sharing the same script but whichever sprite the script was last attached to would be the one referred to as "&current_sprite". The only extra behaviour would be that you can trigger the scripts normal procedures from both sprites. For instance, if you had "&current_sprite" saying something in the hit procedure, you can trigger it by hitting any sprite that shares the same script, but only one sprite will say the line (whichever sprite the script was last attached to).

Part 4: An example application for the actual way script_attach works
When I previously said you can have multiple scripts with the same active sprite number attached, you could think of any extra scripts(with same sprite number attached), as a passive external - that is, on initial attachment it won't automatically execute the main procedure and the original script won't have to wait until it's done anything to continue executing, they will just co-exist and sit in memory until you call upon them. In both scripts "&current_sprite" will refer to the same sprite and you could run parts of the script whenever you want, or have them coincide with each other. Just store the script number of the second script in a custom key attached to the sprite, so the sprite can find it, since the sprite will only be storing the first script's script number. In the second script(with the same sprite number attached to it), do the following:
sp_custom("script2", &current_sprite, &current_script);

Then, in the original script(which is actually attached to the sprite), you can poke procedures in script2 like this:
int &getscript = sp_custom("script2", &current_sprite, -1);
run_script_by_number(&getscript, "custom_procedure");


Both scripts can refer to the sprite with &current_sprite.

Another application, is rather than using globals to store sprites on a screen, you can juggle the active sprite number attached to a script around and then each time you attach a new active sprite number to the script, store &current_sprite in a new local. Then when you have all the sprites saved in locals, just use script_attach to change the active sprite number attached to the script back to what it was before. You will then have a bunch of sprites all saved in local variables.

When will the script die?
It should be noted that a scripts survival is dependant on the active sprite number attached to the script, NOT the other way around.
So for example, if a script is attached to a sprite, and you use 'script_attach()' to attach a different active sprite number to the script, you can actually kill off the old sprite (using sp_active or some other method), and the script will survive, only thing is you can't trigger it's predefined procedures anymore, since it isn't attached to a sprite anymore (again, the script has an active sprite number attached to it, and '&current_sprite' is equal to that active sprite number). If you however kill off the current active sprite number attached to the script, the script will die with it.

This can be useful in a way. You could almost have like a trash can for scripts. If you use 'script_attach' to attach one active sprite number to multiple scripts, and then you kill the sprite with that sprite number, all those scripts will die with it.

Conclusion
If you are only using it in the ways it's traditionally been used, obviously it still works the same way, although the understanding of why it works that way was incorrect.

Knowing how it actually works, does allow some other useful applications for this though, rather than just wondering why your script that you attached to a sprite is bugging out. No it's not bugged, it's just not what the function actually does.
April 28th 2021, 03:00 PM
spike.gif
SlipDink
Peasant He/Him United States bloop rumble
2nd generation. No easy way to be free. 
Terrific Analysis Robj!

Is the behavior you outlined the same for all known versions of the "Dink engine"?
April 28th 2021, 11:55 PM
custom_robj.png
Robj
Jester He/Him Australia
You feed the madness, and it feeds on you. 
As far as I can tell, yes.