The Dink Network

sp_distance and sp_range effects on enemy sprites

May 28th, 05:52 AM
custom_simon.gif
SimonK
Peasant He/Him Australia
 
So after watching Robj and the black scorpions in SOB I thought to take another look at ways to adjust when an enemy strikes and at what distance the strike is effective.

So sp_distance sets a value of pixels that determine when the sp_base_attack seq occurs - as per the DinkC Ref:

For an active_sprite with sp_brain() 9 targeting another sprite (through sp_target()), the active sprite will try to walk within distance pixels of its target. If the distance value is 0, it will default to 5. Once within range, the active_sprite will attack the target if it has a sp_base_attack() set and is not waiting to attack (from sp_attack_wait()).

So is the distance a measurement based on the direction the sprite is currently facing? I assume so, but have learnt not to assume anything in DinkC.

Then sp_range will extend the hardbox of all other sprites during an attack (20 years ago I thought it extended the range or hardbox of the current_sprite, opps)

So in DinkC Ref sp_range does the following:

For an active_sprite that is playing an animation sequence with a special damage frame (i.e. attack sequences), the range value is used to temporarily deform the hardbox of all other sprites according to the current direction of the active_sprite. The active_sprite will hit any of the active_sprites that it overlaps.

This is where I think it doesn't. I did a test where I changed the sp_distance of the black scorpion to 35 and the range to 90. You can position Dink such that he is within the sp_distance to trigger the attack, and the hardboxes do overlap, but Dink is not actually hit/damaged. And I made sure Dink should be getting damaged as I tweaked the sp_strength value to be 30 points more than his current Defense.

Here is a image in Debug mode of this in action

Here is a overlay-ed version showing what the various hardboxes are, the blood waterfall sprites of which there are two vertically stacked, the water/blood outlet sprite, and Dink's range extended hardbox coloured green, and the scorpion's hardbox coloured red, the orange colour is the overlap of those two hardboxes as they are transparent layers in the original image.

So I thought, what if I used the set_sprite_info line just to increase that sprite frame's hardbox - as was done in the original Slayer enemy, but no - even taking the hardbox to a square almost half the size of the screen, Dink could still position himself in a way where the enemy scorpion is forever attacking and never hitting Dink.

This is a section of the game play test showing this
May 28th, 05:09 PM
custom_robj.png
Robj
Jester He/Him Australia
You feed the madness, and it feeds on you. 
That's really strange... I think the intended behaviour is definitely if the hardboxes overlap, it should be doing damage. Weird... it even sounds like it is making the "hit" sounds when the scorpion strike, but no damage is being dealt.
May 28th, 10:51 PM
spike.gif
Interesting research! I did some testing, and I think it's hardbox over depth dot rather than hardbox over hardbox. Or at least from my dirty testing that would seem to visually pan out:

https://i.imgur.com/u5qlZrK.png
208 range is a hit, 207 range is not. (PS. Dink's hardbox is very down and to the right, I changed it to see if it's hardbox or depth dot the game cares about)

Also, an interesting quirk: Increasing sp_range extends hardboxes on the Y axis as well as the X axis when attacking left or right (by the full sp_range amount on the X axis, and roughly half? on the Y axis), but only on the Y axis when attacking down or up.

https://i.imgur.com/73kPUh0.png
Look at that fat hardbox! Bonca has 200 range.

https://i.imgur.com/3nVNecQ.png
Look at that skinny hardbox! The only thing that changed is that Dink moved to the right so that the bonca attacks in direction 8 instead of direction 4.
May 29th, 12:15 AM
peasantmb.gif
yeoldetoast
Peasant They/Them Australia
LOOK UPON MY DEFORMED FACE! 
>is the distance a measurement based on the direction the sprite is currently facing?

It seems so. There are separate calculations performed according to whether or not "smooth follow" is on as well.
May 29th, 01:15 AM
custom_simon.gif
SimonK
Peasant He/Him Australia
 
I think the hit sound is being played because it is hitting the blood waterfall, should put a nohit on that one.
May 29th, 01:48 AM
custom_simon.gif
SimonK
Peasant He/Him Australia
 
Ah, I see, so if the revised hardbox of any sprite overlaps with the depth dot of the enemy sprite, then the attack procedure runs.

Well, maybe the X width of the revised hardbox needs to extend, say 1/4 of the range value when the enemy sprite is facing either in direction 2 or 8, and you would get a more believable/angry enemy.

Currently it adds something to the width as I can see when comparing the original waterfall hardbox with the sp_range modified one, just not enough.
June 1st, 11:45 AM
peasantmb.gif
yeoldetoast
Peasant They/Them Australia
LOOK UPON MY DEFORMED FACE! 
Bit of ambiguity, the distance between the origin sprite and the target sprite is determined purely by their X and Y values, so from depth dot to depth dot. Hardboxes are not taken into account when measuring sprite distances for either target or follow. When the distance between the origin and target sprite is determined to be less than the specified distance, the origin sprite attacks.

