Reference Scene Graph compiles

Sidekick Component: The First Mate's Moods Aboard the Beached Pirate Galleon

On the Beached Pirate Galleon, players recruit a parrot-perched First Mate NPC that rides along on every raid. Instead of scripting animations by hand, you read and react to the Sidekick's built-in emotional state to make it feel alive.

Updated Examples verified on the live UEFN compiler

Overview

There's a specific kind of magic when a companion NPC feels like yours instead of a generic quest-giver bolted onto a follow path. That's the job of sidekick_component: it wraps mood state, reaction playback, and cosmetic identity into one device so a recruitable NPC can react to the world instead of just standing near it looking decorative.

We built this at the Beached Pirate Galleon, belowdecks, where the First Mate — your first recruit on the island — trails the player into the hold. Three moments needed to land:

  • Skeleton crew burst out of the cargo hold. The First Mate should flinch, then go combat-ready, and the HUD should reflect that shift without us hand-authoring a cutscene.
  • The player pries open a sea chest. The First Mate should celebrate — but only if it isn't currently mid-swing at a skeleton.
  • The moment a player recruits the First Mate, it should stop looking like a generic NPC and start looking like their Sidekick — same skin, same swagger.

Reach for sidekick_component any time a follower needs to emote in response to gameplay events rather than a fixed animation timeline: ambushes, puzzle solves, boss phases, recruitment moments. It's the difference between an NPC that's in the encounter and one that's just standing in the room where the encounter happens.

API Reference

sidekick_component

Component to manage functionality shared by all Sidekick types.

Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse). Inherited members are merged from component.

sidekick_component<native><public> := class<abstract><final_super><epic_internal>(component):

Events (subscribe a handler to react):

Event Signature Description
ChangeMoodEvent ChangeMoodEvent<native><public>:listenable(tuple(sidekick_mood, sidekick_mood)) Signaled whenever the Sidekick's mood changes, either via the underlying mood system, or an override is applied. Returns the previous and new mood.
StartPlayReactionEvent StartPlayReactionEvent<native><public>:listenable(sidekick_reaction) Signaled when the Sidekick starts to play a reaction, returns the reaction that started playing.
StopPlayReactionEvent StopPlayReactionEvent<native><public>:listenable(sidekick_reaction) Signaled when the Sidekick ends playing a reaction, returns the reaction that played.

Methods (call these to make the device act):

Method Signature Description
GetMood GetMood<public>()<reads>:sidekick_mood Get the Sidekick's current mood.
PlayReaction PlayReaction<public>(Reaction:sidekick_reaction)<transacts><decides>:void Request to play a given reaction on the Sidekick. This reaction is not guaranteed to play immediately; instead, the StartPlayReactionEvent should be used to monitor this. This will fail if the Sidekick cannot play the given reaction.
Entity Entity<native><public>:entity The parent entity of this component. * Components must have a parent entity pointer provided when being constructed. * Components cannot be moved between parents.
RemoveFromEntity RemoveFromEntity<native><final><public>():void Removes the component from the entity. * Removed components are removed from the scene and can only be added back to the same entity. * Flows through OnEndSimulation-> OnRemovingFromScene.
IsInScene IsInScene<native><final><public>()<reads><decides>:void Succeeds if the component is currently in the scene. * After OnAddedToScene is called this call succeeds. * After OnRemovingFromScene is called this call fails.
IsSimulating IsSimulating<native><final><public>()<reads><decides>:void Succeeds if the component is currently simulating. * After OnBeginSimulation is called this call succeeds. * After OnEndSimulation is called this call fails.
SendDown SendDown<native><native_callable><final><public>(SceneEvent:scene_event):logic Send a scene event to this component, invoking OnReceive. Returns true if any participant consumed the event.

component

Base class for authoring logic and data in the SceneGraph. Using components you can author re-usable building blocks of logic and data which can then be added to entities in the scene. Components are a very low level building block which can be used in many ways. For example: * Exposing engine level concepts like mesh or sound * Adding gameplay capabilities like damage or interaction * Storing an

Full public surface, resolved verbatim from the live Epic digest (Verse.digest.verse).

component<native><public> := class<abstract><unique><castable><final_super_base>:

Methods (call these to make the device act):

Method Signature Description
Entity Entity<native><public>:entity The parent entity of this component. * Components must have a parent entity pointer provided when being constructed. * Components cannot be moved between parents.
RemoveFromEntity RemoveFromEntity<native><final><public>():void Removes the component from the entity. * Removed components are removed from the scene and can only be added back to the same entity. * Flows through OnEndSimulation-> OnRemovingFromScene.
IsInScene IsInScene<native><final><public>()<reads><decides>:void Succeeds if the component is currently in the scene. * After OnAddedToScene is called this call succeeds. * After OnRemovingFromScene is called this call fails.
IsSimulating IsSimulating<native><final><public>()<reads><decides>:void Succeeds if the component is currently simulating. * After OnBeginSimulation is called this call succeeds. * After OnEndSimulation is called this call fails.
SendDown SendDown<native><native_callable><final><public>(SceneEvent:scene_event):logic Send a scene event to this component, invoking OnReceive. Returns true if any participant consumed the event.

