Gameplay Testing Utilities
A kit of placeable sandbox utilities for a testing level — the Crimson equivalent of Epic's Lyra teleporter, gameplay-effect pad, and launch pad. Each is a Crimson-prefixed AActor you drag straight into a level (or subclass as a Blueprint for a mesh + config defaults). They double as live showcases of the CrimsonCamera, CrimsonTeams, CrimsonAbilitySystem, and CrimsonInventory APIs.
UCrimsonTeamAgentComponent, or a UCrimsonInventoryManagerComponent) — the standard ACrimsonCharacter + experience setup provides all of them. No C++ is required to place or configure any utility.What ships
| Actor | What it does |
|---|---|
ACrimsonTestingVolumeBase | Abstract base for all of them: a trigger primitive (box, or a sphere via subobject override), a player-only filter, an occupant counter, and enter/exit hooks. Never placed directly. |
ACrimsonTeleportVolume | Teleports an entering actor to a DestinationActor (+ offset). Point two at each other for a portal. |
ACrimsonGameplayEffectZone | Applies a GameplayEffect while inside. Instant GEs fire once on entry; Duration/Infinite GEs are removed on exit. |
ACrimsonLaunchPad | Sphere pad. Launches a character with a configurable velocity (world or pad-local). |
ACrimsonItemSpawnerPad | Grants an inventory item on contact, then cools down and refills. Hides its mesh during cooldown. |
ACrimsonCameraZone | Pushes a camera mode on the local pawn while inside; pops it on exit. |
ACrimsonTeamChangerVolume | Reassigns the entering actor's team tags — flip a pawn hostile for PvP / attitude tests. |
ACrimsonAbilitySetGranterVolume | Grants a UCrimsonAbilitySet on enter; revokes on exit or leaves it as a permanent buff pad. |
Net-authority model
Placed actors exist on the server and every client, so overlaps fire locally on each machine. The base does not gate on authority — each utility decides for itself:
- Server mutations (
HasAuthority()): teleport, launch, GE application, team change, ability grant, item grant. These drive already-replicated state (character movement, ASC, team component, inventory), so nothing extra is replicated. - Client-local (
IsLocallyControlled()):ACrimsonCameraZoneonly — the camera is a per-client concern, so it runs on the machine that controls the pawn. - Self-replicating:
ACrimsonItemSpawnerPadalone (bReplicates), so itsbIsAvailablecooldown flag reaches clients and hides the mesh.
ACrimsonGameplayEffectZone applies on the server and never on a client. A UAbilitySystemComponent replicates its active effects to clients automatically — applying on a client too would double-apply. The same rule holds for ability-set grants and team changes.Place and configure
Every utility is Blueprintable. The fastest path is to drag the C++ class straight into the level from the Place Actors panel and set its properties per instance. For a reusable prop with a mesh and FX, make a Blueprint subclass under Content/GameplayTesting/ instead. Resize each actor's Trigger Volume (box or sphere) to cover the area you want.
| Utility | Set on the placed instance |
|---|---|
| Teleport | DestinationActor = the target actor (a second teleporter or a plain marker). Optional DestinationOffset, bReorientToDestination. |
| GE Zone | GameplayEffectClass = a heal / damage / buff GE, plus EffectLevel. A Duration or Infinite GE is removed on exit; an Instant GE fires once per entry. |
| Launch Pad | LaunchVelocity (e.g. (0,0,1200)), bWorldSpace, bXYOverride, bZOverride. |
| Item Spawner | ItemToGrant = a UCrimsonInventoryItemDefinition subclass, plus StackCount, CooldownSeconds. Set DisplayMesh to the item's mesh. |
| Camera Zone | CameraModeClass = a UCrimsonCameraMode. CameraModeOwnerTag = a unique tag (see below). |
| Team Changer | TeamTagsToAssign = the team to force. bRestoreOnExit reverts on leaving. |
| Ability Granter | AbilitySet = a UCrimsonAbilitySet. bRevokeOnExit (false = permanent buff pad). |
PushCameraMode/PopCameraMode are keyed by CameraModeOwnerTag. If two camera zones that can overlap the same pawn share a tag, the second push replaces the first, and the first zone's exit-pop yanks the override the second still needs. Give every overlapping camera zone a distinct tag.Pair two teleporters
Place two ACrimsonTeleportVolume actors. On each, set DestinationActor to the other one and give a DestinationOffset that lands the pawn clear of the destination box (otherwise it re-overlaps and can ping-pong). That is the whole setup — the teleport runs on the server and the client corrects to the new position.
Images/CrimsonCore/gameplay-testing-teleporter-pair.pngDamage-test dummy
There is no separate testing-kit dummy — the existing ACrimsonTargetDummy (see Testing Dummy) is the target. It already survives lethal hits and regenerates, so pair it with a damage ACrimsonGameplayEffectZone or your abilities. Floating damage numbers come from UCrimsonNumberPopSubsystem::RequestNumberPop(...), and adding a UCrimsonLockOnTargetComponent to its Blueprint makes it a lock-on test target.
Extend in C++
To add your own utility, subclass ACrimsonTestingVolumeBase and override HandleActorEnterVolume(AActor*) / HandleActorExitVolume(AActor*). Gate the body yourself — if (!HasAuthority()) return; for a server mutation, or an IsLocallyControlled() check for a client-local effect. To use a sphere trigger instead of the default box, chain the subobject override in your constructor:
AMyVolume::AMyVolume(const FObjectInitializer& OI): Super(OI.SetDefaultSubobjectClass<USphereComponent>(TriggerVolumeName)){}
See also
- Testing Dummy — the immortal, regenerating target these zones are usually pointed at.
- The CrimsonCamera, CrimsonTeams, CrimsonAbilitySystem, and CrimsonInventory wikis — the systems each showcase utility drives.
- Source:
Plugins/CrimsonCore/Source/CrimsonCore/Public/GameplayTesting/(+ matching.cppunderPrivate/GameplayTesting/).