Skip to content
/a/ FaceCue Performance Studio

Strain

How hard the character is working.

Two independent axes: one for breathing and one for the eyes. A character can be out of breath without squinting, or squinting without being out of breath.

The Source

Implement IStrainSource and assign it to the brain's StrainSource.

Member What it returns
float RespiratoryStrain { get; } How hard the character is breathing, from rest upward
float OcularStrain { get; } How much the eyes are straining, from rest upward

A source that reads your character controller's exertion, or your game's own notion of effort, is the steady answer.

Two Axes, Each Its Own Lane

The two are overridden, released and owned separately.

brain.SetRespiratoryStrain(this, 0.8f);
brain.SetOcularStrain(this, 0.2f);
Member What it does
void SetRespiratoryStrain(float value) Claims the anonymous lane
void SetRespiratoryStrain(object owner, float value) Claims the lane as this owner
bool ReleaseRespiratoryStrainOverride() Gives back the anonymous lane. True when there was one to give back
bool TryReleaseRespiratoryStrainOverride(object owner) Gives the lane back only if this owner still holds it. True when it did
bool ForceClearRespiratoryStrainOverride() Takes the lane back whoever holds it. True when there was an override to clear

OcularStrain has the same five, named the same way (SetOcularStrain, ReleaseOcularStrainOverride and so on). bool ForceClearStrainOverrides() clears both axes at once.

Asking About It

Member Tells you
RespiratoryStrain The resolved value, override or source
OcularStrain The resolved value, override or source
Is…StrainOverridePresent Whether an override is masking the source, per axis
Is…StrainOverrideOwner(object owner) Whether this owner holds it, per axis
…StrainOverrideOwner, …StrainOverrideOwnerKind Who holds it and how, per axis

Events

StrainOverrideChanged fires when either axis's override changes, with a StrainOverrideChange carrying:

Field Holds
Axis Which axis changed: Respiratory or Ocular
Transition Which kind of change. See Sources and Overrides
HadPreviousOverride Whether an override was present before
PreviousValue What it was
PreviousOwnerKind Who held it before

One event serves both axes, so check Axis first.

Where It Reaches

Respiratory strain reaches Breath. Effort deepens and quickens the cycle, and the character settles afterwards instead of snapping back to rest.

Ocular strain reaches the lids. It is the input behind a squint, and it is independent of what the character is feeling: an emotion can narrow the eyes too, and the two compose.