How does RPG handle shield, parry, dodge?

As I never done such mechanics in game before I wonder if this works similar to deal_damage to HealthComponent or there is some differences in approaches ?

Do I subtract or call shield with some Boolean check?

How do you detect if hit came from the back of enemy or front?

Is there maybe formula for parry when to trigger it?

I’m not familiar with the deal_damage or HealthComponent you’re referring to, but if we break down the concepts we might can make a solution. Hopefully I can help conceptualize how to do it

Dodge roll is easy. I did this in my 2D platformer project. I made a “hurtbox” that is an area that receives enemy “hitbox” from attacks. During the dodge roll, just disable the collision shape that is a child of the area. Use a timer to re-enable the collision shape.

Blocking: Maybe use an Area3D that faces the direction the shield does. If an enemy is in this area and they attack, it doesn’t call the player '“take damage” function. If they attack from the side or behind, then the player can still take damage. If enemy attacking direction is a concern, you could use the animation player to move the “hitbox” during the attack. Or you could use a raycast that faces the enemy’s front, so it only hits the player if the raycast detects the player.

For parrying, when you call the shield, you could use a short timer that is the “parry window.” In your “take damage” function, you could use “await timer” to do a short delay, and if you raise the shield during this short window, skip the rest of the logic in the “take damage” function after the timer is up

1 Like

I broke it down here Delay in dealing damage from enemy to player

parry

In the turn based RPG’s I have been playing (very old school), parry is a selectable attack turn option.
It simply reduces the amount of damage taken and usually by a very small percentage. (so small in fact I never use it)
It (maybe) also raises the chance (again, only the tinniest bit) for a missed attack against the player and/or an automatic counter attack; .
Is yours real time battling or turn based and 2d or 3d?

1 Like

To detect if the attacks come from the back or the front. Personnaly I think I would do two différents hit boxes: one in the back, on the the front.

Like this you can easily know from where the attacks is coming from.

About the shield. In my action game I simply handle that in the same function then deal_damages. I just check if a Boolean « has_armor » is true or not and I calculate damages differently inside that if

1 Like

Real time 3d

I remember parry rather not to take damage at all and play sound of two steel swords parry. - in game such as WoW.

I think this is very game dependent. To me a parry is not a block. A parry is also not a dodge. So with Parry, Block and Dodge, I would imagine none of them would have the player take damage. But dodge might reduce energy, block might let the weapon take some damage, parry might give the opportunity for a quicker than normal attack response. Block might be done with a shield, Parry done with the weapon.

And any of them might be automatic responses with a chance_to_parry, chance_to_dodge or change_to_block depending on the type of battle being done or even the type of attack.

I doubt any two games do any of these things exactly the same way.

1 Like

Wow style combat is great. The combat is similar to turn based but the characters speed affects the attack rate. So the characters damage per second (DPS) caused them to attack with different rhythm. There was a parry stat that could be increased by adding gear with agility or parry. When a character gets attacked they have a chance to parry, its like rolling a dice but in WoW is probably a random number between 0 and 1, and the parry chance is a percentage, like 0.3.

1 Like

Yeah this is the ultimate question how to put it together.

So far I think magic attacks and melee attacks, this be best if add limitations for abilities via mana and energy to reduce it not only with cooldown but also by resource management.

All assets are from KayKit, a few thinks makes me wonder about colliders, if I use too many area3d it might get confused what should be activated.

Would I need extra management to identify type of attack to make difference between magic which could be blocked with shield , but would not do parry?

Current state

Latest magic attacks

This was related to decals, which be also another thing to consider as KayKit is multiple meshes, if I should use even decal at all.

1 Like

Do you not already distinguish between magic_attack and physical_attack? And somewhere you must have ranged_attack and proximity_attack or similar. I mean weapon types must distinguish this surely? You cannot do a quick response to a ranged_attack. I would also think that a shield would help agains a magic attack. Might not stop it but might if the magic attack is like an energy beam.

Thinking about this has been quite fun to be honest. It is making me want to make a fighting game too (just as a side project out of interest). It very much depends on your gameplay intentions. Would the player character automatically raise their shield if an arrow was approaching? Or does the player have to activate that behaviour?

But to answer your question, almost certainly you have to know the attack type and manage that. A magical poison cloud that appears around you cannot be parried or blocked. But it will need to drain your health. A freeze attack has to prevent your movement etc.

Also attacks have different speeds, so a large swing of a mace is more easily blocked than a lunge with a light sword. You could parry the sword, but a large heavy mace can only be dodged.

You could just have one attack manager system but the attack would have to convey a lot of information at once. Families of attack types means you don’t need a management system for every attack type, just each family of attacks types.

It is a fascinating problem though. In your prototype you would probably be better off doing an attack management for every attack type initially. Patterns will soon form and you can refactor them later into families.

Your prototype is looking really good BTW, love the sound.

1 Like

I thought do slash/fireball with left click and right click shield or other action , parry only available for dagger/sword .

The bow will be very much similar to magic attack only difference is in not spawning explosion scene and decal .

All is pretty much there in KayKit free assets, most of inspiration is from Character controller and RPG course in Gamedev.tv , also projectile logic is from Bramwell Williams video on YouTube , https://youtu.be/vGpFwaLUG4U he solved there projectile, which later was improved here on forum.

This scene tree could maybe be used instead of manually doing if statements trees and call some of the methods in animation tracks with Boolean check and signal be updating booleans based on area3d enter/exit .

Yeah this is one think which I didn’t consider yet as animation dictate length of attack.

Groups or classes, classes might be better.

I haven’t done a such thing before, currently I would need to divide the player and enemy to sub_class which would use different animation_trees.

So bit update today, Area3D combined with Raycast3D

if is_colliding():
		var collider = get_collider()
		if collider.has_method("take_damage"):
			var dodge_change = randf()
			print(dodge_change)
			if dodge_change <= 0.5:
				print("dodged")
			else:
				collider.take_damage()
		if collider.has_method("hit_shield"):
			collider.hit_shield()

Launcher code updated for Raycast check if enemy can see player

func _on_attack_timer_timeout() -> void:
	if enemy.can_see_target:
		enemy.start_attack()

		var attack = PROJECTILE.instantiate() as RayCast3D
		add_child(attack)
		attack.global_transform = global_transform

		if animation_tree:
			animation_tree.set(ATTACK_ONESHOT_PATH, AnimationNodeOneShot.ONE_SHOT_REQUEST_FIRE)

		await get_tree().create_timer(stop_movement).timeout
		enemy.end_attack()
	else:
		enemy.end_attack()

	timer.start()

Visual