Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
Chonkblonk opened this issue Mar 20, 2024 · 26 comments · Fixed by #7763

Comments

@Chonkblonk
Copy link

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

@julealgon
Copy link
Contributor

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.

@Chonkblonk
Copy link
Author

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.

@kphoenix137
Copy link
Collaborator

kphoenix137 commented Mar 20, 2024

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?

@Chonkblonk
Copy link
Author

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.

@kphoenix137
Copy link
Collaborator

kphoenix137 commented Mar 20, 2024

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.

@StephenCWills
Copy link
Member

... 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.

@FireIceTalon
Copy link

FireIceTalon commented Mar 20, 2024

This behavior isn’t uncommon in vanilla either tbh. Seen it plenty of times over the decades 🙂

@Chonkblonk
Copy link
Author

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.

@julealgon
Copy link
Contributor

julealgon commented Mar 20, 2024

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.

@kphoenix137
Copy link
Collaborator

... 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.

@kphoenix137
Copy link
Collaborator

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.

@kphoenix137
Copy link
Collaborator

May be fixed by: #7043

@qndel
Copy link
Member

qndel commented Aug 25, 2024

What does "may be fixed" mean? Is it fixed or not? If it's fixed, why is the issue still open? :D

@kphoenix137
Copy link
Collaborator

What does "may be fixed" mean? Is it fixed or not? If it's fixed, why is the issue still open? :D

Because nobody seems to be able to reproduce a rare event, but I suspect it's related to the janky tile occupation prior to 1.6.0-dev. Just waiting someone to reproduce in 1.6.0

@StephenCWills
Copy link
Member

StephenCWills commented Aug 25, 2024

The monster aims for enemy.position.future which #7043 doesn't modify, and the missile checks IsTileAvailable() which looks at dPlayer[position.x][position.y] != 0 || dMonster[position.x][position.y] != 0 which checks for positive and negative numbers. So I get the feeling #7043 wouldn't have done anything.

Regardless of what you do about fixing positioning, you can't avoid the case where the target leaves the game just as the monster starts charging. IMO, we should simply adjust the special case for MonsterAIID::Snake in the ProcessRhino() function.

@kphoenix137
Copy link
Collaborator

kphoenix137 commented Feb 4, 2025

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

Can anyone confirm with certainty this can happen? (Assuming that he meant to say "I have spotted one that lunged at me and completely missed, even though I wasn't moving.") If that's not what he meant, I've been focused on the entirely wrong thing this entire time. :D

@Chonkblonk
Copy link
Author

That is what I meant. My memory of this is fuzzy at best though, and I don't have any footage to prove it.
Playing with a Barbarian for a while, I have not experienced this at all, so I don't know if maybe this was fixed, if there's something about the classes or how I play them which makes things different, or if I plain imagined it.

@kphoenix137
Copy link
Collaborator

kphoenix137 commented Feb 17, 2025

That is what I meant. My memory of this is fuzzy at best though, and I don't have any footage to prove it. Playing with a Barbarian for a while, I have not experienced this at all, so I don't know if maybe this was fixed, if there's something about the classes or how I play them which makes things different, or if I plain imagined it.

Just looking for some confirmation of this happening and consistent way to reproduce. I would take a shot at fixing it, but I can't seem to reproduce it, so it's really hard to fix a problem that might not even exist. Nobody has attempted to fix it yet or further investigate, so the issue remains open.

@StephenCWills
Copy link
Member

... it's really hard to fix a problem that might not even exist.

While that is technically true, I think the most obvious solution to the problem that provably does exist would also solve the one that may or may not exist. As curious as I am about whether the snakes can miss a stationary target, if you only allow the snakes to charge maybe one or two tiles instead of continuing on like rhinos, the problem is fixed regardless.

@kphoenix137
Copy link
Collaborator

... it's really hard to fix a problem that might not even exist.

While that is technically true, I think the most obvious solution to the problem that provably does exist would also solve the one that may or may not exist. As curious as I am about whether the snakes can miss a stationary target, if you only allow the snakes to charge maybe one or two tiles instead of continuing on like rhinos, the problem is fixed regardless.

Is there any indication that any charging monster should stop before running into an obstacle? I'm under the impression this is intentional behavior.

@kphoenix137
Copy link
Collaborator

kphoenix137 commented Feb 17, 2025

Desktop.2025.02.17.-.14.02.10.31.mp4

I modified SnakeAI() to always attempt to charge at distances of 0-15 tiles from the player. I continued walking around and teleporting for about 10 minutes and didn't see a single instance of the vipers aiming incorrectly. This is a short clip from that.

@StephenCWills
Copy link
Member

Is there any indication that any charging monster should stop before running into an obstacle? I'm under the impression this is intentional behavior.

Given that the monsters in question are clearly based on snakes and that they can only charge when they are within two tiles of their target, I'm inclined to believe the attack was meant to be more of a lunge than a charge. This makes sense mechanically and thematically.

Letting them continue charging into a far-off wall, however, makes no sense from either perspective. Thematically, because snakes don't slither when they lunge so obviously it cannot keep going forever. Mechanically, because the 2-tile distance doesn't really give them enough time to build up the kind of momentum that would carry them well beyond the target of the attack.

@kphoenix137
Copy link
Collaborator

Is there any indication that any charging monster should stop before running into an obstacle? I'm under the impression this is intentional behavior.

Given that the monsters in question are clearly based on snakes and that they can only charge when they are within two tiles of their target, I'm inclined to believe the attack was meant to be more of a lunge than a charge. This makes sense mechanically and thematically.

Letting them continue charging into a far-off wall, however, makes no sense from either perspective. Thematically, because snakes don't slither when they lunge so obviously it cannot keep going forever. Mechanically, because the 2-tile distance doesn't really give them enough time to build up the kind of momentum that would carry them well beyond the target of the attack.

While I agree with your logical assessment of why the vanilla behavior doesn't make sense when you logically break it down into lore accuracy, I still can't agree with such a change, because there's nothing that I see in the code (so far) that gives me the impression this is an oversight or a bug.

I believe the most likely explanation for the supposed behavior explained in the second half of the report was misremembering events in an action filled scene, where the player did in fact move at a key moment where the lunge was able to aim for what was the correct tile, but no longer the correct tile. I don't believe the original behavior is broken by any metric, and shouldn't be adjusted.

@pionere
Copy link
Contributor

pionere commented Feb 17, 2025

there's nothing that I see in the code (so far) that gives me the impression this is an oversight or a bug.

They use the attack animation just for the snakes and explicitly set the initial frame to 7. So I would say they did not intend to animate them longer than the attack animation. See also.

@StephenCWills
Copy link
Member

I still can't agree with such a change, because there's nothing that I see in the code (so far) that gives me the impression this is an oversight or a bug.

You are ignoring the fact that the code says "snake" in it. If this were an oversight, obviously you wouldn't necessarily see anything if you were looking specifically at the logic they had come up with. The absence of the logic is proof enough that they may have overlooked it. Game design concepts, themes, and lore can give away intent just as well as any function implementation. It's important to keep it all in context.

Also, thanks @pionere, for the additional analysis.

@kphoenix137
Copy link
Collaborator

kphoenix137 commented Feb 17, 2025

there's nothing that I see in the code (so far) that gives me the impression this is an oversight or a bug.

They use the attack animation just for the snakes and explicitly set the initial frame to 7. So I would say they did not intend to animate them longer than the attack animation. See also.

This changed my mind. There would be no reason to explicitly set the animation frame if it was anticipated the animation would loop several times.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants