diasurgical/devilutionX

[Issue Report]: Vipers / Drakes sometimes missing their lunge and slamming into walls or disappearing into the distance

Chonkblonk opened this issue ยท 11 comments

Operating System

Windows x64

DevilutionX version

1.5.2

Describe

Every now and then when fighting the Drakes and Vipers down in the Caves and Hell, I notice that on odd occasion one will miss its lunge, and it doesn't stop short when it does, instead it smacks into a further away wall, or sails the fuck away into the distance somewhere, it just keeps going until it hits something.
Looks pretty funny actually, like a cat running into a glass door.

Wouldn't know what causes this exactly, but I seem to notice it happening more often when my Sorcerer is about to, or in the process of getting surrounded and savagely stunlock gangbanged (not necessarily just by Drakes or Vipers). Could just be fluke on that point, but maybe something is related.
Usually, it's because I stepped out of the way from the lunge (typically accidentally when desperately scrambling to get away from stunlock), but once or twice I have spotted one seeming to just launching its lunge from an incorrect position even when I'm static. Sorry I don't have any footage of this happening, it would probably make the issue much clearer.

This MIGHT be an original Diablo bug, but I have no memory of it ever happening in the vanilla .exe in all my 25 years of playing the game. It's funny enough that I feel I would have remembered it.

To Reproduce

Uh, go find some Cave Vipers or Fire Drakes or whatever and then fidget around with them until you see one going ZOOOOOM.

Expected Behavior

No response

Additional context

No response

This MIGHT be an original Diablo bug, but I have no memory of it ever happening in the vanilla .exe in all my 25 years of playing the game. It's funny enough that I feel I would have remembered it.

I don't remember seeing this with Vipers either... something similar was a common problem with Horned Demons though, but I wouldn't know if they are related or not at this point.

I'd imagine this has something to do with a collision check from the monster while you are attempting to move from one tile to another that must've been changed in DevilutionX.

If it is as rare as you suggest, it could even be a single-frame issue too, which would make it harder to debug.

I think I might have seen it 4 or 5 times just in the past two weeks? I saw it in v1.5.1 also.
It's not a particularly critical bug.

How do you conclude it's a bug? Is it a bug that Fireball missing its target but not exploding shortly after missing is a bug?

Well, first, I have obsessively played Diablo on and off for decades, yet I have never observed this until now, second, the Vipers have a short lunge for closing the distance at short ranges, they are only supposed to do the lunge when you're close.

I suppose that this COULD be intended behavior, but it doesn't seem fully congruous with how it functions normally. To me, it would seem that the Vipers SHOULD stop in place at the same kind of distance as it does if it hits its target.

Monsters enter MonsterMode::Charge, which is dependant on the specific AI being used since it's triggered at different distances depending on which AI, and a new missile called Rhino is created. This missile controls the how charging works and moves itself and the monster during the action. Every frame, the missile checks for tile obstructions. If it hits a tile obstruction, then it deletes the Rhino missile and moves on to the next phase, which is deciding what should happen next (Snakes and Rhinos damage the player with 500 chance to hit, bats just stop in place and do business as usual). The code clearly indicates that the monster will continue charging until there is an obstruction. I'm not seeing evidence of any bug here.

The missile's collision is similar in behavior to any other missile that checks if it should continue to move the missile or stop the missile, which is when there is collision with a player, monster, solid object, or solid map tile. Adding functionality to stop the missile based on some checks to see if it's technically missed the target or not would be just that: adding functionality, not fixing a bug.

	if (!IsTileAvailable(monster, newPos) || (monster.ai == MonsterAIID::Snake && !IsTileAvailable(monster, newPosSnake))) {
		MissToMonst(missile, prevPos);
		missile._miDelFlag = true;
		return;
	}

It's the same in vanilla as well:

	if (!PosOkMonst(monst, missile[i]._mix, missile[i]._miy) || (monster[monst]._mAi == AI_SNAKE && !PosOkMonst(monst, mix2, miy2))) {
		MissToMonst(i, mix, miy);
		missile[i]._miDelFlag = TRUE;
		return;
	}

In conclusion, it's a reasonable assessment to conclude that snakes and bats shouldn't continue charging past the target, as it does look a bit silly. However the code shows no discernment or intent with having different charging behaviors (specifically conditions for ending the charge) based on AI/Monster type, so this type of change would definitely be an arbitrary change that would be of the modding sort.

... but once or twice I have spotted one seeming to just launching its lunge from an incorrect position even when I'm static.

Missing a charge while the player is standing still seems a bit suspect. Perhaps we messed something up with missile changes related to how the charge is aimed? If so, that would also explain why the general consensus seems to be that it happens way more often in DevX than vanilla.

This behavior isnโ€™t uncommon in vanilla either tbh. Seen it plenty of times over the decades ๐Ÿ™‚

In conclusion, it's a reasonable assessment to conclude that snakes and bats shouldn't continue charging past the target, as it does look a bit silly. However the code shows no discernment or intent with having different charging behaviors (specifically conditions for ending the charge) based on AI/Monster type, so this type of change would definitely be an arbitrary change that would be of the modding sort.

I guess it's just rare, then.

This behavior isnโ€™t uncommon in vanilla either tbh. Seen it plenty of times over the decades ๐Ÿ™‚

I suppose that it's just up to fluke. One time playing as a kid I encountered a Rotting Carcass which the game would not allow me to highlight, and which could not be hit with any weapons or spells of any kind (or, any I had, maybe Apocalypse could have worked). I've never heard of anyone else experiencing a similar bug (the other kids at school didn't believe me lol), and I've never had it happen again.

The goofy extended viper lunge seems like intended behavior, however. I guess if I see one which seems to happen out of place I could report back.

Would it make sense to develop a debug feature where we record the last X commands along with the starting state, so that when something like this (a very intermittent, context-dependent problem) happens, the person can press a button to persist that as a re-runnable demo that can be used for debugging purposes?

I know some game consoles do this with recording the last 30 seconds of video or whatever, this would be a slightly different version of that: a demo that starts from a certain memory point and runs the next commands to completion for X seconds.

...just throwing the idea here as it came to my mind as a way to be able to figure issues like this out without needing to go through a lot of setup trouble.

... but once or twice I have spotted one seeming to just launching its lunge from an incorrect position even when I'm static.

Missing a charge while the player is standing still seems a bit suspect. Perhaps we messed something up with missile changes related to how the charge is aimed? If so, that would also explain why the general consensus seems to be that it happens way more often in DevX than vanilla.

Can't say I've ever seen this myself. Would be helpful if someone posted a clip of this happening in case it's just misremembering events.

Monster and player positions as well as dMonster and dPlayer arrays are handled much more cleanly now. Perhaps this would fix the supposed issue with monsters missing a stationary player.