Skip to content

Archive

Tag: fighting

After spending 3 evenings trying to fix my camera management, I was a little disappointed to discover that my camera positioning rules still conflict, causing inelegant jumps in places.

Guess i’ll just have to simplify a little for now. I need to get my fighting system working. Nothing really complex yet. Here’s where I stand:

  • I introduced per frame character bounds for collision detection. OK, say we have a character jumping forward or extending a kick. The character’s location vector doesn’t change. What changes is how the character occupies space. With per frame character bounds, we’re not getting really specific, but we avoid unacceptable approximations.
  • I arrange the PC to orient themselves towards a potential target (and disable hitting when there’s no NPC around). I’m doing this because we’re projecting space on a 2D screen and using an on-screen joypad. I feel it would be difficult for most players to aim at a target efficiently, and it’s not quite the point of my game.

Meanwhile, this stuff doesn’t really resolve how fighting should work in my game… let’s take a few examples to clarify.

RPG style fighting

There are many slightly different ways RPGs resolve fighting. I’ll be ignoring turn based games as this is a bit far off for me. Here’s an idealization of how this works:

  • PC can engage combat or escape.
  • When fighting, PC cannot avoid hits (NPC can miss, but that’s related to stats)
  • NPC cannot avoid hits
  • Timing is not important.
  • PC can use potions during combat
  • Minimally, PC needs to engage combat. In some games you can die because NPCs engage you, but you don’t engage them. In realtime fighting RPGs, the player must push a button for every hit.
  • Typically, PC wins because their stats are better.
  • PC needs to rest after fighting in order to recover health points. This is somewhat of a late addition, but it’s getting quite popular. Depending on the game, HPs are slowly increasing all the time, or potions only can restore HP, or the PC needs to be still, or the PC needs to sleep at an inn.

In RPG style fighting, the intensity of the fight is linked with three parameters:

  • Experience. Two well matched opponents makes for a more ‘interesting’ match.
  • Exhaustion. Even minor NPCs can outmatch a bold PC that went too quick, too far. In other words if an area has many NPCs, the PC doesn’t have time to recover and fighting becomes more risky.
  • Chance. Most RPGs include an element of chance (esp. critical hits) making fighting more interesting, because even a lower level PC or NPC can get lucky and win an otherwise losing match.

Action style fighting (no shooting)

My understanding of that is even fuzzier; roughly speaking, there seems to be three dimensions to consider:

  • Reflexes. The fastest opponent tends to win the fight. Games that rely more on this also rely on the player getting faster over time, as they get more used to the controls. This dimension is likely biased towards the player in many games, because the PC is faster to execute moves than NPCs
  • Range. Often the player’s range is wider than NPCs. This allows a careful player to neutralize opponents before they are in range.
  • Moves. In fighting games, the outcome of a contest seems to be determined on a case basis, depending on moves executed simultaneously/near simultaneously by both opponents. Example: A does a high kick, B does a low kick => B wins. A does a high kick, B does a punch => B loses.

What’s ‘light action’ like?

This is what I want to try in a first approximation:

  • If the PC doesn’t have a weapon good enough, the weapon is, strictly, ineffective.
  • If the PC is hitting the NPC, only the NPC loses points (and, likely, dies in one stroke)
  • If the NPC is hitting the PC, but the PC isn’t hitting them, the PC loses a point.
  • The PC has 3 points.
  • The PC can recover their points after a cooling period.

To be continued?

Today I’ve carried out a telling experiment while creating my first half-decent kick animation (ever):

  • The three step animation recipe doesn’t seem to work so well for a player action – at least it doesn’t feel right. Let’s not throw gold into a well. What I think is happening is that, when hitting a button, a player’s physical action includes preparation and impulse, so the expected behavior (at least for arcade style animation) is to complete the action. At least my animation looks better this way – after I’ve cut the first half, keeping no anticipation and  starting right in the middle of the action phase.
  • My engine has been running to its limit, making balancing pointless in most cases. I’ve noticed that because I tested my animation in Blender first, and it felt smooth at 15FPS, but felt jumpy on the phone even though it was meant to balance around 15. This brings two interesting notes:
    • Around 9-11 FPS, a game needn’t feel jumpy on a small screen, or I would have noticed earlier. Surely 15 to 30 look increasingly smooth, but balancing graphics against FPS is a genuine alternative. Even though I choose 15 as a reference, a colleague more used to targeting 60FPS on desktop platforms shrugged it off, pointing out that camera motion didn’t feel jumpy. However…
    • For my kick animation (and likely other action oriented play) getting my work to look good requires 15 to 20 FPS, and I’d much rather balance at around 18.

