Skip to content

FightingCharacter

namespace Griff.Modules.Fighting;
public sealed class FightingCharacter : Component, IPlaytestReport

A fighting game’s fighter with no code: walks forward and back, jumps (up, forward or back) and crouches on the directions, faces its opponent by itself, and does its Moves, each written in numpad notation (5P a standing punch, 2K a crouching kick, 236P a quarter circle forward and punch, 623P a dragon punch, [4]6P a charge) and played from an animation clip whose hitboxes (drawn in the Clip Editor) are the part that hits, over the startup, active and recovery frames the move gives. Holding back blocks: a blocked hit does only chip damage and holds it in blockstun, and lows must be blocked crouching, overheads standing. A hit holds it in hitstun (its Hitboxes’ Hitstun), where it can do nothing, and the hits an opponent lands while it’s still stunned count up as a combo. A button pressed a few frames early still comes out the moment it can (the input buffer), and moves cancel into the ones they’re allowed to once they’ve connected. Edit its moves in Entity > Edit Moves, or keep them in a table.

It plays its Animation’s Idle, Walk (or Run), WalkBack, Crouch, Jump, Block, CrouchBlock and Hurt clips when it has them, and KO (or Hurt) once its Health runs out, doing nothing more. Everything is counted in steps (frames, at 60 a second) and kept with the scene, so the same input does the same thing every time, and a rewind carries on mid-motion and mid-move. It reads the controls of whoever plays it; in a network game the host runs it, as it lands every hit.

This is a component: its saved properties are on its component page.

public AutoBlock AutoBlock { get; set; }

Blocks by itself: never, everything standing, everything crouching, or always (for a training dummy).

public string AutoBlockName { get; }

Its AutoBlock in words, for a training menu’s label: “Never”, “Standing”, “Crouching” or “Always”.

public float BackWalkSpeed { get; set; }

How fast it walks back, in units a second.

public int BestCombo { get; set; }

The longest combo it has landed. Set by the game.

public string? BlockEffect { get; set; }

A prefab spawned where a blocked hit meets it: a spark.

public string? BlockMessage { get; set; }

A message sent as it blocks a hit, with the chip damage as its data.

public float BlockPushback { get; set; }

How much of a hit’s knockback a blocked one still pushes it back with, 0 to 1.

public string? BlockSound { get; set; }

A sound played as it blocks a hit, e.g. “Sounds/block.wav”.

public bool Blocking { get; set; }

True while it’s blocking: holding back on the ground and free, or in blockstun. Set by the game.

public int Blockstun { get; set; }

Steps of blockstun it has left: after blocking a hit, it can do nothing else until they’re up. Set by the game.

public int BufferFrames { get; set; }

How many steps (frames, at 60 a second) a press is remembered: one made that early still comes out the moment it can (as a move ends, or lands), once. 1 takes only presses made as it can act.

public IReadOnlyList<ValueTuple<string, string>> ButtonList { get; }

Its Buttons read: each button’s name and the action it is.

public string? Buttons { get; set; }

The buttons its moves name and the input action each is, e.g. “P Punch, K Kick” or “L Light, M Medium, H Heavy” (with those actions added in Controls). Up to eight.

public int ChargeFrames { get; set; }

How many steps a charge must be held (back for [4]6P, down for [2]8K) before it’s let go.

public float ChipDamage { get; set; }

How much of a blocked hit’s damage it still takes (chip damage), 0 to 1. A move’s own chip says otherwise.

public int Combo { get; set; }

How many hits its current combo has: each hit it lands while the one it’s hitting is still in hitstun from the last adds one; it’s 0 again once they recover (ComboHits shows it from the second hit on). Set by the game.

public float ComboDamage { get; set; }

The damage its current combo has done. Set by the game.

public int ComboHits { get; }

Its combo’s hits for a HUD: from the second hit on (one hit is no combo yet), 0 before.

public string? ComboOn { get; set; }

Who its combo is on (an id). Set by the game.

public bool Connected { get; set; }

True once the move it’s doing has hit or been blocked: what lets it cancel. Set by the game.

public bool Controllable { get; set; }

Untick it to ignore the player’s input (a training dummy, a cutscene); it still blocks by AutoBlock, and its Perform action still does moves. Its Focus action ticks it and unticks it on everything else the player plays.

public bool Crouching { get; set; }

True while it’s crouching. Set by the game.

public bool FaceOpponent { get; set; }