When a sprite attacks and its "special" frame arrives, the engine "runs through the tag list" to determine what gets hit. To do this, it checks if any sprites (including the specified target's) hardboxes overlap the origin sprite's X,Y position.

I did some slightly cleaner tests south of Windemere with a slayer targeting Dink with a distance of 60 and range 45. The blue boxes are the dink.ini hardboxes, which for the slayer when attacking left or right are quite wide, while the pink ones are after expansion has occurred, except for the slayer for which it is its touch box. Despite Dink's expanded hardbox being within the slayer's dink.ini hardbox the hit did not register, while this one did due to Dink's hardbox coinciding with the slayer's X and Y coordinate (the red thing) which corroborates scratcher's "hardbox over depth dot". Kind of weird, but it's Dink. Scratcher's idunnolol might be a damage indicator text sprite.

Also might be worth mentioning that the DinkC reference claims smooth follow is off by default in 1.07 and earlier, which might be interpreted as a suggestion that it's on by default in 1.08 and later which isn't the case.
June 2nd, 01:22 AM
peasantmb.gif
yeoldetoast
Peasant They/Them Australia
LOOK UPON MY DEFORMED FACE! 
>but only on the Y axis when attacking down or up.

This appears to be a historical bug/oversight. When the origin sprite is facing direction 8 (north) and attacks it looks like it's supposed to expand left and right in line with the other directions but instead adds the calculated range value (range / 8) to the right and then immediately subtracts it, meaning it only gets 15px worth of padding pixels left and right plus 5 on top which you can see here most clearly with the tree.

If added to both left and right properly, in this case it would receive roughly 5 extra pixels (45 / 8) on either side and look like this.
June 2nd, 03:44 AM
spike.gif
if (g_sprite[h].range != 0) box.right += range_amount;
if (g_sprite[h].range != 0) box.right -= range_amount;


Oof, how embarrassing.
June 2nd, 09:05 PM
custom_simon.gif
SimonK
Peasant He/Him Australia
 
Hey let's fix this, and then every DMOD experience will be a new one from this point on!
June 3rd, 01:17 AM
custom_robj.png
Robj
Jester He/Him Australia
You feed the madness, and it feeds on you. 
I'd also argue that fixing this engine bug will only improve existing dmods as well. So there's no reason not to fix it.
June 3rd, 04:38 AM
peasantmb.gif
yeoldetoast
Peasant They/Them Australia
LOOK UPON MY DEFORMED FACE! 
I'll add it to the next yedink with an option to switch to historical calculations if need be.

I also decided to take a look at the talk boxes which determine if you're talking to something, which work very similarly to hitboxes in that they receive some minor padding on all sides plus a direction-dependent expansion, in this case not affected by range. Talkboxes are also expanded from the hardbox rather than the bounding box which is sort of odd but expected.

In this screenshot, the bright green is the talkbox of the fellow traveller when Dink's facing direction 6 (east), blue is dink.ini hardbox, and the red outline is the bounding box.
June 25th, 09:00 PM
seth.gif
Seth
Peasant He/Him Japan
 
>>if (g_sprite[h].range != 0) box.right += range_amount;
>>if (g_sprite[h].range != 0) box.right -= range_amount;

Oops, good find.

is this fix live in yedink? No old stuff broke that relied on it being wrong somehow? If it looks fine I'll fix it in HD too.
June 26th, 04:05 AM
peasantmb.gif
yeoldetoast
Peasant They/Them Australia
LOOK UPON MY DEFORMED FACE! 
Indeed the fix is live, with a setting to switch it off if need be. Most of the time it's only really a few px of difference.
June 26th, 07:44 AM
custom_simon.gif
SimonK
Peasant He/Him Australia
 
Hmm, the few pixels are because it is not hard box overlaps that determine the outcome, rather the hard box of the range extension of the target sprites with the depth dot of the attacking sprites. Seems to me that the best way around this is to have the hard boxes extend further than a few pixels in the directions at right angles to the range extension. So if the range is being extended say 80 in either up or down, then the left and right should be at least 20, rather than a few pixels. This would then make the concept align with the overlapping of hard boxes.
June 29th, 02:05 PM
peasantmb.gif
yeoldetoast
Peasant They/Them Australia
LOOK UPON MY DEFORMED FACE! 
Ah, I meant relatively without the fix applied so as to answer Seth's question. As the tacked-on value is range / 8, even a sprite with a range of 65 only gets 8 extra pixels on each side. It may be possible to multiply it by 2 or something, which I could add to dink.ini as a new command, but for any sort of worthwhile hit collision it's veering into "use a different engine" territory.

Aplogies for diverting the thread, but should Seth read this after the 6502 escapade is over, there's a simple fix that RobJ is eager to have applied with the details here, and the relevant function to be changed here, in which [0] is changed to [i] in both instances.