This doesn’t tell the whole story. To a fair extent its a matter of style. I also remember an animation teacher pointing out that ‘unlike 2D, 3D action dies out as soon as motion stops’. Extrapolating a little, I’d say that, the more an object looks real, the more it requires smooth, convincingly realistic animation. Bit of a worry for me because my technology and craft are kind of half baked, with the modeling side miles ahead the animation.

Graze not, or not just yet…

Right. I removed my pretty grass for now, I know I can chunk it and display much less at once (and I will) but for now several factors point towards simplification:

  • I’m worried about the cost of artwork. This may not be fair because I did spend a lot of time writing modules for my engine while getting on with the artwork.
  • I’m losing illusions regarding game-space. I don’t like game space to be too simple and square, but there are ergonomics and gameplay issues involved. If the terrain is simple and easy to understand, players will tackle the terrain. If the player is complex, some players will head on while others would really rather just ‘point and touch’ and expect an invisible copilot to path-find where they want to go.
  • If I need to balance around 17FPS, something else has to go, at least until I optimize a little more.
  • I feel the need to focus on gameplay versus art. If you remember the boxed product game era, you will probably recall how pretty a game box typically looked compared to the actual product. Well we can think of it as a lie factor, or (generously) as a transposition. While players surely don’t play the box, having fun with the game didn’t necessarily involve high end graphics. Anyway, I feel the revival/long death of 16 bit style gaming may somehow associate simple graphics with cool gameplay.

Enough ramblings. what I really mean is, I probably need to shift the balance a little – less artwork, more gameplay and more speed. But for now…

I’m fixing a couple of frame stepping related bugs.

Note: looking back at my posts, I’m not sure if it’s fair to incriminate artwork when trying to analyze how long this thing is taking. Clearly I’ve been working mostly on the engine and UI for the past 2 weeks or so. Building the engine takes time. If the engine is reused, that’s an investment, otherwise, call it pure waste.
More coding ahoy, see below :)

Working notes for combat

I’m having a go at checking in more detail if I can get a little action to really happen in my game, and I’m not too happy. Here’s the general idea:

  • Characters have actions
  • Some actions can affect other characters.
  • Actions are ranged in various ways (maybe too many ways)
  • Actions can be narrowed using an angle. If the opponent is not facing the target within this angle, no result occurs.

I dunno – I maybe tired or I may be getting lazy. I’m trying this out with rats jumping at the PC, and I see bugs, but I also wonder, why do I really need to define all this stuff? Wouldn’t it be tons easier to refine my boundary testing a little?

Yeah… I guess. And likely much less error prone. Here is what I would  consider:

  1. Bounds need to be evaluated per frame, and take orientation into account.
  2. Bounds can be spherical. Likely that’s faster and easier.
  3. Evaluating bounds using materials can be very useful. This way we can avoid larger than life approximations when simulating, say, sword fight.
  4. Speed is a simple element to consider. Speed is more significant than impact frames. Let’s take a quick example. The rats jump one meter ahead and the impact frame is 25. At around 20 frames per second, that’s a little slower than one meter per second, giving us (for something I can relate to) 3.6 km / hour. That matches pretty well with my original idea: a rat isn’t a projectile, it jumps to bite (I dare hope real rats don’t jump neck high).
    The kick animation is much faster,  covering 1.5 meter in just 3 frames. That makes 6 x 1.5 = 9 meters per second, more like 30 km/hour. Unsurprisingly that’s about the speed limit in villages in France. Granted it’s possible to get really hurt at that speed, the more likely compromise there is that you can see a car coming at that speed, not at 120. A foot is a decent projectile.