Walkthrough

Wiring the component to our First Mate agent. Before any of the mood or reaction logic can fire, the device needs to know which NPC it's driving and get its initial state squared away. This is the boilerplate that turns a plain NPC prop into a Sidekick that can hear events.

verse ref=sidekick-component#setup

Reacting to mood shifts automatically. The ambush is scripted at the encounter-trigger level — skeletons climb out of the hold — but we don't want to hand-place "look worried" and "look ready for a fight" as separate timed events. Instead we subscribe to ChangeMoodEvent and let the underlying mood system tell us when it has already decided the First Mate is Worried or has snapped into Combat. When that event fires, we play a short warning stinger and swap the HUD's companion-status icon to match. The mood system already knows about nearby threats; we're just listening and translating that into audio/UI feedback.

verse ref=sidekick-component#mood-react

Firing the chest-opening celebration safely. Here's the part that separates "cute idea" from "shippable feature": when the chest opens, we don't blindly call PlayReaction. We call GetMood first. If the First Mate is still flagged Combat — say a straggler skeleton is still swinging — we skip the celebration entirely rather than have it moonwalk through a sword fight. Only when the mood check comes back clear do we call PlayReaction(sidekick_reaction.Happy) or, for the big chest, PlayReaction(sidekick_reaction.Dance). This guard is cheap insurance against one of the ugliest bugs in companion AI: reactions stomping on combat animations.

verse ref=sidekick-component#reaction-trigger

Syncing VFX and camera to the actual reaction window. Requesting a reaction and a reaction actually playing are two different moments — there's wind-up, and the animation might get pre-empted. So for the Dance reaction specifically, we don't hang our confetti burst and camera nudge off the PlayReaction call. We subscribe to StartPlayReactionEvent to know the dance has truly begun, kick off confetti and a subtle camera push-in right then, and subscribe to StopPlayReactionEvent to tear it all down. This keeps effects perfectly framed to the animation instead of drifting ahead of or behind it.

verse ref=sidekick-component#reaction-sync

Making the First Mate look like your First Mate. On recruitment, we call npc_sidekick_component.ApplyEquippedSidekickCosmetic(Agent), handing it the recruiting player's Agent. It reads whatever Sidekick skin that player has equipped in their locker and applies it straight onto the galleon NPC. Two players recruiting the same First Mate on different islands end up with two visually distinct companions — which is exactly the "no two crews look alike" promise we wanted at this scene.

verse ref=sidekick-component#cosmetics

Cleaning up between encounters. Once the hold is cleared and the chest is looted, we reset mood and reaction state so the First Mate doesn't wander into the next room still flagged Combat or stuck mid-celebration. This region also clears any lingering VFX handles from the reaction-sync step so nothing leaks into the next encounter.

verse ref=sidekick-component#reset

Put together, that's the whole loop — setup, mood-driven feedback, guarded reaction playback, tightly synced effects, cosmetic identity, and a clean reset — sitting in one device:

verse ref=sidekick-component

Gotchas

  • Don't gate on PlayReaction success alone. Calling PlayReaction tells the system what you want to happen; it doesn't guarantee the animation is playing this frame. Any effect that needs to be visually locked to the reaction (confetti, camera moves, sound one-shots timed to a beat) belongs on StartPlayReactionEvent/StopPlayReactionEvent, not on the call site.
  • Check mood before every celebratory reaction, not just once. A skeleton ambush can restart mid-chest-opening animation if your encounter trigger is timing-sensitive. Cache a stale mood read and you'll get a First Mate dancing while getting hit — call GetMood right before PlayReaction, not earlier in the frame.
  • Cosmetic application needs the right Agent. ApplyEquippedSidekickCosmetic reads the recruiting player's locker, not whoever's currently closest to the NPC. If your recruitment trigger passes the wrong Agent (e.g. a generic "nearest player" query instead of the one who actually accepted the recruit prompt), you'll get a First Mate wearing a stranger's skin.
  • Reset state on scene exit, not just encounter clear. If a player leaves the hold mid-combat mood and re-enters, an un-reset sidekick_component will still think it's in Combat, silently swallowing your next celebration reaction and leaving players wondering why the chest cheer never fires.
  • Don't stack Dance and Happy reactions. Both can be valid responses to a chest, but firing both back-to-back without waiting for StopPlayReactionEvent on the first can visually stutter the NPC. Pick one per celebration trigger, or explicitly queue the second behind the stop event.

Guides & scripts that use sidekick_component

Step-by-step tutorials that put this object to work.

Build your own lesson with sidekick_component

Generate a personalized, step-by-step lesson plan built around this object — grounded in this exact reference and our compile-verified knowledge base.

Build a lesson →