Skip to content

The Echo — Player Action Feedback

The Echo is the only path from game client code into the Living World simulation. When a player hunts an animal, mines a resource, builds a structure, or engages in combat, an Echo event is submitted to the Root. The Root validates and rate-limits Echo events, then applies their effects on the next Pulse tick. The simulation remains authoritative — clients cannot inject arbitrary state changes.

Echo event types

Event typeWhat it representsPrimary simulation targets
HuntPlayer kills a Wild creatureWild — reduces prey population
MinePlayer extracts a mineral resourceFlow — depletes a resource node
HarvestPlayer gathers a plant or organic resourceFlow — depletes a resource node
BuildPlayer constructs a structureAge — minor territorial influence
DestroyPlayer destroys a structureAge — reduces faction influence
TradePlayer completes a trade with an NPC or playerAge — improves diplomatic stance between parties
CombatPlayer deals damage to a faction-affiliated entityAge — shifts diplomatic stance
RitualPlayer performs a world-affecting ritualCustom — developer-defined effects
ExplorePlayer discovers a new zone areaPulse — triggers zone activation

Ritual is a wildcard type: its effects are defined in your World Settings and are applied as a custom modifier to whichever subsystems you configure.

Emitting an Echo from game code

using Softfire.Engine.Worldweave.Echo;
var echo = Services.Get<EchoService>();
// Emit a Hunt echo
await echo.EmitAsync(new EchoEvent
{
Type = EchoEventType.Hunt,
ZoneId = currentZoneId,
SubjectId = "wolf", // The species hunted
Magnitude = 1.0f, // 1.0 = one typical kill
});
// Emit a Mine echo
await echo.EmitAsync(new EchoEvent
{
Type = EchoEventType.Mine,
ZoneId = currentZoneId,
SubjectId = "iron_vein_1", // The resource node ID
Magnitude = 0.5f, // Half a typical extraction
});

EmitAsync is async: it submits the event to the Root via the Strand and awaits the Root’s acknowledgement. The Root may reject an event (invalid zone, rate limit exceeded, implausible magnitude). The returned EchoResult indicates acceptance or rejection with a reason code.

EchoResult result = await echo.EmitAsync(echoEvent);
if (!result.Accepted)
{
Logger.Warn($"Echo rejected: {result.RejectionReason}");
}

A rejected Echo has no effect on the simulation and does not count toward rate limits.

Auto-emission

Most Echo events should not be emitted manually. The engine automatically emits Echoes for common interactions:

  • ResourceNodeService.HarvestAsync() — automatically emits a Harvest or Mine Echo with magnitude proportional to the harvested amount
  • Combat deaths — when an entity with a SpeciesTag component dies in combat, a Hunt Echo is emitted automatically
  • Structure placement — when a prefab tagged as a structure is placed via the scene editor or game code, a Build Echo is emitted

Auto-emission is controlled by EchoAutoEmitConfig. You can disable specific auto-emissions per game if the default behaviour does not match your game’s design:

{
"echoAutoEmit": {
"combatDeaths": true,
"resourceHarvest": true,
"structurePlacement": false
}
}

Security model

The Root enforces several security layers on incoming Echo events:

Rate limiting — each player can submit at most 60 Echo events per real minute. Events exceeding this rate are silently dropped.

Plausibility validation — the Root checks that the submitted event is consistent with known world state. A Hunt event for a species not present in the zone, or a Mine event for a node that is already exhausted, is rejected.

Magnitude clamping — magnitudes above the per-type maximum are clamped. A single Hunt event cannot have a magnitude greater than maxHuntMagnitude (default 3.0). Multiple events are required to represent a large-scale action.

Attribution — every accepted Echo is attributed to the authenticated player’s canonical ID. The Chronicle records player attribution on significant events.

Clients cannot spoof another player’s Echo events. The session token from the Root is required for Echo submission and is not accessible to other clients.

The ModifyWorldInfluence mod permission

Mods that call EchoService.EmitAsync() — or trigger game actions that produce auto-emitted Echoes — must declare the ModifyWorldInfluence permission in their ModManifest. Players are shown a prominent warning before installing such mods. See Mod Permissions for full details.