It’s not about simulating, more about making life easier – not just defining impact frames takes time (open blender, scroll through animations, copy parameters…) it also makes stuff inherently fragile.

Like copying object coordinates instead of loading them; but that’s another story.

In my previous article, I drafted/debugged basic combat behavior in a game prototype. A simple combat system probably needs to account for the following – if only to get animations to sync correctly if character actions are independent.

  • Impact Frame – unless you have fine grained collision detection, the impact frame determines when the opponent actually gets hit.
    I am adding per action impact frames – each action can define it’s own frame/time offset. I’ll probably use a time offset instead later, but that will be part of a general effort on my part to move from frame based to time based modelling.
  • Passive reaction – When an actor gets hit, they cannot enforce their decisions.
  • Impact condition. A simple model can take into account the orientation relative to, and distance from, the target. My model already has this but that seems a little buggy.

Writing a class to hold impact frames is nothing, although you might legitimately want to store your impact frame information anywhere else:

#import “ImpactFrames.h”

#import “Definitions.h” // used for the ‘act’ typedef which is just a NSString*

@implementation ImpactFrames

static NSMutableDictionary* map;

+(void)putFrameOffset:(int)frameOffset forAction:(act)action{

if (map==nil)map=[[NSMutableDictionary alloc]init];

[map setObject:[NSNumber numberWithInt:frameOffset] forKey:action];

}

+(int)getFrameOffset:(act)forAction{

return [((NSNumber*)[map objectForKey:forAction]) intValue];

}

+(void)clear{

[map release];

map=nil;

}

@end

Passive reactions can be implemented using three tags: action, affect and activity

  • Activity represents the current action.
  • Affect represents a passive reaction to an external action
  • Action represents the actor’s decision.

Then each evaluation can be structured as follows:

  1. If an affect is defined, override action with affect
  2. If the current activity matches the current action, continue.
    1. If we have not reached the last frame for this action, continue to the next frame.
    2. If we have reached the last frame, clear the affect and action labels.
  3. If the current activity is the ‘rip state’ return immediately.
  4. If the current action is different from the current activity, initialize this action.

I had to patch my actions a little because I manage motion and activity independently, so I need to replicate some of the logic.

I have this little character that goes on to hit an NPC for a test, and the NPC dies on the spot. Actually, now that I remember, I have an animation for the death of my NPC. What I want to make happen:

  • The PC getting hit
    • A NPC needs to aim their action at the PC.
    • User interaction needs to be disabled while the PC register the hit.
    • An animation needs to be played.
    • Other effects may be seen, e.g. lose life points
  • The NPC not chasing after the PC while dying (that’s a bug)

I’d rather use my behavior (pseudo)scripting API instead of just hacking away. Conceptually, integrating player decisions with standard NPC scripting fits fairly well, so I should put my code where my brains are.

Design bites back, the dog doesn’t.

My ‘biting dog’ script doesn’t seem to work as well as it used to be. This relates in part to design issues with my framework:

  • In my script, the dog would walk to the player and start to bite. If the player moves away, the dog starts chasing the player. This is correct since the player has moved within ‘chase range’ and is now out of biting range. However, at that point the biting action is not reset and that has reached frame zero. I need to reset an action whenever it completes, so I have introduced a ‘reset’ method.
    >> actions are instantiated too early. The action descriptor should be used to regenerate the action whenever the condition is filled. This will avoid relying on a ‘reset’ call. In other words, the condition should be armed and attached to the agent; the action descriptor should be attached to the condition. When the condition is fulfilled, a new instance of the matching action should be created.
  • I used to rely on the agent having non zero speed to determine the agent state is ‘walking’. This is more than wrong. There are various factors that can affect an agent speed. I have corrected this but forgot to update the action tag in Approach, Avoid, MoveTo, etc…

Let the player be hurt

I add a couple of lignes to my script (in fact i add a player script since I have none) for the player to be ‘hurt’. Hurt is just a label here, but that could bind an animation.