Turns to face its opponent whenever it’s on the ground and free, so forward is always towards them.

public float Friction { get; set; }

How quickly it stops sliding on the ground (after a knockback or a push), in units a second per second.

public bool Held { get; set; }

True while something holds it still and deaf to its controls (a versus match before a round’s “Fight!” and after its K.O.): it stands, falls and recovers, but walks, jumps, blocks by hand and starts no moves. Set by the game.

public string? History { get; set; }

What it has pressed lately, oldest first: a direction a step as it faced (with any buttons pressed then), a run of the same written once with how many (“5*40 2 3 6P”). What motions and the input buffer read. Set by the game.

public bool HoldBackToBlock { get; set; }

Holding back (away from the opponent) blocks; down-back blocks crouching. Off, it never blocks unless AutoBlock says.

public bool IsFree { get; }

True while it can do something new: not in a move, hitstun or blockstun.

public float JumpHeight { get; set; }

How high a jump goes, in units. 0 can’t jump.

public float JumpSpeed { get; set; }

How fast a jump forward or back goes sideways, in units a second.

public bool JustBlocked { get; set; }

True on the step it blocks a hit. Set by the game.

public int MotionFrames { get; set; }

How many steps a motion (a quarter circle, a dragon punch) may take, from its first direction to the button.

public string? Move { get; set; }

The move it’s doing, by name; empty when it’s free. Set by the game.

public int MoveFrame { get; set; }

Steps into the move it’s doing. Set by the game.

public IReadOnlyList<FighterMove> MoveList { get; }

Its Moves read (those that make sense), without the table’s.

public IReadOnlyList<string> Moves { get; set; }

Its moves, a line each: a name and a colon, the input in numpad notation as the fighter faces right (6 forward, 2 down, 5 neither; j. in front for the air; [4] for back held as a charge), then any of clip Name (the clip it plays: its name without spaces if left out), frames 3/2/6 (steps of startup, active and recovery; left out, the clip’s own speed), low or high, blockstun 10, chip 0.25, push 2,0 (forward and up as it hits), message Name, sound Path and last cancels special (or move names). E.g. Jab: 5P frames 3/2/6 cancels special, Fireball: 236P frames 12/4/30. When two fit, the longer motion wins, then the one whose last direction came nearest the button, then the one listed first.

public string? MovesTable { get; set; }

A table of more moves, a row each, after its own: the row’s name, and columns Input, Clip, Startup, Active, Recovery, Hits (Low or High), Blockstun, Chip, Push, Cancels, Message and Sound. Empty for its own moves only.

public bool OnGround { get; set; }

True if it stood on something after the last step’s physics: what it walks, jumps and blocks by (kept with the scene, so a rewind knows it’s on the ground before physics has run again). Set by the game.

public string? Opponent { get; set; }

Who it fights, by name: it faces them. Empty for the nearest other fighter not on its team.

public MovePhase Phase { get; }

Which part of its move it’s in.

public string PhaseName { get; }

Which part of its move it’s in: Startup, Active (its hitboxes hit), Recovery, or None when it’s free.

public float WalkSpeed { get; set; }

How fast it walks forward, in units a second.

public void NextAutoBlock()

Changes its AutoBlock to the next: Never, Standing, Crouching, Always, and round again (a training dummy’s guard).

public static IReadOnlyList<ValueTuple<string, string>> ParseButtons(string? text)

“P Punch, K Kick” read: a name and an action each, up to eight.

public void Perform(string move)

Does the move called move next step if it’s free then, as if its input were pressed: for a trigger, a wire or a computer player.

public void ResetCombo()

Ends its combo count (the HUD’s “hits” goes back to 0).

public override string? SetupNote()
public static MoveTiming TimingOf(FighterMove move, Animation? animation, Hitboxes? boxes, int stepRate = 60)

How move plays on a fighter with animation and boxes at stepRate steps a second: its startup, active and recovery in steps (its own, or from its clip’s frames before, with and after hitboxes), and which of the clip’s frames shows at each step.

public override bool Uses(string property)
public event Action<HitInfo>? Blocked

Raised as it blocks a hit, with the hit (its damage the chip it took).

public event Action<FighterMove>? MoveStarted

Raised as it starts a move, with the move.

public const string DefaultButtons

The buttons a fighter starts with: P (the Punch action: J or the gamepad’s X) and K (Kick: K or the gamepad’s A).