OpenRA/OpenRA · error · YamlException
WithAimAnimation needs exactly one sprite body with matching
Error message
WithAimAnimation needs exactly one sprite body with matching name.
What it means
Thrown in WithAimAnimationInfo.RulesetLoaded when SingleOrDefault finds zero WithSpriteBodyInfo traits with a Name matching the Body field. WithAimAnimation switches a sprite body to an aiming sequence when the actor is targeting, so it needs exactly one WithSpriteBody to control. Note: SingleOrDefault throws InvalidOperationException if there are multiple matches, but this YamlException is thrown only for the zero-match case.
Source
Thrown at OpenRA.Mods.Common/Traits/Render/WithAimAnimation.cs:36
{
[Desc("Armament name")]
public readonly string Armament = "primary";
[SequenceReference]
[FieldLoader.Require]
[Desc("Displayed while targeting.")]
public readonly string Sequence = null;
[Desc("Which sprite body to modify.")]
public readonly string Body = "body";
public override object Create(ActorInitializer init) { return new WithAimAnimation(init, this); }
public override void RulesetLoaded(Ruleset rules, ActorInfo ai)
{
var match = ai.TraitInfos<WithSpriteBodyInfo>().SingleOrDefault(w => w.Name == Body);
if (match == null)
throw new YamlException("WithAimAnimation needs exactly one sprite body with matching name.");
base.RulesetLoaded(rules, ai);
}
}
public class WithAimAnimation : ConditionalTrait<WithAimAnimationInfo>, INotifyAiming
{
readonly AttackBase[] attackBases;
readonly WithSpriteBody wsb;
public WithAimAnimation(ActorInitializer init, WithAimAnimationInfo info)
: base(info)
{
attackBases = init.Self.TraitsImplementing<AttackBase>().ToArray();
wsb = init.Self.TraitsImplementing<WithSpriteBody>().First(w => w.Info.Name == Info.Body);
}
void UpdateSequence(bool isAiming)View on GitHub (pinned to a520984d91)
Solutions
- Ensure the actor has exactly one WithSpriteBody trait whose Name matches the Body field on WithAimAnimation (default 'body' for both).
- If the Body field is customized, verify the matching WithSpriteBody Name is spelled identically.
- If the actor has no sprite body, remove the WithAimAnimation trait.
Example fix
// before (no matching WithSpriteBody) WithAimAnimation: Body: torso WithSpriteBody: Name: body // after (names match) WithAimAnimation: Body: body WithSpriteBody: Name: body
Defensive patterns
Strategy: validation
Validate before calling
// Verify exactly one WithSpriteBody matches the Body field
var spriteBodies = actorInfo.TraitInfos<WithSpriteBodyInfo>();
foreach (var waa in actorInfo.TraitInfos<WithAimAnimationInfo>())
{
var match = spriteBodies.SingleOrDefault(w => w.Name == waa.Body);
if (match == null)
Log.Error($"WithAimAnimation on {actorName}: no WithSpriteBody with Name '{waa.Body}'.");
} Prevention
- Keep WithSpriteBody Name and WithAimAnimation Body in sync; both default to 'body'.
- When renaming a sprite body, search for all referencing traits.
- Use the default 'body' name unless multiple sprite bodies are needed.
When it happens
Trigger: An actor has a WithAimAnimation trait with Body set to a name (default 'body'), but no WithSpriteBody trait exists on the actor with that name. This can happen if WithSpriteBody was removed or renamed, or the Body field references a non-existent body.
Common situations: Renaming a WithSpriteBody's Name without updating WithAimAnimation.Body; removing WithSpriteBody while leaving WithAimAnimation; adding WithAimAnimation to an actor that uses a different body trait (e.g. WithEmbeddedBodyPalette but no sprite body); typo in the Body field.
Related errors
- WithAttackAnimation needs exactly one sprite body with match
- ProximityCapturableBase requires the `Player` actor to have
- ReloadsAmmoPool.AmmoPool requires exactly one AmmoPool with
- Hovers.BobDistance must be a negative value.
- Hovers.Ticks must be higher than zero.
AI-assisted analysis of OpenRA/OpenRA@a520984d91 (2026-08-13).
Data as JSON: /api/errors/b98ff72b157390e7.
Report an issue: GitHub.