Roughly speaking, things work out pretty good, but not good enough. If the player targets the dog, the PC and NPC end up rushing each other. I can’t clearly see which one hits the other first. The player seems to have the upper hand.

Bite me, Stab me

I still need to ensure two things:

  • I seem to have a targeting problem.
    • There is a limit angle for a hit to register – an actor needs to be facing the target. This shouldn’t, but seems to be a problem.
  • Both the player and the dog should be able to hit each other in turn.
    • As far as I know there is no lag time between hits.
    • Also, I have no ‘impact frame’ defined. In other words, while an actor is acting, the actor is being hit – these are ‘linked states’ rather than an action and reaction.

Whenever I bind a script using my Interpreter, the following occurs:

  1. For each type definition in the script (a type definition is associated with an actor’s label, bindType is invoked.
  2. bindType, creates both a reflex map and an affect map.
  3. Actions are added to the reflex map ; interactions are added to the affect map.

This means that action/interaction couples are grouped per actor in the main transition. Although not ideal, this seems to work fine:

(Aim) player aims action:stab

(AffectAction) player targetted by:hurt

(BasicActorUpdates) resolve Actor player {…} to hurt

(BasicActorUpdates) resolve Actor dog {…} to bite

What the log indicates is that even though the player aims the stab action, it is being hurt, which overrides the player’s intent.

If I look at AffectBinding (which causes both the dog to bite the dust and the player to be hurt when attacked), I see that states are linked at every frame. In retrospect, this is an obviously poor design. It would be way more efficient and probably more useful to just trigger the affect once. But what happens in my case is that the affect triggers over and over until the activity stops.

So in this case, for as long as the dog is in ‘bite state’, the player state is ‘hurt’. Since the dog bites in a loop, the player can never counter-attack, because affects (passive actions) override decisions.

In ActorAffectCondition (a condition that triggers an affect, such as being hurt, when another actor is performing an action on the target), i have a checkAgainst: method. There, I add a condition specifying an ‘impact frame’ for the source action.

The result is immediate (and visually obvious) – instead of  sticking to the ‘hurt state’ the PC now blips between hurt and normal. This also means that the PC can counter-attack.

R.I.P

I still have this problem with the ‘zombie dog’. The death state shouldn’t allow wagging dog tail and biting a victorious player.

In theory I could add a capacity switch to the dog’s stab response. But there’s nothing to check for capacities just yet. Since being dead is a peculiar state, I will hack this once.

Activity change is ultimately driven by an actor’s step: method. This iterates activities and cycles them. For now, this allows all activities to be interrupted.

I could force all activities to complete before another starts. Trying this is interesting but for now, not very effective, causing more inconsistent behavior.

Instead I only force the ‘rip state’ to be sticky.

Oh my. This dog is still running around though. Motion is controlled independently from action… so I wire another hack into my
[BasicActorUpdates updateActorLocation:]
method.

Conclusion

This is my first debugging session on the behavior engine since I wrote the original draft and validated the test suite. Since the test suite was so simple – testing really basic cases – surprises tend to occur.

The design of behavior implementation isn’t good. I’ll make another implementation later I guess, including only current activities in the loop and adopting an event driven approach for higher level behaviors. This will be cleaner, more intuitive, and reduce processing load.

Meanwhile, there are also shortages in action descriptions:

  • An action should at least have a flag (maybe with a default) indicating whether this action can be interrupted. Passive responses shouldn’t be interruptible. Many actions (e.g., walk cycle) work out better if they can be interrupted.
  • An action should specify an impact frame, and whether the effect is punctual or continuous.
  • An action should ideally have a lag time. This could somehow be made integral to impact frames.

At higher level, a working combat model should take into account the following:

  1. The speed of an attack depends on the length of the attack animation. If the attack has an ‘impact frame’ then a longer attack means attacking less often.
  2. If the attack can be interrupted, then the later the impact frame, the easier it is for the player to anticipate the attack.
  3. The speed of recovery determines the ability to counter-attack. If recovery is slow, then the opponent may be able to attack another time.

Tomorrow, I need to:

  • Allow specifying impact frames.
  • Test with actual animations
  • Allow specifying which actions can be interrupted, and which cannot.