From d6ffad85ccab94f3690cfc00d3ebe170fc776dbe Mon Sep 17 00:00:00 2001 From: DazedAnon Date: Wed, 15 Jul 2026 05:06:01 -0500 Subject: [PATCH] Refactor activity action and prose handling to improve clarity and expand functionality. Removed unused templates from ActivityActionComposer, introduced new clauses for observed targets and carrying actions in ActivityClauseAssembler, and updated ActivitySpeciesVoice to include additional authored verbs. Enhanced ActivityVerbMap to support new action mappings and incremented version in mod.json to reflect these changes. --- IdleSpectator/ActivityActionComposer.cs | 91 +- IdleSpectator/ActivityClauseAssembler.cs | 35 +- IdleSpectator/ActivityProse.cs | 860 +---------------- IdleSpectator/ActivitySpeciesVoice.cs | 36 +- IdleSpectator/ActivitySpeciesVoiceCatalog.cs | 93 ++ .../ActivitySpeciesVoices.Animals.Extended.cs | 259 +++++ ...tivitySpeciesVoices.Animals.Specialized.cs | 119 +++ .../ActivitySpeciesVoices.Civs.Extended.cs | 883 ++++++++++++++++++ .../ActivitySpeciesVoices.Civs.Specialized.cs | 351 +++++++ .../ActivitySpeciesVoices.Fantasy.Extended.cs | 836 +++++++++++++++++ ...tivitySpeciesVoices.Fantasy.Specialized.cs | 333 +++++++ .../ActivitySpeciesVoices.Fantasy.cs | 20 +- ...itySpeciesVoices.Invertebrates.Extended.cs | 459 +++++++++ ...SpeciesVoices.Invertebrates.Specialized.cs | 207 ++++ .../ActivitySpeciesVoices.Mammals.Extended.cs | 534 +++++++++++ ...tivitySpeciesVoices.Mammals.Specialized.cs | 240 +++++ IdleSpectator/ActivityVerbMap.cs | 95 +- IdleSpectator/ActivityVoiceHarness.cs | 71 +- IdleSpectator/AgentHarness.cs | 14 + IdleSpectator/HarnessScenarios.cs | 4 +- IdleSpectator/mod.json | 2 +- 21 files changed, 4555 insertions(+), 987 deletions(-) create mode 100644 IdleSpectator/ActivitySpeciesVoices.Animals.Extended.cs create mode 100644 IdleSpectator/ActivitySpeciesVoices.Animals.Specialized.cs create mode 100644 IdleSpectator/ActivitySpeciesVoices.Civs.Extended.cs create mode 100644 IdleSpectator/ActivitySpeciesVoices.Civs.Specialized.cs create mode 100644 IdleSpectator/ActivitySpeciesVoices.Fantasy.Extended.cs create mode 100644 IdleSpectator/ActivitySpeciesVoices.Fantasy.Specialized.cs create mode 100644 IdleSpectator/ActivitySpeciesVoices.Invertebrates.Extended.cs create mode 100644 IdleSpectator/ActivitySpeciesVoices.Invertebrates.Specialized.cs create mode 100644 IdleSpectator/ActivitySpeciesVoices.Mammals.Extended.cs create mode 100644 IdleSpectator/ActivitySpeciesVoices.Mammals.Specialized.cs diff --git a/IdleSpectator/ActivityActionComposer.cs b/IdleSpectator/ActivityActionComposer.cs index 8133278..2f84354 100644 --- a/IdleSpectator/ActivityActionComposer.cs +++ b/IdleSpectator/ActivityActionComposer.cs @@ -1,76 +1,10 @@ using System; -using System.Collections.Generic; namespace IdleSpectator; /// Single deterministic action-selection pipeline. public static class ActivityActionComposer { - private static readonly Dictionary BeatTemplates = - new Dictionary(StringComparer.Ordinal) - { - ["BehUnloadResources"] = new[] - { - "unloads {carrying} at {place}", - "delivers {carrying} into store{place_at}" - }, - ["BehThrowResources"] = new[] - { - "throws {carrying} toward storage", - "tosses {carrying} from the pack" - }, - ["BehSocializeTalk"] = new[] - { - "talks{with}{place_at}", - "shares words{with}{place_at}" - }, - ["BehTryToSocialize"] = new[] - { - "tries to socialize{with}{place_at}", - "looks for a conversation{with}{place_at}" - }, - ["BehPlantCrops"] = new[] - { - "plants crops{place_at}{job_as}", - "sets seed in the soil{place_at}" - }, - ["BehCityActorFertilizeCrop"] = new[] - { - "fertilizes the crops{place_at}{job_as}", - "feeds the soil{place_at}" - }, - ["BehBuildTarget"] = new[] - { - "works the build{place_at}{job_as}", - "raises construction{place_at}" - }, - ["BehPoopOutside"] = new[] - { - "steps aside for a private moment outdoors", - "tends to nature's call outside" - }, - ["BehPoopInside"] = new[] - { - "steps aside for a private moment indoors", - "tends to nature's call inside" - }, - ["BehBoatFishing"] = new[] - { - "fishes from the boat{place_at}", - "works the waters from aboard{place_at}" - }, - ["BehBoatCollectFish"] = new[] - { - "collects the catch aboard{place_at}", - "hauls in the boat's catch{place_at}" - }, - ["BehClaimZoneForCityActorBorder"] = new[] - { - "claims border land{place_at}", - "stakes new ground for the settlement{place_at}" - } - }; - public static string Compose( ActivityContext ctx, string key, @@ -82,31 +16,12 @@ public static class ActivityActionComposer ctx ??= ActivityContext.Empty; ProseVoice voice = EnsureVoice(ctx); - if (!string.IsNullOrEmpty(key) - && BeatTemplates.TryGetValue(key, out string[] beatBag) - && voice.AssetKind != ActivityAssetKind.Vehicle) - { - return Pick(beatBag, subjectId, lineIndex); - } - string verb = ActivityVerbMap.Resolve(key); if (string.IsNullOrEmpty(verb)) { - string factual = ActivityProse.FactualActionPhrase(rawFact, key, hasTarget); - factual = ActivityClauseAssembler.StripSpeciesTokensPublic(factual, ctx); - if (!string.IsNullOrEmpty(factual)) - { - return factual; - } - - string patterned = ActivityProse.PatternActionPhrase(key, hasTarget); - if (!string.IsNullOrEmpty(patterned)) - { - return patterned; - } - - string humanized = ActivityProse.HumanizeKeyPublic(key); - verb = string.IsNullOrEmpty(humanized) ? "move" : humanized.ToLowerInvariant(); + // Future unknown tasks still get the mob's authored work voice. + // The exhaustive runtime audit blocks every current task from reaching this branch. + verb = "work"; } string[] bag = ActivityActionLexicon.GetBag(voice, verb, hasTarget, ctx.Terrain); diff --git a/IdleSpectator/ActivityClauseAssembler.cs b/IdleSpectator/ActivityClauseAssembler.cs index f0f9d54..38c1ce8 100644 --- a/IdleSpectator/ActivityClauseAssembler.cs +++ b/IdleSpectator/ActivityClauseAssembler.cs @@ -56,11 +56,42 @@ public static class ActivityClauseAssembler // Traits stay on the dossier chips - they only salt variety below, never named here. - string pressure = BuildPressureClause(ctx, action); - string line = subject + " " + action + pressure; + string target = BuildObservedTargetClause(ctx, action); + string carrying = BuildCarryingClause(ctx, action); + string pressure = BuildPressureClause(ctx, action + target); + string line = subject + " " + action + target + carrying + pressure; return CollapseSpaces(line).Trim(); } + private static string BuildObservedTargetClause(ActivityContext ctx, string action) + { + if (ctx == null + || !ctx.TargetIsActor + || string.IsNullOrEmpty(ctx.TargetName) + || ctx.InCombat + || ctx.HasAttackTarget + || action.IndexOf("{target}", StringComparison.Ordinal) >= 0 + || action.IndexOf("{with}", StringComparison.Ordinal) >= 0) + { + return ""; + } + + return " with {target}"; + } + + private static string BuildCarryingClause(ActivityContext ctx, string action) + { + if (ctx == null + || string.IsNullOrEmpty(ctx.CarryingLabel) + || action.IndexOf("{carrying}", StringComparison.Ordinal) >= 0 + || action.IndexOf(ctx.CarryingLabel, StringComparison.OrdinalIgnoreCase) >= 0) + { + return ""; + } + + return " while carrying {carrying}"; + } + private static string BuildSubject(ActivityContext ctx, string action, out bool placeInAppositive) { placeInAppositive = false; diff --git a/IdleSpectator/ActivityProse.cs b/IdleSpectator/ActivityProse.cs index be842b3..e6c4de5 100644 --- a/IdleSpectator/ActivityProse.cs +++ b/IdleSpectator/ActivityProse.cs @@ -1,395 +1,13 @@ -using System.Collections.Generic; - namespace IdleSpectator; /// -/// Fact-preserving activity sentences with colored actor/target names. +/// Fact-preserving activity sentence formatting with colored actor/target names. +/// supplies templates from the verb map and authored species bags. /// public static class ActivityProse { public const string NameColorHex = "#F0C14A"; - /// - /// Long detailed templates. Tokens: {actor}{target}{species}{place}{place_at}{job}{job_as}{carrying}{with}. - /// Never invent outcomes - only flavor observed tasks. - /// Prefer for full alive composition; Variants seed action phrases. - /// - private static readonly Dictionary Variants = new Dictionary - { - ["attack"] = new[] - { - "{actor} strikes hard at {target}{place_at}", - "{actor} presses the attack on {target}{place_at}", - "{actor} lunges toward {target} with clear intent{place_at}" - }, - ["fight"] = new[] - { - "{actor} fights {target} in a fierce clash{place_at}", - "{actor} clashes with {target}{place_at}{job_as}", - "{actor} trades blows with {target}{place_at}" - }, - ["fighting"] = new[] - { - "{actor} is locked in combat with {target}{place_at}", - "{actor} fights {target} without giving ground{place_at}", - "{actor} clashes with {target}{place_at}" - }, - ["hunt"] = new[] - { - "{actor} pursues {target}{place_at}", - "{actor} stalks {target} from cover{place_at}", - "{actor} closes in on {target}{place_at}" - }, - ["BehAttackActorHuntingTarget"] = new[] - { - "{actor} hunts {target} and strikes when the moment opens{place_at}", - "{actor} closes on {target} in the chase{place_at}", - "{actor} strikes at {target} while hunting{place_at}" - }, - ["heal"] = new[] - { - "{actor} tends carefully to {target}{place_at}", - "{actor} works to heal {target}{place_at}", - "{actor} binds {target}'s wounds with steady hands{place_at}" - }, - ["check_heal"] = new[] - { - "{actor} checks over wounds with worried care{place_at}", - "{actor} looks closely at injuries{place_at}", - "{actor} takes stock of pain before moving on{place_at}" - }, - ["cure"] = new[] - { - "{actor} seeks a cure for what ails them{place_at}", - "{actor} works to recover from sickness{place_at}", - "{actor} fights sickness with stubborn will{place_at}" - }, - ["eat"] = new[] - { - "{actor} sits down to eat{place_at}{job_as}", - "{actor} finds something to eat{place_at}", - "{actor} finishes a meal{place_at}" - }, - ["eating"] = new[] - { - "{actor} sits down to eat{place_at}{job_as}", - "{actor} finds something to eat{place_at}", - "{actor} finishes a meal{place_at}" - }, - ["sleep"] = new[] - { - "{actor} settles into sleep and lets the world go quiet{place_at}", - "{actor} rests deeply after the day's demands{place_at}{job_as}", - "{actor} curls into sleep{place_at}" - }, - ["decide_where_to_sleep"] = new[] - { - "{actor} searches for a safe place to sleep{place_at}", - "{actor} weighs where to rest for the night{place_at}", - "{actor} seeks shelter before settling down{place_at}" - }, - ["random_move"] = new[] - { - "{actor} wanders without hurry{place_at}", - "{actor} roams nearby, looking around{place_at}", - "{actor} drifts along with nowhere urgent to be{place_at}" - }, - ["city_idle_walking"] = new[] - { - "{actor} walks the streets at an easy pace{place_at}{job_as}", - "{actor} strolls through the settlement, watching life pass{place_at}", - "{actor} paces familiar paths between errands{place_at}" - }, - ["move"] = new[] - { - "{actor} is on the move with purpose{place_at}{job_as}", - "{actor} travels onward through the world{place_at}", - "{actor} heads out toward the next mark{place_at}" - }, - ["pollinate"] = new[] - { - "{actor} dusts the blossom with careful work{place_at}", - "{actor} works the flower and leaves the air sweet{place_at}", - "{actor} leaves pollen behind on the bloom{place_at}" - }, - ["BehPollinate"] = new[] - { - "{actor} dusts the blossom with careful work{place_at}", - "{actor} works the flower and leaves the air sweet{place_at}", - "{actor} leaves pollen behind on the bloom{place_at}" - }, - ["farm"] = new[] - { - "{actor} tends the fields with patient labor{place_at}{job_as}", - "{actor} works the soil until it answers{place_at}", - "{actor} farms the plot through the day{place_at}" - }, - ["harvest"] = new[] - { - "{actor} harvests the ripe crop with practiced hands{place_at}{job_as}", - "{actor} gathers the yield before it spoils{place_at}", - "{actor} cuts the ripe fields clean{place_at}" - }, - ["forag"] = new[] - { - "{actor} forages through wild growth for food{place_at}", - "{actor} gathers what the land offers freely{place_at}", - "{actor} searches the brush for forage{place_at}" - }, - ["gather"] = new[] - { - "{actor} gathers stores for leaner days{place_at}{job_as}", - "{actor} collects goods with steady purpose{place_at}", - "{actor} forages supplies into the pack{place_at}" - }, - ["mine"] = new[] - { - "{actor} delves the mine for ore and stone{place_at}{job_as}", - "{actor} chips at the rock face with hard labor{place_at}", - "{actor} works the dig until the haul is ready{place_at}" - }, - ["build"] = new[] - { - "{actor} builds with focused craft{place_at}{job_as}", - "{actor} raises walls and timber into shape{place_at}", - "{actor} labors on construction until it stands{place_at}" - }, - ["woodcut"] = new[] - { - "{actor} fells timber for the settlement's need{place_at}{job_as}", - "{actor} takes an axe to the trees with measured swings{place_at}", - "{actor} cuts wood and stacks the haul{place_at}" - }, - ["fire"] = new[] - { - "{actor} races the blaze and fights to keep it down{place_at}", - "{actor} douses flames before they claim more ground{place_at}", - "{actor} battles the fire with urgent work{place_at}" - }, - ["BehCityActorRemoveFire"] = new[] - { - "{actor} races the blaze and fights to keep it down{place_at}", - "{actor} douses flames before they claim more ground{place_at}", - "{actor} beats back the fire with urgent work{place_at}" - }, - ["social"] = new[] - { - "{actor} talks at length{with}{place_at}{job_as}", - "{actor} socializes and shares the moment{with}{place_at}", - "{actor} converses warmly{with}{place_at}" - }, - ["socialize"] = new[] - { - "{actor} talks at length{with}{place_at}{job_as}", - "{actor} socializes and shares the moment{with}{place_at}", - "{actor} joins company nearby{with}{place_at}" - }, - ["lover"] = new[] - { - "{actor} seeks out {target} with unmistakable longing{place_at}", - "{actor} is drawn toward {target} through the day{place_at}", - "{actor} pursues {target}'s affection with quiet resolve{place_at}" - }, - ["breed"] = new[] - { - "{actor} tries to start a family with {target}{place_at}", - "{actor} courts {target} with clear intent{place_at}", - "{actor} seeks offspring with {target}{place_at}" - }, - ["sexual_reproduction"] = new[] - { - "{actor} tries to start a family with {target}{place_at}", - "{actor} courts {target} with clear intent{place_at}", - "{actor} seeks offspring with {target}{place_at}" - }, - ["unload"] = new[] - { - "{actor} unloads {carrying} into store{place_at}", - "{actor} delivers {carrying} after a long haul{place_at}", - "{actor} empties the pack of {carrying}{place_at}" - }, - ["BehUnloadResources"] = new[] - { - "{actor} unloads {carrying} at {place}", - "{actor} delivers {carrying} into store{place_at}", - "{actor} empties the pack of {carrying}{place_at}" - }, - ["job"] = new[] - { - "{actor} looks for honest work{place_at}", - "{actor} looks for a job that will keep them fed{place_at}", - "{actor} searches for employment through the settlement{place_at}" - }, - ["find_city_job"] = new[] - { - "{actor} seeks work in town{place_at}", - "{actor} checks the available city jobs{place_at}", - "{actor} searches the settlement for employment{place_at}" - }, - ["find_house"] = new[] - { - "{actor} looks for a house to call home{place_at}", - "{actor} seeks shelter and a lasting roof{place_at}", - "{actor} searches for a place to settle{place_at}" - }, - ["claim"] = new[] - { - "{actor} claims new ground for the settlement{place_at}", - "{actor} stakes a claim on open land{place_at}", - "{actor} takes claim of border ground{place_at}" - }, - ["warrior"] = new[] - { - "{actor} follows the army with disciplined steps{place_at}", - "{actor} marches with the warband{place_at}{job_as}", - "{actor} keeps formation and waits for orders{place_at}" - }, - ["army"] = new[] - { - "{actor} follows the army with disciplined steps{place_at}", - "{actor} marches with the warband{place_at}", - "{actor} keeps formation among the ranks{place_at}" - }, - ["wait"] = new[] - { - "{actor} waits in watchful quiet{place_at}{job_as}", - "{actor} holds still and lets the moment pass{place_at}", - "{actor} bides time without wasting motion{place_at}" - }, - ["make_decision"] = new[] - { - "{actor} considers next steps with care{place_at}", - "{actor} weighs a choice before moving{place_at}{job_as}", - "{actor} pauses in thought while the world waits{place_at}" - }, - ["reflection"] = new[] - { - "{actor} reflects on what the day has asked{place_at}", - "{actor} takes a quiet moment to think things over{place_at}", - "{actor} settles into reflection away from noise{place_at}" - }, - ["run_away"] = new[] - { - "{actor} flees hard for safer ground{place_at}", - "{actor} runs for safety without looking back{place_at}", - "{actor} retreats in a burst of fear{place_at}" - }, - ["trade"] = new[] - { - "{actor} keeps a careful eye on traded goods{place_at}{job_as}", - "{actor} barters over prices{place_at}", - "{actor} makes a trading run{place_at}" - }, - ["fish"] = new[] - { - "{actor} waits patiently for a bite{place_at}{job_as}", - "{actor} casts for fish where the current runs{place_at}", - "{actor} works the waters for a catch{place_at}" - }, - ["family_group"] = new[] - { - "{actor} joins the herd and stays close to kin{place_at}", - "{actor} seeks the family group across open ground{place_at}", - "{actor} gathers with kin for safety and company{place_at}" - }, - ["generate_loot"] = new[] - { - "{actor} gathers loot from what the fight left behind{place_at}", - "{actor} claims spoils with practical hands{place_at}", - "{actor} picks through loot before moving on{place_at}" - }, - ["laughing"] = new[] - { - "{actor} laughs aloud and lets the mood carry{place_at}", - "{actor} bursts into laughter without restraint{place_at}", - "{actor} keeps laughing until short of breath{place_at}" - }, - ["happy_laughing"] = new[] - { - "{actor} laughs with bright, unguarded joy{place_at}", - "{actor} laughs happily among nearby company{place_at}", - "{actor} chuckles aloud until the mood softens{place_at}" - }, - ["just_laughed"] = new[] - { - "{actor} just finished laughing and catches a breath{place_at}", - "{actor} settles after a laugh, still smiling{place_at}", - "{actor} catches their breath from laughing{place_at}" - }, - ["singing"] = new[] - { - "{actor} sings out for whoever will hear{place_at}{job_as}", - "{actor} lifts a song into the open air{place_at}", - "{actor} is singing through the quiet stretch{place_at}" - }, - ["task_unit_play"] = new[] - { - "{actor} moves about in quick, restless bursts{place_at}", - "{actor} darts back and forth for a while{place_at}", - "{actor} bounds around with eager energy{place_at}" - }, - ["just_played"] = new[] - { - "{actor} slows down after playing{place_at}", - "{actor} stops to catch a breath{place_at}", - "{actor} settles after a burst of activity{place_at}" - }, - ["child_play_at_one_spot"] = new[] - { - "{actor} hops and pivots without wandering far{place_at}", - "{actor} keeps busy in one small spot{place_at}", - "{actor} turns and bounces in place{place_at}" - }, - ["child_random_flips"] = new[] - { - "{actor} flips and tumbles about{place_at}", - "{actor} rolls forward and springs upright{place_at}", - "{actor} tries one quick flip after another{place_at}" - }, - ["child_random_jump"] = new[] - { - "{actor} jumps about in quick bursts{place_at}", - "{actor} leaps forward and doubles back{place_at}", - "{actor} bounces around without settling{place_at}" - }, - ["child_follow_parent"] = new[] - { - "{actor} follows a parent with careful steps{place_at}", - "{actor} stays close to {target} through the day{place_at}", - "{actor} trails after kin and will not stray far{place_at}" - }, - ["random_fun_move"] = new[] - { - "{actor} frolics and wheels around{place_at}", - "{actor} darts off and circles back{place_at}", - "{actor} skips along without hurry{place_at}" - }, - ["godfinger_random_fun_move"] = new[] - { - "{actor} moves in sudden, unpredictable turns{place_at}", - "{actor} darts one way, then abruptly another{place_at}", - "{actor} loops around in restless motion{place_at}" - }, - ["try_to_read"] = new[] - { - "{actor} tries to read and settle into the page{place_at}", - "{actor} opens a book and gives it quiet attention{place_at}", - "{actor} settles in to read while the world softens{place_at}" - }, - ["try_to_poop"] = new[] - { - "{actor} looks for a private moment away from eyes{place_at}", - "{actor} tends to nature's call with hurried dignity{place_at}", - "{actor} steps aside briefly for a private need{place_at}" - }, - ["try_to_launch_fireworks"] = new[] - { - "{actor} tries to launch fireworks into celebration{place_at}", - "{actor} readies a firework with careful hands{place_at}", - "{actor} prepares a celebration blast for the sky{place_at}" - } - }; - public static string ColorName(string name) { if (string.IsNullOrEmpty(name)) @@ -464,15 +82,10 @@ public static class ActivityProse varietyId, lineIndex); + // Unreachable by composer contract. Preserve empty output so missing authored coverage remains auditable. if (string.IsNullOrEmpty(template)) { - template = "{actor} attends to " + LowerFirst(HumanizeKey(key)) - + "{place_at}{job_as}"; - if (string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(rawFact)) - { - template = GerundSentence(rawFact); - } - + return; } plain = Apply(template, ctx, colored: false); @@ -526,34 +139,11 @@ public static class ActivityProse } } - /// Action-only phrase from pattern heuristics (no subject). - public static string PatternActionPhrase(string key, bool hasTarget) - { - string full = PatternTemplate(key, hasTarget); - if (string.IsNullOrEmpty(full)) - { - return ""; - } - - return ActivityClauseAssembler.StripSubject(full); - } - - public static string HumanizeKeyPublic(string key) - { - return HumanizeKey(key); - } - public static string HumanizeJobPublic(string jobId) { return HumanizeJob(jobId); } - /// Observed localized fact as an action-only phrase for unknown task ids. - public static string FactualActionPhrase(string rawFact, string key, bool hasTarget) - { - return ActivityClauseAssembler.StripSubject(LocalizedTemplate(rawFact, key, hasTarget)); - } - /// Legacy helper used by older call sites / harness. public static string Format( ActivityKind kind, @@ -670,362 +260,6 @@ public static class ActivityProse return LowerFirst(s); } - private static string PatternTemplate(string key, bool hasTarget) - { - if (string.IsNullOrEmpty(key)) - { - return null; - } - - string k = key.ToLowerInvariant(); - const string clauses = "{place_at}{job_as}"; - - if (k.StartsWith("try_to_")) - { - return "{actor} tries to " + HumanizeKey(k.Substring("try_to_".Length)) - + " with careful effort" + clauses; - } - - if (k.StartsWith("check_")) - { - return "{actor} checks " + HumanizeKey(k.Substring("check_".Length)) - + " before deciding what comes next" + clauses; - } - - if (k.StartsWith("find_")) - { - return "{actor} looks for " + HumanizeKey(k.Substring("find_".Length)) - + clauses; - } - - if (k.StartsWith("decide_")) - { - return "{actor} decides " + HumanizeKey(k.Substring("decide_".Length)) - + " after a moment of thought" + clauses; - } - - if (k.StartsWith("build_")) - { - return "{actor} builds " + HumanizeKey(k.Substring("build_".Length)) - + " with steady hands" + clauses; - } - - if (k.StartsWith("boat_")) - { - return "{actor} " + BoatVerb(k.Substring("boat_".Length)) + clauses; - } - - if (k.StartsWith("warrior_")) - { - return WarriorTemplate(k, hasTarget) + clauses; - } - - if (k.StartsWith("socialize_")) - { - return hasTarget - ? "{actor} spends time with {target}" + clauses - : "{actor} looks for company" + clauses; - } - - if (k.StartsWith("sexual_reproduction") || k.StartsWith("asexual_reproduction")) - { - return hasTarget - ? "{actor} tries to start a family with {target}" + clauses - : "{actor} tries to reproduce and carry life forward" + clauses; - } - - if (k.StartsWith("child_")) - { - return "{actor} " + LowerFirst(HumanizeKey(k.Substring("child_".Length))) - + " eagerly" + clauses; - } - - if (k.StartsWith("ant_") || k.StartsWith("bee_") || k.StartsWith("ufo_") - || k.StartsWith("dragon_") || k.StartsWith("worm_")) - { - return "{actor} " + LowerFirst(HumanizeKey(StripCreaturePrefix(k))) - + clauses; - } - - if (k.StartsWith("task_unit_")) - { - return LocalizedStyleFromId(k.Substring("task_unit_".Length), hasTarget); - } - - if (k.Contains("laugh")) - { - return "{actor} laughs aloud and lets the mood carry" + clauses; - } - - if (k.Contains("sing")) - { - return "{actor} sings out for whoever will hear" + clauses; - } - - if (k.Contains("play") && !k.Contains("display")) - { - return hasTarget - ? "{actor} plays with {target}" + clauses - : "{actor} finds a way to amuse itself" + clauses; - } - - if (k.Contains("wait")) - { - return "{actor} waits in watchful quiet" + clauses; - } - - if (k.Contains("sleep")) - { - return "{actor} settles into sleep and lets the world go quiet" + clauses; - } - - if (k.Contains("idle") || k.Contains("random_move") || k.EndsWith("_move") - || k.Contains("walking")) - { - return "{actor} wanders without hurry" + clauses; - } - - if (k.Contains("fight") || k.Contains("attack") || k.Contains("hunt")) - { - return hasTarget - ? "{actor} strikes at {target} with clear intent" + clauses - : "{actor} braces for a fight" + clauses; - } - - if (k.Contains("heal") || k.Contains("cure")) - { - return hasTarget - ? "{actor} tends carefully to {target}" + clauses - : "{actor} tends to wounds with worried care" + clauses; - } - - if (k.Contains("eat") || k.Contains("food")) - { - return "{actor} sits down to eat" + clauses; - } - - if (k.Contains("farm") || k.Contains("harvest") || k.Contains("forag") - || k.Contains("gather") || k.Contains("chop") || k.Contains("mine") - || k.Contains("build") || k.Contains("woodcut")) - { - return "{actor} " + LowerFirst(HumanizeKey(k)) - + " with steady labor" + clauses; - } - - if (k.Contains("trade") || k.Contains("fish") || k.Contains("unload") - || k.Contains("claim") || k.Contains("fire")) - { - return "{actor} " + LowerFirst(HumanizeKey(k)) - + clauses; - } - - return null; - } - - private static string WarriorTemplate(string k, bool hasTarget) - { - if (k.Contains("follow")) - { - return hasTarget - ? "{actor} follows {target} with disciplined steps" - : "{actor} follows the army with disciplined steps"; - } - - if (k.Contains("train")) - { - return "{actor} trains for war with hard repetition"; - } - - if (k.Contains("join")) - { - return "{actor} tries to join the army and take a place in the ranks"; - } - - if (k.Contains("attack")) - { - return hasTarget - ? "{actor} marches on {target} with the warband" - : "{actor} marches to attack with the warband"; - } - - if (k.Contains("wait") || k.Contains("idle")) - { - return "{actor} holds formation and waits for orders"; - } - - return "{actor} " + LowerFirst(HumanizeKey(k.Replace("warrior_", ""))) - + " among the ranks"; - } - - private static string BoatVerb(string rest) - { - if (rest.Contains("fish")) - { - return "fishes from the boat and waits for a bite"; - } - - if (rest.Contains("trade")) - { - return "carries trade goods by boat"; - } - - if (rest.Contains("dock") || rest.Contains("return")) - { - return "returns to dock after time on the water"; - } - - if (rest.Contains("load")) - { - return "loads the boat for the next run"; - } - - if (rest.Contains("unload")) - { - return "unloads the boat and clears the hold"; - } - - if (rest.Contains("idle")) - { - return "waits aboard between trips"; - } - - return LowerFirst(HumanizeKey(rest)) + " aboard"; - } - - private static string StripCreaturePrefix(string k) - { - int idx = k.IndexOf('_'); - return idx > 0 && idx < k.Length - 1 ? k.Substring(idx + 1) : k; - } - - private static string LocalizedStyleFromId(string rest, bool hasTarget) - { - const string clauses = "{place_at}{job_as}"; - if (rest == "play") - { - return "{actor} finds a way to amuse itself" + clauses; - } - - if (rest == "wait") - { - return "{actor} waits in watchful quiet" + clauses; - } - - if (rest == "walk") - { - return "{actor} walks at an easy pace" + clauses; - } - - if (rest.Contains("social")) - { - return hasTarget - ? "{actor} spends time with {target}" + clauses - : "{actor} looks for company" + clauses; - } - - return "{actor} " + LowerFirst(HumanizeKey(rest)) - + clauses; - } - - /// - /// Turn game localized labels like "Laughing" / "Job Seeking" into real sentences. - /// - private static string LocalizedTemplate(string rawFact, string key, bool hasTarget) - { - string loc = ExtractLocalizedBody(rawFact, key); - if (string.IsNullOrEmpty(loc)) - { - return null; - } - - return GerundSentence(loc); - } - - private static string ExtractLocalizedBody(string rawFact, string key) - { - if (string.IsNullOrEmpty(rawFact)) - { - return null; - } - - string body = rawFact; - int arrow = body.IndexOf('→'); - if (arrow < 0) - { - arrow = body.IndexOf("->", System.StringComparison.Ordinal); - } - - if (arrow >= 0) - { - body = body.Substring(0, arrow).Trim(); - } - - if (body.StartsWith("Task:", System.StringComparison.OrdinalIgnoreCase)) - { - return null; - } - - // Ignore if it's just the raw key. - if (!string.IsNullOrEmpty(key) - && body.Equals(key, System.StringComparison.OrdinalIgnoreCase)) - { - return null; - } - - return body.Trim(); - } - - private static string GerundSentence(string loc) - { - if (string.IsNullOrEmpty(loc)) - { - return null; - } - - string body = loc.Trim(); - // "Laughing" / "Job Seeking" / "Holding Still" - if (IsGerundPhrase(body)) - { - return "{actor} is " + LowerFirst(body) - + "{place_at}{job_as}"; - } - - // Already a short verb phrase - still give it place/job room. - return "{actor} " + LowerFirst(body) + "{place_at}{job_as}"; - } - - private static bool IsGerundPhrase(string body) - { - if (string.IsNullOrEmpty(body)) - { - return false; - } - - string[] parts = body.Split(new[] { ' ' }, System.StringSplitOptions.RemoveEmptyEntries); - if (parts.Length == 0 || parts.Length > 4) - { - return false; - } - - // Last token ends with -ing (Laughing, Seeking, Holding...) - string last = parts[parts.Length - 1]; - return last.Length > 4 - && last.EndsWith("ing", System.StringComparison.OrdinalIgnoreCase); - } - - private static string HumanizeKey(string key) - { - if (string.IsNullOrEmpty(key)) - { - return ""; - } - - string s = key.Replace("Beh", "").Replace('_', ' ').Trim(); - // Collapse common noise words for readability. - s = s.Replace("task unit ", "").Replace("type ", ""); - return s; - } - private static string LowerFirst(string s) { if (string.IsNullOrEmpty(s)) @@ -1040,90 +274,4 @@ public static class ActivityProse return char.ToLowerInvariant(s[0]) + s.Substring(1); } - - private static string PickTemplate(string key, long subjectId, int lineIndex, bool hasTarget) - { - if (string.IsNullOrEmpty(key)) - { - return null; - } - - string[] bag = null; - if (Variants.TryGetValue(key, out bag) && bag != null && bag.Length > 0) - { - return PreferTargetAware(bag, hasTarget, subjectId, key, lineIndex); - } - - string lower = key.ToLowerInvariant(); - string bestKey = null; - string[] bestBag = null; - int bestLen = -1; - foreach (KeyValuePair kv in Variants) - { - if (kv.Value == null || kv.Value.Length == 0) - { - continue; - } - - if (lower.IndexOf(kv.Key, System.StringComparison.Ordinal) >= 0 && kv.Key.Length > bestLen) - { - bestLen = kv.Key.Length; - bestKey = kv.Key; - bestBag = kv.Value; - } - } - - if (bestBag == null) - { - return null; - } - - return PreferTargetAware(bestBag, hasTarget, subjectId, bestKey, lineIndex); - } - - private static string PreferTargetAware( - string[] bag, - bool hasTarget, - long subjectId, - string key, - int lineIndex) - { - var suited = new List(bag.Length); - for (int i = 0; i < bag.Length; i++) - { - string line = bag[i]; - bool needsTarget = line.IndexOf("{target}", System.StringComparison.Ordinal) >= 0; - if (hasTarget || !needsTarget) - { - suited.Add(line); - } - } - - if (suited.Count == 0) - { - suited.AddRange(bag); - } - - return suited[PickIndex(subjectId, key, lineIndex, suited.Count)]; - } - - private static int PickIndex(long subjectId, string key, int lineIndex, int count) - { - if (count <= 1) - { - return 0; - } - - unchecked - { - int h = (int)(subjectId * 397) ^ (key?.GetHashCode() ?? 0) ^ (lineIndex * 31); - h ^= (int)(UnityEngine.Time.unscaledTime * 10f); - if (h < 0) - { - h = -h; - } - - return h % count; - } - } } diff --git a/IdleSpectator/ActivitySpeciesVoice.cs b/IdleSpectator/ActivitySpeciesVoice.cs index c4da63a..5acae30 100644 --- a/IdleSpectator/ActivitySpeciesVoice.cs +++ b/IdleSpectator/ActivitySpeciesVoice.cs @@ -17,10 +17,16 @@ public enum ActivityVoiceSource /// public sealed class ActivitySpeciesVoice { - public static readonly string[] CoreVerbs = + public static readonly string[] AuthoredVerbs = { "move", "wait", "play", "eat", "sleep", - "hunt", "fight", "social", "laugh", "work" + "hunt", "fight", "social", "laugh", "work", + "sing", "lover", "farm", "pollinate", "trade", + "fish", "haul", "heal", "fire", "flee", + "settle", "warrior", "read", "gather_life", "relieve", + "confused", "recharge", "strange_urge", "steal", "possessed", + "dream", "ignite", "extinguish", "group", "harvest_life", + "loot", "cry", "swear" }; private readonly Dictionary _bags; @@ -35,6 +41,20 @@ public sealed class ActivitySpeciesVoice _bags = bags ?? new Dictionary(StringComparer.Ordinal); } + public static bool IsAuthoredVerb(string verb) + { + string key = verb ?? ""; + for (int i = 0; i < AuthoredVerbs.Length; i++) + { + if (AuthoredVerbs[i].Equals(key, StringComparison.Ordinal)) + { + return true; + } + } + + return false; + } + public string[] GetBag(string verb, ActivityTerrain terrain) { string key = verb ?? ""; @@ -51,9 +71,9 @@ public sealed class ActivitySpeciesVoice public bool HasCompleteCore() { - for (int i = 0; i < CoreVerbs.Length; i++) + for (int i = 0; i < AuthoredVerbs.Length; i++) { - if (!_bags.TryGetValue(CoreVerbs[i], out string[] bag) + if (!_bags.TryGetValue(AuthoredVerbs[i], out string[] bag) || bag == null || bag.Length < 2 || string.IsNullOrEmpty(bag[0]) @@ -73,4 +93,12 @@ public sealed class ActivitySpeciesVoice _liquidBags[verb] = bag; } } + + internal void SetBag(string verb, string[] bag) + { + if (!string.IsNullOrEmpty(verb) && bag != null && bag.Length > 0) + { + _bags[verb] = bag; + } + } } diff --git a/IdleSpectator/ActivitySpeciesVoiceCatalog.cs b/IdleSpectator/ActivitySpeciesVoiceCatalog.cs index a7d34f7..c19b243 100644 --- a/IdleSpectator/ActivitySpeciesVoiceCatalog.cs +++ b/IdleSpectator/ActivitySpeciesVoiceCatalog.cs @@ -16,6 +16,16 @@ public static partial class ActivitySpeciesVoiceCatalog AddAnimalVoices(voices); AddInvertebrateVoices(voices); AddFantasyVoices(voices); + AddCivExtendedVoices(voices); + AddMammalExtendedVoices(voices); + AddAnimalExtendedVoices(voices); + AddInvertebrateExtendedVoices(voices); + AddFantasyExtendedVoices(voices); + AddCivSpecializedVoices(voices); + AddMammalSpecializedVoices(voices); + AddAnimalSpecializedVoices(voices); + AddInvertebrateSpecializedVoices(voices); + AddFantasySpecializedVoices(voices); return voices; } @@ -91,6 +101,89 @@ public static partial class ActivitySpeciesVoiceCatalog } } + private static void AddExtended( + Dictionary voices, + string id, + string[] sing, + string[] lover, + string[] farm, + string[] pollinate, + string[] trade, + string[] fish, + string[] haul, + string[] heal, + string[] fire, + string[] flee, + string[] settle, + string[] warrior, + string[] read, + string[] gatherLife, + string[] relieve, + string[] confused, + string[] recharge, + string[] strangeUrge, + string[] steal, + string[] possessed, + string[] dream) + { + if (!voices.TryGetValue(id, out ActivitySpeciesVoice voice)) + { + throw new InvalidOperationException("Extended voice has no base entry: " + id); + } + + Set(voice, "sing", sing); + Set(voice, "lover", lover); + Set(voice, "farm", farm); + Set(voice, "pollinate", pollinate); + Set(voice, "trade", trade); + Set(voice, "fish", fish); + Set(voice, "haul", haul); + Set(voice, "heal", heal); + Set(voice, "fire", fire); + Set(voice, "flee", flee); + Set(voice, "settle", settle); + Set(voice, "warrior", warrior); + Set(voice, "read", read); + Set(voice, "gather_life", gatherLife); + Set(voice, "relieve", relieve); + Set(voice, "confused", confused); + Set(voice, "recharge", recharge); + Set(voice, "strange_urge", strangeUrge); + Set(voice, "steal", steal); + Set(voice, "possessed", possessed); + Set(voice, "dream", dream); + } + + private static void Set(ActivitySpeciesVoice voice, string verb, string[] phrases) + { + voice.SetBag(verb, Contextualize(phrases)); + } + + private static void AddSpecialized( + Dictionary voices, + string id, + string[] ignite, + string[] extinguish, + string[] group, + string[] harvestLife, + string[] loot, + string[] cry, + string[] swear) + { + if (!voices.TryGetValue(id, out ActivitySpeciesVoice voice)) + { + throw new InvalidOperationException("Specialized voice has no base entry: " + id); + } + + Set(voice, "ignite", ignite); + Set(voice, "extinguish", extinguish); + Set(voice, "group", group); + Set(voice, "harvest_life", harvestLife); + Set(voice, "loot", loot); + Set(voice, "cry", cry); + Set(voice, "swear", swear); + } + private static string[] V(string first, string second) { return new[] { first, second }; diff --git a/IdleSpectator/ActivitySpeciesVoices.Animals.Extended.cs b/IdleSpectator/ActivitySpeciesVoices.Animals.Extended.cs new file mode 100644 index 0000000..e88670c --- /dev/null +++ b/IdleSpectator/ActivitySpeciesVoices.Animals.Extended.cs @@ -0,0 +1,259 @@ +using System.Collections.Generic; + +namespace IdleSpectator; + +public static partial class ActivitySpeciesVoiceCatalog +{ + private static void AddAnimalExtendedVoices(Dictionary voices) + { + AddExtended( + voices, + "chicken", + V("lifts its beak through a bright clucking phrase", "pulses its throat while its comb bobs in rhythm"), + V("sidles close with one wing lowered", "touches beak tips through slow head bobs"), + V("rakes backward with alternating clawed feet", "pecks in a measured row with tail raised"), + V("brushes its breast feathers through repeated crouches", "dips its beak while wing tips sweep past"), + V("extends its neck and taps its beak twice", "steps beak-first through a deliberate exchange"), + V("cocks one eye before stabbing its beak downward", "holds a low crouch before a quick beak snap"), + V("leans breast-first and drives with both feet", "hooks its beak forward while legs keep pushing"), + V("preens along a wing with careful beak strokes", "parts breast feathers with short inspecting pecks"), + V("fans both wings through forceful downward beats", "stamps its feet while flight feathers flick rapidly"), + V("hurries in high steps with wings spread wide", "ducks its comb and runs with tail feathers level"), + V("circles twice before folding its legs beneath", "scrapes with both feet and lowers its feathered breast"), + V("raises its spurs while wings brace outward", "marches with comb high and beak held forward"), + V("tracks side to side with one bright eye", "tilts its head between small beak-led nods"), + V("combs its beak through rapid low sweeps", "scratches once before pinching with its beak"), + V("drops its tail and flexes beneath puffed feathers", "crouches low while its vent feathers lift"), + V("turns its head in abrupt one-eyed checks", "crosses its feet while its comb swivels back"), + V("shudders from breast to wing tips in quick pulses", "stiffens both legs as neck feathers ripple"), + V("jerks its beak sideways between uneven wing flicks", "pivots on one foot while its head bobs off-beat"), + V("crouches behind spread wings and darts its beak", "tiptoes with neck tucked before a sudden peck"), + V("paces in rigid steps with feathers standing out", "twists its neck while both wings twitch together"), + V("tucks its beak beneath one wing as toes curl", "settles into feathered stillness with comb tilted")); + + AddExtended( + voices, + "crab", + V("clicks alternating pincers beneath pulsing mouthparts", "raises both claws through a clattering cadence"), + V("crosses pincers gently beneath touching eyestalks", "sidesteps close with both claws folded inward"), + V("rakes backward with alternating pointed walking legs", "clips repeatedly with one pincer while eyestalks track"), + V("sweeps both antennae through precise brushing arcs", "opens its pincers around a series of delicate dabs"), + V("presents one open claw then closes it slowly", "passes a measured pincer tap from side to side"), + V("holds one claw poised before a sudden pinch", "probes in short arcs with both pincers parted"), + V("grips forward and rows backward on six legs", "leans its shell rim ahead while pincers pull"), + V("grooms a bent leg between careful pincers", "picks along its shell seam with the smaller claw"), + V("fans its mouthparts while claws beat downward", "stamps its walking legs beneath a lifted shell"), + V("scuttles crabwise with pincers guarding its face", "drops its shell low and pedals every leg rapidly"), + V("tests a circle with antennae before folding its legs", "presses its shell down as pincers sweep outward"), + V("brandishes the larger claw above a squared stance", "locks both pincers forward while legs spread wide"), + V("tracks a line with independently turning eyestalks", "taps each pincer tip while mouthparts count"), + V("clips in tiny bites with alternating claw tips", "rakes its walking legs as antennae inspect each pass"), + V("lifts its shell rim while rear legs flex", "settles low as its abdominal flap tightens"), + V("sidesteps twice then reverses with claws crossed", "aims its eyestalks apart while legs shuffle inward"), + V("vibrates every walking leg beneath a rigid shell", "pumps its mouthparts as both claws slowly rise"), + V("winds one pincer overhead while circling crabwise", "flicks its antennae crosswise through uneven claw taps"), + V("reaches under its shell rim with the smaller pincer", "backs away while one claw closes out of sight"), + V("jerks sideways as both eyestalks dip together", "marches stiff-legged while pincers open and shut"), + V("folds its claws beneath the shell with legs tucked", "rests on bent joints as eyestalks gradually lower")); + + AddExtended( + voices, + "crocodile", + V("lifts its long snout through a rumbling bellow", "vibrates its armored throat beneath parted jaws"), + V("rests jaw-to-jaw with its tail curled", "rubs plated snouts through a slow sideward sweep"), + V("pushes its snout forward while foreclaws rake", "presses its belly low and scrapes with splayed claws"), + V("sweeps its broad muzzle through low brushing passes", "nudges forward as ridged scales skim repeatedly"), + V("opens its jaws halfway then closes them with care", "angles its armored head through a measured jaw display"), + V("holds only its eyes and nostrils high before snapping", "creeps belly-low with jaws poised for a sideways clamp"), + V("drives its plated shoulders behind a steady shove", "backs with jaw muscles locked and tail braced"), + V("scrapes its teeth gently along a foreleg scale", "rubs one plated flank with slow hind-claw strokes"), + V("lashes its heavy tail through broad beating arcs", "raises its chest and stamps with splayed forefeet"), + V("surges low with tail whipping behind its plates", "scrambles on spread legs with jaw clamped shut"), + V("circles with snout lowered before flattening its belly", "slides its armored side through a full-length turn"), + V("stands high on splayed legs with jaws agape", "sweeps its plated tail behind a forward-facing snout"), + V("tracks side to side with one ridged eyelid narrowing", "tilts its long jaw between deliberate tooth-lined pauses"), + V("rakes backward with foreclaws beside its muzzle", "roots with its snout through short armored thrusts"), + V("raises its tail base while hind legs straighten", "arches its plated back above a low belly press"), + V("turns in a tight arc around its planted forefeet", "halts mid-crawl as jaw and tail point opposite ways"), + V("shudders along every dorsal ridge from snout to tail", "pumps its throat while all four claws grip"), + V("rolls one shoulder as its jaws yaw sideways", "corkscrews its plated torso through a sudden half-turn"), + V("slides its lower jaw forward beneath closed teeth", "hooks its snout aside while foreclaws conceal a motion"), + V("stalks stiff-legged with tail twitching in sections", "snaps at empty space as armored eyelids flutter"), + V("rests chin-flat with teeth hidden and legs folded", "lies motionless while its heavy tail slowly curves")); + + AddExtended( + voices, + "frog", + V("inflates its throat sac through a rolling croak", "pulses its round throat beneath a chirping trill"), + V("presses splayed forefeet close through matching blinks", "leans in with throat pulsing and hind legs folded"), + V("scrapes backward with webbed hind toes", "plants its forefeet while long legs kick in alternation"), + V("brushes its belly past with toes spread broadly", "dabs with forefeet between short throat pulses"), + V("extends both forefeet then draws them to its chest", "bobs on folded legs through a deliberate toe display"), + V("aims both eyes before a lightning tongue flick", "compresses its hind legs beneath a still snout"), + V("shoves from the hips in repeated squat-legged thrusts", "braces both forefeet while long hind legs drive"), + V("wipes one round eye with a flexible forefoot", "rubs its mottled flank using a folded hind leg"), + V("springs upright as forefeet pat rapidly downward", "puffs its throat while webbed toes slap in sequence"), + V("bounds in low arcs with forelegs reaching ahead", "kicks backward in rapid leaps with eyes wide"), + V("tests a small circle by hopping toe-first", "squats centrally with all four feet spread"), + V("rises tall on hind legs with forefeet thrust forward", "crouches like a spring while throat sac stays taut"), + V("follows marks with alternating eye swivels", "counts along with tiny foretoe taps and blinks"), + V("snaps its tongue between careful forward hops", "parts with splayed fingers during short collecting dabs"), + V("lifts its rump while forelegs hold a deep squat", "stretches both hind legs behind a lowered belly"), + V("hops sideways then freezes with crossed forefeet", "swivels each eye separately while toes flex"), + V("quivers through its thighs as throat sac pulses fast", "stiffens its forelegs while hind toes tremble"), + V("jerks through crooked hops with tongue briefly extended", "twists its squat body between mismatched leg kicks"), + V("crouches over its forefeet before a furtive tongue snap", "folds its hind legs tight while one foretoe hooks inward"), + V("bounces without rhythm as both eyes roll", "puffs and collapses its throat through rigid little jumps"), + V("draws every foot beneath its belly and blinks slowly", "rests squat with throat pulses becoming shallow")); + + AddExtended( + voices, + "ostrich", + V("stretches its long neck through a hollow booming call", "clacks its broad beak while throat feathers pulse"), + V("weaves raised necks through mirrored curves", "fans short wings while lowering its beak close"), + V("scrapes backward with alternating two-toed feet", "bends its tall neck through repeated beak dips"), + V("sweeps breast feathers past in a low-necked pass", "brushes with short wing plumes while stepping precisely"), + V("extends its flat beak then draws its neck upright", "bows on long legs through a measured wing display"), + V("holds its neck rigid before a downward beak jab", "tracks intently then lunges on lengthening strides"), + V("leans its feathered breast into a long-legged drive", "hooks its beak as both two-toed feet push"), + V("preens beneath one short wing with its flat beak", "combs shaggy breast feathers through quick beak pinches"), + V("beats both short wings while stamping long feet", "fans loose plumes through forceful sideward sweeps"), + V("runs with neck lowered and wing tips spread", "takes bounding strides while tail plumes flatten"), + V("paces a broad circle before folding its knees", "scrapes twice and lowers its feathered body centrally"), + V("stands neck-high with one long leg lifted", "drives a two-toed kick beneath spread wing plumes"), + V("traces side to side with high-set eyes", "bobs its long neck through deliberate beak-led pauses"), + V("pinches repeatedly while striding in a straight line", "rakes with one two-toed foot before a deep beak dip"), + V("raises its tail plumes as long knees bend", "squats with wings lifted from its feathered flanks"), + V("crosses its long legs while neck looping backward", "stares past its own shoulder as wing tips twitch"), + V("shivers from tall neck to loose tail plumes", "locks both knees while breast feathers ripple downward"), + V("whips its neck in an uneven curve between stamps", "circles with one wing fanned and one folded"), + V("stoops behind spread plumes and hooks its beak inward", "tiptoes on two-toed feet with neck tightly curved"), + V("struts stiff-kneed as its long neck zigzags", "kicks aside while both short wings flap together"), + V("folds long legs beneath its feathered body", "rests with its neck curled and broad beak still")); + + AddExtended( + voices, + "penguin", + V("raises its narrow beak through a braying phrase", "pumps its chest beneath a chain of sharp honks"), + V("taps beaks softly with both flippers lowered", "leans chest-close while matching slow head tilts"), + V("scrapes with broad webbed feet between beak dips", "patters in rows while flippers balance each bend"), + V("brushes its white breast through low waddling passes", "sweeps stiff flipper edges with short side steps"), + V("extends its beak and flares one flipper", "bows from the ankles through a deliberate beak tap"), + V("leans beak-first before a sudden neck snap", "fixes both eyes while its webbed feet stop paddling"), + V("shoves with its chest through heel-to-heel steps", "braces stiff flippers backward as broad feet drive"), + V("preens its white breast with tiny beak pinches", "runs its narrow beak along one stiff flipper"), + V("slaps both flippers in rapid downward strokes", "stamps webbed feet while its compact chest bucks"), + V("waddles rapidly with flippers stretched sideways", "drops its belly low and paddles with both feet"), + V("turns heel-to-heel before settling on its belly", "traces a compact circle with beak taps and steps"), + V("squares its chest behind outstretched flippers", "marches upright with narrow beak leveled forward"), + V("tracks a line through alternating head tilts", "touches its beak along a sequence of tiny nods"), + V("picks in quick rows while flippers hold balance", "rakes backward with webbed feet before a beak pinch"), + V("lifts its short tail above a deep ankle crouch", "rocks forward as belly feathers spread apart"), + V("waddles sideways while looking straight behind", "crosses its webbed feet as both flippers point inward"), + V("trembles from white chest into rigid flipper tips", "stiffens upright while its short tail vibrates"), + V("windmills one flipper through a lopsided turn", "jerks its beak upward between uneven foot pats"), + V("hunches behind both flippers and darts its beak", "sidles heel-first with narrow beak tucked low"), + V("paces upright as flippers twitch in unison", "pecks sharply while its compact body rocks backward"), + V("rests belly-down with flippers fitted to its sides", "tucks its beak low as broad feet stop flexing")); + + AddExtended( + voices, + "piranha", + V("pulses its gill covers around a clicking jaw rhythm", "flares paired fins while teeth chatter in cadence"), + V("aligns flank-close with fins beating in synchrony", "circles tightly through matched tail flicks"), + V("rakes with its lower jaw as paired fins brace", "nudges repeatedly with its blunt snout and folded fins"), + V("brushes past with scales angled and fins extended", "fans its paired fins through a sequence of close passes"), + V("opens its toothed jaw then folds both fins", "presents one scaled flank through a measured pivot"), + V("fixes its round eye before a rapid tooth snap", "stills every fin before its compact body darts"), + V("drives snout-first with strong lateral tail beats", "locks its jaws while paired fins reverse together"), + V("scrapes one scaled flank with a fin ray", "works its lower jaw while gill covers open wide"), + V("whips its tail as every fin beats rapidly", "bucks its compact body through forceful gill pulses"), + V("darts in sharp angles with fins pinned close", "lashes its tail through a rapid zigzag retreat"), + V("circles tightly with snout angled inward", "hovers centrally as paired fins make tiny corrections"), + V("flares every fin behind a fully opened jaw", "charges in a straight burst with teeth exposed"), + V("tracks a sequence with one round eye", "ticks its jaw between deliberate paired-fin pauses"), + V("nips in careful rows with tail held nearly still", "probes snout-first between short jaw closures"), + V("arches its belly as the tail base rises", "angles its vent downward while paired fins spread"), + V("faces backward through a tight tail-led pivot", "rolls half sideways as its fins oppose each other"), + V("shivers from gill covers through the forked tail", "stiffens its fin rays while its jaw vibrates"), + V("spirals unevenly with one paired fin folded", "jerks tail-first while the toothed mouth gapes"), + V("nips furtively then hides its jaw beneath a turn", "slides flankwise with paired fins shielding its mouth"), + V("darts in rigid bursts as gill covers flutter", "snaps repeatedly while its forked tail twists"), + V("hangs nearly still with fins tucked to scales", "slows its tail beats as the lower jaw settles")); + + AddExtended( + voices, + "seal", + V("raises its whiskered muzzle through a chesty bark", "pulses its throat beneath a run of blunt honks"), + V("touches whiskers softly with foreflippers folded", "rests muzzle-close through matching head tilts"), + V("rakes backward with broad foreflippers", "presses its chest low through repeated muzzle nudges"), + V("sweeps whiskers through close side-to-side passes", "brushes with foreflipper edges while its muzzle dips"), + V("extends its whiskered muzzle then folds one flipper", "rises chest-high through a measured foreflipper pat"), + V("aims its whiskers before a quick jaw clamp", "holds its hind flippers straight before surging snout-first"), + V("drives its broad chest through foreflipper pulls", "hooks its teeth as hind flippers brace together"), + V("combs its whiskers with one curled foreflipper", "scratches its thick flank using pointed hind claws"), + V("slaps both foreflippers through heavy downward beats", "bucks its chest while hind flippers clap together"), + V("lurches forward with foreflippers reaching fast", "bunches its thick body through rapid chest-first surges"), + V("turns a full circle on alternating foreflippers", "presses its belly centrally with muzzle sweeping around"), + V("props its chest high above squared foreflippers", "bares pointed teeth while hind flippers stiffen"), + V("follows a sequence with whiskers twitching", "nods its rounded head between deliberate flipper taps"), + V("probes in rows with its whiskered muzzle", "scrapes lightly with one foreflipper before a tooth pinch"), + V("raises its hind flippers above an arched rump", "flexes its thick belly behind planted foreflippers"), + V("rolls sideways while its muzzle stays forward", "crosses foreflippers as hind flippers fan apart"), + V("quivers from whiskered muzzle through thick shoulders", "stiffens both foreflippers while its chest trembles"), + V("twists through a crooked roll with jaws ajar", "jerks its head between mismatched flipper sweeps"), + V("hunches over folded foreflippers and snaps sideways", "inches backward with whiskers tucked against its muzzle"), + V("lurches stiff-bodied as both flippers twitch", "bites at empty space while its thick torso rolls"), + V("curls with foreflippers pressed against its chest", "rests its whiskered muzzle atop one broad flipper")); + + AddExtended( + voices, + "snake", + V("raises its head through a long pulsing hiss", "flicks its forked tongue between breathy scales of sound"), + V("rests its jaw across a parallel coil", "matches slow tongue flicks with necks intertwined"), + V("pushes its snout ahead while ribs ripple forward", "presses broad coils through repeated sideward bends"), + V("brushes its scaled flanks through close looping passes", "sweeps its forked tongue along a winding route"), + V("extends its head then loops its neck inward", "lifts one body coil through a measured tongue display"), + V("holds its forked tongue still before striking", "compresses its front coils beneath an aligned jaw"), + V("loops around and contracts in traveling bands", "braces its tail while rib waves pull forward"), + V("rubs its jaw along a smooth body coil", "scrapes between scales with a brief tail-tip stroke"), + V("lashes its tail as rib muscles bunch rapidly", "rears its neck and pounds down through stacked coils"), + V("streams forward in narrow bends with head lowered", "uncoils rapidly as its tail whips behind"), + V("traces a tight circle before stacking its coils", "presses its belly scales into a compact spiral"), + V("raises a third of its body above braced loops", "flares its neck while jaws part around curved teeth"), + V("tracks a sequence with forked tongue samples", "nods its narrow head between deliberate coil shifts"), + V("probes in rows with snout and tongue together", "rakes belly scales backward through short rippling passes"), + V("lifts its tail while the rear coils tighten", "arches its scaled body above a flattened belly section"), + V("loops backward while its head keeps facing ahead", "knots its middle briefly as tail and neck cross"), + V("shivers along every scale from jaw to tail tip", "stiffens into a curve while its ribs pulse rapidly"), + V("corkscrews through uneven coils with tongue extended", "jerks its neck sideways as the tail circles opposite"), + V("folds its head beneath an outer coil", "slides tail-first while its jaw remains hidden"), + V("rears in rigid bends as its tongue flicks erratically", "snaps at empty space while body loops twitch"), + V("settles its jaw atop a tightly wound coil", "draws head and tail inward as rib waves slow")); + + AddExtended( + voices, + "turtle", + V("extends its neck through a throaty chirping phrase", "clicks its hard beak while throat folds pulse"), + V("touches shell rims through slow neck stretches", "rests beak-close with foreclaws folded inward"), + V("scrapes backward with alternating foreclaws", "bends its long neck through repeated beak dips"), + V("brushes its shell edge through low deliberate passes", "sweeps with clawed forefeet while its beak points down"), + V("extends its neck and opens its hard beak slowly", "raises one foreclaw through a measured shell-rock"), + V("holds its neck rigid before a sudden beak clip", "plants all four claws before thrusting shell and head"), + V("drives shell-first as foreclaws pull in sequence", "hooks its beak forward while hind claws keep pushing"), + V("scrapes its beak gently along one foreleg scale", "rubs beneath its shell rim with a hooked hind claw"), + V("pumps all four legs as its shell rocks sharply", "stamps foreclaws while neck and beak jab downward"), + V("plods rapidly with neck stretched straight ahead", "pulls its shell in hurried alternating claw strokes"), + V("walks a small circle before drawing its limbs close", "presses its shell centrally as neck sweeps around"), + V("stands high on straightened legs beneath its shell", "drives forward behind a hard open beak"), + V("follows a sequence with slow sideward head turns", "taps one foreclaw between deliberate beak-led nods"), + V("clips in careful rows with its hard beak", "rakes backward with foreclaws before each neck reach"), + V("lifts its tail while hind legs brace the shell", "raises the rear shell rim above bent forelegs"), + V("turns backward while its neck stays extended ahead", "crosses its forefeet as head and tail angle sideways"), + V("shudders beneath its shell from neck to hind claws", "stiffens all four legs while shell plates vibrate"), + V("rocks unevenly as its neck loops to one side", "jerks its beak between mismatched foreclaw steps"), + V("withdraws its head behind the shell rim and bites", "sidles with one foreclaw tucked beneath its shell"), + V("plods rigidly as neck and tail twitch together", "snaps at empty space while its shell rocks backward"), + V("draws head and limbs beneath the shell rim", "rests its chin inside the shell as claws uncurl")); + } +} diff --git a/IdleSpectator/ActivitySpeciesVoices.Animals.Specialized.cs b/IdleSpectator/ActivitySpeciesVoices.Animals.Specialized.cs new file mode 100644 index 0000000..da3cc69 --- /dev/null +++ b/IdleSpectator/ActivitySpeciesVoices.Animals.Specialized.cs @@ -0,0 +1,119 @@ +using System.Collections.Generic; + +namespace IdleSpectator; + +public static partial class ActivitySpeciesVoiceCatalog +{ + private static void AddAnimalSpecializedVoices(Dictionary voices) + { + AddSpecialized( + voices, + "chicken", + V("fans a spark into flame with rapid wingbeats", "pecks a spark into flame beneath beating primaries"), + V("beats flame low beneath overlapping wings", "smothers flame under spread breast feathers"), + V("presses feathered flanks among gathering kin", "tucks wing-to-wing into a clustered flock"), + V("draws visible essence through its pulsing throat", "pulls observed life-glow along raised neck feathers"), + V("searches with one bright eye and quick beak tilts", "reaches ahead with neck stretched and beak parted"), + V("wails through a trembling comb and open beak", "keens in thin clucks as its throat quivers"), + V("clacks its beak through a harsh squawk", "lashes both wings beneath a rasping cackle")); + + AddSpecialized( + voices, + "crab", + V("clicks a spark into flame between closing pincers", "fans a spark into flame with beating mouthparts"), + V("clamps flame low beneath its broad shell rim", "beats flame down with alternating flattened claws"), + V("locks jointed legs beside gathering kin", "fits shell-to-shell into a clustered cast"), + V("draws visible essence through pulsing mouthparts", "pulls observed life-glow between raised pincers"), + V("searches with swiveling eyestalks and parted claws", "reaches ahead with one open pincer"), + V("rasps through fluttering mouthparts and lowered eyestalks", "clatters both pincers beneath a quivering shell"), + V("snaps raised pincers in a jagged clatter", "grinds its mouthparts under a rigid shell")); + + AddSpecialized( + voices, + "crocodile", + V("breathes a spark into flame through parted jaws", "fans a spark into flame with a plated tail sweep"), + V("presses flame low beneath its armored belly", "beats flame down with broad sweeps of its plated tail"), + V("settles flank-to-flank among gathering kin", "fits its plated body into a jaw-aligned congregation"), + V("draws visible essence through vibrating throat plates", "pulls observed life-glow between rows of exposed teeth"), + V("searches with ridged eyes above a slowly opening jaw", "reaches forward with its long snout and spread foreclaws"), + V("bellows through a heaving armored throat", "moans between slack jaws as its tail trembles"), + V("claps its jaws around a gravelly roar", "lashes its plated tail beneath a guttural bark")); + + AddSpecialized( + voices, + "frog", + V("puffs a spark into flame from its swelling throat sac", "fans a spark into flame with rapid webbed kicks"), + V("presses flame low beneath its broad belly", "beats flame down with slapping webbed hind feet"), + V("folds splayed feet among gathering kin", "presses squat flanks into a croaking cluster"), + V("draws visible essence through its pulsing throat sac", "pulls observed life-glow along an unfurling tongue"), + V("searches with separately swiveling round eyes", "reaches ahead with a flicking tongue and spread forefeet"), + V("keens through a collapsed throat sac", "trills thinly as its webbed toes quiver"), + V("blasts a raw croak through its swollen throat", "slaps both forefeet beneath a rasping chirr")); + + AddSpecialized( + voices, + "ostrich", + V("fans a spark into flame with broad wing plumes", "puffs a spark into flame through its long feathered throat"), + V("beats flame low beneath sweeping short wings", "presses flame down with broad two-toed feet"), + V("weaves its raised neck among gathering kin", "presses feathered flanks into a long-legged cluster"), + V("draws visible essence along its extended throat", "pulls observed life-glow through fanned breast plumes"), + V("searches with high-set eyes and low beak sweeps", "reaches ahead on a fully extended neck"), + V("booms through a sagging feathered throat", "keens with its broad beak agape and neck bowed"), + V("clacks its broad beak beneath a harsh boom", "lashes short wings around a guttural hiss")); + + AddSpecialized( + voices, + "penguin", + V("fans a spark into flame with rigid flipper strokes", "puffs a spark into flame through its narrow raised beak"), + V("beats flame low beneath alternating stiff flippers", "presses flame down with its dense feathered belly"), + V("fits shoulder-to-shoulder among gathering kin", "presses its white breast into a compact huddle"), + V("draws visible essence through its pumping chest", "pulls observed life-glow along both rigid flippers"), + V("searches through sharp head tilts and beak dips", "reaches ahead with narrow beak and one flared flipper"), + V("brays through a bowed head and shaking chest", "keens softly with its beak tucked against white breast feathers"), + V("honks harshly through a thrust-up beak", "slaps both flippers beneath a grating bray")); + + AddSpecialized( + voices, + "piranha", + V("fans a spark into flame with beating fin rays", "snaps a spark into flame between chattering teeth"), + V("beats flame low with a whipping forked tail", "presses flame down beneath its compact scaled flank"), + V("aligns fin-to-fin among gathering kin", "fits its scaled flank into a tight shoal"), + V("draws visible essence through pulsing gill covers", "pulls observed life-glow between its parted teeth"), + V("searches with round eyes and sweeping paired fins", "reaches ahead with blunt snout and open toothed jaw"), + V("chatters its teeth as both gill covers shudder", "rasps through pumping gills and folded fins"), + V("gnashes exposed teeth behind flared gill covers", "whips its forked tail beneath a jagged jaw rattle")); + + AddSpecialized( + voices, + "seal", + V("fans a spark into flame with broad foreflippers", "puffs a spark into flame past its whiskered muzzle"), + V("beats flame low beneath alternating foreflippers", "presses flame down with its thick chest and folded flippers"), + V("presses thick flanks among gathering kin", "fits whiskered muzzle to shoulder in a clustered rookery"), + V("draws visible essence through its heaving chest", "pulls observed life-glow along trembling whiskers"), + V("searches with sweeping whiskers and lifted muzzle", "reaches ahead with one broad foreflipper"), + V("moans through a lowered whiskered muzzle", "keens as its thick chest and throat quiver"), + V("barks harshly behind bared pointed teeth", "slaps both foreflippers beneath a guttural roar")); + + AddSpecialized( + voices, + "snake", + V("breathes a spark into flame past its forked tongue", "fans a spark into flame with rapid rib pulses"), + V("presses flame low beneath stacked muscular coils", "beats flame down with broad sweeps of its scaled body"), + V("threads its coils among gathering kin", "stacks parallel loops into a clustered knot"), + V("draws visible essence through flicking tongue tips", "pulls observed life-glow along rippling belly scales"), + V("searches with forked tongue and sideward jaw turns", "reaches ahead on a straightened neck coil"), + V("hisses through a lowered jaw and slack coils", "keens in thin breath as its tail tip quivers"), + V("spits a harsh hiss between exposed fangs", "lashes its tail beneath a rasping jaw gape")); + + AddSpecialized( + voices, + "turtle", + V("puffs a spark into flame through its hard beak", "fans a spark into flame with alternating clawed forefeet"), + V("presses flame low beneath its broad shell", "beats flame down with sweeping clawed forefeet"), + V("fits shell rim to shell rim among gathering kin", "folds clawed feet into a close-shelled cluster"), + V("draws visible essence through pulsing throat folds", "pulls observed life-glow along its patterned shell plates"), + V("searches with slow head turns and beak dips", "reaches ahead on an extended wrinkled neck"), + V("keens through a lowered beak and trembling throat folds", "rasps softly as its foreclaws curl beneath the shell rim"), + V("clacks its hard beak through a throaty hiss", "stamps clawed forefeet beneath a grating chirr")); + } +} diff --git a/IdleSpectator/ActivitySpeciesVoices.Civs.Extended.cs b/IdleSpectator/ActivitySpeciesVoices.Civs.Extended.cs new file mode 100644 index 0000000..3d3a0ad --- /dev/null +++ b/IdleSpectator/ActivitySpeciesVoices.Civs.Extended.cs @@ -0,0 +1,883 @@ +using System.Collections.Generic; + +namespace IdleSpectator; + +public static partial class ActivitySpeciesVoiceCatalog +{ + private static void AddCivExtendedVoices(Dictionary voices) + { + AddExtended(voices, "civ_acid_gentleman", + V("sings in clipped upright phrases", "holds each note behind a formal posture"), + V("courts with measured bows", "mates without loosening a rigid stance"), + V("cultivates in ruler-straight passes", "squares both shoulders while cultivating"), + V("pollinates with precise fingertip touches", "visits each bloom in strict order"), + V("trades through exacting hand gestures", "bargains with chin held level"), + V("fishes from a square-footed stance", "fishes in straight ruler-like pulls"), + V("hauls with back severely straight", "bears the weight at matching angles"), + V("tends wounds with level steady hands", "treats wounds in measured hand passes"), + V("faces the flames with cuffs held clear", "handles fire with formal precision"), + V("retreats in controlled backward strides", "flees without breaking upright form"), + V("settles into equal-ranked formation", "joins the civic cluster at exact spacing"), + V("drills behind a rigid forearm guard", "patrols in sharply measured steps"), + V("reads with one finger marking each line", "studies with chin and shoulders held square"), + V("gathers kin into ordered ranks", "collects spoils in matching groups"), + V("relieves the body from a rigid squat", "straightens immediately after relieving itself"), + V("starts one duty at conflicting angles", "pauses stiffly over a mistaken sequence"), + V("recovers with spine still vertical", "recharges through counted intervals of stillness"), + V("obeys an odd impulse through formal gestures", "answers the compulsion in exact measures"), + V("pilfers with cuffed hands held level", "takes covertly behind a rigid bow"), + V("moves under possession in rigid counts", "executes unseen commands without bending"), + V("dreams with hands folded symmetrically", "sleeps through small ceremonial gestures")); + + AddExtended(voices, "civ_alpaca", + V("hums through a wool-soft throat", "sings with chin lifted above the fleece"), + V("courts in springy side steps", "mates beneath a close woolly press"), + V("cultivates with light four-footed pacing", "tends planted growth beneath bobbing fleece"), + V("pollinates with a soft probing muzzle", "brushes blooms beneath forward ears"), + V("trades through soft nose-led greetings", "bargains with ears tipped forward"), + V("fishes with long legs planted wide", "leans woolly chest-first and fishes"), + V("hauls against a padded shoulder", "carries weight in a fleece-deep sway"), + V("nuzzles wounds with slow wool-framed lips", "tends wounds beneath a lowered woolly neck"), + V("steps around flames on nimble feet", "faces fire with fleece drawn back"), + V("bounds away on long springing legs", "flees with ears flattened into the wool"), + V("settles with all four feet neatly tucked", "forms a close fleece-lined civic cluster"), + V("drills in high-stepping charges", "guards with chest wool pushed forward"), + V("reads with muzzle hovering close", "studies while long ears track each pause"), + V("herds kin with low humming calls", "gathers spoils against thick chest wool"), + V("relieves itself with tail held clear", "squats lightly on folded hind legs"), + V("turns long ears toward the wrong duty", "stutters through uncertain four-footed steps"), + V("recharges with legs folded under fleece", "rests upright in a woolly bundle"), + V("follows a strange urge in sideways hops", "bobs sideways under an inexplicable compulsion"), + V("pilfers with soft lips and lifted chin", "sidles away beneath upright ears"), + V("bounds possessed in stiff-legged pulses", "fleece trembles through each compelled bound"), + V("dreams with ears twitching above the wool", "dozes through tiny long-legged kicks")); + + AddExtended(voices, "civ_armadillo", + V("chitters beneath rattling back plates", "sings through a half-curled shell"), + V("courts by circling plated flank to flank", "mates beneath overlapping armor"), + V("cultivates with low digging claws", "tends planted growth beneath bobbing plates"), + V("pollinates with a narrow snuffling snout", "nudges blooms beneath a domed back"), + V("trades through brisk shell taps", "bargains from a guarded half-curl"), + V("fishes with foreclaws braced low", "snuffles between short claw-led pulls"), + V("hauls beneath a plated shoulder", "rolls weight against the curved shell"), + V("tends wounds with small digging claws", "uncurls one plate at a time and treats wounds"), + V("curls beside flames behind thick plates", "tests fire from beneath a shell rim"), + V("scuttles away under lowered armor", "flees in a tight plated roll"), + V("scrapes and curls into civic formation", "settles with shell backs facing outward"), + V("drills in armored rolling charges", "guards from a clawed half-curl"), + V("reads with snout nearly touching", "studies beneath a raised plate edge"), + V("gathers kin into a plated ring", "rolls spoils beneath the shell curve"), + V("relieves itself from a low squat", "uncurls the plated rear to relieve itself"), + V("circles the wrong duty in a puzzled half-roll", "scratches at the wrong step with small claws"), + V("recharges tightly sealed in armor", "rests while overlapping plates settle"), + V("scuttles after an odd inward tug", "rolls onward under a strange compulsion"), + V("pilfers with one small hooking claw", "curls away around the taking"), + V("rattles possessed inside a rigid shell", "rolls under unseen direction"), + V("dreams in a fully plated curl", "sleeps while tiny claws paddle beneath armor")); + + AddExtended(voices, "civ_bear", + V("sings in broad chest-deep rumbles", "holds a note through a lifted muzzle"), + V("courts with heavy shoulder sways", "mates in a broad paw-braced embrace"), + V("cultivates with sweeping forepaws", "tends planted growth behind a broad muzzle"), + V("pollinates with a wide lowered snout", "brushes blooms between blunt claws"), + V("trades with booming paw-led emphasis", "bargains while looming on hind legs"), + V("fishes with paws poised to scoop", "fishes with broad chest leaning forward"), + V("hauls high against a massive chest", "bears weight between sweeping forearms"), + V("tends wounds with broad slow paws", "sniffs over wounds before treating them"), + V("rears beside flames with paws raised", "handles fire behind a thick forearm guard"), + V("lumbers away before breaking into bounds", "flees with heavy paws pounding"), + V("settles into a broad paw-marked formation", "joins the civic cluster with a heavy chest brace"), + V("drills through weighty upright blows", "patrols with rolling shoulders"), + V("reads between two broad paws", "studies with muzzle lowered over the lines"), + V("calls kin together with a low roar", "scoops spoils against the chest"), + V("relieves itself from a heavy haunch squat", "rises broad-backed after relieving itself"), + V("swipes uncertainly between opposing duties", "rears and sniffs at a mistaken duty"), + V("recharges curled around both forepaws", "rests in deep belly-driven breaths"), + V("lumbers after a baffling inner pull", "answers it through ponderous paw sweeps"), + V("pilfers in one broad scooping paw", "lumbers away behind broad shoulders"), + V("rears possessed with claws spread", "moves under command in crushing steps"), + V("dreams through deep muzzle-rumbling breaths", "sleeps while massive paws flex")); + + AddExtended(voices, "civ_beetle", + V("sings in dry wing-case vibrations", "clicks a measured carapace chorus"), + V("courts with antennae tracing paired arcs", "mates beneath locked wing cases"), + V("cultivates in straight six-legged measures", "tends growth with clipping mouthparts"), + V("pollinates beneath sweeping antennae", "walks each bloom on hooked feet"), + V("trades through coded feeler taps", "bargains with polished wing cases raised"), + V("fishes from six evenly braced legs", "fishes in jointed six-leg pulses"), + V("hauls under a hard domed back", "drives weight with all six legs"), + V("examines wounds with circling feelers", "tends wounds between delicate forelegs"), + V("faces flame behind sealed wing cases", "tests fire with one extended antenna"), + V("skitters away in a six-legged burst", "flees with feelers folded against the shell"), + V("settles into a geometric carapace cluster", "locks into civic formation along straight traces"), + V("drills with horn and shell aligned", "patrols in clicking six-step measures"), + V("reads by tracking lines with antennae", "studies beneath a lowered horn"), + V("signals kin into an antenna-linked group", "pushes spoils beneath the wing case"), + V("relieves itself with hind legs spread", "locks the forelegs while relieving itself"), + V("turns both feelers between conflicting duties", "clicks through an uncertain leg pattern"), + V("recharges with every joint locked", "rests sealed beneath the hard wing case"), + V("skitters under a strange antenna-led impulse", "clicks through it in rigid segments"), + V("pilfers between quick clipping forelegs", "withdraws beneath closed cases"), + V("marches possessed on synchronized legs", "wing cases rattle through compelled steps"), + V("dreams with antennae drawing slow circles", "rests while folded legs twitch in sequence")); + + AddExtended(voices, "civ_buffalo", + V("sings in horn-framed bellows", "rolls a note through a massive chest"), + V("courts with broad forehead presses", "mates on firmly planted hooves"), + V("cultivates in heavy hoof-timed passes", "keeps horns level while tending planted growth"), + V("pollinates with a broad brushing muzzle", "moves between blooms beneath curved horns"), + V("trades through solid brow-led gestures", "bargains without shifting planted hooves"), + V("fishes with horns angled aside", "fishes through massive shoulder pulls"), + V("hauls from a thick horn-set neck", "pulls weight through four grinding hooves"), + V("nudges wounds with a broad muzzle", "tends wounds while standing horn-outward"), + V("faces flames with horns lowered", "stamps around fire on heavy hooves"), + V("thunders away with tail held straight", "flees behind a rolling wall of shoulders"), + V("settles in a horn-outward civic ring", "joins the formation through deep hoof presses"), + V("drills in low repeated charges", "patrols with horns maintaining a broad front"), + V("reads with muzzle lowered between horns", "studies while one hoof holds position"), + V("bellows kin into a guarded circle", "pushes spoils together with the broad brow"), + V("relieves itself on widely planted hooves", "flicks the tail clear while relieving itself"), + V("paws between two mistaken directions", "swings the horned head over a confused duty"), + V("recharges standing on locked heavy legs", "rests with chin sunk into the chest"), + V("charges toward an inexplicable duty", "obeys a strange tug with horns forward"), + V("pilfers behind the curve of one horn", "backs away on guarded hooves"), + V("stamps possessed in a rigid cadence", "drives forward beneath unseen direction"), + V("dreams with nostrils pulsing under the horns", "dozes while thick hooves scrape softly")); + + AddExtended(voices, "civ_candy_man", + V("sings in bright crackling trills", "rings a note through glossy layers"), + V("courts with striped spinning bows", "mates in a springy wrapped embrace"), + V("cultivates in glossy heel-to-toe turns", "crinkles both hands through planted growth"), + V("pollinates with quick lacquered fingertips", "twirls between blooms on pointed heels"), + V("trades through wide striped flourishes", "bargains with palms turned brightly outward"), + V("fishes in a balanced glossy crouch", "fishes with elastic arms snapping straight"), + V("hauls against a hardened bright shoulder", "bears weight on springing striped legs"), + V("tends wounds with light crinkling fingers", "bends glossy limbs incrementally and treats wounds"), + V("circles flames on quick polished heels", "faces fire with glossy hands fluttering"), + V("skips away in sharp zigzag bounds", "flees with striped limbs snapping straight"), + V("settles into a neatly wrapped civic cluster", "aligns glossy edges with the formation"), + V("drills in snapping spiral turns", "patrols on bright quick heels"), + V("reads with one shiny finger tracing", "studies while striped shoulders stay square"), + V("crackles a call to gather kin", "folds spoils against a glossy chest"), + V("relieves itself in a compact crinkled squat", "unbends glossy knees after relieving itself"), + V("twists between mismatched duty steps", "crinkles uncertainly over the wrong duty"), + V("recharges folded into a bright compact curl", "rests while glossy limbs regain their spring"), + V("springs after an inexplicable impulse", "twirls onward under the strange compulsion"), + V("pilfers with quick lacquered fingers", "skips away with striped arms tucked"), + V("jerks possessed on rigid glossy joints", "striped limbs spin through compelled turns"), + V("dreams with striped limbs softly uncurling", "sleeps through tiny wrapper-like crackles")); + + AddExtended(voices, "civ_capybara", + V("sings in low blunt-muzzled pulses", "hums steadily through a rounded chest"), + V("courts with slow flank-to-flank nudges", "mates on broad evenly planted feet"), + V("cultivates at an unhurried four-footed pace", "tends growth with a steady blunt muzzle"), + V("pollinates with whiskered nose touches", "ambles bloom to bloom on broad feet"), + V("trades through repeated chin-led nods", "bargains without shifting its broad stance"), + V("fishes from a low balanced crouch", "fishes by cycling both small forepaws"), + V("hauls against a solid rounded shoulder", "moves weight in broad measured steps"), + V("nuzzles wounds with a blunt nose", "tends wounds from a low broad stance"), + V("sits solidly beside the flames", "handles fire with whiskers held back"), + V("ambles away before lengthening its stride", "flees low with broad feet drumming"), + V("settles into a close flank-sharing group", "joins the formation at a measured pace"), + V("drills through compact shoulder shoves", "patrols without breaking its even stride"), + V("reads with blunt chin held close", "studies while small ears remain still"), + V("gathers kin through low pulsing calls", "pushes spoils together with both forepaws"), + V("relieves itself on folded broad haunches", "rises at the same measured pace afterward"), + V("stares between duties with whiskers twitching", "ambles through an uncertain wrong turn"), + V("recharges in a compact low curl", "rests with blunt chin sunk to the chest"), + V("follows a strange urge at the same slow pace", "ambles through it on measured paws"), + V("pilfers beneath a low rounded chest", "ambles away without lifting its head"), + V("moves possessed in unnaturally even steps", "obeys unseen direction with a fixed muzzle"), + V("dreams with whiskers pulsing softly", "dozes while broad forefeet paddle once")); + + AddExtended(voices, "civ_cat", + V("sings in narrow purring rises", "trills with tail curled high"), + V("courts through arched circling rubs", "closes the mating crouch with paws braced"), + V("cultivates in silent paw-timed passes", "tends growth with tail balancing each turn"), + V("pollinates with delicate whiskered sniffs", "steps among blooms on soft paws"), + V("trades through slow blinks and tail flicks", "bargains with whiskers angled forward"), + V("fishes from a motionless paw-raised crouch", "fishes with quick hooking claws"), + V("hauls low between clenched teeth", "draws weight backward on padded paws"), + V("licks around wounds with a rough tongue", "tends wounds through light paw-tip taps"), + V("watches flames through narrowed eyes", "pats toward fire then snaps the paw back"), + V("springs away with spine arched", "flees low with tail streaming straight"), + V("settles after three tail-led circles", "joins the civic cluster cheek and flank first"), + V("drills in silent pouncing bursts", "patrols with claws sheathed and tail level"), + V("reads with one paw held firmly down", "tracks each line through narrowed eyes"), + V("calls kin with a throaty chirrup", "draws spoils inward beneath both paws"), + V("relieves itself in a low hind-leg squat", "scrapes backward after relieving itself"), + V("stalks the wrong duty with puzzled whiskers", "switches duties after an abrupt tail twitch"), + V("recharges curled nose-to-tail", "rests through a deep chest purr"), + V("pounces toward a baffling private impulse", "obeys the odd urge with twitching tail"), + V("pilfers with silent hooked claws", "slips away on noiseless paws"), + V("arches possessed with pupils fixed", "pads under command in stiff silence"), + V("dreams with paws kneading the air", "sleeps while whiskers and tail tip twitch")); + + AddExtended(voices, "civ_chicken", + V("sings in sharp beak-led bursts", "crows with neck feathers lifted"), + V("courts through wing-dropped circling steps", "mates in a brief flapping crouch"), + V("cultivates through quick claw scratches", "pecks planted growth in repeated beats"), + V("pollinates by brushing blooms with feathers", "pecks among blossoms on quick feet"), + V("trades through brisk clucks and head bobs", "bargains with one sideways eye fixed"), + V("fishes with beak held motionless", "fishes by pecking in abrupt bursts"), + V("hauls in short beak-gripped tugs", "drags weight with wings spread for balance"), + V("preens slowly around wounds", "tends wounds with measured beak taps"), + V("flaps around flames with feathers raised", "pecks toward fire between quick retreats"), + V("scurries away with wings beating", "flees in darting head-low steps"), + V("settles into a close feathered civic circle", "joins the cluster through quick scratching turns"), + V("drills with spurred hopping strikes", "patrols in stiff head-bobbing strides"), + V("reads with one eye turned to each line", "reads each line with head-bobbing pecks"), + V("clucks kin into a tight cluster", "scratches spoils into a beak-reached heap"), + V("relieves itself in a brief feathered squat", "flicks the tail after relieving itself"), + V("pecks at the wrong duty in confusion", "turns each eye toward a different duty"), + V("recharges with beak tucked under wing", "rests in a fluffed rounded crouch"), + V("scurries after an unexplained pecking urge", "obeys the urge with wings half spread"), + V("pilfers in one quick beak jab", "darts away on scratching feet"), + V("struts possessed in abrupt rigid beats", "wings flap through each compelled step"), + V("dreams with one wing twitching", "dozes through tiny claw scratches")); + + AddExtended(voices, "civ_cow", + V("sings in long dewlap-shaking tones", "moans a broad muzzle-led melody"), + V("courts with slow flank-brushing circles", "mates on four firmly spread hooves"), + V("cultivates in steady cud-chewing passes", "tends growth beneath a swinging dewlap"), + V("pollinates with a broad damp muzzle", "walks among blooms with tail flicking"), + V("trades through low calls and horn tilts", "bargains from a repeated hipshot stance"), + V("fishes with muzzle lowered between horns", "fishes muzzle-low at a steady pace"), + V("hauls through a broad horn-set neck", "draws weight on evenly grinding hooves"), + V("tends wounds with a wide slow tongue", "treats wounds from a broadside stance"), + V("faces flames with broad nostrils pulsing", "steps around fire on evenly placed hooves"), + V("trots away with dewlap swinging", "flees behind a broad lowered head"), + V("settles into a shoulder-close civic herd", "joins the formation through steady hoof steps"), + V("drills in sweeping horn-led turns", "patrols with head low and hooves even"), + V("reads with muzzle close beneath the brow", "studies while chewing in slow cycles"), + V("calls kin together in mellow waves", "pushes spoils inward with a broad muzzle"), + V("relieves itself with tail held aside", "stands hipshot while relieving itself"), + V("chews through a long uncertain pause", "turns the broad head between mistaken duties"), + V("recharges on folded heavy legs", "rests with muzzle laid against one flank"), + V("plods after an inexplicable inward nudge", "chews steadily through the compelled duty"), + V("pilfers beneath a broad lowered muzzle", "backs away on quiet hooves"), + V("walks possessed with dewlap held rigid", "obeys unseen direction on locked legs"), + V("dreams through slow cyclical chewing", "dozes while the tail flicks once")); + + AddExtended(voices, "civ_crab", + V("sings in alternating claw clacks", "bubbles a sideways shell-borne rhythm"), + V("courts through mirrored pincer waves", "mates beneath interlocking side-held claws"), + V("cultivates in lateral eight-legged sequences", "tends growth with paired cutting pincers"), + V("pollinates with delicate pincer brushes", "sidesteps from bloom to bloom"), + V("trades through exact shell-and-claw taps", "bargains with eyestalks held level"), + V("fishes with both pincers poised", "fishes through sideways claw tugs"), + V("hauls between paired locking claws", "sidesteps weight beneath a raised shell"), + V("tends wounds with fine pincer tips", "circles wounds on evenly moving jointed legs"), + V("faces flames behind a lifted shell edge", "tests fire with one extended claw"), + V("scuttles sideways in a rapid retreat", "flees with eyestalks folded low"), + V("settles into a shell-outward civic ring", "joins the circle with paired pincers raised"), + V("drills in hammering claw combinations", "patrols laterally with pincers raised"), + V("reads with eyestalks tracking separate lines", "studies between two balanced claws"), + V("clacks kin into a tight shell cluster", "snips spoils into a central grouping"), + V("relieves itself beneath a lowered rear shell", "plants all jointed legs while relieving itself"), + V("sidesteps between contradictory duties", "waves both claws over a confused duty"), + V("recharges sealed beneath shell and limbs", "rests with pincers folded to the mouth"), + V("scuttles after a strange sideways compulsion", "alternates both claws under compulsion"), + V("pilfers in one narrow pincer snip", "sidles away behind the raised claw"), + V("clacks possessed in exact harsh beats", "moves under command on rigid jointed legs"), + V("dreams with eyestalks slowly retracting", "sleeps while folded pincers click once")); + + AddExtended(voices, "civ_crocodile", + V("sings in deep jaw-parted rumbles", "rolls a note along a plated throat"), + V("courts through low tail-sweeping circles", "mates in a heavy splay-legged press"), + V("cultivates belly-low on clawed feet", "tends growth with plated back held flat"), + V("pollinates with the long snout lowered", "brushes blooms beneath still nostrils"), + V("trades through slow jaw and tail signals", "bargains without lifting the armored belly"), + V("fishes with jaws held motionless", "fishes with one sudden jaw snap"), + V("hauls backward in a low jaw-locked drag", "pulls weight with tail and splayed legs"), + V("nudges wounds with the closed snout", "tends wounds between slow claw-tip taps"), + V("lies plated and still beside flames", "tests fire with jaws slightly open"), + V("bursts away from a motionless crouch", "flees low with armored tail whipping"), + V("settles into a low civic wall of plated backs", "joins formation on firmly splayed feet"), + V("drills in jaw-led lunges and tail sweeps", "patrols belly-low behind armored ridges"), + V("reads with one eye fixed on each line", "studies between motionless open jaws"), + V("rumbles kin into a plated gathering", "sweeps spoils together with the heavy tail"), + V("relieves itself on braced splayed legs", "raises the plated rear while relieving itself"), + V("snaps between mismatched duty directions", "lies still over a confused duty"), + V("recharges flat beneath settled back plates", "rests with jaws open and eyes narrowed"), + V("slides toward an inexplicable compulsion", "answers it with plated belly held low"), + V("pilfers with one swift closing jaw", "slides away behind a sweeping tail"), + V("lunges possessed from complete stillness", "rigid jaws drive each compelled lunge"), + V("dreams with the plated tail slowly flexing", "sleeps while one eye opens briefly")); + + AddExtended(voices, "civ_dog", + V("sings in muzzle-lifted howling phrases", "barks a tail-beating civic rhythm"), + V("courts through quick circling sniffs", "mates on braced hind legs"), + V("cultivates in nose-led bounding passes", "tends planted growth in brisk pawing bursts"), + V("pollinates with a soft searching nose", "bounds among blooms with ears forward"), + V("trades through paw taps and quick barks", "bargains with tail sweeping behind"), + V("fishes with one paw held poised", "fishes through sharp single-paw snaps"), + V("hauls in a firm jaw-held pull", "draws weight at a quick trot"), + V("licks wounds in repeated tongue strokes", "tends wounds with ears trained close"), + V("barks at flames from a paw-wide stance", "circles fire with nostrils pulsing"), + V("bounds away with ears streaming", "flees low as the tail draws tight"), + V("settles after repeated tail-led circling", "joins a close muzzle-facing civic cluster"), + V("drills in shoulder-first rushing tackles", "patrols nose-first with ears alert"), + V("reads with muzzle resting near the lines", "studies while one forepaw taps"), + V("calls kin together with repeated barks", "gathers spoils beneath both forepaws"), + V("relieves itself with one hind leg raised", "sniffs twice before relieving itself"), + V("paces between duties with ears askew", "sniffs at an obviously mistaken duty"), + V("recharges curled around twitching paws", "rests through long open-mouthed breaths"), + V("bounds after a baffling urge", "answers it with tail beating in bursts"), + V("pilfers between quick closing jaws", "trots away with ears flattened"), + V("stalks possessed on stiffened paws", "obeys unseen direction without sniffing"), + V("dreams with forepaws running in place", "sleeps through muffled muzzle twitches")); + + AddExtended(voices, "civ_fox", + V("sings in quick narrow muzzle-notes", "barks a tail-curled rising refrain"), + V("courts through crossing tail-led circles", "mates in a light black-pawed crouch"), + V("cultivates through angled silent passes", "tends growth with quick crossing paw strokes"), + V("pollinates with a narrow whiskered muzzle", "threads between blooms on black paws"), + V("trades through oblique bows and ear tilts", "bargains with tail masking the paws"), + V("fishes from a poised tail-balanced crouch", "fishes with one hooking black paw"), + V("hauls by backing on quiet black feet", "draws weight beneath a level sweeping tail"), + V("licks wounds with a narrow moving tongue", "tends wounds with narrow paw-tip touches"), + V("circles flames in angled crossing steps", "tests fire with whiskers held sideways"), + V("darts away through crossing turns", "flees with brush held straight behind"), + V("settles into an offset civic formation", "joins it through angled body circuits"), + V("drills in feinting black-pawed rushes", "patrols by crossing its own earlier line"), + V("reads with the brush wrapped around its feet", "tracks each line through bright narrowed eyes"), + V("calls kin with clipped rising barks", "sweeps spoils inward beneath the long brush"), + V("relieves itself in a light hind-leg crouch", "flicks the brush aside while relieving itself"), + V("tilts both ears over conflicting duties", "circles a mistaken duty with puzzled whiskers"), + V("recharges nose-deep in the sweeping tail", "rests in a narrow black-pawed curl"), + V("slips after a peculiar inward whisper", "follows it on tiptoe black paws"), + V("pilfers with nimble narrow teeth", "weaves away behind the broad brush"), + V("paces possessed in unnaturally straight lines", "obeys unseen direction with tail rigid"), + V("dreams with brush and black paws twitching", "sleeps through tiny muzzle-led feints")); + + AddExtended(voices, "civ_frog", + V("sings through a round pulsing throat", "croaks a springy civic refrain"), + V("courts with throat-puffed hopping displays", "folds long legs into the mating crouch"), + V("cultivates in compact repeated leaps", "handles planted growth between broad splayed hands"), + V("pollinates with quick tongue-tip touches", "springs bloom to bloom on folded legs"), + V("trades through rhythmic croaks and blinks", "bargains from a deep squat"), + V("fishes with tongue poised and eyes wide", "fishes in long tongue-led leaps"), + V("hauls in short two-handed hops", "drags weight with long hind legs braced"), + V("tends wounds with broad damp hands", "leans round-eyed while treating wounds"), + V("squats beside flames with throat pulsing", "springs around fire on tucked legs"), + V("bounds away in long rapid arcs", "flees with throat flat and eyes wide"), + V("settles into a close croaking cluster", "joins the formation through repeated short hops"), + V("drills in double-footed kicking leaps", "patrols by springing between low crouches"), + V("reads with both round eyes lowered", "tracks the lines with one broad fingertip"), + V("croaks kin into a facing circle", "gathers spoils between splayed hands"), + V("relieves itself in a deep compact squat", "unfolds long legs after relieving itself"), + V("hops between contradictory duty cues", "blinks broadly over the wrong duty"), + V("recharges folded into a tiny crouch", "rests while the round throat slows"), + V("springs toward an unexplained urge", "answers it in throat-pulsing hops"), + V("pilfers in a quick two-handed flick", "bounds away with eyes forward"), + V("leaps possessed in fixed repeating arcs", "the throat croaks through compelled leaps"), + V("dreams with long hind feet twitching", "dozes while the throat pulses silently")); + + AddExtended(voices, "civ_garlic_man", + V("sings through rustling layered breaths", "crackles a papery civic tune"), + V("courts by unfurling outer layers", "bundles knobby limbs during mating"), + V("cultivates with alternating layered hands", "tends planted growth on knobby bobbing feet"), + V("pollinates with soft papery brushes", "rustles between blooms in layered turns"), + V("trades through peeling hand flourishes", "bargains with bundled layers drawn tight"), + V("fishes with knobby feet firmly planted", "fishes by rustling both layered arms"), + V("hauls against a densely layered shoulder", "bears weight on knotted feet"), + V("wraps wounds in overlapping outer layers", "tends wounds with knobby fingertips"), + V("draws papery layers back from flames", "circles fire with dry arms held wide"), + V("rolls away in a rustling rush", "flees with loose layers streaming"), + V("settles into a tightly layered civic cluster", "bundles into formation along concentric lines"), + V("drills in knotted head-first rushes", "patrols with papery arms spread"), + V("reads while smoothing each rustling layer", "studies with one knobby finger tracing"), + V("rustles kin into a layered cluster", "bundles spoils between both dry arms"), + V("relieves itself from a knobby-footed squat", "gathers loose layers after relieving itself"), + V("peels back layers over a mistaken duty", "bobs uncertainly between duties"), + V("recharges folded inside dry outer layers", "rests while papery edges settle"), + V("rustles after an inexplicable impulse", "unfolds through the duty layer by layer"), + V("pilfers behind loose overlapping layers", "rolls away on knobby feet"), + V("bobs possessed beneath rigid dry layers", "bundled arms jerk under compulsion"), + V("dreams as papery layers softly shift", "sleeps with knobby feet tucked inward")); + + AddExtended(voices, "civ_goat", + V("sings in sharp horn-framed bleats", "trills with chin lifted above the beard"), + V("courts through high springing head tosses", "mates on nimble split hooves"), + V("cultivates in quick hoof-timed passes", "tends growth with browsing lips"), + V("pollinates with a nimble probing muzzle", "clatters among blooms on split hooves"), + V("trades through repeated horn tilts", "bargains from a high braced stance"), + V("fishes with beard hanging over the stance", "fishes from four nimble split hooves"), + V("hauls through a low horn-set neck", "draws weight with split hooves gripping"), + V("nuzzles wounds beneath curled horns", "tends wounds with slow browsing lips"), + V("bounds around flames with beard held clear", "faces fire behind lowered curled horns"), + V("scrambles away in high uneven leaps", "flees on clattering split hooves"), + V("settles into a high-standing horned cluster", "joins the formation with brisk hoof stamps"), + V("drills in sudden brow-first charges", "patrols with curled horns tipped forward"), + V("reads with beard brushing close", "studies while one ear cocks sideways"), + V("bleats kin into a head-to-head group", "nudges spoils together beneath the horns"), + V("relieves itself on flexed hind legs", "holds the short tail clear while relieving itself"), + V("nibbles at the wrong duty in confusion", "tilts horns between opposing duties"), + V("recharges kneeling on tucked split hooves", "rests with beard against the chest"), + V("leaps toward an inexplicable urge", "answers it on firmly split hooves"), + V("pilfers with agile browsing lips", "bounds away behind raised horns"), + V("charges possessed in repeated straight lines", "clatters under unseen direction"), + V("dreams with beard and hooves twitching", "dozes through tiny horn-led head tosses")); + + AddExtended(voices, "civ_hyena", + V("sings in rising broken whoops", "cackles a slope-backed refrain"), + V("courts through looping shoulder-low runs", "mates on broad jaw-braced haunches"), + V("cultivates in sloping side-to-side passes", "tends growth with heavy jaws flexing close"), + V("pollinates with a broad sniffing muzzle", "loops among blooms on uneven shoulders"), + V("trades through cackling jaw displays", "bargains with sloped back held low"), + V("fishes from a crooked shoulder-heavy stance", "fishes with broad jaws snapping sideways"), + V("hauls in a crushing jaw grip", "draws weight with hindquarters driving"), + V("licks wounds between low pulsing whoops", "tends wounds with broad muzzle lowered"), + V("paces around flames with jaws parted", "faces fire from a low sloping crouch"), + V("lopes away in widening loops", "flees with shoulders low and jaws shut"), + V("settles into a shoulder-close laughing clan", "circles the civic group before lying low"), + V("drills through harrying jaw-first passes", "patrols in broad looping circuits"), + V("reads with jaws slightly parted", "studies while sloped shoulders rock"), + V("whoops kin into a close flank group", "crushes spoils into manageable groupings"), + V("relieves itself from crooked lowered haunches", "sniffs around after relieving itself"), + V("loops between duties with puzzled jaws open", "cackles once at a mistaken duty"), + V("recharges in a loose slope-backed sprawl", "rests with chin between heavy forepaws"), + V("lopes after a strange private compulsion", "answers it in slope-backed widening circles"), + V("pilfers inside heavy closing jaws", "veers away on crooked strides"), + V("cackles possessed without opening its jaws", "runs under command in rigid loops"), + V("dreams through broken throat-whoops", "sleeps while heavy jaws flex silently")); + + AddExtended(voices, "civ_lemon_man", + V("sings in sharp rind-bright squeaks", "fizzes through a pointed-crown refrain"), + V("courts with springy rolling pivots", "presses rounded limbs together during mating"), + V("cultivates in bouncing segmented passes", "tends growth with rounded feet and quick palms"), + V("pollinates with pointed fingertip touches", "rolls between blooms before popping upright"), + V("trades through brisk rind-polishing gestures", "bargains with pointed crown held high"), + V("fishes from a springy rounded crouch", "fishes with quick puckered mouth pulses"), + V("hauls against the firm curved rind", "rolls weight on rounded feet"), + V("tends wounds with quick alternating palms", "leans the pointed crown away and treats wounds"), + V("pivots around flames with rind held back", "faces fire on bouncing rounded feet"), + V("rolls away before springing upright", "flees with pointed crown angled forward"), + V("settles into a neatly segmented civic cluster", "joins formation through rounded divisions"), + V("drills in rolling pointed-crown charges", "patrols with quick springing pivots"), + V("reads with mouth held in a pucker", "traces lines beneath the pointed crown"), + V("squeaks kin into a rounded cluster", "presses spoils together with both palms"), + V("relieves itself in a tight rounded squat", "straightens the pointed crown after relieving itself"), + V("rolls between mismatched duty segments", "puckers over an obviously mistaken duty"), + V("recharges curled against the firm rind", "rests with rounded feet tucked close"), + V("bounces after an inexplicable impulse", "answers it through pointed-crown rolling starts"), + V("pilfers with a quick rounded pivot", "rolls away beneath the pointed crown"), + V("jerks possessed on spring-locked limbs", "the pointed crown spins through compelled turns"), + V("dreams with rounded feet softly bouncing", "sleeps while the pointed crown tilts")); + + AddExtended(voices, "civ_liliar", + V("sings in layered silvery trills", "chimes through unfurled throat-frills"), + V("courts through slow frill-unfolding bows", "mates in a slender layered embrace"), + V("cultivates with long interweaving hands", "tends planted growth beneath drifting frills"), + V("pollinates with delicate leaf-edge brushes", "glides bloom to bloom on slender steps"), + V("trades through broad many-layered gestures", "bargains with long fingers interlaced"), + V("fishes from a stem-straight stance", "fishes through supple long-armed arcs"), + V("hauls with layered arms braided together", "bears weight along a supple upright frame"), + V("wraps wounds in overlapping soft frills", "tends wounds with long leaflike fingers"), + V("unfurls around flames at a measured distance", "faces fire with layered edges drawn inward"), + V("glides away with frills streaming", "flees in long supple sweeping steps"), + V("settles into a facing circle of layered forms", "weaves the civic group into interlocking bands"), + V("drills in supple stem-led turns", "patrols with sharpened frills held outward"), + V("reads with one long finger following lines", "studies behind folded layered hands"), + V("chimes kin into a layered ring", "braids spoils together between slender arms"), + V("relieves itself in a folded upright crouch", "closes lower frills while relieving itself"), + V("unfurls toward two conflicting duties", "tilts layered hands over a confused duty"), + V("recharges enclosed by overlapping frills", "rests upright with slender hands joined"), + V("glides after an unaccountable inner pull", "unfurls through it in supple arcs"), + V("pilfers behind overlapping layered frills", "sweeps away on silent slender steps"), + V("unfurls possessed in severe symmetry", "rigid frills repeat the compelled pattern"), + V("dreams while layered edges slowly open", "sleeps as long fingers weave delicate patterns")); + + AddExtended(voices, "civ_monkey", + V("sings in rapid chest-patting chatter", "howls a long-armed civic refrain"), + V("courts through tail-curled swinging displays", "grapples long limbs and tail during mating"), + V("cultivates with hands, feet, and tail alternating", "crouches nimbly while tending growth"), + V("pollinates with quick fingertip inspections", "swings among blooms with tail curled"), + V("trades through animated many-handed gestures", "bargains while hanging from the tail"), + V("fishes with one hand poised below the other", "fishes from a long-armed squat"), + V("hauls with tail and both hands braced", "bears weight across long swinging arms"), + V("grooms wounds with nimble fingertips", "tends wounds through long-fingered grooming"), + V("circles flames on hands and feet", "reaches toward fire then recoils up the arms"), + V("scrambles away on all four limbs", "flees with tail streaming behind"), + V("settles into a close grooming civic troop", "joins the troop through swinging circuits"), + V("drills in long-armed grappling turns", "patrols above and below on nimble limbs"), + V("reads while tracing with fingers and toes", "studies with tail curled around the stance"), + V("chatters kin into a hand-linked cluster", "gathers spoils with hands, feet, and tail"), + V("relieves itself from a low long-armed squat", "raises the curling tail while relieving itself"), + V("scratches its head between conflicting duties", "swings toward an obviously mistaken duty"), + V("recharges curled inside long arms and tail", "rests with both hands beneath the head"), + V("scrambles after a peculiar sudden urge", "answers it while hanging tail-first"), + V("pilfers with quick curling fingers", "swings away with tail wrapped tight"), + V("clambers possessed in repetitive limb patterns", "teeth chatter through compelled climbing"), + V("dreams with hands grasping empty air", "sleeps while tail and toes curl")); + + AddExtended(voices, "civ_penguin", + V("sings in upright bill-led honks", "warbles while both flippers beat time"), + V("courts through formal flipper-spread bows", "huddles upright with flippers during mating"), + V("cultivates in waddling parallel passes", "tends growth with bill and flipper taps"), + V("pollinates with repeated narrow-bill touches", "waddles among blooms with flippers out"), + V("trades through stiff bows and bill clicks", "bargains while rocking heel to heel"), + V("fishes with narrow bill held poised", "fishes through belly-first lunges"), + V("hauls by sliding on the rounded belly", "pushes weight with both broad flippers"), + V("preens wounds with measured bill touches", "tends wounds through soft flipper presses"), + V("rocks beside flames with flippers shielding", "faces fire from a close upright stance"), + V("slides away on the rounded belly", "flees in short rapid waddles"), + V("settles into a shoulder-locked civic huddle", "joins the group with bill facing inward"), + V("drills in stiff bill-and-flipper jabs", "patrols with flippers spread for balance"), + V("reads with the narrow bill tracking lines", "studies while rocking on flat heels"), + V("honks kin into a packed huddle", "slides spoils inward between flippers"), + V("relieves itself from a brief upright squat", "lifts the short tail while relieving itself"), + V("waddles between mismatched duties", "tilts the bill over a confused duty"), + V("recharges with bill tucked under flipper", "rests upright inside the huddle"), + V("slides toward an inexplicable urge", "answers it with both flippers stiff"), + V("pilfers between narrow bill and chest", "waddles away behind spread flippers"), + V("marches possessed without its usual waddle", "the narrow bill honks through rigid steps"), + V("dreams with flippers paddling softly", "dozes while the narrow bill twitches")); + + AddExtended(voices, "civ_piranha", + V("sings in sharp jaw-clicking pulses", "vibrates a fin-beaten civic refrain"), + V("courts through tight synchronized fin loops", "spirals through mating with synchronized tail flicks"), + V("cultivates in darting fin-led passes", "tends growth with quick shearing mouthparts"), + V("pollinates in level fin-guided passes", "darts among blooms without snapping"), + V("trades through flashing jaw-and-fin signals", "bargains in a tightly held hover"), + V("fishes in sudden fin-led lunges", "fishes with jaws poised between tail flicks"), + V("hauls by driving with tail and fins", "bears weight against a compact scaled flank"), + V("tends wounds with closed mouthparts", "hovers level while fins guide each touch"), + V("circles flames in quick snapping turns", "faces fire with fins making tiny corrections"), + V("darts away in a flashing straight burst", "flees with fins clamped close"), + V("settles into a tight fin-aligned civic school", "joins the school through circling ranks"), + V("drills in repeated jaw-first rushes", "patrols through coordinated fin turns"), + V("reads while hovering rigidly level", "tracks lines with quick eye and fin shifts"), + V("clicks kin into a close-moving school", "herds spoils together with snapping turns"), + V("relieves itself during a brief tail-held hover", "flicks away after relieving itself"), + V("circles between contradictory duty signals", "snaps once at a mistaken duty"), + V("recharges nearly motionless on tucked fins", "rests with only the tail tip correcting"), + V("darts after an inexplicable compulsion", "answers it in jaw-clicking loops"), + V("pilfers inside flashing shearing teeth", "veers away behind beating fins"), + V("darts possessed in rigid repeated circuits", "clicks jaws under unseen direction"), + V("dreams with fins making tiny corrections", "rests while the tail flicks in bursts")); + + AddExtended(voices, "civ_rabbit", + V("sings in soft nose-trembling trills", "pipes a long-eared civic refrain"), + V("courts through high twisting leaps", "mates in a compact hind-leg crouch"), + V("cultivates in quick paired-foot passes", "tends growth with nimble forepaws"), + V("pollinates with twitching nose brushes", "bounds among blooms beneath upright ears"), + V("trades through ear tilts and paw taps", "bargains while sitting tall on haunches"), + V("fishes with forepaws held close together", "fishes with long ears laid backward"), + V("hauls in short double-footed bounds", "bears weight against a compact chest"), + V("nuzzles wounds with a trembling nose", "tends wounds between soft forepaws"), + V("hops around flames with ears flattened", "faces fire from a spring-loaded crouch"), + V("zigzags away in rapid paired bounds", "flees with long ears streaming backward"), + V("settles into a close ear-alert formation", "joins the group with quick forepaw taps"), + V("drills in alternating paw-boxing bursts", "patrols through sharp zigzag leaps"), + V("reads with ears rotating above the lines", "studies between two lifted forepaws"), + V("thumps kin into a compact gathering", "draws spoils close with quick paw sweeps"), + V("relieves itself on folded springy haunches", "raises the small tail while relieving itself"), + V("turns each long ear toward a different duty", "hops once toward the mistaken duty"), + V("recharges folded into a tight crouch", "rests with ears laid over the shoulders"), + V("bounds after an unexplained twitching urge", "answers it in ear-streaming hops"), + V("pilfers between two cupped forepaws", "zigzags away with ears low"), + V("boxes possessed at empty space", "leaps under command in rigid doubles"), + V("dreams with hind feet kicking softly", "dozes while long ears rotate")); + + AddExtended(voices, "civ_rat", + V("sings in high whisker-twitching squeaks", "pipes a quick tail-curled civic refrain"), + V("courts through close nose-led circles", "mates in a low nimble crouch"), + V("cultivates in narrow whisker-guided turns", "tends growth with tiny gripping paws"), + V("pollinates with rapid whiskered sniffs", "scurries among blooms on quick toes"), + V("trades through paw rubbing and low squeaks", "bargains with whiskers pitched forward"), + V("fishes with both small paws poised", "fishes from a tail-balanced squat"), + V("hauls backward in a firm tooth-grip", "draws weight with the long tail balancing"), + V("grooms wounds between tiny moving paws", "tends wounds through alternating paw presses"), + V("sniffs around flames with whiskers recoiling", "faces fire from a low paw-ready crouch"), + V("scurries away through narrow turns", "flees with tail drawn straight"), + V("settles into a whisker-touching civic cluster", "joins the group through tight scurrying runs"), + V("drills in low darting bites", "patrols nose-first along every edge"), + V("reads with one paw tracking the line", "studies while whiskers sweep side to side"), + V("squeaks kin into a tail-linked cluster", "sorts spoils rapidly between both paws"), + V("relieves itself from a low tail-lifted squat", "combs whiskers after relieving itself"), + V("scurries between mismatched duties", "rubs both paws over a confused duty"), + V("recharges curled tightly around the tail", "rests with whiskers tucked to the chest"), + V("follows an odd nose-led compulsion", "scurries through it in whisker-led bursts"), + V("pilfers beneath the chest in small paws", "scurries away with whiskers flat"), + V("moves possessed in sharp repeated darts", "squeaks beneath unseen direction"), + V("dreams with paws sorting empty air", "sleeps while whiskers and tail twitch")); + + AddExtended(voices, "civ_rhino", + V("sings in rough horn-backed bellows", "rumbles a thick-chested civic note"), + V("courts through heavy horn-side head sweeps", "mates on four massively planted feet"), + V("cultivates in deep hoof-timed passes", "tends growth beneath a lowered horn"), + V("pollinates with the broad lower lip", "walks between blooms behind an angled horn"), + V("trades through blunt horn-and-ear gestures", "bargains from an immovable stance"), + V("fishes with the horn angled aside", "fishes through thick shoulder thrusts"), + V("hauls behind a massive pushing brow", "drives weight on pounding broad feet"), + V("nudges wounds with the broad lower lip", "tends wounds while standing hide-outward"), + V("faces flames behind a lowered horn", "stamps around fire in heavy arcs"), + V("thunders away with horn held level", "flees on pounding thick legs"), + V("settles into a hide-and-horn civic barrier", "joins the formation through massive hoof presses"), + V("drills in direct horn-led charges", "patrols with thick hide facing outward"), + V("reads with small eyes close to the lines", "studies beneath the shadow of the horn"), + V("bellows kin into a heavy defensive ring", "pushes spoils together with the broad snout"), + V("relieves itself on widely braced thick legs", "raises the short tail while relieving itself"), + V("swings the horn between conflicting duties", "stamps over an obviously mistaken duty"), + V("recharges in a massive folded crouch", "rests with thick chin against the chest"), + V("charges after an inexplicable inner pull", "answers it with the heavy horn lowered"), + V("pilfers behind the lowered heavy horn", "backs away on heavy guarded feet"), + V("stomps possessed in an unbroken straight line", "obeys unseen direction without turning"), + V("dreams with broad feet grinding softly", "dozes while the heavy horn tilts")); + + AddExtended(voices, "civ_scorpion", + V("sings in dry pincer-clicking measures", "rasps a tail-arched civic refrain"), + V("courts through mirrored claw and tail waves", "mates beneath crossed and lifted stingers"), + V("cultivates in eight-legged segmented passes", "tends growth between paired pincers"), + V("pollinates with delicate claw-tip touches", "skitters among blooms beneath a curled tail"), + V("trades through exact pincer signals", "bargains with stinger held ceremonially high"), + V("fishes with paired claws poised", "fishes beneath a balancing arched tail"), + V("hauls between locking heavy pincers", "draws weight on eight gripping feet"), + V("tends wounds with fine claw tips", "keeps the stinger clear and treats wounds"), + V("faces flames behind raised pincers", "tests fire beneath a tightly curled tail"), + V("skitters away with stinger flattened", "flees on eight rapid jointed feet"), + V("settles into a claw-outward civic circle", "aligns tail arches across the formation"), + V("drills in pincer grabs and stinger feints", "patrols with eight feet keeping cadence"), + V("reads with both claws held level", "studies beneath a motionless stinger"), + V("clicks kin into a pincer-linked group", "draws spoils inward with paired claws"), + V("relieves itself on spread rear legs", "lifts the arched tail while relieving itself"), + V("turns pincers toward conflicting duties", "trembles the stinger over a confused duty"), + V("recharges with limbs folded under armor", "rests beneath the tail's tight curve"), + V("skitters after a strange claw-led impulse", "answers it beneath a poised stinger"), + V("pilfers between tightly clasped pincers", "backs away beneath the raised tail"), + V("marches possessed on rigid synchronized legs", "strikes empty air under unseen command"), + V("dreams with pincers clicking softly", "sleeps while the curled tail tightens")); + + AddExtended(voices, "civ_seal", + V("sings in bouncing whiskered barks", "honks a broad-flippered civic tune"), + V("courts through rolling flipper claps", "presses belly-down with flippers during mating"), + V("cultivates in low galumphing passes", "tends growth with broad flipper sweeps"), + V("pollinates with soft whiskered nose touches", "flops among blooms on broad flippers"), + V("trades through claps and whisker-led nods", "bargains while balanced upright"), + V("fishes with whiskers pitched forward", "fishes through sleek rolling body turns"), + V("hauls by sliding on the broad belly", "pushes weight with paired flippers"), + V("nuzzles wounds with a whiskered muzzle", "tends wounds using soft flipper presses"), + V("claps around flames from a low position", "faces fire with whiskers drawn back"), + V("galumphs away in rolling lunges", "flees belly-low on beating flippers"), + V("settles into a close whisker-touching cohort", "joins the cohort with broad flipper strokes"), + V("drills in rolling body-first charges", "patrols with alternating flipper strokes"), + V("reads propped upright on the belly", "tracks lines with whiskers almost touching"), + V("barks kin into a flipper-close gathering", "sweeps spoils inward across the belly"), + V("relieves itself from a low tail-lifted crouch", "claps once after relieving itself"), + V("rolls between duties with whiskers askew", "flops toward an obviously mistaken duty"), + V("recharges in a loose whiskered curl", "rests with nose against the tail"), + V("galumphs after a baffling impulse", "answers it through whiskered flipper claps"), + V("pilfers beneath one broad flipper", "slides away belly-first"), + V("flops possessed in exact repeated rolls", "whiskered barks punctuate each compelled roll"), + V("dreams with broad flippers paddling", "dozes while whiskers tremble")); + + AddExtended(voices, "civ_sheep", + V("sings in soft fleece-muffled bleats", "warbles with woolly chest trembling"), + V("courts through close wool-brushing circles", "mates on four softly planted feet"), + V("cultivates in even fleece-bobbing passes", "tends growth with small repeated bites"), + V("pollinates with a soft wool-framed muzzle", "steps among blooms beneath drooping ears"), + V("trades through low bleats and brow dips", "bargains while fleece settles around the stance"), + V("fishes with wool held clear of the reach", "fishes from four close-set hooves"), + V("hauls against a thickly padded shoulder", "draws weight in even woolly steps"), + V("nuzzles wounds through soft fleece", "tends wounds with a slow narrow muzzle"), + V("edges around flames with wool pulled back", "faces fire behind a lowered thick brow"), + V("bounds away with fleece bouncing", "flees on close quick hooves"), + V("settles into a shoulder-tight civic flock", "joins the flock in a fleece-close cluster"), + V("drills in thick-browed rushing turns", "patrols with woolly flanks kept together"), + V("reads with muzzle beneath the woolly fringe", "studies while drooping ears hold still"), + V("bleats kin into a fleece-packed group", "nudges spoils inward with the soft brow"), + V("relieves itself on folded hind legs", "holds the woolly tail aside while relieving itself"), + V("turns drooping ears between mistaken duties", "nibbles uncertainly at the wrong duty"), + V("recharges folded into deep fleece", "rests with muzzle against one woolly flank"), + V("follows a strange flockless compulsion", "answers it on fleece-muted quick steps"), + V("pilfers beneath thick overlapping fleece", "trots away with ears low"), + V("marches possessed without flock formation", "fleece shivers through compelled steps"), + V("dreams with fleece shivering lightly", "dozes while small hooves twitch")); + + AddExtended(voices, "civ_snake", + V("sings in long coiling hisses", "rattles a winding civic refrain"), + V("courts through paired rising coils", "mates in closely interwoven loops"), + V("cultivates in smooth coiling curves", "tends growth with a flicking tongue"), + V("pollinates with repeated tongue-tip tests", "winds among blooms in polished curves"), + V("trades through poised head and coil gestures", "bargains with tongue flicking in measured beats"), + V("fishes from a motionless raised coil", "fishes through a single coil-driven strike"), + V("hauls by winding loops around the weight", "draws backward through muscular coils"), + V("wraps wounds in a loose supporting loop", "tends wounds with repeated tongue tests"), + V("coils beside flames with head raised", "tests fire through rapid tongue flicks"), + V("flows away in tightening curves", "flees with head low and coils lengthened"), + V("settles into a low interlocking civic coil", "links the group through overlapping loops"), + V("drills in sudden coil-driven strikes", "patrols in silent looping curves"), + V("reads with tongue tracking each line", "studies from a neatly raised coil"), + V("hisses kin into an overlapping knot", "winds spoils together inside broad loops"), + V("relieves itself with the rear coils straightened", "recoils compactly after relieving itself"), + V("loops between contradictory duty cues", "raises the head over a confused duty"), + V("recharges knotted into compact coils", "rests beneath overlapping muscular loops"), + V("winds after a strange tongue-led impulse", "coils through it in repeated curves"), + V("pilfers inside one tightening loop", "flows away without a sound"), + V("strikes possessed at empty space", "coils under command in rigid symmetry"), + V("dreams with tongue flicking silently", "sleeps while polished coils tighten")); + + AddExtended(voices, "civ_turtle", + V("sings in slow shell-deep tones", "wheezes a measured beak-led refrain"), + V("courts through slow shell-to-shell circles", "mates on four widely braced feet"), + V("cultivates in shell-shadowed passes", "tends growth with a clipping beaked mouth"), + V("pollinates with slow beak-tip touches", "plods among blooms beneath the ridged shell"), + V("trades through long nods over the shell rim", "bargains without changing its planted stance"), + V("fishes with beak poised beyond the shell", "fishes through slow shell-paced reaches"), + V("hauls beneath the weight-bearing shell", "draws steadily on short braced legs"), + V("nudges wounds with a slow hooking beak", "extends incrementally from the shell and treats wounds"), + V("faces flames from behind the shell rim", "tests fire with the beak then withdraws"), + V("plods away before drawing limbs inward", "flees under the protection of the shell"), + V("settles into a slow shell-rimmed civic ring", "joins the ring through repeated circuits"), + V("drills in shell-braced forward shoves", "patrols without breaking its measured pace"), + V("reads with chin resting on the shell rim", "tracks lines using slow beak movements"), + V("calls kin into a ridged-shell cluster", "pushes spoils together with the shell edge"), + V("relieves itself on short firmly planted legs", "extends the rear beyond the shell to relieve itself"), + V("turns slowly between conflicting duties", "withdraws halfway over a confused duty"), + V("recharges fully enclosed by the shell", "rests with chin on the ridged rim"), + V("plods after an inexplicable inner direction", "answers it through shell-paced steps"), + V("pilfers with a slow hooking beak", "withdraws behind the shell"), + V("marches possessed at an unnatural pace", "extends under command with eyes fixed"), + V("dreams with limbs shifting inside the shell", "sleeps while the beaked mouth moves")); + + AddExtended(voices, "civ_unicorn", + V("sings in clear horn-lifted tones", "trills while the long mane settles"), + V("courts through high-stepping mane tosses", "mates on four high-braced legs"), + V("cultivates in high-hoofed passes", "tends growth beneath a lifted horn"), + V("pollinates with the horn tip held aside", "steps among blooms on light raised hooves"), + V("trades through high horn-led bows", "bargains with mane and tail held still"), + V("fishes with horn angled above the stance", "fishes on lightly planted high hooves"), + V("hauls through a high arched neck", "draws weight in high even steps"), + V("tends wounds beneath the horn tip", "tends wounds with slow muzzle nudges"), + V("circles flames with mane drawn clear", "faces fire behind a level pointed horn"), + V("gallops away with mane streaming", "flees in long horn-forward strides"), + V("settles into a horn-outward civic formation", "joins it through high hoof circuits"), + V("drills in poised horn-led charges", "patrols with lifted hooves and neck arched"), + V("reads with the horn held straight", "studies while the mane falls to one side"), + V("trills kin into a high-stepping group", "draws spoils together with alternating hoof nudges"), + V("relieves itself on lightly flexed hind legs", "holds the flowing tail clear while relieving itself"), + V("tosses the mane between opposing duties", "angles the horn over a confused duty"), + V("recharges with long legs folded evenly", "rests beneath a mane spread along the neck"), + V("canters after a strange inward summons", "answers it with horn held high"), + V("pilfers beneath a lifted narrow chin", "prances away behind the leveled horn"), + V("gallops possessed in severe straight lines", "the rigid mane follows each compelled stride"), + V("dreams with long hooves stepping softly", "dozes while the horn and mane tilt")); + + AddExtended(voices, "civ_wolf", + V("sings in long muzzle-raised howls", "carries a shoulder-deep pack refrain"), + V("courts through close muzzle-and-flank circles", "mates on firmly braced hind legs"), + V("cultivates in coordinated pack-timed passes", "tends growth as paws alternate in formation"), + V("pollinates with scenting muzzle passes", "ranges among blooms on quiet paws"), + V("trades through low growls and ear signals", "bargains from a shoulder-close stance"), + V("fishes with muzzle poised and paws spread", "fishes through a swift jaw-led lunge"), + V("hauls in a firm jaw-held formation", "draws weight with rolling shoulders"), + V("licks wounds with slow repeated strokes", "tends wounds while standing flank-outward"), + V("circles flames with muzzle testing the air", "faces fire behind a low shoulder guard"), + V("ranges away in long driving strides", "flees with ears flat and tail low"), + V("settles into a close shoulder-linked formation", "joins it through pack-timed circuits"), + V("drills in coordinated flanking rushes", "patrols with shoulders rolling in formation"), + V("reads with muzzle between both forepaws", "studies while ears track every pause"), + V("howls kin into a shoulder-close pack", "gathers spoils within a guarded ring"), + V("relieves itself with one hind leg lifted", "tests the air after relieving itself"), + V("turns ears toward contradictory duties", "circles an obviously mistaken duty"), + V("recharges curled muzzle-to-flank", "rests with tail wrapped over the paws"), + V("ranges after a strange solitary compulsion", "breaks pack formation through compelled strides"), + V("pilfers in quick closing jaws", "slips away with flank held low"), + V("runs possessed without pack signals", "the raised muzzle howls through rigid strides"), + V("dreams with paws coursing in place", "sleeps through low muzzle-rumbles")); + + AddExtended(voices, "dwarf", + V("sings in beard-shaking chest notes", "booms a compact marching refrain"), + V("courts through stout forearm clasps", "mates on short powerfully braced legs"), + V("cultivates in short forceful passes", "tends growth with beard tucked close"), + V("pollinates with thick fingertip taps", "moves bloom to bloom on compact strides"), + V("trades through blunt palm and beard gestures", "bargains with thick arms folded"), + V("fishes from a low immovable stance", "fishes with short beard-braced pulls"), + V("hauls against a stout shoulder", "bears weight on short driving legs"), + V("braces wounds with thick forearms", "tends wounds through compact hand presses"), + V("faces flames with beard gathered close", "handles fire from a deep braced crouch"), + V("retreats in short pounding strides", "flees with beard and elbows tucked"), + V("settles into a tightly joined civic formation", "aligns with it from a stout square stance"), + V("drills in compact hammering blows", "patrols with fists at a low guard"), + V("reads with one thick finger under each line", "studies above a beard spread on the chest"), + V("booms kin into a forearm-linked gathering", "stacks spoils in compact ordered groups"), + V("relieves the body from a stout squat", "straightens the beard after relieving itself"), + V("stamps between two conflicting duties", "pulls the beard over a confused duty"), + V("recharges in a short solid curl", "rests beneath a beard spread wide"), + V("marches after an inexplicable compulsion", "answers it with beard and jaw set"), + V("pilfers with thick compact fingers", "backs away behind folded forearms"), + V("stomps possessed in a harsh compact cadence", "marches under command with beard rigid"), + V("dreams with thick fists closing softly", "sleeps while short legs brace")); + + AddExtended(voices, "elf", + V("sings in clear long-breathed phrases", "threads a light civic melody"), + V("courts through poised fingertip bows", "mates in a light long-limbed embrace"), + V("cultivates in near-silent even passes", "tends growth with long alternating fingers"), + V("pollinates with delicate fingertip brushes", "steps among blooms without stirring them"), + V("trades through small repeated hand signs", "bargains with head lightly inclined"), + V("fishes from a silent balanced stance", "fishes in fine long-fingered arcs"), + V("hauls with long arms held evenly", "bears weight on light measured steps"), + V("tends wounds with slender steady hands", "leans close and treats wounds in small touches"), + V("faces flames with long fingers held clear", "handles fire through silent measured gestures"), + V("withdraws in quick near-silent steps", "flees with long limbs gathered close"), + V("settles into a quietly ordered civic formation", "joins it through light even pacing"), + V("drills in swift narrow strikes", "patrols without sound on balanced feet"), + V("reads with a long finger tracing lines", "studies while head remains lightly bowed"), + V("calls kin together in a clear low phrase", "arranges spoils with slender exact fingers"), + V("relieves the body in a poised crouch", "rises lightly after relieving itself"), + V("tilts the head between incompatible duties", "places long fingers over a mistaken duty"), + V("recharges with limbs folded in balance", "rests through slow controlled breaths"), + V("glides after a strange inward prompting", "answers it with long fingers tracing silently"), + V("pilfers on light slender fingers", "steps away without a sound"), + V("moves possessed in severe straight measures", "obeys unseen direction without blinking"), + V("dreams with long fingers tracing the air", "sleeps while light feet shift")); + + AddExtended(voices, "human", + V("sings in open breath-shaped phrases", "keeps rhythm with alternating hand taps"), + V("courts through close face-to-face gestures", "mates in a balanced two-armed embrace"), + V("cultivates in brisk alternating passes", "tends growth as both hands alternate"), + V("pollinates with alternating fingertip touches", "moves between blooms on steady feet"), + V("trades through animated hand bargaining", "negotiates with eyes fixed on the exchange"), + V("fishes with both hands held ready", "fishes through steady alternating arm pulls"), + V("hauls with shoulders and knees aligned", "bears weight between both arms"), + V("braces wounds with both hands", "kneels close and tends each wound"), + V("faces flames with forearms shielding", "handles fire from a balanced crouch"), + V("runs away with arms driving hard", "flees in quick alternating strides"), + V("settles into a hand-linked civic formation", "joins it through paced alternating turns"), + V("drills through balanced alternating hand strikes", "patrols with eyes and shoulders forward"), + V("reads with one finger tracking the line", "studies while shifting weight between feet"), + V("calls kin into an arm-linked gathering", "sorts spoils between quick alternating hands"), + V("relieves the body from a low squat", "stands and adjusts posture after relieving itself"), + V("hesitates between two incompatible duties", "starts the wrong duty before stopping"), + V("recharges with knees drawn close", "rests through slow even breaths"), + V("walks after an inexplicable duty impulse", "answers it with alternating hand sweeps"), + V("pilfers in one quick palm sweep", "backs away with hands held close"), + V("moves possessed in stiff alternating steps", "marches beneath unseen direction"), + V("dreams with fingers and eyelids twitching", "sleeps while feet make tiny steps")); + + AddExtended(voices, "orc", + V("sings in tusk-bared booming chants", "pounds a broad chest through the refrain"), + V("courts through heavy forearm clashes", "mates on wide powerfully braced legs"), + V("cultivates in forceful shoulder-driven passes", "tends growth with broad hands and tusks high"), + V("pollinates with repeated knuckle touches", "moves among blooms on heavy feet"), + V("trades through loud tusk-framed bargaining", "negotiates with fists open at the sides"), + V("fishes from a deep shoulder-heavy crouch", "fishes through hard two-armed pulls"), + V("hauls against one massive shoulder", "heaves weight with both thick arms"), + V("braces wounds with broad hands", "tends wounds behind a tusk-bared guard"), + V("faces flames with fists raised", "handles fire while keeping tusks and chest clear"), + V("pounds away in long heavy strides", "flees with shoulders hunched and tusks forward"), + V("settles into a forearm-locked civic formation", "joins it through heavy heel stamps"), + V("drills in chopping fist-and-forearm blows", "patrols with tusks high and shoulders broad"), + V("reads with one heavy finger under the lines", "studies while tusks frame a lowered jaw"), + V("bellows kin into a shoulder-packed gathering", "heaves spoils into a guarded grouping"), + V("relieves the body from a deep wide squat", "rises with fists braced after relieving itself"), + V("growls between conflicting duties", "headbutts toward an obviously mistaken duty"), + V("recharges in a heavy loose sprawl", "rests with one fist closed against the chest"), + V("stalks after a strange compelling duty", "answers it with tusks and fists clenched"), + V("pilfers in one broad sweeping hand", "backs away behind raised forearms"), + V("marches possessed with fists locked", "strikes empty air beneath unseen command"), + V("dreams with tusks bared and fists flexing", "sleeps through low chest-deep growls")); + } +} diff --git a/IdleSpectator/ActivitySpeciesVoices.Civs.Specialized.cs b/IdleSpectator/ActivitySpeciesVoices.Civs.Specialized.cs new file mode 100644 index 0000000..590ed5a --- /dev/null +++ b/IdleSpectator/ActivitySpeciesVoices.Civs.Specialized.cs @@ -0,0 +1,351 @@ +using System.Collections.Generic; + +namespace IdleSpectator; + +public static partial class ActivitySpeciesVoiceCatalog +{ + private static void AddCivSpecializedVoices(Dictionary voices) + { + AddSpecialized(voices, "civ_acid_gentleman", + V("flicks a caustic spark into flame", "draws a green flame between rigid fingertips"), + V("presses both palms down against the flame", "sweeps a rigid forearm across the flames"), + V("bows into a gathering circle", "beckons the family together with one formal hand"), + V("draws a soul upward in an emerald strand", "coaxes life essence between poised fingers"), + V("searches the spoils with precise fingertips", "lifts spoils with a measured bow"), + V("weeps behind one upright hand", "releases a clipped, trembling sob"), + V("snaps out a curse through clenched teeth", "cuts the air with a rigid, scolding finger")); + + AddSpecialized(voices, "civ_alpaca", + V("puffs a bright flame from pursed lips", "kicks a spark into a spreading flame"), + V("stamps broad feet through the flames", "presses a woolly chest down against the flame"), + V("hums while joining the herd", "nudges the family into a close cluster"), + V("draws a soul along a curling breath", "pulls life essence between soft lips"), + V("sniffs through the spoils", "hooks spoils closer with one forefoot"), + V("warbles through a streaming nose", "folds long ears through a breathy sob"), + V("spits a sharp curse through soft lips", "stamps both forefeet while swearing")); + + AddSpecialized(voices, "civ_armadillo", + V("strikes plated claws into a flickering flame", "rolls a spark into a widening flame"), + V("rakes low claws across the flames", "presses a plated curl against the flame"), + V("uncurls among the gathering family", "trundles into a shell-to-shell group"), + V("draws a soul beneath overlapping plates", "cups life essence between curved claws"), + V("snuffles through the spoils", "rakes spoils beneath a plated forearm"), + V("chitters through a tightly curled body", "rocks inside the shell with dry sobs"), + V("clacks out a curse from a half-curl", "scrapes both claws while swearing")); + + AddSpecialized(voices, "civ_bear", + V("claps broad paws around a newborn flame", "rakes a spark into a rising flame"), + V("beats heavy paws against the flames", "presses a broad forepaw over the flame"), + V("lumbers into the gathered family", "pulls the group close with both forelegs"), + V("draws a soul between cupped paws", "inhales life essence with a deep rumble"), + V("sniffs heavily through the spoils", "scoops spoils between broad paws"), + V("roars through a shaking muzzle", "covers the eyes with both paws and sobs"), + V("bellows a curse through bared teeth", "swears with both paws raised")); + + AddSpecialized(voices, "civ_beetle", + V("rasps wing cases until a flame sparks", "clicks a bright flame between hooked feet"), + V("fans rigid wing cases against the flames", "scrapes jointed feet across the flame"), + V("clicks while entering the gathered group", "fits carapace to carapace among the family"), + V("draws a soul between trembling antennae", "guides life essence beneath the wing case"), + V("feels through the spoils with both antennae", "clasps spoils between hooked feet"), + V("rattles the wing case through thin cries", "folds every leg beneath a clicking sob"), + V("rasps out a curse with snapping mouthparts", "jabs both antennae while swearing")); + + AddSpecialized(voices, "civ_buffalo", + V("strikes both horns into a bursting flame", "snorts a spark into a broad flame"), + V("stamps heavy hooves across the flames", "sweeps lowered horns through the flame"), + V("shoulders into the gathered herd", "calls the family into a horn-ringed group"), + V("draws a soul between curved horns", "pulls life essence into a deep breath"), + V("roots through the spoils with a broad muzzle", "hooks spoils inward with one horn"), + V("bellows with tears streaking the muzzle", "bows the heavy head through rumbling sobs"), + V("snorts out a rolling curse", "slashes both horns in a sharp arc while swearing")); + + AddSpecialized(voices, "civ_candy_man", + V("snaps glossy fingers into a sparkling flame", "spins a bright flame from striped palms"), + V("claps glossy hands around the flame", "pats quick palms across the flames"), + V("twirls into the gathering family", "waves the group into a striped circle"), + V("draws a soul through spiraling fingers", "winds life essence around glossy hands"), + V("taps through the spoils with glossy fingertips", "tucks spoils against a striped chest"), + V("crackles through a high, wet sob", "covers glossy eyes with trembling hands"), + V("snaps out a brittle curse", "wags a striped finger while swearing")); + + AddSpecialized(voices, "civ_capybara", + V("nudges a spark into a low flame", "breathes steadily until a flame catches"), + V("presses broad forepaws against the flames", "rolls a blunt muzzle across the flame"), + V("ambles into the gathered family", "settles flank-first among the group"), + V("draws a soul beneath a blunt chin", "pulls life essence between cupped forepaws"), + V("sniffs slowly through the spoils", "draws spoils close between both forepaws"), + V("squeaks through streaming eyes", "rests the muzzle low through bubbling sobs"), + V("chatters out a blunt curse", "slaps one broad forepaw while swearing")); + + AddSpecialized(voices, "civ_cat", + V("strikes a claw-tip spark into flame", "whips a spark into a rising flame"), + V("bats quick paws against the flames", "presses both forepaws over the flame"), + V("threads into the gathered family", "winds tail-first through the group"), + V("draws a soul between hooked claws", "laps life essence from the air"), + V("paws silently through the spoils", "hooks spoils beneath one forepaw"), + V("yowls with whiskers wet", "hides the face beneath both paws and sobs"), + V("hisses a curse through flattened whiskers", "lashes the tail while swearing")); + + AddSpecialized(voices, "civ_chicken", + V("scratches a spark into a darting flame", "flaps a small flame into a wider blaze"), + V("scratches both feet across the flames", "beats spread wings against the flame"), + V("clucks while joining the gathered group", "calls the family into a feathered group"), + V("draws a soul beneath a lifted beak", "pecks life essence into a pulsing strand"), + V("scratches briskly through the spoils", "pecks spoils into reach"), + V("keens with the beak held open", "tucks the face beneath one wing and sobs"), + V("squawks out a clipped curse", "spurs the air while swearing")); + + AddSpecialized(voices, "civ_cow", + V("scuffs a hoof-spark into a steady flame", "blows a low flame into a broad flare"), + V("tramples heavy hooves through the flames", "sweeps a broad muzzle against the flame"), + V("lows while joining the gathered herd", "presses shoulder-first into the family group"), + V("draws a soul between wide nostrils", "pulls life essence beneath a heavy brow"), + V("sniffs through the spoils with a broad muzzle", "nudges spoils between split hooves"), + V("moans with tears tracing the muzzle", "bows the head through long, shaking sobs"), + V("bellows a deep curse", "stamps one split hoof while swearing")); + + AddSpecialized(voices, "civ_crab", + V("clacks both claws into a snapping flame", "fans a spark into a sideways flame"), + V("presses both claws against the flames", "rakes jointed legs across the flame"), + V("sidesteps into the gathered family", "waves the group into a shell-close cluster"), + V("draws a soul between raised pincers", "pulls life essence beneath the shell"), + V("probes the spoils with both claws", "pinches spoils between polished pincers"), + V("bubbles through a shuddering shell", "covers both eyestalks with trembling claws"), + V("clacks out a jagged curse", "brandishes both pincers while swearing")); + + AddSpecialized(voices, "civ_crocodile", + V("snaps broad jaws around a sudden flame", "whips a spark into a crawling flame"), + V("beats the flames with a plated tail", "presses a broad jaw against the flame"), + V("slides into the gathered family", "rumbles the group into a flank-close line"), + V("draws a soul between parted jaws", "pulls life essence beneath plated eyelids"), + V("sniffs low through the spoils", "drags spoils beneath one foreleg"), + V("rumbles with tears beneath plated lids", "rests the jaw low through heaving sobs"), + V("growls a curse through locked teeth", "lashes the tail while swearing")); + + AddSpecialized(voices, "civ_dog", + V("scratches a paw-spark into lively flame", "pants a small flame into a wider flare"), + V("digs both forepaws across the flames", "beats the flame with quick paw strokes"), + V("bounds into the gathered family", "calls the group into a nose-close cluster"), + V("draws a soul along a lifted muzzle", "laps life essence from a wavering strand"), + V("sniffs rapidly through the spoils", "pulls spoils closer between both paws"), + V("whines with tears on the muzzle", "covers the nose with both paws and sobs"), + V("barks out a sharp curse", "stamps alternating paws while swearing")); + + AddSpecialized(voices, "civ_fox", + V("flicks a black paw into a slender flame", "sweeps a spark into a spreading flame"), + V("beats the flames with a broad tail", "scrapes quick forepaws across the flame"), + V("slips into the gathered family", "curls tail-to-tail among the group"), + V("draws a soul around the tail tip", "pulls life essence between narrow jaws"), + V("sniffs sidelong through the spoils", "hooks spoils closer with one black paw"), + V("barks through wet whiskers", "folds the tail over the face and sobs"), + V("spits a quick curse through narrow teeth", "slashes the tail sideways while swearing")); + + AddSpecialized(voices, "civ_frog", + V("flicks a tongue-spark into a bobbing flame", "inflates the throat and blows up a flame"), + V("slaps broad hands against the flames", "presses a broad tongue over the flame"), + V("hops into the gathered family", "croaks the group into a squat circle"), + V("draws a soul along the tongue", "pulls life essence into a pulsing throat"), + V("prods through the spoils with long fingers", "flicks spoils closer with the tongue"), + V("croaks through streaming round eyes", "folds low beneath a throbbing sob"), + V("ribbits out a booming curse", "slaps both hands down while swearing")); + + AddSpecialized(voices, "civ_garlic_man", + V("rubs papery fingers into a crackling flame", "fans a spark into layered flame"), + V("beats loose layers against the flames", "presses knobby hands over the flame"), + V("rustles into the gathering family", "bundles the group into a layered cluster"), + V("draws a soul between folded layers", "wraps life essence around knobby fingers"), + V("rustles through the spoils with both hands", "tucks spoils beneath folded layers"), + V("crinkles through a dry, shaking sob", "covers the face with papery hands and weeps"), + V("crackles out a jagged curse", "shakes both knobby fists while swearing")); + + AddSpecialized(voices, "civ_goat", + V("strikes split hooves into a jumping flame", "tosses a horn-spark into spreading flame"), + V("stamps split hooves across the flames", "sweeps curled horns through the flame"), + V("bounds into the gathered herd", "butts shoulder-first into the family group"), + V("draws a soul between curled horns", "pulls life essence beneath a lifted chin"), + V("noses quickly through the spoils", "hooks spoils closer with one horn"), + V("bleats with tears on the muzzle", "bows between sharp, shaking sobs"), + V("brays out a rasping curse", "clatters both forehooves while swearing")); + + AddSpecialized(voices, "civ_hyena", + V("scrapes broad jaws into a crackling flame", "kicks a spark into a loping flame"), + V("rakes heavy forepaws through the flames", "snaps broad jaws against the flame"), + V("whoops while joining the gathered family", "shoulders into the close group"), + V("draws a soul between crushing jaws", "pulls life essence along a rising whoop"), + V("sniffs in circles through the spoils", "drags spoils close beneath one paw"), + V("whoops through streaming eyes", "folds sloping shoulders around broken sobs"), + V("cackles out a coarse curse", "snaps broad jaws while swearing")); + + AddSpecialized(voices, "civ_lemon_man", + V("rubs pointed fingers into a fizzing flame", "sprays a spark into a sharp flame"), + V("presses rounded palms against the flames", "rolls a pointed crown across the flame"), + V("bounces into the gathering family", "pivots the group into a rind-close circle"), + V("draws a soul around the pointed crown", "presses life essence between rounded palms"), + V("taps through the spoils with pointed fingers", "rolls spoils closer with both hands"), + V("squeaks through streaming eyes", "folds both hands over the face and sobs"), + V("spits out a sharp curse", "jabs the pointed crown forward while swearing")); + + AddSpecialized(voices, "civ_liliar", + V("rubs slender leaves into a silver flame", "unfurls a spark into layered flame"), + V("folds broad frills against the flames", "lashes sharpened leaves across the flame"), + V("glides into the gathering family", "unfurls the group into a facing circle"), + V("draws a soul along a supple stem", "folds life essence between layered frills"), + V("sifts through the spoils with slender fingers", "draws spoils beneath layered arms"), + V("chimes through trembling frills", "folds slender hands over the face and sobs"), + V("trills out a cutting curse", "flicks sharpened leaves while swearing")); + + AddSpecialized(voices, "civ_monkey", + V("claps long hands into a flashing flame", "whips a spark into a growing flame"), + V("slaps broad palms against the flames", "presses a curling tail over the flame"), + V("swings into the gathered family", "chatters the group into a long-armed cluster"), + V("draws a soul around a curling tail", "pulls life essence between cupped hands"), + V("picks rapidly through the spoils", "grasps spoils with hands and tail"), + V("howls with both hands over wet eyes", "curls the tail tight through chattering sobs"), + V("shrieks out a tumbling curse", "slaps both palms while swearing")); + + AddSpecialized(voices, "civ_penguin", + V("claps stiff flippers into a small flame", "pecks a spark into a rising flame"), + V("slaps broad flippers against the flames", "presses a rounded belly over the flame"), + V("waddles into the gathered family", "honks the group into a shoulder-close huddle"), + V("draws a soul along a narrow bill", "folds life essence between stiff flippers"), + V("pecks through the spoils", "slides spoils between both flippers"), + V("honks with tears along the bill", "hides the face beneath one flipper and sobs"), + V("squawks out a clipped curse", "claps both flippers while swearing")); + + AddSpecialized(voices, "civ_piranha", + V("snaps bright teeth into a darting flame", "flicks the tail and spreads a thin flame"), + V("presses quick fins against the flames", "lashes a narrow tail over the flame"), + V("darts into the gathered family", "clicks the group into a tight-finned cluster"), + V("draws a soul between flashing teeth", "pulls life essence past pulsing gills"), + V("nips rapidly through the spoils", "tugs spoils between sharp teeth"), + V("chatters through trembling gills", "bows the head through thin, clicking sobs"), + V("snaps out a staccato curse", "bares flashing teeth while swearing")); + + AddSpecialized(voices, "civ_rabbit", + V("scratches quick paws into a hopping flame", "kicks a spark into a spreading flame"), + V("beats long ears against the flames", "scrapes both forepaws across the flame"), + V("bounds into the gathered family", "thumps the group into an ear-close cluster"), + V("draws a soul between upright ears", "pulls life essence beneath a twitching nose"), + V("sniffs rapidly through the spoils", "cups spoils between both forepaws"), + V("sniffles with long ears folded low", "covers the nose with both paws and sobs"), + V("thumps out a sharp curse", "boxes the air while swearing")); + + AddSpecialized(voices, "civ_rat", + V("scratches nimble claws into a thin flame", "whips a spark into a spreading flame"), + V("rakes both forepaws across the flames", "presses a bare tail over the flame"), + V("scurries into the gathered family", "squeaks the group into a whisker-close cluster"), + V("draws a soul along trembling whiskers", "winds life essence around a bare tail"), + V("sniffs quickly through the spoils", "pulls spoils close between nimble paws"), + V("squeals with whiskers dripping", "wrings both paws through rapid sobs"), + V("shrills out a jagged curse", "lashes the tail while swearing")); + + AddSpecialized(voices, "civ_rhino", + V("drives the horn-tip into a bursting flame", "stomps a spark into a broad flame"), + V("tramples heavy feet through the flames", "sweeps the thick horn across the flame"), + V("stomps into the gathered herd", "shoulders the family into a horn-outward group"), + V("draws a soul along the heavy horn", "pulls life essence beneath thick eyelids"), + V("roots heavily through the spoils", "hooks spoils closer with the horn"), + V("bellows with tears beneath thick lids", "bows the heavy head through booming sobs"), + V("snorts out a crushing curse", "stamps both feet while swearing")); + + AddSpecialized(voices, "civ_scorpion", + V("strikes the stinger into a green flame", "clacks both pincers into a spreading flame"), + V("rakes eight feet across the flames", "snips raised pincers against the flame"), + V("skitters into the gathered family", "clicks the group into a tail-outward ring"), + V("draws a soul along the arched stinger", "pulls life essence between heavy pincers"), + V("feels through the spoils with both claws", "clasps spoils between heavy pincers"), + V("clicks through a trembling plated body", "folds both pincers over the face and sobs"), + V("rasps out a dry curse", "jabs the arched stinger while swearing")); + + AddSpecialized(voices, "civ_seal", + V("claps broad flippers into a bouncing flame", "barks a spark into a rising flame"), + V("slaps both flippers against the flames", "rolls a broad belly across the flame"), + V("galumphs into the gathered family", "barks the group into a whisker-close cluster"), + V("draws a soul along trembling whiskers", "folds life essence between broad flippers"), + V("sniffs through the spoils", "draws spoils close with both flippers"), + V("barks with tears dripping from whiskers", "covers the face with both flippers and sobs"), + V("honks out a blunt curse", "claps both flippers while swearing")); + + AddSpecialized(voices, "civ_sheep", + V("strikes split hooves into a soft flame", "puffs a spark into a widening flame"), + V("stamps split hooves across the flames", "presses thick fleece against the flame"), + V("bleats while joining the gathered herd", "nestles into the family group"), + V("draws a soul through settling fleece", "pulls life essence beneath a lowered muzzle"), + V("sniffs gently through the spoils", "nudges spoils between both forehooves"), + V("bleats with tears along the muzzle", "buries the face in thick fleece and sobs"), + V("brays out a wavering curse", "stamps one forehoof while swearing")); + + AddSpecialized(voices, "civ_snake", + V("flicks a forked tongue into a winding flame", "rattles a spark into a rising flame"), + V("presses tight coils against the flames", "lays overlapping loops across the flame"), + V("glides into the gathered family", "coils among the close group"), + V("draws a soul along a forked tongue", "winds life essence between tightening coils"), + V("tastes through the spoils", "loops spoils inside a curling tail"), + V("hisses with wet scales beneath the eyes", "knots into a tight coil and sobs"), + V("hisses out a winding curse", "strikes the air while swearing")); + + AddSpecialized(voices, "civ_turtle", + V("scrapes a beaked spark into a low flame", "fans a small flame with broad forefeet"), + V("presses the shell rim against the flames", "rakes measured forefeet across the flame"), + V("plods into the gathered family", "settles shell-to-shell among the group"), + V("draws a soul beneath the shell rim", "pulls life essence between slow forefeet"), + V("probes slowly through the spoils", "draws spoils beneath the shell edge"), + V("wheezes with tears beneath lowered lids", "withdraws the face and sobs inside the shell"), + V("croaks out a slow curse", "snaps the beaked mouth while swearing")); + + AddSpecialized(voices, "civ_unicorn", + V("touches the horn-tip to a radiant flame", "casts a bright flame from the lifted horn"), + V("presses split hooves against the flames", "stamps raised hooves across the flame"), + V("canters into the gathered herd", "bows the family into a horn-outward group"), + V("draws a soul along the shining horn", "winds life essence through a streaming mane"), + V("tests the spoils with the horn tip", "draws spoils closer between lifted hooves"), + V("trills with tears beneath the mane", "folds long legs through ringing sobs"), + V("rings out a piercing curse", "slashes the horn in a sharp arc while swearing")); + + AddSpecialized(voices, "civ_wolf", + V("scratches a paw-spark into a lean flame", "howls a thin flame into a wider flare"), + V("rakes broad paws across the flames", "presses a heavy tail over the flame"), + V("trots into the gathered family", "calls the group into a muzzle-close ring"), + V("draws a soul along a lifted howl", "pulls life essence between bared teeth"), + V("sniffs methodically through the spoils", "drags spoils close beneath one paw"), + V("howls with tears along the muzzle", "covers the nose with both paws and sobs"), + V("growls out a rough curse", "bares every tooth while swearing")); + + AddSpecialized(voices, "dwarf", + V("strikes thick knuckles into a bright flame", "cups a deep flame between stout hands"), + V("beats heavy palms against the flames", "stamps short feet across the flame"), + V("clasps forearms within the gathering group", "calls the family into a stout circle"), + V("draws a soul through a braided beard", "pulls life essence between thick fingers"), + V("sorts through the spoils with square hands", "tucks spoils beneath one stout arm"), + V("sobs into a bristling beard", "covers both eyes with thick, shaking hands"), + V("booms out a bearded curse", "shakes both square fists while swearing")); + + AddSpecialized(voices, "elf", + V("traces slender fingers into a clear flame", "coaxes a silver flame between long hands"), + V("sweeps long fingers across the flames", "presses slender palms against the flame"), + V("bows into the gathering kin-group", "beckons the family into a facing circle"), + V("draws a soul between long fingertips", "guides life essence along an open palm"), + V("searches the spoils with light fingertips", "draws spoils beneath one slender arm"), + V("weeps behind long, trembling fingers", "releases a clear, unsteady sob"), + V("speaks a cutting curse through still lips", "points one long finger while swearing")); + + AddSpecialized(voices, "human", + V("rubs bare palms into a sudden flame", "snaps a spark into a climbing flame"), + V("beats both hands against the flames", "stamps alternating feet across the flame"), + V("waves the family into a gathering circle", "steps among the forming civic group"), + V("draws a soul between cupped hands", "pulls life essence toward the chest"), + V("searches through the spoils with both hands", "gathers spoils against one forearm"), + V("weeps into both open hands", "draws shaking breaths between audible sobs"), + V("shouts a clipped curse", "jabs one finger while swearing")); + + AddSpecialized(voices, "orc", + V("claps heavy fists into a roaring flame", "scrapes broad tusks into a spreading flame"), + V("pounds thick forearms against the flames", "stamps heavy feet across the flame"), + V("shoulders into the gathering group", "calls the family into a tusk-outward group"), + V("draws a soul between broad tusks", "pulls life essence into a clenched fist"), + V("rakes through the spoils with heavy hands", "hauls spoils beneath one thick arm"), + V("roars with tears across broad tusks", "bows over both fists through heavy sobs"), + V("barks out a brutal curse", "pounds both fists together while swearing")); + } +} diff --git a/IdleSpectator/ActivitySpeciesVoices.Fantasy.Extended.cs b/IdleSpectator/ActivitySpeciesVoices.Fantasy.Extended.cs new file mode 100644 index 0000000..7951b91 --- /dev/null +++ b/IdleSpectator/ActivitySpeciesVoices.Fantasy.Extended.cs @@ -0,0 +1,836 @@ +using System.Collections.Generic; + +namespace IdleSpectator; + +public static partial class ActivitySpeciesVoiceCatalog +{ + private static void AddFantasyExtendedVoices(Dictionary voices) + { + AddExtended(voices, "UFO", + V("broadcasts a layered electronic hymn", "sings through synchronized hull tones"), + V("reproduces through pulsing silver light", "begins replication beneath cycling lights"), + V("tends growth with measured underlight", "cultivates in scanning passes"), + V("pollinates {target} through a soft tractor pulse", "sweeps pollen across {target} with controlled underlight"), + V("trades through sequenced signal flashes", "pulses colored lights during exchange"), + V("fishes with a narrow scanning beam", "tracks fish beneath pulsing sensors"), + V("hauls through steady lifting force", "moves the load beneath its hull"), + V("heals {target} under a soft scanning ray", "bathes {target} in modulated light"), + V("projects a concentrated heat ray", "fires a bright lower pulse"), + V("flees {target} in a silent silver rush", "banks away from {target} with lights streaming"), + V("settles into a stable hover", "anchors itself with downward force"), + V("patrols with sensor lights sweeping", "holds formation in guarded flight"), + V("reads through a traveling scan bar", "decodes marks in flickering lights"), + V("gathers life through calibrated scans", "samples living signals with underlight"), + V("vents a brief waste vapor", "purges residue beneath its hull"), + V("wobbles as its lights missequence", "spins while indicators flash irregularly"), + V("recharges with every light brightening", "draws power into its humming hull"), + V("jitters through erratic hover loops", "flashes compulsive signal bursts"), + V("steals {target} beneath dimmed lights", "reaches for {target} with lifting force"), + V("shudders under foreign signal pulses", "flickers as another force pilots it"), + V("sees {target} in projected dreams", "drifts dormant through waves of colored light")); + + AddExtended(voices, "alien", + V("sings in clicking throat pulses", "layers chirps through its throat sac"), + V("reproduces with synchronized body pulses", "begins mating through mirrored gestures"), + V("tends growth with four quick hands", "cultivates through nimble fingerwork"), + V("pollinates {target} with trembling narrow fingers", "brushes pollen across {target} through rapid handwork"), + V("trades through taps and soft clicks", "braids its fingers during exchange"), + V("fishes with darting eyes and hands", "grabs near fish with springing reflexes"), + V("hauls against its springing shoulders", "moves the load with four hands"), + V("heals {target} through careful narrow fingertips", "presses {target} with clicking mouthparts"), + V("fires a sharp bioelectric pulse", "launches crackling force from its wrists"), + V("flees {target} in bounding sideways leaps", "scuttles away from {target} on springing legs"), + V("settles into a compact crouch", "claims space with tapping fingertips"), + V("stands guard on flexed legs", "patrols with darting eyes"), + V("reads by tracing marks rapidly", "studies symbols with unblinking eyes"), + V("gathers life with tasting fingertips", "samples living traces through mouthparts"), + V("relieves itself in a low crouch", "expels waste as its throat sac contracts"), + V("tilts as its eyes desynchronize", "fumbles while four hands disagree"), + V("recharges through pulsing throat sacs", "draws energy into springing limbs"), + V("twitches through compulsive hand patterns", "scuttles in abrupt repeated bursts"), + V("steals {target} with four synchronized hands", "lunges toward {target} with grasping fingers"), + V("jerks as its limbs move independently", "chatters while foreign pulses seize it"), + V("sees {target} in dreams as eyelids flutter", "curls tightly while throat colors ripple")); + + AddExtended(voices, "angle", + V("sings in resonant celestial chimes", "voices a hymn through radiant pulses"), + V("reproduces within converging holy radiance", "begins mating as divine light swells"), + V("tends growth beneath measured brilliance", "cultivates with steady sacred light"), + V("pollinates {target} in a radiant wash", "guides pollen across {target} through holy light"), + V("trades beneath steady divine illumination", "pulses sacred light during exchange"), + V("fishes through revealing celestial light", "sweeps radiant force near fish"), + V("hauls within surrounding radiance", "moves the load through divine force"), + V("heals {target} beneath holy light", "bathes {target} in celestial brilliance"), + V("releases a searing sacred flash", "fires a focused surge of divinity"), + V("flees {target} as radiance streams behind", "withdraws from {target} in a burst of holy light"), + V("settles beneath a steadfast sacred glow", "holds its station with radiant presence"), + V("keeps watch in unwavering brilliance", "patrols as a celestial presence"), + V("reads as divine light reveals marks", "studies symbols within pale radiance"), + V("gathers life in revealing holy light", "reaches for living essence through sacred radiance"), + V("relieves itself in a fading shimmer", "releases waste beneath veiling radiance"), + V("flickers as its sacred glow falters", "wanders while divine pulses misfire"), + V("recharges in gathering celestial brilliance", "draws holy power into its presence"), + V("surges through repeated radiant flashes", "burns with an erratic sacred pulse"), + V("steals {target} beneath a muted sacred glow", "reaches for {target} through radiance"), + V("flares as foreign force grips it", "shudders beneath a distorted holy glow"), + V("sees {target} in radiant dreams", "rests as celestial visions pulse visibly")); + + AddExtended(voices, "assimilator", + V("sings through several borrowed throats", "layers mismatched voices across its surface"), + V("reproduces by budding a pulsing mass", "begins mating as membranes intermingle"), + V("tends growth with braided tendrils", "cultivates through probing filaments"), + V("pollinates {target} with rippling surface cilia", "spreads pollen across {target} on tasting tendrils"), + V("trades through shifting grasping limbs", "layers borrowed voices during exchange"), + V("fishes with a snapping membrane", "senses fish through trailing filaments"), + V("hauls with braided grasping tendrils", "moves the load beneath its mass"), + V("heals {target} by matching living tissue", "covers {target} beneath a clear membrane"), + V("fires a hardened organic barb", "launches a dense pulse of tissue"), + V("flees {target} in rolling bodily surges", "flees {target} on rapidly pulling tendrils"), + V("settles by anchoring many filaments", "spreads into a rooted living mound"), + V("guards with hardened surface plates", "patrols on braided tendrils"), + V("reads through borrowed clustered eyes", "traces marks with tasting filaments"), + V("gathers life into sampling membranes", "draws living traces through cilia"), + V("expels waste through opening pores", "sheds a clouded outer membrane"), + V("ripples through mismatched borrowed forms", "stumbles as limbs repeatedly reform"), + V("recharges as inner pulses quicken", "draws energy beneath its surface"), + V("buds grasping hands in repeated cycles", "surges through rapid transformations"), + V("steals {target} with a sudden pseudopod", "reaches around {target} with a clear membrane"), + V("convulses as foreign patterns spread", "forms unfamiliar faces across its surface"), + V("sees {target} in borrowed dream-faces", "rests while remembered forms ripple")); + + AddExtended(voices, "civ_crystal_golem", + V("sings in deep crystalline resonance", "rings harmonics through its faceted chest"), + V("reproduces as core light divides", "begins mating through synchronized core pulses"), + V("tends growth with heavy faceted hands", "cultivates beneath refracted core light"), + V("pollinates {target} through prismatic light pulses", "brushes pollen across {target} with crystal fingertips"), + V("trades with slow resonant hand taps", "pulses chest light during exchange"), + V("fishes through refracted glints", "closes faceted palms near fish"), + V("hauls against its massive crystal frame", "moves the load with stone hands"), + V("heals {target} through refracted core light", "presses {target} beneath glowing facets"), + V("fires a concentrated prismatic burst", "releases core light in a hot flash"), + V("flees {target} with heavy ringing strides", "flees {target} as core light races"), + V("settles into rooted statue stillness", "plants its faceted feet firmly"), + V("guards with broad crystal arms", "patrols in resonant heavy steps"), + V("reads through shifting facet reflections", "studies marks in core light"), + V("gathers life through vibrating fingertips", "draws living traces into its core"), + V("vents powdered residue from its seams", "sheds dull grit between crystal joints"), + V("staggers as core light scatters", "turns while facets flash inconsistently"), + V("recharges as its core intensifies", "draws energy through glowing seams"), + V("trembles with compulsive core surges", "strides as facets flash erratically"), + V("steals {target} with a heavy crystal hand", "reaches for {target} between glowing facets"), + V("cracks with invading dark pulses", "moves as foreign light fills its core"), + V("sees {target} in prismatic dreams", "rests as visions cross its facets")); + + AddExtended(voices, "cold_one", + V("sings through chiming frozen breath", "voices a brittle frost cadence"), + V("reproduces amid mingling cold vapor", "begins mating as rime pulses"), + V("tends growth beneath numbing palms", "cultivates with measured cooling touch"), + V("pollinates {target} on emitted cold vapor", "brushes pollen across {target} with frost-rimmed fingers"), + V("trades with clicks of frozen teeth", "emits pale vapor during exchange"), + V("fishes by sensing warmth below", "closes whitening hands near fish"), + V("hauls with rigid frostbound limbs", "moves the load across slick rime"), + V("heals {target} beneath a frost sheen", "numbs {target} with a pale palm"), + V("fires a lance of intense cold", "releases a burst of hard rime"), + V("flees {target} in a skidding frost trail", "flees {target} behind emitted cold vapor"), + V("settles beneath an anchored ice crust", "plants stiff limbs in spreading rime"), + V("guards behind hardening frost", "patrols with whitening palms ready"), + V("reads as rime highlights marks", "studies symbols through pale eyes"), + V("gathers life through heat-sensing fingers", "draws living warmth into rime"), + V("relieves itself in brittle frozen waste", "expels waste beneath cold vapor"), + V("stares as frost pulses unevenly", "stumbles while rime locks its limbs"), + V("recharges as its rime thickens", "draws energy into a whitening core"), + V("scrapes compulsively at its own frost", "paces beneath surging cold vapor"), + V("steals {target} with a numbing quick palm", "reaches for {target} through hardening rime"), + V("jerks as black frost spreads", "moves beneath an invading cold pulse"), + V("sees {target} in dreams beneath sleeping ice", "rests as emitted vapor forms visions")); + + AddExtended(voices, "crabzilla", + V("sings in thunderous shell resonance", "booms a rhythm through colossal plates"), + V("reproduces through booming pincer displays", "begins mating as shell plates rumble"), + V("tends growth beneath careful claw taps", "cultivates with immense measured pincers"), + V("pollinates {target} with sweeping pincer beats", "fans pollen across {target} beneath colossal claws"), + V("trades through monumental claw gestures", "rumbles its shell during exchange"), + V("fishes between immense closing pincers", "tracks fish with sweeping eye stalks"), + V("hauls beneath its fortress shell", "moves the load with colossal pincers"), + V("heals {target} by applying plated pressure", "presses {target} beneath a broad claw"), + V("fires a crushing pressure blast", "launches force between snapping pincers"), + V("flees {target} in thundering sideways strides", "flees {target} behind its fortress shell"), + V("settles on folded towering limbs", "anchors its shell with planted legs"), + V("guards behind raised colossal pincers", "patrols with eye stalks sweeping"), + V("reads through swiveling eye stalks", "studies marks with careful claw taps"), + V("gathers life through vibrating leg tips", "samples living motion with eye stalks"), + V("relieves itself beneath folded rear plates", "expels waste below its vast shell"), + V("clacks while eye stalks cross", "lurches as towering legs mistime"), + V("recharges as shell plates vibrate", "draws energy through planted leg tips"), + V("stamps through compulsive sideways surges", "snaps both pincers without cause"), + V("steals {target} with one sweeping pincer", "reaches for {target} beneath its shell"), + V("shudders as shell plates darken", "stomps beneath an invading pulse"), + V("sees {target} in rumbling dreams", "rests as eye stalks twitch")); + + AddExtended(voices, "crystal_sword", + V("sings through a ringing crystal blade", "voices a clear hilt-deep peal"), + V("reproduces as prismatic light separates", "begins mating through crossed resonant tones"), + V("tends growth with careful blade glints", "cultivates beneath refracted light"), + V("pollinates {target} through sweeping flat-side passes", "guides pollen across {target} on prismatic pulses"), + V("trades with a formal hilt dip", "rings clearly during exchange"), + V("fishes in a swift point-first dive", "flashes beneath fish with its flat"), + V("hauls beneath its hovering guard", "moves the load with lifting resonance"), + V("heals {target} by laying its flat nearby", "bathes {target} in prismatic shimmer"), + V("fires a piercing crystal pulse", "releases a bright blast from its point"), + V("flees {target} in a ringing aerial sweep", "flees {target} point-first through prismatic light"), + V("settles point-down in steady hover", "anchors its presence through low resonance"), + V("guards upright with edge forward", "patrols in measured sweeping arcs"), + V("reads by tracing marks with light", "studies symbols reflected along its blade"), + V("gathers life through testing resonance", "draws living traces along its fuller"), + V("sheds cloudy residue from its facets", "vents dull particles beneath its guard"), + V("wobbles as its resonance breaks", "spins while prismatic light scatters"), + V("recharges as its facets brighten", "draws energy along its fuller"), + V("slashes through repeated empty sweeps", "rings in rapidly recurring bursts"), + V("steals {target} beneath a muted prismatic shimmer", "hooks toward {target} with its guard"), + V("jerks as dark resonance grips it", "rings harshly under foreign control"), + V("sees {target} in chiming dreams", "rests as visions shimmer along its blade")); + + AddExtended(voices, "demon", + V("sings in a cracked furnace roar", "chants through smoking fangs"), + V("reproduces amid mingling embers", "begins mating with pulsing wingbeats"), + V("tends growth with ember-warm claws", "cultivates beneath controlled heat"), + V("pollinates {target} with careful wingbeats", "fans pollen across {target} with leathery wings"), + V("trades with horns lowered formally", "sheds red sparks during exchange"), + V("fishes with heat-sensing nostrils", "closes hooked claws near fish"), + V("hauls against its horned shoulders", "moves the load with clawed hands"), + V("heals {target} beneath claw heat", "presses {target} with ember-warm claws"), + V("fires a scorching throat burst", "hurls flame from both claws"), + V("flees {target} on smoking hooves", "flees {target} behind beating wings"), + V("settles within a scorched crouch", "plants smoking hooves firmly"), + V("guards with horns and claws raised", "patrols beneath folded wings"), + V("reads through ember-bright eyes", "traces marks with a hot claw"), + V("gathers life through flared nostrils", "draws living heat into embers"), + V("relieves itself in smoking waste", "expels waste beneath folded wings"), + V("snarls as sparks misfire", "stumbles when hooves flare unevenly"), + V("recharges around a red-hot core", "draws energy through smoking horns"), + V("lashes its tail compulsively", "paces beneath uncontrolled embers"), + V("steals {target} with a hooked claw", "reaches for {target} beneath one wing"), + V("convulses as black flame spreads", "moves beneath a foreign infernal pulse"), + V("sees {target} in ember-lit dreams", "rests while wing membranes twitch")); + + AddExtended(voices, "dragon", + V("sings in rolling chest thunder", "voices a vast plated resonance"), + V("reproduces through synchronized wing displays", "begins mating amid pulsing throat glow"), + V("tends growth with careful foreclaws", "cultivates beneath measured warm breath"), + V("pollinates {target} with broad wingbeats", "fans pollen across {target} with controlled wings"), + V("trades with a formal horn dip", "rumbles its chest during exchange"), + V("fishes in a talon-first plunge", "tracks fish with unblinking eyes"), + V("hauls against its plated shoulders", "moves the load in closed talons"), + V("heals {target} beneath warming breath", "presses {target} with careful foreclaws"), + V("fires a narrow blazing torrent", "launches a throat-deep blast"), + V("flees {target} on vast wingbeats", "flees {target} with plated tail streaming"), + V("settles onto folded haunches", "anchors itself beneath spread talons"), + V("guards with wings half spread", "patrols beneath a horned gaze"), + V("reads with one unblinking eye", "traces marks using a foreclaw"), + V("gathers life through flared nostrils", "draws living traces in deep breaths"), + V("relieves itself beneath a raised tail", "expels waste in a plated crouch"), + V("tilts as its pupils lose focus", "missteps while tail and wings disagree"), + V("recharges as throat glow deepens", "draws energy beneath plated scales"), + V("snaps through compulsive wingbeats", "paces under surging throat light"), + V("steals {target} in a swift talon sweep", "reaches for {target} beneath its chest"), + V("thrashes as scales pulse darkly", "moves under an invading throat glow"), + V("sees {target} in smoke-lit dreams", "rests while vast wings twitch")); + + AddExtended(voices, "druid", + V("sings in layered rustling tones", "chants as leaf fibers tremble"), + V("reproduces amid entwining living fibers", "begins mating as leaf patterns pulse"), + V("tends growth through coaxing palms", "cultivates with fresh root magic"), + V("pollinates {target} with rustling leaves", "guides pollen across {target} through curling vines"), + V("trades with a leaf-hood bow", "rustles living fibers during exchange"), + V("fishes with sensing root magic", "draws fish near through living fibers"), + V("hauls with tightening green vines", "moves the load through living growth"), + V("heals {target} beneath fresh green fibers", "binds {target} with curling growth"), + V("fires a burst of hard thorns", "launches force through snapping vines"), + V("flees {target} beneath streaming leaf fibers", "flees {target} on quick curling roots"), + V("settles as roots spread below", "anchors itself through living fibers"), + V("guards behind layered thorn growth", "patrols as leaves listen"), + V("reads as leaf veins trace marks", "studies symbols through living grain"), + V("gathers life through fine roots", "draws living traces into fresh growth"), + V("relieves itself into absorbing roots", "releases waste beneath folded leaves"), + V("turns as leaves rustle erratically", "stumbles while roots pull apart"), + V("recharges as fresh leaves unfurl", "draws energy through living fibers"), + V("sprouts vines in compulsive bursts", "paces while leaves pulse rapidly"), + V("steals {target} with a curling vine", "reaches around {target} with living fibers"), + V("jerks as black roots spread", "moves beneath invading thorn growth"), + V("sees {target} in leaf-veined dreams", "rests while roots trace visions")); + + AddExtended(voices, "evil_mage", + V("sings in layered shadow whispers", "chants through violet sparks"), + V("reproduces amid merging dark sigils", "begins mating as shadows pulse"), + V("tends growth beneath violet force", "cultivates through crawling dark symbols"), + V("pollinates {target} with circling shadows", "guides pollen across {target} with violet sparks"), + V("trades with a hooded bow", "cycles dark sigils during exchange"), + V("fishes through a hovering violet gaze", "draws fish upward with shadow force"), + V("hauls within grasping shadows", "moves the load through violet force"), + V("heals {target} beneath binding dark symbols", "presses {target} with smoking fingertips"), + V("fires crackling violet force", "launches a burst of shadow"), + V("flees {target} inside emitted black vapor", "flees {target} as shadows fold inward"), + V("settles within hovering dark sigils", "anchors shadows beneath its robe"), + V("guards behind a violet barrier", "patrols with shadows circling"), + V("reads through crawling luminous symbols", "studies marks beneath violet light"), + V("gathers life through a circling gaze", "draws living traces into shadow"), + V("relieves itself beneath folded darkness", "expels waste inside layered shadow"), + V("flickers as sigils scramble", "wanders while shadows point elsewhere"), + V("recharges as violet symbols brighten", "draws energy into layered shadow"), + V("casts compulsive empty sigils", "paces amid uncontrolled dark sparks"), + V("steals {target} through a grasping shadow", "reaches for {target} with folded darkness"), + V("convulses beneath foreign pale symbols", "moves while foreign shadows pull"), + V("sees {target} in violet dreams", "rests as shadows reenact visions")); + + AddExtended(voices, "fairy", + V("sings in tiny bell trills", "layers bright notes with wingbeats"), + V("reproduces amid mingling shimmer", "begins mating through synchronized glow pulses"), + V("tends growth with sparkling fingertips", "cultivates beneath a tiny warm glow"), + V("pollinates {target} with shimmering wingbeats", "dusts pollen across {target} with sparkling motes"), + V("trades through spiraling light ribbons", "trills brightly during exchange"), + V("fishes in quick shimmering dives", "tracks fish through pulsing glow"), + V("hauls within a sparkling lift", "moves the load on rapid wingbeats"), + V("heals {target} beneath bright motes", "bathes {target} in a tiny flash"), + V("fires a needle-thin sparkle", "launches a bright mote burst"), + V("flees {target} in looping wing flashes", "flees {target} with glow streaming"), + V("settles into a hovering shimmer", "perches with wings folded upright"), + V("guards with wings buzzing brightly", "patrols in tight glowing loops"), + V("reads by tracing marks in light", "studies symbols through tiny glints"), + V("gathers life into sparkling motes", "samples living traces with shimmer"), + V("relieves itself beneath veiling motes", "releases waste during a brief hover"), + V("loops as its glow pulses unevenly", "hovers while wings lose rhythm"), + V("recharges inside a swelling glow", "draws energy through shimmering wings"), + V("darts through compulsive tiny loops", "scatters motes in urgent bursts"), + V("steals {target} in a quick sparkling pass", "reaches for {target} through shimmer"), + V("jerks as its glow turns harsh", "flies under an invading pulse"), + V("sees {target} in glowing dreams", "rests as wings trace visions")); + + AddExtended(voices, "fire_elemental", + V("sings in roaring flame harmonics", "crackles through a rising cadence"), + V("reproduces as core flame divides", "begins mating through mingling fire"), + V("tends growth with measured warmth", "cultivates beneath careful flame"), + V("pollinates {target} with controlled heat pulses", "guides pollen across {target} with thin flames"), + V("trades through sequenced spark bursts", "flares white during exchange"), + V("fishes by sensing cooler motion", "surrounds fish with curling heat"), + V("hauls within a lifting heat column", "moves the load through flowing flame"), + V("heals {target} beneath measured warmth", "presses {target} with a white fingertip"), + V("fires a roaring arm of flame", "launches a white-hot burst"), + V("flees {target} as streaming orange ribbons", "flees {target} in a sudden flare"), + V("settles into a steady upright blaze", "anchors around a white-hot core"), + V("guards as a broad wall of fire", "patrols in folding flames"), + V("reads as heat reveals marks", "studies symbols through flickering tongues"), + V("gathers life through trembling flames", "draws living warmth toward its core"), + V("sheds spent ash beneath itself", "vents dark smoke from its core"), + V("flares as tongues split repeatedly", "wavers while its core pulses unevenly"), + V("recharges around a whitening core", "draws energy through every flame"), + V("lashes out in compulsive firebursts", "surges through uncontrolled flares"), + V("steals {target} behind a curtain of flame", "reaches for {target} through lowered heat"), + V("blackens as foreign fire spreads", "moves beneath an invading blaze"), + V("sees {target} in ember dreams", "rests as flames replay visions")); + + AddExtended(voices, "fire_elemental_blob", + V("sings in bubbly molten pops", "gurgles through bright crackles"), + V("reproduces by budding a hot lobe", "begins mating as molten surfaces mingle"), + V("tends growth with warm pseudopods", "cultivates beneath soft heat"), + V("pollinates {target} with popping heat bubbles", "brushes pollen across {target} with glowing lobes"), + V("trades through shaped molten gestures", "pops a bright bubble during exchange"), + V("fishes with a stretching hot lobe", "senses fish through surface ripples"), + V("hauls within several molten lobes", "moves the load across its surface"), + V("heals {target} beneath a warm fold", "covers {target} with controlled heat"), + V("fires a clinging heat glob", "launches a popping molten burst"), + V("flees {target} in wobbling molten hops", "flees {target} with flames streaming"), + V("settles into a broad hot puddle", "anchors through spreading molten folds"), + V("guards behind swelling fiery lobes", "patrols in bouncing molten surges"), + V("reads through traveling surface bubbles", "traces marks with a narrow pseudopod"), + V("gathers life across tasting folds", "draws living traces beneath its skin"), + V("expels dark slag from one fold", "sheds spent crust beneath itself"), + V("wobbles as bubbles reverse direction", "splits and rejoins in repeated cycles"), + V("recharges as its center brightens", "draws energy through molten skin"), + V("buds compulsive grasping lobes", "pops through urgent surface surges"), + V("steals {target} with a stretching pseudopod", "reaches around {target} with one fold"), + V("convulses as black bubbles spread", "moves while foreign pulses deform it"), + V("sees {target} in rippling dreams", "rests as bubbles form visions")); + + AddExtended(voices, "fire_elemental_horse", + V("sings in furnace-bright whinnies", "nickers through a crackling mane"), + V("reproduces amid synchronized flame pulses", "begins mating through blazing prances"), + V("tends growth with warm careful hooves", "cultivates beneath controlled hoof heat"), + V("pollinates {target} with mane-driven pulses", "fans pollen across {target} with a fiery tail"), + V("trades through ember-bright muzzle dips", "flares one hoof during exchange"), + V("fishes with smoke-sensitive nostrils", "strikes near fish with a hot hoof"), + V("hauls against its blazing shoulders", "moves the load in a heated stride"), + V("heals {target} beneath a warming muzzle", "presses {target} with controlled hoof heat"), + V("fires a blazing forward breath", "launches sparks through a sharp snort"), + V("flees {target} on streaming fiery hooves", "flees {target} with mane blazing"), + V("settles onto folded ember legs", "plants four compact flame hooves"), + V("guards with mane fully raised", "patrols in a measured hot canter"), + V("reads through ember-bright eyes", "traces marks with one hot hoof"), + V("gathers life through flared nostrils", "draws living traces through warm breath"), + V("relieves itself beneath a lifted flame tail", "expels glowing waste in a crouch"), + V("sidesteps as mane pulses unevenly", "stamps while nostrils flare repeatedly"), + V("recharges as its mane whitens", "draws energy through glowing hooves"), + V("prances in compulsive fiery bursts", "stamps through uncontrolled sparks"), + V("steals {target} in a quick muzzle sweep", "reaches for {target} with glowing teeth"), + V("bucks as black flame spreads", "gallops beneath a foreign pulse"), + V("sees {target} in ember-lit dreams", "rests while blazing legs twitch")); + + AddExtended(voices, "fire_elemental_slug", + V("sings in wet sizzling whistles", "bubbles through a molten trill"), + V("reproduces amid mingling mantle glow", "begins mating as hot bodies pulse"), + V("tends growth with a heated foot", "cultivates beneath mantle warmth"), + V("pollinates {target} with curling feeler sparks", "brushes pollen across {target} with flame feelers"), + V("trades through paired feeler curls", "pulses its mantle during exchange"), + V("fishes with heat-sensitive feelers", "surrounds fish in a slow hot fold"), + V("hauls atop its broad heated foot", "moves the load beneath a mantle fold"), + V("heals {target} under a warm body trail", "covers {target} with controlled mantle heat"), + V("fires a strip of clinging flame", "launches a hot mantle spark"), + V("flees {target} in a swift molten glide", "flees {target} beneath streaming feelers"), + V("settles into a low smoldering coil", "anchors through its broad heated foot"), + V("guards with both feelers blazing", "patrols along a narrow hot trail"), + V("reads by sweeping sensitive feelers", "traces marks with its heated foot"), + V("gathers life across tasting skin", "draws living traces through feelers"), + V("leaves a dark waste bead behind", "expels residue beneath its mantle"), + V("coils as feelers point apart", "glides while mantle pulses misfire"), + V("recharges as its mantle glows", "draws energy through its broad underside"), + V("curls through compulsive hot spirals", "flicks feelers in urgent bursts"), + V("steals {target} beneath a mantle fold", "reaches for {target} along its heated foot"), + V("writhes as black heat spreads", "glides beneath an invading pulse"), + V("sees {target} in mantle dreams", "rests as feelers trace visions")); + + AddExtended(voices, "fire_elemental_snake", + V("sings in a crackling hiss", "rattles through bright flame notes"), + V("reproduces amid braided fiery coils", "begins mating as core flames pulse"), + V("tends growth within warm loose coils", "cultivates through measured body heat"), + V("pollinates {target} with sweeping coils", "guides pollen across {target} with a flame tongue"), + V("trades through paired coil gestures", "rattles its tail during exchange"), + V("fishes with a heat-sensitive tongue", "strikes near fish with glowing jaws"), + V("hauls within tightening fiery coils", "moves the load along its body"), + V("heals {target} beneath a warm coil", "surrounds {target} with controlled flame"), + V("fires a searing tongue bolt", "launches flame from raised jaws"), + V("flees {target} in a swift incandescent slither", "flees {target} with tail sparks"), + V("settles into a banked ember coil", "anchors through overlapping fiery loops"), + V("guards with head raised brightly", "patrols in tight burning curves"), + V("reads through tongue-tip heat changes", "traces marks with a glowing tail"), + V("gathers life through its split tongue", "draws living warmth into coils"), + V("expels glowing waste behind its coils", "leaves a dark residue pellet"), + V("knots as tongue flicks erratically", "turns while coils pull against themselves"), + V("recharges as every coil brightens", "draws energy through a flickering tongue"), + V("strikes through compulsive empty lunges", "rattles beneath uncontrolled flame"), + V("steals {target} within a swift coil", "reaches around {target} with its body"), + V("writhes as dark flame bands it", "slithers under a foreign pulse"), + V("sees {target} in coiling dreams", "rests while its tail twitches")); + + AddExtended(voices, "fire_skull", + V("sings through a blazing hollow howl", "cackles in pitched jaw notes"), + V("reproduces as crown flame divides", "begins mating through synchronized jaw fire"), + V("tends growth with measured crown heat", "cultivates beneath careful flame breath"), + V("pollinates {target} with hollow-mouth pulses", "guides pollen across {target} with crown sparks"), + V("trades through formal jaw clacks", "pulses socket flame during exchange"), + V("fishes through heat-sensing sockets", "snaps fish between blazing teeth"), + V("hauls with gripping fiery jaws", "moves the load beneath its chin"), + V("heals {target} beneath measured flame breath", "presses {target} with warm teeth"), + V("fires a compact mouth bolt", "launches flame through open jaws"), + V("flees {target} with crown flame streaming", "flees {target} in a hollow rush"), + V("settles jaw-down in low hover", "anchors beneath a banked blue crown"), + V("guards with sockets fixed forward", "patrols in snapping fiery arcs"), + V("reads through pulsing empty sockets", "traces marks with crown light"), + V("gathers life through hollow nostrils", "draws living warmth into its crown"), + V("drops dark ash through its jaw", "vents spent soot from hollow sockets"), + V("spins as sockets flare unevenly", "chatters while crown flame misfires"), + V("recharges as its crown whitens", "draws energy through hollow jaws"), + V("snaps compulsively at empty space", "bobs through uncontrolled flame bursts"), + V("steals {target} in a sudden jaw snap", "reaches for {target} between blazing teeth"), + V("rattles as black flame crowns it", "flies under an invading socket glow"), + V("sees {target} in crown-lit dreams", "rests as jaws silently chatter")); + + AddExtended(voices, "ghost", + V("sings in airy layered echoes", "warbles through a translucent form"), + V("reproduces as two auras intermingle", "begins mating through synchronized fading"), + V("tends growth with spectral pressure", "cultivates beneath a cool aura"), + V("pollinates {target} with spectral pressure", "guides pollen across {target} with translucent hands"), + V("trades through pulsing aura gestures", "bows its spectral form during exchange"), + V("fishes with an unseen lifting force", "tracks fish through its emitted mist"), + V("hauls through steady unseen pressure", "moves the load without contact"), + V("heals {target} beneath a spectral veil", "presses {target} with translucent hands"), + V("fires a chilling spectral pulse", "launches force through a sudden wail"), + V("flees {target} as a thinning pale streak", "flees {target} within its trailing mist"), + V("settles into a faint hovering veil", "anchors as a dim silhouette"), + V("guards with aura spread broadly", "patrols through silent drifting passes"), + V("reads by passing through marks", "studies symbols as its aura ripples"), + V("gathers life through spectral fingertips", "draws living traces into its emitted mist"), + V("releases cloudy residue through itself", "sheds a dim spectral waste"), + V("fades in and out irregularly", "drifts while hands pass through itself"), + V("recharges as its outline brightens", "draws energy into a hollow form"), + V("loops through compulsive fading passes", "wails beneath an urgent aura pulse"), + V("steals {target} through a passing spectral hand", "reaches for {target} within its emitted mist"), + V("distorts as foreign shadow crosses its mist", "moves beneath a foreign spectral pull"), + V("sees {target} in translucent dreams", "rests as its aura reenacts visions")); + + AddExtended(voices, "god_finger", + V("sings by drumming its nail", "wiggles through a silent fingertip ballad"), + V("reproduces through paired fingertip pulses", "begins mating as nail glints synchronize"), + V("tends growth with its sensitive tip", "cultivates with measured fingertip presses"), + V("pollinates {target} with nail-tip taps", "brushes pollen across {target} with its fingertip"), + V("trades through a formal fingertip curl", "taps its nail during exchange"), + V("fishes with a sudden fingertip flick", "tests for fish with its sensitive tip"), + V("hauls by bracing its curved body", "nudges the load with its nail"), + V("heals {target} with measured pressure", "tends {target} with careful fingertip taps"), + V("fires a bright nail-tip pulse", "flicks a compact burst forward"), + V("flees {target} in upright hops", "slides away as its fingertip bends"), + V("settles upright on its rounded tip", "curls into a stable resting posture"), + V("stands guard with nail raised", "patrols in deliberate fingertip hops"), + V("reads by tracing marks with its nail", "taps symbols in measured sequence"), + V("gathers life through its sensitive tip", "samples living traces with its nail"), + V("relieves itself through a brief tip contraction", "expels waste while curled low"), + V("wobbles as its fingertip flexes backward", "taps unrelated marks in confusion"), + V("recharges as its nail gleams", "draws energy through its rounded tip"), + V("flicks repeatedly under a strange urge", "curls and uncurls without pause"), + V("steals {target} with a quick hook", "flicks {target} toward its curled body"), + V("jerks as a foreign pulse bends it", "taps in an imposed rhythm"), + V("sees {target} in fingertip dreams", "rests as its nail glints in sleeping pulses")); + + AddExtended(voices, "greg", + V("sings in a wobbling nasal honk", "bellows notes through a slack jaw"), + V("reproduces through an uneven mating dance", "begins mating with elbows flung wide"), + V("tends growth with alternating hand pats", "cultivates in a lopsided crouch"), + V("pollinates {target} with windmilling hands", "brushes pollen across {target} with spread fingers"), + V("trades through an overlarge two-hand wave", "nods after each exchange gesture"), + V("fishes with abrupt two-handed grabs", "peers for fish beneath one arm"), + V("hauls against one oversized shoulder", "shoves the load with both palms"), + V("heals {target} with clumsy hand pressure", "pats {target} with splayed fingers"), + V("fires a forceful open-mouthed burst", "claps both hands into a shock pulse"), + V("flees {target} in a crooked shuffle", "lopes away with elbows swinging"), + V("settles into a wide heel squat", "plants mismatched feet and sways"), + V("stands guard with windmilling fists", "patrols in abrupt sideways hops"), + V("reads with its jaw hanging open", "follows marks using a waggling finger"), + V("gathers life through noisy close sniffs", "pokes at living traces with one finger"), + V("relieves itself in a slack-limbed squat", "expels waste with shoulders bouncing"), + V("stares while its hands copy each other", "turns in place with one eye narrowed"), + V("recharges as its limbs twitch awake", "draws energy through a wide yawn"), + V("hops twice whenever the urge strikes", "waves both hands in repeated bursts"), + V("steals {target} in a windmilling grab", "snatches {target} with both hands"), + V("lurches as its limbs move out of sequence", "grins while foreign force jerks its elbows"), + V("sees {target} in lopsided dreams", "sleeps while fingers mime crooked gestures")); + + AddExtended(voices, "jumpy_skull", + V("sings through rapid tooth clacks", "rattles a tune inside its cranium"), + V("reproduces through synchronized jaw bounces", "begins mating as empty sockets pulse"), + V("tends growth with light crown taps", "cultivates through measured jaw hops"), + V("pollinates {target} with bouncing jawbeats", "puffs pollen across {target} through clenched teeth"), + V("trades with alternating tooth clicks", "bobs its cranium during exchange"), + V("fishes in quick jaw-first snaps", "tracks fish through tilted sockets"), + V("hauls with the load between its teeth", "pushes the load using its crown"), + V("heals {target} with light crown pressure", "tends {target} through pulsing socket light"), + V("fires a bolt between open jaws", "launches force in a snapping bounce"), + V("flees {target} in ricocheting hops", "boings away on its springing jaw"), + V("settles crown-down with jaw tucked", "balances quietly on its lower teeth"), + V("guards with teeth clenched forward", "patrols in quick rebounding arcs"), + V("reads by tapping symbols with teeth", "tilts one socket across the marks"), + V("gathers life through hollow socket pulses", "samples living traces with chattering teeth"), + V("drops waste through its open jaw", "expels residue during a low bounce"), + V("spins while its sockets point apart", "bounces between unrelated marks"), + V("recharges as its sockets brighten", "draws energy through clenched teeth"), + V("snaps repeatedly at a strange urge", "boings in place without stopping"), + V("steals {target} in a teeth-first hop", "clamps {target} between chattering teeth"), + V("rattles as foreign light fills its sockets", "bounces in an imposed rhythm"), + V("sees {target} in bouncing dreams", "rests as dim scenes cross its sockets")); + + AddExtended(voices, "living_house", + V("sings through resonant inner rooms", "rings a tune through door and shutters"), + V("reproduces as its foundation stones divide", "begins mating while windows pulse together"), + V("tends growth with careful shutter movements", "cultivates through measured foundation taps"), + V("pollinates {target} with rhythmic shutter beats", "fans pollen across {target} through its doorway"), + V("trades through opening and closing windows", "rings from within during exchange"), + V("fishes with a swiveling window gaze", "snaps its door near passing fish"), + V("hauls against its broad foundation", "draws the load through its doorway"), + V("heals {target} with sheltering inner warmth", "tends {target} through a softly lit window"), + V("fires a forceful chimney pulse", "launches a blast through its doorway"), + V("flees {target} on lurching foundation stones", "shuffles away as shutters flap"), + V("settles with every foundation stone braced", "rests squarely with shutters tucked"), + V("guards behind a firmly shut door", "patrols with windows swiveling"), + V("reads by scanning marks through its windows", "opens shutters in response to symbols"), + V("gathers life through listening walls", "samples living motion with swiveling windows"), + V("expels waste through a brief door opening", "vents residue through its chimney"), + V("lurches as doors open out of sequence", "turns while its windows face different ways"), + V("recharges as every window brightens", "draws energy through its open doorway"), + V("rattles shutters under a strange urge", "opens and closes its door repeatedly"), + V("steals {target} through a sudden doorway snap", "draws {target} past its threshold"), + V("shudders as foreign light fills its windows", "moves while its door slams by itself"), + V("sees {target} in window-lit dreams", "rests as scenes flicker behind its windows")); + + AddExtended(voices, "living_plants", + V("sings through rustling layered leaves", "rattles seed pods in a leafy cadence"), + V("reproduces as living fibers intertwine", "begins mating while central buds pulse"), + V("tends growth with fine probing roots", "cultivates through careful vine curls"), + V("pollinates {target} with shaking seed pods", "dusts {target} through trembling blooms"), + V("trades through paired tendril gestures", "opens a bright bloom during exchange"), + V("fishes with sensitive trailing roots", "curls a vine near passing fish"), + V("hauls with several tightening vines", "pulls the load across braided roots"), + V("heals {target} with soft binding fibers", "tends {target} beneath layered leaves"), + V("fires a cluster of hardened thorns", "snaps a vine into a forceful burst"), + V("flees {target} on rapidly probing roots", "pulls away with leaves streaming"), + V("settles as roots spread beneath its body", "folds broad leaves around its stem"), + V("guards behind thorned vines", "patrols with roots and tendrils extended"), + V("reads by tracing marks with tendrils", "turns leaf surfaces toward each symbol"), + V("gathers life through fine root hairs", "samples living traces with sensitive leaves"), + V("releases waste through opening leaf pores", "sheds a dark bead from its roots"), + V("twists as roots pull opposite ways", "turns while leaves open and close randomly"), + V("recharges as every leaf unfurls", "draws energy through its central bud"), + V("sprouts grasping vines under a strange urge", "shakes seed pods in repeated bursts"), + V("steals {target} with a curling tendril", "draws {target} between layered leaves"), + V("jerks as dark growth crosses its stem", "moves beneath an invading root pulse"), + V("sees {target} in leafy dreams", "rests while leaf veins replay dim scenes")); + + AddExtended(voices, "mush_animal", + V("sings in soft gill-puff squeaks", "chuffs a tune beneath its broad cap"), + V("reproduces through a pulsing spore release", "begins mating as gills synchronize"), + V("tends growth with quick forepaw pats", "cultivates beneath a tilted cap"), + V("pollinates {target} with soft spore puffs", "brushes pollen across {target} with short paws"), + V("trades through cap dips and chirps", "puffs its gills during exchange"), + V("fishes with a porous snout", "pounces near fish with both forepaws"), + V("hauls against its squat shoulders", "pushes the load beneath its cap"), + V("heals {target} with soft gill puffs", "tends {target} using quick paw presses"), + V("fires a dense spore burst", "launches force from beneath its cap"), + V("flees {target} in cap-bobbing bounds", "scampers away on stubby feet"), + V("settles beneath its lowered cap", "curls into a squat spongy ball"), + V("guards with cap tilted forward", "patrols in quick snout-led bounds"), + V("reads by sniffing along marks", "taps symbols with one short paw"), + V("gathers life through trembling gills", "samples living traces with its snout"), + V("relieves itself beneath its lowered cap", "expels waste as its gills contract"), + V("paws at spores that are not there", "turns while its gills pulse unevenly"), + V("recharges as its gills swell", "draws energy beneath its broad cap"), + V("pounces repeatedly under a strange urge", "shakes spores from its cap without pause"), + V("steals {target} with a quick paw swipe", "nudges {target} beneath its cap"), + V("convulses as dark spores fill its gills", "bounds in an imposed rhythm"), + V("sees {target} in spore-filled dreams", "rests as spores form fleeting scenes")); + + AddExtended(voices, "mush_unit", + V("sings in low papery gill notes", "voices a rhythm beneath its broad cap"), + V("reproduces through a measured spore release", "begins mating as cap pulses synchronize"), + V("tends growth with pale careful hands", "cultivates through controlled spore puffs"), + V("pollinates {target} with a directed spore plume", "brushes pollen across {target} with pale fingers"), + V("trades with a formal cap tilt", "presses its palms during exchange"), + V("fishes with tapping fingertips", "tracks fish through trembling gills"), + V("hauls against its stalk-like shoulders", "moves the load with both pale hands"), + V("heals {target} with measured palm pressure", "tends {target} beneath a soft spore veil"), + V("fires a compact hardened spore burst", "launches force between both palms"), + V("flees {target} in long cap-led strides", "marches away as gills pulse rapidly"), + V("settles upright beneath its lowered cap", "folds pale arms beneath hanging gills"), + V("guards with forearms raised", "patrols with cap tilted forward"), + V("reads by tracing marks with fingertips", "studies symbols while its gills pulse"), + V("gathers life through sensing spores", "samples living traces with tapping hands"), + V("relieves itself in a cap-covered squat", "expels waste as its gills close"), + V("tilts its cap between unrelated marks", "stares while its gills pulse out of sequence"), + V("recharges as its gills brighten", "draws energy through its stalk-like body"), + V("casts spore puffs under a strange urge", "taps both hands in repeated patterns"), + V("steals {target} with both pale hands", "draws {target} beneath its lowered cap"), + V("jerks as black spores cross its gills", "moves while foreign pulses bend its arms"), + V("sees {target} in cap-shadowed dreams", "rests as gill pulses form dim scenes")); + + AddExtended(voices, "necromancer", + V("sings in layered papery whispers", "chants while pale fragments rattle"), + V("reproduces through paired spectral pulses", "begins mating as pale runes synchronize"), + V("tends growth with grave-pale fingertips", "cultivates beneath orbiting bone light"), + V("pollinates {target} with circling pale fragments", "guides pollen across {target} through spectral force"), + V("trades through measured rune flashes", "bows its hood during exchange"), + V("fishes with a searching spectral wisp", "draws near fish through pale force"), + V("hauls within grasping spectral hands", "moves the load through pale force"), + V("heals {target} with binding pale runes", "tends {target} using spectral fingertips"), + V("fires a grave-pale force bolt", "launches grasping spectral hands"), + V("flees {target} inside streaming pale runes", "glides away as bone light circles faster"), + V("settles within a low rune glow", "rests upright as pale fragments orbit"), + V("guards behind spectral hands", "patrols with bone light circling"), + V("reads through hovering pale runes", "traces symbols with a spectral fingertip"), + V("gathers life through a cold spectral wisp", "samples living traces with pale runes"), + V("relieves itself beneath folded robes", "expels waste as orbiting fragments turn aside"), + V("stares while pale runes reorder themselves", "turns as spectral hands point apart"), + V("recharges as bone light intensifies", "draws energy through raised fingertips"), + V("summons empty hands under a strange urge", "casts pale runes in repeated bursts"), + V("steals {target} with a spectral hand", "draws {target} into circling pale light"), + V("convulses as foreign runes cross its robe", "moves while foreign whispers leave its mouth"), + V("sees {target} in bone-lit dreams", "rests while pale runes replay visions")); + AddExtended(voices, "plague_doctor", + V("sings in filtered beak notes", "hums while round lenses vibrate"), + V("reproduces through a measured mating display", "begins mating as masked breaths synchronize"), + V("tends growth with precise gloved fingers", "cultivates beneath the lowered beak"), + V("pollinates {target} with careful glove strokes", "brushes pollen across {target} beneath its beak"), + V("trades through a formal masked bow", "raises one glove during exchange"), + V("fishes by tracking motion through round lenses", "snaps its long beak near fish"), + V("hauls against its coated shoulders", "moves the load with both gloves"), + V("heals {target} with measured gloved pressure", "examines {target} through round lenses"), + V("fires a narrow beak-directed pulse", "launches force between raised gloves"), + V("flees {target} with coat tails snapping", "hurries away beneath the forward beak"), + V("settles with gloved hands clasped", "rests upright beneath the long mask"), + V("guards with lenses fixed forward", "patrols in quick coated strides"), + V("reads through round mask lenses", "traces marks with one gloved finger"), + V("gathers life through filtered beak breaths", "samples living traces with close lens work"), + V("relieves itself beneath folded coat tails", "expels waste while the beak points aside"), + V("tilts its mask toward unrelated marks", "fumbles as gloved hands repeat different motions"), + V("recharges through slow filtered breaths", "draws energy behind the beaked mask"), + V("taps its beak under a strange urge", "flexes both gloves in repeated patterns"), + V("steals {target} with a quick gloved hand", "draws {target} beneath one folded sleeve"), + V("jerks as foreign vapor fills the beak", "moves while its lenses flash unnaturally"), + V("sees {target} in masked dreams", "rests as its gloved fingers twitch")); + + AddExtended(voices, "printer", + V("sings through sequenced electronic tones", "chatters a tune through turning gears"), + V("reproduces through synchronized print cycles", "begins replication as indicators pulse together"), + V("tends growth with measured roller passes", "cultivates beneath a traveling scan bar"), + V("pollinates {target} with tray-driven puffs", "feeds pollen across {target} beneath its rollers"), + V("trades by printing matching marks", "beeps twice during exchange"), + V("fishes with its traveling scan bar", "snaps its tray near detected fish"), + V("hauls atop its extended tray", "moves the load through humming rollers"), + V("heals {target} with a scanning pass", "applies measured pressure to {target} with its tray"), + V("fires a rapid sheet burst", "launches a pulse from its scan bar"), + V("flees {target} on humming rollers", "trundles away with its tray rattling"), + V("settles with print head parked", "rests with tray tucked closed"), + V("guards with scan bar traveling", "patrols on steady humming rollers"), + V("reads through its narrow glass slit", "copies symbols beneath the scan bar"), + V("gathers life through calibrated scans", "samples living traces with its glass slit"), + V("ejects a strip of dark residue", "purges waste through its lower tray"), + V("feeds blank strips without printing", "flashes conflicting indicators"), + V("recharges as its display brightens", "draws power into humming internal gears"), + V("cycles its tray under a strange urge", "prints repeated marks without pause"), + V("steals {target} through snapping rollers", "draws {target} into its open tray"), + V("shudders as foreign marks fill its display", "runs an imposed sequence of gear turns"), + V("renders {target} in dim display dreams", "rests while its print head twitches")); + + AddExtended(voices, "skeleton", + V("sings through hollow jaw clacks", "rattles a tune across bare ribs"), + V("reproduces through synchronized bone taps", "begins mating as rib cages resonate"), + V("tends growth with bony fingertips", "cultivates through alternating foot rakes"), + V("pollinates {target} with rib-driven puffs", "brushes pollen across {target} with finger bones"), + V("trades through measured jaw clicks", "raises a bare hand during exchange"), + V("fishes with empty sockets lowered", "snaps bare teeth near fish"), + V("hauls against its exposed rib cage", "moves the load with hooked bone fingers"), + V("heals {target} with careful bone pressure", "tends {target} using jointed fingertips"), + V("fires a rattling bone burst", "launches force through its open rib cage"), + V("flees {target} in clattering strides", "scatters away and reassembles farther on"), + V("settles into a neatly folded bone pile", "rests with hands hooked through ribs"), + V("guards with sharpened forearms raised", "patrols in hollow clattering steps"), + V("reads by tapping marks with finger bones", "tilts empty sockets across symbols"), + V("gathers life through vibrating bare feet", "samples living motion with empty sockets"), + V("drops dry waste through its pelvis", "expels residue between loose ribs"), + V("reassembles with bones misplaced", "turns while its jaw chatters at nothing"), + V("recharges as its bones resonate", "draws energy through its empty mouth"), + V("juggles knuckles under a strange urge", "detaches and replaces its jaw repeatedly"), + V("steals {target} with hooked finger bones", "draws {target} behind its rib cage"), + V("rattles as foreign light fills its sockets", "marches in an imposed bone rhythm"), + V("sees {target} in rattling dreams", "rests as dim scenes cross its sockets")); + + AddExtended(voices, "tumor_monster_animal", + V("sings through several wet throats", "gurgles a rhythm across pulsing growths"), + V("reproduces as fleshy buds divide", "begins mating while nodules pulse together"), + V("tends growth with quick uneven paws", "cultivates beneath probing tendrils"), + V("pollinates {target} with trembling nodules", "brushes pollen across {target} with extra limbs"), + V("trades through pulsing sensory lobes", "raises a hooked limb during exchange"), + V("fishes with a ring of wet nostrils", "snaps clustered mouths near fish"), + V("hauls against its swollen shoulder", "moves the load with hooked extra limbs"), + V("heals {target} with soft tissue pressure", "tends {target} using probing tendrils"), + V("fires a hardened tissue barb", "launches force from a pulsing nodule"), + V("flees {target} on scrambling uneven limbs", "lopes away with growths shaking"), + V("settles around its largest pulsing mass", "folds several limbs beneath its body"), + V("guards behind hardened growths", "patrols with wet nostrils testing"), + V("reads by touching marks with tendrils", "turns clustered eyes across symbols"), + V("gathers life through sensitive nodules", "samples living traces with wet nostrils"), + V("expels waste through a puckered opening", "releases residue beneath folded limbs"), + V("stumbles as its limbs choose different paths", "snaps mouths while clustered eyes cross"), + V("recharges as its nodules throb", "draws energy through several mouths"), + V("paws at its flank under a strange urge", "twitches extra limbs in repeated bursts"), + V("steals {target} with a hooked extra limb", "draws {target} beneath a sensory lobe"), + V("convulses as dark pulses cross its growths", "moves while foreign force tightens its tendrils"), + V("sees {target} in pulsing dreams", "rests while clustered eyes flicker")); + + AddExtended(voices, "tumor_monster_unit", + V("sings in overlapping throat pitches", "drums a rhythm across hardened nodules"), + V("reproduces as smaller hands interlace", "begins mating while clustered eyes synchronize"), + V("tends growth with three careful hands", "cultivates through a tasting tendril"), + V("pollinates {target} with several quick palms", "brushes pollen across {target} with extra fingers"), + V("trades through alternating hand signs", "blinks clustered eyes during exchange"), + V("fishes with a thin tasting tendril", "grabs near fish with a smaller hand"), + V("hauls against its oversized arm", "moves the load using three hands"), + V("heals {target} with several measured palms", "tends {target} through soft tissue pressure"), + V("fires a dense tissue pulse", "launches force from its oversized palm"), + V("flees {target} on mismatched legs", "lumbers away with extra arms swinging"), + V("settles with every hand braced", "folds extra limbs around its torso"), + V("guards behind an oversized forearm", "patrols with clustered eyes blinking"), + V("reads by tracing marks with three hands", "turns clustered eyes across symbols"), + V("gathers life through a tasting tendril", "samples living traces with clustered eyes"), + V("expels waste through a side opening", "releases residue beneath its swollen torso"), + V("reaches in several directions at once", "stares while clustered eyes blink out of sequence"), + V("recharges as its growths pulse faster", "draws energy into its swollen frame"), + V("wrestles its own hands under a strange urge", "drums nodules in repeated bursts"), + V("steals {target} with its smaller hands", "draws {target} behind its oversized arm"), + V("jerks as foreign pulses cross its abdomen", "moves while clustered eyes glow darkly"), + V("sees {target} in many-handed dreams", "rests while its nodules replay slow pulses")); + + AddExtended(voices, "white_mage", + V("sings in clear pearl-bright notes", "chants while pale sigils pulse"), + V("reproduces through synchronized light patterns", "begins mating as pearl glows intermingle"), + V("tends growth with open glowing palms", "cultivates beneath woven pale light"), + V("pollinates {target} with pearl-bright motes", "guides pollen across {target} through pale light"), + V("trades through ordered sigil flashes", "bows its bright-edged hood during exchange"), + V("fishes with a searching luminous mote", "draws near fish through pale force"), + V("hauls within woven pale light", "moves the load between open palms"), + V("heals {target} with cleansing light", "tends {target} beneath pearl radiance"), + V("fires a concentrated pale pulse", "launches force between open palms"), + V("flees {target} inside streaming pale light", "glides away as sigils brighten"), + V("settles within ordered pale sigils", "rests with both palms open"), + V("guards behind a shining barrier", "patrols with pearl motes circling"), + V("reads as pale light reveals marks", "studies symbols through ordered sigils"), + V("gathers life through a luminous mote", "samples living traces with pearl light"), + V("relieves itself beneath a pale veil", "releases waste as sigils turn aside"), + V("flickers while sigils reorder themselves", "turns as pearl motes point apart"), + V("recharges as robe edges brighten", "draws energy through open palms"), + V("folds light under a strange urge", "casts empty sigils in repeated bursts"), + V("steals {target} with a pale force pulse", "draws {target} between open palms"), + V("shudders as dark sigils cross its robe", "moves while foreign light bends its hands"), + V("sees {target} in pearl-lit dreams", "rests as pale sigils replay visions")); + + AddExtended(voices, "zombie", + V("sings in a broken throaty moan", "groans a rhythm through its crooked jaw"), + V("reproduces through a stiff mating display", "begins mating as dead limbs twitch together"), + V("tends growth with slow stiff fingers", "cultivates through repeated palm presses"), + V("pollinates {target} with dragging hand sweeps", "brushes pollen across {target} with stiff fingers"), + V("trades through a delayed hand raise", "groans once during exchange"), + V("fishes with an unbroken forward stare", "snaps broken teeth near fish"), + V("hauls against its stiff shoulders", "pushes the load with both rigid arms"), + V("heals {target} with slow hand pressure", "tends {target} using stiff fingertips"), + V("fires a hoarse mouth pulse", "launches force with both reaching hands"), + V("flees {target} in a dragging lurch", "shambles away with arms swinging"), + V("settles into a limp heap", "rests upright with jaw hanging"), + V("guards with both stiff hands raised", "patrols in slow dragging steps"), + V("reads with an unbroken stare", "traces marks using one rigid finger"), + V("gathers life through a ruined nose", "samples living traces with broken teeth"), + V("relieves itself without changing its stare", "expels waste in a stiff crouch"), + V("turns toward unrelated movement", "reaches while its feet remain planted"), + V("recharges as dead limbs twitch", "draws energy through its open mouth"), + V("reaches repeatedly under a strange urge", "rocks side to side without pause"), + V("steals {target} with both stiff hands", "draws {target} against its rigid chest"), + V("jerks as foreign force straightens it", "marches while dark pulses cross its limbs"), + V("sees {target} in twitching dreams", "rests as its fingers grasp at dim visions")); + + AddExtended(voices, "snowman", + V("sings in cold hollow crunches", "rumbles a tune through packed sections"), + V("reproduces as packed sections bud", "begins mating while cold pulses synchronize"), + V("tends growth with stick-like limb taps", "cultivates through careful body pressure"), + V("pollinates {target} with broad limb sweeps", "brushes pollen across {target} with packed hands"), + V("trades through a rounded body dip", "waves one stick-like limb during exchange"), + V("fishes through pulsing cold-body effects", "scoops near fish with packed limbs"), + V("hauls against its rounded lower section", "pushes the load with both stick-like limbs"), + V("heals {target} with numbing body pressure", "tends {target} using packed hands"), + V("fires a burst of packed body snow", "launches cold force between raised limbs"), + V("flees {target} in a swaying waddle", "pivots away as packed sections wobble"), + V("settles into a stable stacked posture", "rests with stick-like limbs tucked"), + V("guards with both limbs spread", "patrols in slow rounded pivots"), + V("reads by tapping marks with one limb", "rotates its upper section across symbols"), + V("gathers life through cold-body pulses", "samples living traces with packed hands"), + V("releases waste beneath its lower section", "expels dark residue while sections compress"), + V("rotates its sections in conflicting directions", "points both limbs toward unrelated marks"), + V("recharges as its packed body brightens", "draws energy through stacked sections"), + V("twirls both limbs under a strange urge", "rotates its upper section repeatedly"), + V("steals {target} with a sweeping limb", "draws {target} against its rounded body"), + V("shudders as dark cold pulses spread", "moves while foreign force twists its sections"), + V("sees {target} in cold-pulsed dreams", "rests while cold-body pulses replay visions")); + } +} diff --git a/IdleSpectator/ActivitySpeciesVoices.Fantasy.Specialized.cs b/IdleSpectator/ActivitySpeciesVoices.Fantasy.Specialized.cs new file mode 100644 index 0000000..adc2876 --- /dev/null +++ b/IdleSpectator/ActivitySpeciesVoices.Fantasy.Specialized.cs @@ -0,0 +1,333 @@ +using System.Collections.Generic; + +namespace IdleSpectator; + +public static partial class ActivitySpeciesVoiceCatalog +{ + private static void AddFantasySpecializedVoices(Dictionary voices) + { + AddSpecialized(voices, "UFO", + V("kindles flame beneath a focused heat ray", "spreads fire with a sweeping thermal beam"), + V("smothers flame beneath a cooling field", "dims fire with a pulsing suppression ray"), + V("gathers with kin through synchronized signals", "joins kin beneath matching light pulses"), + V("draws observed essence through a scanning beam", "samples visible life force beneath its hull"), + V("searches with a narrow scan", "reaches with a controlled lifting field"), + V("sounds a rising electronic trill", "pulses a wavering alarm tone"), + V("blasts clipped synthetic notes", "flashes harsh signals with a metallic buzz")); + + AddSpecialized(voices, "alien", + V("sparks flame between clicking fingertips", "spreads fire with crackling wrist pulses"), + V("presses flame down with splayed hands", "quenches fire beneath a bioelectric pulse"), + V("gathers with kin through rapid clicks", "joins kin in mirrored body pulses"), + V("draws observed essence through tasting fingertips", "samples visible life force with its mouthparts"), + V("searches with four darting hands", "reaches with narrow grasping fingers"), + V("cries through a trembling throat sac", "releases a chain of bubbling chirps"), + V("chatters in jagged throat clicks", "snaps out a harsh clicking burst")); + + AddSpecialized(voices, "angle", + V("kindles flame with holy radiance", "spreads fire through a surge of divine light"), + V("suppresses flame beneath sacred brilliance", "dims fire within steady celestial light"), + V("gathers with kin through shared holy radiance", "joins kin beneath shared divine light"), + V("draws life essence into holy radiance", "channels life force through celestial light"), + V("searches beneath revealing sacred light", "reaches through a pulse of divine radiance"), + V("sounds a sustained celestial chime", "releases a trembling hymn of light"), + V("voices sharp sacred tones", "flares with a harsh divine cadence")); + + AddSpecialized(voices, "assimilator", + V("kindles flame with a searing membrane pulse", "spreads fire through reaching hot tendrils"), + V("smothers flame beneath a widening membrane", "draws fire into heat-drinking tissue"), + V("gathers with kin through braided tendrils", "joins kin by matching surface pulses"), + V("draws observed essence through tasting filaments", "absorbs visible life force beneath rippling tissue"), + V("searches with many probing feelers", "reaches through a forming grasping limb"), + V("cries through several borrowed throats", "releases mismatched wails across its surface"), + V("barks layered borrowed syllables", "snaps through a chorus of harsh voices")); + + AddSpecialized(voices, "civ_crystal_golem", + V("kindles flame with a white-hot core pulse", "spreads fire through radiant crystal seams"), + V("suppresses flame beneath cooling crystal light", "draws fire into dimming core seams"), + V("gathers with kin through resonant core hums", "joins kin as inner lights pulse together"), + V("draws observed essence through luminous facets", "channels visible life force into its core"), + V("searches with refracted inner light", "reaches with broad crystalline hands"), + V("cries in a deep crystalline peal", "rings from every facet in trembling notes"), + V("booms in sharp core-deep pulses", "clashes its facets through a harsh resonance")); + + AddSpecialized(voices, "cold_one", + V("kindles flame with a concentrated pale spark", "spreads fire from a pale crackling palm"), + V("smothers flame beneath hardening rime", "quenches fire with a numbing cold pulse"), + V("gathers with kin through clicking frozen teeth", "joins kin as cold vapors mingle"), + V("draws observed essence through a whitening palm", "pulls visible life force into its rime"), + V("searches with heat-sensitive fingers", "reaches with a frost-rimmed hand"), + V("cries in a thin ice-cracking shriek", "releases a long chime through frozen teeth"), + V("snaps out brittle frozen clicks", "rasps through a burst of cracking rime")); + + AddSpecialized(voices, "crabzilla", + V("kindles flame between grinding mouthplates", "spreads fire with a vast heated breath"), + V("smothers flame beneath a colossal pincer", "quenches fire with a crushing shell-borne pressure"), + V("gathers with kin through booming pincer clacks", "joins kin as armored shells resonate"), + V("draws observed essence through sweeping eye stalks", "pulls visible life force between its mouthplates"), + V("searches with swiveling eye stalks", "reaches with a colossal open pincer"), + V("cries in a shell-rattling bellow", "clacks its mouthparts in thunderous pulses"), + V("snaps both pincers in a harsh barrage", "grinds out a booming plated rasp")); + + AddSpecialized(voices, "crystal_sword", + V("kindles flame along its glowing edge", "spreads fire through a searing blade pulse"), + V("parts flame with a cooling edge", "draws fire into dimming crystal facets"), + V("gathers with kin through matching crystal peals", "joins kin as suspended blades resonate"), + V("draws observed essence along its fuller", "channels visible life force into its jeweled guard"), + V("searches with its point slowly testing", "reaches with a hovering hilt"), + V("cries in a high sustained ring", "trembles through a descending crystal peal"), + V("rings in sharp metallic bursts", "shivers its edge through a harsh bright note")); + + AddSpecialized(voices, "demon", + V("kindles flame between blackened claws", "spreads fire with a scorching breath"), + V("smothers flame inside a smoking palm", "draws fire beneath ember-hot skin"), + V("gathers with kin through heated snarls", "joins kin as smoking bodies press close"), + V("draws observed essence through glowing fangs", "pulls visible life force into its hot core"), + V("searches with heat-sensing nostrils", "reaches with hooked claws"), + V("cries in a cracked furnace howl", "releases a throat-deep scorching wail"), + V("barks harsh syllables through smoking fangs", "snarls in short ember-spitting bursts")); + + AddSpecialized(voices, "dragon", + V("kindles flame behind serrated teeth", "spreads fire with a broad searing breath"), + V("smothers flame beneath a plated foreclaw", "draws fire back through flared nostrils"), + V("gathers with kin through chest-deep rumbles", "joins kin as plated bodies resonate"), + V("draws observed essence through flared nostrils", "pulls visible life force between glowing teeth"), + V("searches with unblinking eyes", "reaches with an open foreclaw"), + V("cries in a vast chest-deep roar", "releases a long horn-rattling bellow"), + V("snaps out thunderous guttural syllables", "growls through bursts of bright sparks")); + + AddSpecialized(voices, "druid", + V("kindles flame between bark-lined palms", "spreads fire through glowing sap"), + V("smothers flame beneath unfurling leaves", "draws fire into darkening living grain"), + V("gathers with kin through rustling leaf-signals", "joins kin as living fibers intertwine"), + V("draws observed essence through root-like fingers", "pulls visible life force into living grain"), + V("searches with curling rootlets", "reaches with a vine-wrapped hand"), + V("cries through a dry leafy rasp", "releases a low wooden groan"), + V("utters clipped syllables through rustling leaves", "snaps living grain in a harsh cadence")); + + AddSpecialized(voices, "evil_mage", + V("kindles flame from violet fingertips", "spreads fire through crawling dark sparks"), + V("smothers flame beneath folded shadow", "draws fire into a dim violet aura"), + V("gathers with kin through layered whispers", "joins kin as dark auras overlap"), + V("draws observed essence into a shadowed palm", "pulls visible life force through violet sparks"), + V("searches through a circling violet eye", "reaches with a shadow-wrapped hand"), + V("cries in a thin echoing rasp", "releases a wavering chorus of whispers"), + V("hisses clipped words through violet static", "barks a harsh syllable as shadows pulse")); + + AddSpecialized(voices, "fairy", + V("kindles flame from sparkling fingertips", "spreads fire through pulsing bright motes"), + V("dims flame beneath cooling shimmer", "smothers fire inside a veil of motes"), + V("gathers with kin through matching light pulses", "joins kin as tiny glows mingle"), + V("draws observed essence into sparkling motes", "pulls visible life force through its shimmer"), + V("searches with flickering motes", "reaches with both tiny hands"), + V("cries in a piercing bell-like trill", "releases a trembling chain of tiny notes"), + V("chirps sharp syllables in rapid bursts", "flashes harshly through a clipped trill")); + + AddSpecialized(voices, "fire_elemental", + V("kindles flame from its white-hot core", "spreads fire through reaching tongues of flame"), + V("draws loose flame back into its core", "banks fire beneath a dim ember shell"), + V("gathers with kin as sparks intermingle", "joins kin through merging flame pulses"), + V("draws observed essence into its burning core", "pulls visible life force through licking flames"), + V("searches with thin reaching flames", "reaches with a forming arm of fire"), + V("cries in a roaring cascade of crackles", "releases a long furnace-like howl"), + V("snaps in harsh explosive pops", "flares through a jagged crackling burst")); + + AddSpecialized(voices, "fire_elemental_blob", + V("kindles flame from a bubbling hot lobe", "spreads fire through clinging molten droplets"), + V("draws flame beneath a cooling crust", "smothers fire inside its soft molten body"), + V("gathers with kin through shared bubbling pulses", "joins kin as molten sides mingle"), + V("draws observed essence through a glowing pseudopod", "pulls visible life force beneath its liquid surface"), + V("searches with a wavering hot lobe", "reaches with a stretching pseudopod"), + V("cries in a wet chain of fiery pops", "gurgles through a long bubbling wail"), + V("bursts in harsh sputtering pops", "slaps its molten surface through a jagged hiss")); + + AddSpecialized(voices, "fire_elemental_horse", + V("kindles flame between glowing teeth", "spreads fire through a blazing breath"), + V("draws flame into its ember-bright muzzle", "stamps fire beneath a cooling hoof"), + V("gathers with kin through furnace nickers", "joins kin as fiery manes mingle"), + V("draws observed essence through flared nostrils", "pulls visible life force into its burning chest"), + V("searches with a glowing muzzle", "reaches with ember-bright teeth"), + V("cries in a rising furnace whinny", "releases a long crackling nicker"), + V("snorts sharp bursts of sparks", "barks a harsh note through glowing teeth")); + + AddSpecialized(voices, "fire_elemental_slug", + V("kindles flame beneath its glowing mantle", "spreads fire through a molten body ribbon"), + V("draws flame under a cooled black crust", "smothers fire beneath its broad heated underside"), + V("gathers with kin through touching flame feelers", "joins kin as glowing mantles pulse together"), + V("draws observed essence through heat-sensitive feelers", "pulls visible life force beneath its mantle"), + V("searches with sweeping flame feelers", "reaches with an extended glowing mantle"), + V("cries in a long wet sizzle", "releases a bubbling crackle through its mantle"), + V("pops in sharp hissing bursts", "rasps through a harsh chain of sizzles")); + + AddSpecialized(voices, "fire_elemental_snake", + V("kindles flame behind a forked fire tongue", "spreads fire along its blazing coils"), + V("draws flame into banked coils", "smothers fire beneath overlapping ember scales"), + V("gathers with kin through braided burning coils", "joins kin as forked sparks pulse together"), + V("draws observed essence through its split flame tongue", "pulls visible life force along glowing coils"), + V("searches with a flickering forked tongue", "reaches with an opening fiery coil"), + V("cries in a long crackling hiss", "rattles out a wavering chain of pops"), + V("hisses in clipped searing bursts", "snaps its flame tongue through harsh crackles")); + + AddSpecialized(voices, "fire_skull", + V("kindles flame inside its hollow mouth", "spreads fire through snapping blazing jaws"), + V("draws flame into empty sockets", "smothers fire beneath its dimming crown"), + V("gathers with kin through synchronized jaw clacks", "joins kin as hollow sockets flare together"), + V("draws observed essence through empty sockets", "pulls visible life force between blazing teeth"), + V("searches with fixed hollow sockets", "reaches with opening jaws"), + V("cries in a hollow fire-fed howl", "cackles through a trembling loose jaw"), + V("clacks out harsh tooth-borne bursts", "barks through a flare of roaring fire")); + + AddSpecialized(voices, "ghost", + V("kindles pale flame in a spectral palm", "spreads fire through a wavering aura"), + V("smothers flame inside its translucent form", "dims fire beneath a chilling spectral pulse"), + V("gathers with kin through overlapping outlines", "joins kin as spectral auras mingle"), + V("draws observed essence into its hollow form", "pulls visible life force through a translucent hand"), + V("searches through a wavering outline", "reaches with a spectral hand"), + V("cries in a long airy wail", "moans through a trembling echo"), + V("rasps in clipped hollow syllables", "warbles through a harsh spectral pulse")); + + AddSpecialized(voices, "god_finger", + V("kindles flame beneath its rounded tip", "spreads fire with a heated nail pulse"), + V("presses flame beneath its broad tip", "draws fire into a dimming nail"), + V("gathers with kin through fingertip taps", "joins kin as nails pulse together"), + V("draws observed essence through its sensitive tip", "pulls visible life force beneath its nail"), + V("searches with its tip flexing", "reaches with a slowly curling digit"), + V("cries through rapid self-drumming taps", "trembles out a rolling nail-borne rattle"), + V("taps out a harsh clipped sequence", "snaps its nail in sharp repeated bursts")); + + AddSpecialized(voices, "greg", + V("kindles flame between rubbing palms", "spreads fire through a hot open-mouthed breath"), + V("smothers flame beneath both broad hands", "blows a forceful breath across the fire"), + V("gathers with kin through matching nasal honks", "joins kin in close shoulder contact"), + V("draws observed essence through spread fingertips", "pulls visible life force into its open mouth"), + V("searches with unblinking eyes", "reaches with both open hands"), + V("cries in a long nasal honk", "wheezes through a trembling throat"), + V("barks blunt syllables through clenched teeth", "snorts a harsh broken cadence")); + + AddSpecialized(voices, "jumpy_skull", + V("kindles flame between chattering teeth", "spreads fire through snapping hot jaws"), + V("smothers flame beneath its heavy cranium", "draws fire into hollow sockets"), + V("gathers with kin through rapid jaw clacks", "joins kin as bare craniums rattle together"), + V("draws observed essence through hollow sockets", "pulls visible life force between chattering teeth"), + V("searches with tilted empty sockets", "reaches with an opening jaw"), + V("cries in a hollow rattling shriek", "cackles through uncontrollable jaw clacks"), + V("snaps out a harsh tooth-clacking barrage", "rattles its cranium through clipped bursts")); + + AddSpecialized(voices, "living_house", + V("kindles flame within its glowing interior", "spreads fire through heat pulsing from its openings"), + V("smothers flame behind closing shutters", "draws fire into a darkened interior"), + V("gathers with kin through resonant inner bells", "joins kin as windows pulse together"), + V("draws observed essence through open windows", "pulls visible life force into its interior"), + V("searches through swiveling windows", "reaches with an opening doorway"), + V("cries through rattling windows and walls", "releases a long foundation-deep groan"), + V("slams its openings in harsh succession", "rings a sharp booming inner bell")); + + AddSpecialized(voices, "living_plants", + V("kindles flame through heating sap", "spreads fire along glowing vines"), + V("smothers flame beneath broad folded leaves", "draws fire into thick cooling sap"), + V("gathers with kin through intertwining roots", "joins kin as leaf pulses synchronize"), + V("draws observed essence through fine root hairs", "pulls visible life force into its central bud"), + V("searches with probing roots", "reaches with a curling vine"), + V("cries in a long rustling rasp", "releases a dry pod-rattling wail"), + V("snaps leaves in a harsh cadence", "rattles dry pods through clipped bursts")); + + AddSpecialized(voices, "mush_animal", + V("kindles flame through a hot spore puff", "spreads fire beneath a pulsing cap"), + V("smothers flame beneath its broad damp cap", "quenches fire with a dense cooling spore cloud"), + V("gathers with kin through synchronized gill puffs", "joins kin as broad caps press together"), + V("draws observed essence through porous gills", "pulls visible life force beneath its cap"), + V("searches with a porous snout", "reaches with quick forepaws"), + V("cries in a damp bubbling squeal", "chuffs through rapidly pulsing gills"), + V("snaps flat teeth through harsh squeaks", "puffs clipped rasping bursts from its gills")); + + AddSpecialized(voices, "mush_unit", + V("kindles flame in a heated spore puff", "spreads fire beneath its broad cap"), + V("smothers flame under pulsing damp gills", "quenches fire with a dense cooling spore veil"), + V("gathers with kin through shared spore pulses", "joins kin as broad caps touch"), + V("draws observed essence through hanging gills", "pulls visible life force beneath its cap"), + V("searches with trembling fingertips", "reaches with a pale open hand"), + V("cries in a low papery wail", "releases a trembling puff through its gills"), + V("rasps clipped syllables beneath its cap", "snaps out harsh papery puffs")); + + AddSpecialized(voices, "necromancer", + V("kindles grave-pale flame in one hand", "spreads fire through cold spectral wisps"), + V("smothers flame beneath a wan magic pulse", "draws fire into circling pale light"), + V("gathers with kin through layered bone-dry whispers", "joins kin as pale auras overlap"), + V("draws observed essence into a raised hand", "pulls visible life force through grave-pale magic"), + V("searches through a floating spectral wisp", "reaches with a pale open hand"), + V("cries in a papery hollow wail", "releases a chorus of rattling whispers"), + V("hisses clipped syllables through pale static", "rasps in a harsh bone-dry cadence")); + + AddSpecialized(voices, "plague_doctor", + V("kindles flame through a narrow filtered breath", "spreads fire from a heated gloved palm"), + V("smothers flame beneath both gloved hands", "quenches fire through a cooling filtered breath"), + V("gathers with kin through measured beak clicks", "joins kin as masked heads incline together"), + V("draws observed essence through round mask lenses", "pulls visible life force into the narrow beak"), + V("searches through round dark lenses", "reaches with a gloved hand"), + V("cries in a muffled hollow rasp", "releases a long filtered wheeze"), + V("barks clipped syllables behind the beak", "snaps out harsh muffled sounds")); + + AddSpecialized(voices, "printer", + V("kindles flame beneath an overheating print head", "spreads fire through a hot internal pulse"), + V("smothers flame beneath a cooling internal vent", "suppresses fire with a pulsing thermal cutoff"), + V("gathers with kin through synchronized status beeps", "joins kin as indicator lights match"), + V("draws observed essence through its scan bar", "samples visible life force across its glass slit"), + V("searches with a traveling scan light", "reaches with its extending tray"), + V("cries in a wavering electronic whine", "chatters its gears through a broken alarm"), + V("blasts sharp electronic tones", "rattles out a harsh mechanical sequence")); + + AddSpecialized(voices, "skeleton", + V("kindles flame inside its hollow rib cage", "spreads fire through snapping bare fingers"), + V("smothers flame beneath interlocked bones", "draws fire into empty sockets"), + V("gathers with kin through matching bone rattles", "joins kin as bare ribs clack together"), + V("draws observed essence through empty sockets", "pulls visible life force into its rib cage"), + V("searches with its hollow gaze", "reaches with a bare jointed hand"), + V("cries in a hollow jaw-flapping wail", "rattles from skull to toes in long pulses"), + V("clacks teeth in a harsh barrage", "snaps finger bones through clipped beats")); + + AddSpecialized(voices, "tumor_monster_animal", + V("kindles flame from a heated pulsing nodule", "spreads fire through a searing tendril"), + V("smothers flame beneath a broad fleshy lobe", "draws fire into cooling swollen tissue"), + V("gathers with kin through matching tissue pulses", "joins kin as sensory lobes touch"), + V("draws observed essence through wet nostrils", "pulls visible life force into a pulsing growth"), + V("searches with sensitive nodules", "reaches with a twitching tendril"), + V("cries through several throats at once", "releases a wet overlapping wail"), + V("snaps crowded teeth through harsh gurgles", "barks from several mouths in clipped bursts")); + + AddSpecialized(voices, "tumor_monster_unit", + V("kindles flame in a throbbing heated palm", "spreads fire through a searing extra limb"), + V("smothers flame beneath an oversized hand", "draws fire into cooling pulsing tissue"), + V("gathers with kin through synchronized nodules", "joins kin as sensory tendrils touch"), + V("draws observed essence through clustered eyes", "pulls visible life force into a pulsing abdomen"), + V("searches with clustered blinking eyes", "reaches with several open hands"), + V("cries in overlapping throaty pitches", "releases a wet wail from several vents"), + V("barks clipped sounds from a sideways mouth", "snorts through several vents in harsh bursts")); + + AddSpecialized(voices, "white_mage", + V("kindles flame in a pearl-bright palm", "spreads fire through cleansing light"), + V("suppresses flame beneath a pale luminous veil", "dims fire within cooling pearl light"), + V("gathers with kin through shared luminous pulses", "joins kin as pale auras overlap"), + V("draws observed essence through an open palm", "pulls visible life force into pearl-white light"), + V("searches through a revealing luminous mote", "reaches with a light-wrapped hand"), + V("cries in a clear sustained ring", "releases a trembling luminous hum"), + V("voices clipped ringing syllables", "flashes sharply through a harsh bright cadence")); + + AddSpecialized(voices, "zombie", + V("kindles flame between stiff rubbing hands", "spreads fire through a hot broken-toothed breath"), + V("smothers flame beneath both stiff hands", "presses its cold body against the fire"), + V("gathers with kin through matching groans", "joins kin in close cold contact"), + V("draws observed essence through a ruined nose", "pulls visible life force into its open mouth"), + V("searches with an unbroken stare", "reaches with both stiff hands"), + V("cries through a long crooked-jaw groan", "gurgles in a wavering broken-throat call"), + V("barks hoarse clipped syllables", "snaps broken teeth through a harsh rasp")); + + AddSpecialized(voices, "snowman", + V("kindles flame between its cold stick-like limbs", "spreads fire through a heat pulse from its packed body"), + V("smothers flame beneath its packed cold body", "quenches fire with a burst of its own cold powder"), + V("gathers with kin through matching body tremors", "joins kin as packed sides press together"), + V("draws observed essence through its rounded upper body", "pulls visible life force into its packed middle"), + V("searches by rotating its upper body", "reaches with both stick-like limbs"), + V("cries in a powdery body-deep crunch", "releases a long packed-body rumble"), + V("snaps its stick-like limbs in harsh beats", "crunches through a clipped rumbling burst")); + } +} diff --git a/IdleSpectator/ActivitySpeciesVoices.Fantasy.cs b/IdleSpectator/ActivitySpeciesVoices.Fantasy.cs index 611e0cb..14e8431 100644 --- a/IdleSpectator/ActivitySpeciesVoices.Fantasy.cs +++ b/IdleSpectator/ActivitySpeciesVoices.Fantasy.cs @@ -31,16 +31,16 @@ public static partial class ActivitySpeciesVoiceCatalog V("sorts material by shape with four quick hands", "fits task material with narrow fingers")); Add(voices, "angle", - V("slides point-first along a rigid path", "turns through a perfectly sharp corner"), - V("balances on one luminous vertex", "hangs motionless between intersecting lines"), - V("folds and unfolds into crisp new shapes", "traces a tiny polygon with luminous edges"), - V("absorbs energy through its luminous edges", "draws energy into its center"), - V("flattens into a dim, closed figure", "rests with every edge neatly aligned"), - V("hunts {target} with straight geometric feelers", "hunts {target} from a rotating vertex"), - V("attacks {target} with a razor-straight edge", "attacks {target} by closing its angles"), - V("meets another outline edge to edge", "signals by changing the count of its corners"), - V("chimes with laughter from every taut edge", "chimes a laugh in two exact intervals"), - V("scores precise boundaries across task material", "squares a precision task one line at a time")); + V("glides beneath a mantle of holy radiance", "advances as divine light gathers around it"), + V("stands watch in unwavering celestial brilliance", "holds vigil within pale radiance"), + V("sends brief gleams through its aura", "pulses its radiant presence in a bright cadence"), + V("draws energy into its divine glow", "brightens as holy power fills its presence"), + V("dims to a quiet celestial ember", "rests within a gently fading aura"), + V("hunts {target} through revealing holy light", "hunts {target} as its radiance intensifies"), + V("attacks {target} with a surge of divine light", "attacks {target} in cleansing brilliance"), + V("greets nearby company with a sacred glow", "answers another presence with radiant pulses"), + V("chimes with bright celestial laughter", "laughs as celestial light ripples outward"), + V("casts divine radiance over its labor", "shapes each effort with steady divine light")); Add(voices, "assimilator", V("pulls itself forward on braided tendrils", "rolls its shifting bulk in measured surges"), diff --git a/IdleSpectator/ActivitySpeciesVoices.Invertebrates.Extended.cs b/IdleSpectator/ActivitySpeciesVoices.Invertebrates.Extended.cs new file mode 100644 index 0000000..0b77911 --- /dev/null +++ b/IdleSpectator/ActivitySpeciesVoices.Invertebrates.Extended.cs @@ -0,0 +1,459 @@ +using System.Collections.Generic; + +namespace IdleSpectator; + +public static partial class ActivitySpeciesVoiceCatalog +{ + private static void AddInvertebrateExtendedVoices(Dictionary voices) + { + AddExtended( + voices, + "acid_blob", + V("warbles through fizzing surface bubbles", "ripples its rim in a wet, rising cadence"), + V("folds a budding lobe slowly into a reproductive union", "tightens its surface around a pulsing germ"), + V("etches planting seams with a narrow acidic feeler", "bathes each planting point in a measured secretion"), + V("dusts reproductive grains from one tacky lobe to another", "rolls a pollen film across its adhesive rim"), + V("pinches off a measured bead and absorbs one in return", "opens a surface pocket to barter with pulsing rim-signals"), + V("sweeps a thin pseudopod in search of a catch", "fans a sensing film outward before snapping it inward"), + V("rolls its mass forward in a series of hauling surges", "anchors its rear rim and drags with a broad front lobe"), + V("lays a mild sealing film over {target}", "presses a cool regenerative lobe against {target}"), + V("spreads into a smothering sheet over the flame", "jets damp acidic foam at the flame"), + V("streams away in one stretched ribbon", "retracts every feeler and pours into a rapid glide"), + V("anchors a broad rim and raises a stable central mound", "spreads firm lobes until its mass rests securely"), + V("hardens its leading edge into a rippling guard", "raises a striking lobe charged with corrosive pressure"), + V("tracks each line with a hair-thin surface filament", "pulses paired eye-like spots from mark to mark"), + V("draws loose life-glow through its translucent skin", "cups a fading essence inside a sealed inner bubble"), + V("opens a rear pore and expels a spent acidic bead", "contracts from front to back and releases spent fluid"), + V("sends contradictory ripples around its rim", "splits its leading lobe twice before drawing both halves back"), + V("pulls its mass inward as inner bubbles brighten", "rests wide while restorative pulses thicken its center"), + V("raises an unbidden spire that curls into its own surface", "paddles one lobe against the rhythm of the rest"), + V("slides a silent filament toward {target}", "reaches an opaque surface pocket toward {target}"), + V("bucks as foreign pulses race through its mass", "forms jagged lobes that strike without its usual flow"), + V("drifts in sleep while dim shapes bloom beneath its skin", "replays slow phantom ripples across its resting pool")); + + AddExtended( + voices, + "ant_black", + V("stridulates a clipped rhythm through its body plates", "clicks its mandibles beneath a steady antenna beat"), + V("aligns abdomen to abdomen in a brisk reproductive clasp", "circles once with linked feelers before mating"), + V("scores straight planting furrows with its mandibles", "tamps each planting point with all six feet"), + V("combs pollen along its forelegs and antennae", "presses its dusted body against receptive blossoms"), + V("barters with rapid paired feeler taps", "passes and receives with precise mandible grips"), + V("searches for a catch with jaws poised", "waits under still antennae before snapping its mandibles"), + V("locks its jaws on the haul and pulls in a straight course", "braces all six feet and drags without veering"), + V("grooms {target} with fine mouthpart strokes", "presses both antenna tips gently against {target}"), + V("beats at the flame with rapid abdomen sweeps", "scrapes a smothering path forward with its forelegs"), + V("scurries away in a low straight burst", "folds its feelers back and drives all six feet rapidly"), + V("tests its surroundings with brisk antenna taps before stopping", "settles all six feet into a compact ordered stance"), + V("sets its feet square and opens its mandibles", "advances in a disciplined line with antennae level"), + V("follows each mark with alternating feeler taps", "holds still while both antennae read from side to side"), + V("hooks a fading life-thread between its mandibles", "draws the gathered essence along both antennae"), + V("raises its abdomen and releases a compact dropping", "plants its forefeet as its abdomen briefly contracts"), + V("crosses and recrosses a straight path", "taps one antenna rapidly while the other holds rigid"), + V("folds low as energy returns through its six limbs", "grooms each leg in sequence during recovery"), + V("marches backward while its antennae insist forward", "repeatedly opens one mandible and closes the other"), + V("slips flattened antennae and mandibles toward {target}", "tries to pinch {target} before backing away silently"), + V("jerks in broken straight lines under an alien impulse", "snaps its jaws while both feelers curl against its head"), + V("tucks all six feet close as its antennae twitch in sleep", "makes faint marching motions beneath a resting crouch")); + + AddExtended( + voices, + "ant_blue", + V("ticks its mouthparts in a measured ascending scale", "draws paired antenna arcs to a precise body hum"), + V("matches alternating feeler strokes before a balanced mating clasp", "joins abdomen tips while all six feet hold a careful stance"), + V("sets planting points at equal intervals with paired jaws", "levels each furrow with alternating forefoot strokes"), + V("maps pollen between crossing antennae and forelegs", "turns in exact angles while brushing reproductive dust onward"), + V("barters with mirrored feeler taps on both sides", "rotates paired mouthparts in a measured give-and-take"), + V("angles its antennae while searching for a catch", "closes both jaws in a precisely timed fishing snap"), + V("sets centered mandibles on the haul and steps backward evenly", "pulls with alternating six-foot braces"), + V("sweeps both antennae symmetrically over {target}", "tends {target} with equal strokes of its paired mouthparts"), + V("fans the flame with alternating wingless body pivots", "presses a measured smothering edge forward with both forelegs"), + V("retreats in exact zigzags with feelers laid back", "sidesteps away through alternating angular turns"), + V("surveys in widening antenna arcs before planting its feet", "settles into alignment with paired forefoot adjustments"), + V("holds a high squared stance with jaws centered", "paces in measured angular steps with mandibles ready"), + V("brackets each line between parallel antennae", "advances both feeler tips across the marks together"), + V("triangulates a loose life-spark between its feelers", "channels gathered essence down paired antennae in matched pulses"), + V("balances high and releases a neat abdominal pellet", "holds every foot fixed as its abdomen contracts"), + V("turns left and right by identical angles without advancing", "draws mismatched symbols with its crossing antennae"), + V("rests on straightened legs as strength pulses in pairs", "folds each limb in mirrored sequence while recharging"), + V("traces an exact circle with only one feeler", "steps in a rigid pattern its body did not choose"), + V("times a reach for {target} between alternating antenna sweeps", "tries to nip {target} before withdrawing in a precise zigzag"), + V("moves in impossible angles as foreign force bends its joints", "crosses both antennae tightly while its feet pace alone"), + V("rests narrow while paired feelers sketch silent patterns", "ticks its feet in symmetrical dream motions")); + + AddExtended( + voices, + "ant_green", + V("scrapes its jaws in springing syncopation", "drums raised forelegs beneath a bouncing chirr"), + V("vaults into a hooked reproductive embrace", "links feelers overhead while abdomen tips meet"), + V("cuts planting slits with hooked forefeet", "vaults between planting points and presses them with its abdomen"), + V("sweeps pollen onward with raised forelegs", "hooks reproductive dust into the hairs of its wrists"), + V("barters with mandibles lifted high", "links its forelegs in an arched give-and-take"), + V("poises on folded hind legs while seeking a catch", "hooks downward with both raised forefeet"), + V("loops its forelegs around the haul and bounds backward", "hooks underneath and pulls in springing steps"), + V("clasps {target} gently between hooked wrists", "grooms {target} with elevated mandible strokes"), + V("beats both raised forelegs over the flame", "springs past the flame with broad abdomen sweeps"), + V("vaults away with forelegs tucked over its head", "bounds back in quick doubled leaps"), + V("hooks its forefeet down and settles its weight", "arches its body above six firm leg braces"), + V("raises both forelegs like hooked standards", "bounds forward with mandibles lifted for battle"), + V("holds the marks aloft between its forefeet", "reads each line with one hooked wrist"), + V("catches a life-glimmer between uplifted feelers", "channels gathered essence down its raised forelegs"), + V("rears on four feet and releases from its abdomen", "folds its forelegs overhead as its abdomen contracts"), + V("vaults forward and lands facing the same direction", "grooms one feeler while the other circles wildly"), + V("curls into a high-legged rest as vigor rebounds", "pumps its folded hind legs in a restoring rhythm"), + V("clasps its own antennae and tries to vault beneath them", "holds both forelegs aloft while spinning involuntarily"), + V("hooks one raised foreleg toward {target}", "tries to snag {target} before bounding away"), + V("rears repeatedly as an outside rhythm seizes its legs", "swings its hooked forefeet at empty intervals"), + V("curls around raised forelegs while hind legs twitch", "makes tiny sleeping vaults without leaving its crouch")); + + AddExtended( + voices, + "ant_red", + V("clacks wide mandibles in a fierce rolling cadence", "stamps all six feet beneath a hard body rattle"), + V("locks into a forceful reproductive coupling", "circles with jaws spread before abdomen tips join"), + V("tears planting furrows with driving mandible strokes", "rams each planting point with its plated head"), + V("charges among blossoms with dusted body hairs", "scrapes pollen onward using forceful foreleg strokes"), + V("barters between jaws held wide", "seals its give-and-take with a hard antenna strike"), + V("crouches with mandibles open while seeking a catch", "lunges into a sudden six-legged fishing snap"), + V("clamps onto the haul and drives backward without pause", "shoves with head low and legs churning"), + V("braces {target} firmly between its jaws", "tends {target} with rapid mouthpart strokes"), + V("charges the flame with beating forelegs", "drives a smothering body sweep across the flame"), + V("bursts away with jaws still spread", "scrambles backward on splayed feet before turning"), + V("rams its head down before settling on braced feet", "paces with rigid antennae before dropping into a low stance"), + V("plants six feet wide and brandishes open mandibles", "surges into battle in short aggressive bursts"), + V("pins the markings beneath its forefeet", "jabs an antenna along each line in rapid strokes"), + V("seizes a life-flare between its jaws", "drives gathered essence down rigid feelers"), + V("braces low and expels a hard abdominal pellet", "keeps its jaws spread as its abdomen forcefully releases"), + V("charges three directions in quick succession", "locks its jaws open while antennae whip apart"), + V("crouches taut as energy surges back through its legs", "pumps its abdomen in hard restoring pulses"), + V("bites at its own forefeet under a sudden compulsion", "rushes in a tight circle with abdomen raised"), + V("snaps its jaws toward {target}", "tries to clamp {target} before retreating in a rapid burst"), + V("lunges in broken bursts as another will drives it", "clamps and releases its jaws against its own rhythm"), + V("rests low while dream-battles twitch through all six feet", "snaps its mandibles softly in sleep")); + + AddExtended( + voices, + "bee", + V("sings through a bright sustained wing hum", "modulates its buzz with pulses of its abdomen"), + V("joins in a brief airborne reproductive coupling", "fans its wings during an abdomen-to-abdomen mating clasp"), + V("scrapes planting points with its forelegs", "presses each planting point using the tip of its abdomen"), + V("brushes pollen from body hairs into packed leg combs", "dusts reproductive grains onward with a vibrating abdomen"), + V("barters with a compact waggle", "gives and receives with precise mouthpart touches"), + V("hovers with forelegs poised while searching for a catch", "dips its legs and rises on a sudden fishing sweep"), + V("hooks its legs around the haul and beats upward", "pulls with wings buzzing at a deep pitch"), + V("fans warm pulsing air over {target}", "grooms {target} with delicate mouthpart strokes"), + V("buffets the flame with concentrated wingbeats", "drives cooling air directly at the flame"), + V("zips away with its abdomen tucked under", "accelerates in a rising line on frantic wings"), + V("tests its surroundings with antennae and circling flights", "settles after repeated abdomen presses against the surface"), + V("curls its abdomen forward and deepens its warning buzz", "holds a rigid hover with legs spread for combat"), + V("walks its forefeet along each line", "reads with both antennae angled over the marks"), + V("draws a life-glow into the pulse of its abdomen", "gathers loose essence through vibrating body hairs"), + V("hangs its abdomen and releases a tiny dropping in flight", "lands, lifts its abdomen, and contracts once"), + V("hovers sideways while its antennae point apart", "starts a waggle sequence and repeatedly breaks the pattern"), + V("rests with wings folded as its body hum steadies", "vibrates flight muscles in a low restorative pulse"), + V("waggles in a pattern that loops against itself", "grooms one wing while the other beats without command"), + V("slips toward {target} on muted wingbeats", "reaches both forelegs toward {target} before darting away"), + V("buzzes at a fractured pitch as its abdomen jerks", "flies in rigid angles under a foreign impulse"), + V("folds its wings while tiny flight tremors cross its body", "waggles faintly in sleep with antennae tucked")); + + AddExtended( + voices, + "beetle", + V("rasps hooked feet against its plated sides", "clicks its wing cases in a hollow measured refrain"), + V("opens its wing cases during a close reproductive mounting", "locks hooked feet gently during mating"), + V("furrows planting lines with its hardened brow", "presses planting points beneath its plated body"), + V("brushes pollen onward with hairy forefeet", "parts its wing cases while reproductive dust crosses its back"), + V("barters with taps from both feelers", "takes measured turns with its hooked forefeet"), + V("plants hooked feet and searches for a catch", "snaps its head forward after a still feeler sweep"), + V("wedges its plated back beneath the haul", "grips and drags with forefeet on six braced legs"), + V("presses a smooth wing case against {target}", "tends {target} with careful mouthpart strokes"), + V("beats open wing cases against the flame", "shoves its plated front over the flame"), + V("trundles away with legs pumping beneath sealed cases", "opens its wing cases and bolts on buzzing wings"), + V("tests its footing with hooked feet before settling", "leans its hardened back into a stable resting brace"), + V("lowers its armored brow and spreads all six feet", "opens its wing cases into a broad warrior display"), + V("reads with short feeler sweeps", "pins each line beneath a hooked forefoot"), + V("cups a fading life-light beneath its wing cases", "draws gathered essence through seams in its plated back"), + V("raises its rear plates and releases a compact pellet", "anchors all six feet as its abdomen slowly pushes"), + V("rolls onto its back and pedals without direction", "opens one wing case while keeping the other sealed"), + V("locks its feet and rests as strength returns beneath its shell", "pulses its folded wings in a low restoring rhythm"), + V("rocks on its plated back with legs folded", "repeatedly opens and seals its wing cases without flight"), + V("hooks a folded foreleg toward {target}", "tries to catch {target} before withdrawing with wing cases shut"), + V("clatters as foreign force pries its plates apart", "marches stiffly while its feelers curl inward"), + V("seals its wing cases while sleeping legs slowly pedal", "rocks inside its plated rest through a hollow dream")); + + AddExtended( + voices, + "bioblob", + V("warbles through elastic membrane pops", "pulses its rounded skin in a soft resonant sequence"), + V("buds a second pulse within a reproductive membrane join", "mingles inner currents around a tightening germ"), + V("forms shallow planting pockets with rhythmic squeezes", "presses each planting point beneath a rounded membrane dimple"), + V("rolls pollen across its adhesive outer skin", "pulses reproductive dust from one temporary pocket to another"), + V("forms two clear barter chambers in its membrane", "trades with alternating contractions of its surface pockets"), + V("extends a springy membrane tube in search of a catch", "snaps a sensing bulge inward with a whole-body squeeze"), + V("wraps gripping pockets around the haul and heaves", "bounds backward with its membrane held taut"), + V("spreads a warm regenerative film over {target}", "pulses restorative fluid against {target} through a membrane patch"), + V("flattens its damp body across the flame", "pumps cooling fluid through a broad outer blister"), + V("bounds away in rapid whole-body contractions", "stretches forward and recoils into a springing escape"), + V("widens its base and firms the settling membrane", "pulses downward until its rounded body holds steady"), + V("hardens its front into a resilient bulwark", "compresses into a taut spring ready to strike"), + V("forms clear lens-spots that move across each line", "ripples written marks beneath a thin sensing membrane"), + V("draws a life-spark into a glowing inner vesicle", "surrounds gathered essence with concentric pulses"), + V("opens a temporary pore and squeezes out spent matter", "contracts its inner chamber and releases spent fluid"), + V("wobbles between two incompatible shapes", "sends pulses inward when its rim tries to move outward"), + V("draws membrane tight as inner fluid brightens", "rests in a dome while deep restorative pulses recur"), + V("pinches off a bead and repeatedly reels it back", "bounces in place as one inner current reverses"), + V("extends a nearly invisible membrane pocket toward {target}", "tries to fold its reaching membrane over {target}"), + V("jerks into sharp shapes under an alien current", "pops and swells as foreign pulses seize its membrane"), + V("sags into sleep while luminous forms drift inside", "quivers around slow inner dream-currents")); + + AddExtended( + voices, + "butterfly", + V("flutters a papery rhythm beneath a faint thoracic hum", "fans broad wings in a slow singing cadence"), + V("joins abdomen tips in a delicate reproductive pairing", "holds a close wing-to-wing mating posture"), + V("scores planting points with slender feet", "presses each planting point beneath the tip of its abdomen"), + V("dusts broad wings and legs with pollen", "unfurls its feeding tube while reproductive grains brush onward"), + V("barters while circling in matched wing arcs", "curls its forelegs in a delicate give-and-take"), + V("skims with feeding tube uncurled while seeking a catch", "dips slender feet and lifts on one broad fishing sweep"), + V("clasps the haul with its legs and laboring wings", "leans its whole flight into the pull"), + V("fans {target} with slow warming wingbeats", "touches {target} gently with its feeding tube tip"), + V("beats broad wings hard across the flame", "folds and opens its wings in repeated smothering strokes"), + V("rises away in steep uneven spirals", "folds its legs tight and drives forward on rapid wingbeats"), + V("tests its footing lightly and comes to rest", "holds its wings upright while its feet establish a steady brace"), + V("spreads its wings into a broad warning plane", "dives to battle with slender legs extended"), + V("walks its feeding tube along written lines", "opens and closes its wings as slender feet track each mark"), + V("catches a life-glimmer between its wing scales", "draws gathered essence along the veins of its wings"), + V("hangs its abdomen and releases a tiny dropping", "holds its wings still as its abdomen briefly contracts"), + V("spirals upward, folds, and drops before opening again", "uncurls its feeding tube toward nothing and recoils"), + V("rests with wings spread as warmth returns through their veins", "pumps its thorax slowly beneath closed wings"), + V("beats left and right wings in opposing rhythms", "loops downward under an unbidden abdominal curl"), + V("settles near {target} with wings concealing its legs", "reaches curled forelegs toward {target} before lifting away"), + V("flaps in rigid jolts as an outside will pulls its abdomen", "folds its wings midflight under a foreign impulse"), + V("sleeps behind closed wings while the edges faintly tremble", "makes slow dream-flights with tucked, twitching legs")); + + AddExtended( + voices, + "flower_bud", + V("rustles layered petals in a rising vegetal refrain", "hums through a vibrating hollow stalk"), + V("presses its receptive center into a reproductive bloom", "twines rootlets while pollen reaches its opened core"), + V("parts planting seams with branching root tips", "cups each planting point beneath a leaf"), + V("opens its crown and brushes pollen across receptive petals", "shakes reproductive dust from anther to central folds"), + V("barters by cupping and uncurling paired leaves", "inclines its crown as leaf tips give and receive"), + V("extends a fine root filament in search of a catch", "snaps a curled leaf closed after a patient tremor"), + V("winds rootlets around the haul and contracts its stalk", "braces its base while paired leaves pull"), + V("lays a sap-rich leaf over {target}", "presses regenerative pollen gently onto {target}"), + V("folds damp petals over the flame", "fans broad leaves directly at the flame"), + V("hitches away on frantic root contractions", "draws every petal closed and bends rapidly from danger"), + V("sinks fine roots into a steady settling brace", "opens its crown as its stalk establishes a firm base"), + V("stiffens its stalk and closes petals into a pointed crown", "spreads leaves around a root-braced warrior stance"), + V("traces each line with a curling leaf tip", "turns its crown as root hairs sense each mark"), + V("draws life-light into its receptive center", "channels gathered essence down the veins of its petals"), + V("opens a basal pore and sheds spent fibrous residue", "contracts its root crown and expels dry fibers"), + V("turns its crown between opposing directions", "opens alternating petals while its stalk coils"), + V("roots deeply as sap rises through its stalk", "closes its petals while restorative light pulses at the center"), + V("twines its own leaves around its stalk without cause", "opens one petal repeatedly against the rhythm of the crown"), + V("folds its leaves toward {target} and retracts its roots", "tries to cup {target} between closing petals"), + V("lashes its leaves as foreign sap pulses seize the stalk", "blooms and closes in jagged involuntary bursts"), + V("bows into sleep while dream-petals open inside the bud", "twitches its rootlets beneath a softly pulsing crown")); + + AddExtended( + voices, + "fly", + V("buzzes a thin wavering melody on glassy wings", "rubs its wings into a sharp repeating trill"), + V("clasps in a brief reproductive pairing on braced legs", "joins abdomen tips while forefeet drum rapidly"), + V("scratches planting points with bent forelegs", "tamps each planting point with quick six-foot steps"), + V("brushes pollen onward with hairy feet and body", "rubs reproductive dust from forelegs to hind legs"), + V("barters with rapid forefoot drums", "sponges and releases with lowered mouthparts"), + V("hovers in abrupt stops while searching for a catch", "darts downward and snaps back on whining wings"), + V("grips the haul with all six feet and beats backward", "pulls in short bursts of wing speed"), + V("sponges {target} with careful mouthpart presses", "grooms {target} with rapid foreleg strokes"), + V("buffets the flame with whining wingbeats", "darts past the flame in repeated cooling passes"), + V("shoots away through a chain of right-angle turns", "folds its forelegs and accelerates on blurred wings"), + V("samples its footing with each foot before settling", "orbits tightly before bracing on all six legs"), + V("faces forward with wings spread and forelegs raised", "charges into battle in abrupt aerial bursts"), + V("wipes its eyes before tracking each line", "drums bent forefeet along the printed marks"), + V("draws a life-flicker across its many-faceted eyes", "gathers loose essence through vibrating wing veins"), + V("lifts its abdomen and releases a minute dropping", "rubs its forelegs as its abdomen releases"), + V("darts in a square and misses the final turn", "wipes one eye repeatedly while circling on three legs"), + V("rests with wings flat as flight muscles regain their hum", "vibrates its thorax in a low restoring buzz"), + V("loops upside down and hovers there too long", "rubs its hind legs while both forelegs point rigidly ahead"), + V("lands silently beside {target} on padded feet", "reaches all six legs toward {target} before lifting"), + V("jerks through angular flight under a foreign command", "buzzes in broken pulses as its legs grasp at nothing"), + V("sleeps with wings flat while its feet make tiny wiping strokes", "twitches through silent dream-darts")); + + AddExtended( + voices, + "garl", + V("rustles papery layers beneath a reedy leaf whistle", "shivers its narrow leaves in a dry descending song"), + V("braids receptive root fibers in a reproductive joining", "parts its layered bulb while pollen settles into its core"), + V("rakes planting seams with fibrous roots", "presses each planting point beneath its layered bulb"), + V("catches pollen among narrow leaves and papery folds", "shakes reproductive dust downward along its stalk"), + V("barters by opening and closing two papery layers", "alternates curled leaf tips in a measured give-and-take"), + V("threads a fine root outward in search of a catch", "jerks its bulb backward when root fibers tighten"), + V("hooks root bundles around the haul and leans away", "wedges its dense bulb behind and drives forward"), + V("binds {target} with a sap-damp layer", "presses pungent regenerative fibers against {target}"), + V("lashes narrow leaves across the flame", "presses its dense damp bulb against the flame"), + V("scrambles away on bunching root fibers", "folds its leaves tight and lurches rapidly aside"), + V("spreads root fibers into a broad settling hold", "stacks its layered bulb firmly above anchored roots"), + V("stiffens narrow leaves into a bristling crown", "swings its dense bulb from a root-braced warrior stance"), + V("runs a leaf tip beneath each line", "parts papery layers as root fibers trace the marks"), + V("draws life-light between its layered skins", "pulls gathered essence down its fibrous roots"), + V("parts its basal layers and expels spent pulp", "tightens its bulb and sheds dry fibers"), + V("winds root fibers in opposite directions", "fans one leaf while every other leaf folds"), + V("rests its bulb low as sap pressure returns", "draws strength inward through tightly coiled roots"), + V("peels one papery layer back and wraps it again", "braids its own leaf tips under an unbidden impulse"), + V("folds dry skins toward {target}", "tries to draw {target} between layered bulb scales"), + V("thrashes its leaves as foreign pressure twists the stalk", "lurches on roots that contract outside its rhythm"), + V("bows its stalk while sleeping roots slowly curl", "rustles inside closed papery layers as it dreams")); + + AddExtended( + voices, + "grasshopper", + V("scrapes a bright skipping song from leg against wing", "pulses its hind legs through a rising chirr"), + V("clasps tightly during a balanced reproductive mounting", "joins abdomen tips with hind legs folded close"), + V("kicks planting furrows with spined hind feet", "presses planting points beneath short forefoot stamps"), + V("brushes pollen onward with its body and jointed legs", "springs between pollinating contacts with dusted feet"), + V("barters with alternating forefoot taps", "gives and receives with precise serrated mouthparts"), + V("crouches on folded hind legs while seeking a catch", "springs upward after a sudden fishing snap"), + V("grips the haul with its forefeet and hops backward", "drives forward with both hind feet"), + V("combs {target} with delicate forefoot strokes", "presses its mouthparts carefully against {target}"), + V("kicks across the flame with broad hind-leg sweeps", "leaps past the flame while fanning both wings"), + V("launches away in successive full-length bounds", "folds its feelers back and springs without pause"), + V("tests its footing with deep hind-foot presses", "settles into a stable four-point crouch"), + V("raises on extended hind legs with jaws working", "bounds into battle forefeet-first"), + V("tracks each line with one long feeler", "holds the markings between forefeet while mouthparts tick"), + V("catches a life-spark between extended feelers", "draws gathered essence through a resonant wing pulse"), + V("lifts its abdomen and drops a compact pellet", "folds its hind legs as its abdomen briefly releases"), + V("springs straight up and lands facing backward", "scrapes one broken chirr while both feelers cross"), + V("crouches low as strength coils into its hind legs", "pumps both jumping limbs with slow restoring bends"), + V("kicks one hind leg while the other stays locked", "leaps in place under an unexplained abdominal twitch"), + V("snatches at {target} with folded forefeet", "tries to clasp {target} before bounding away"), + V("launches in jagged bursts under a foreign rhythm", "scrapes a harsh chirr while its hind legs kick alone"), + V("sleeps with long legs folded as tiny jumps twitch within", "moves its mouthparts through a faint dream-chirr")); + + AddExtended( + voices, + "lemon_snail", + V("sings through a wet rasp beneath its shell lip", "rocks its shell to a slow foot-pulsed hum"), + V("presses foot to foot in a reciprocal reproductive joining", "touches mating pores beneath crossed feelers"), + V("rasps shallow planting seams with its toothed tongue", "presses planting points beneath the broad front of its foot"), + V("collects pollen on its moist body and feeler tips", "glides reproductive dust across receptive surfaces"), + V("barters with touches from both long feelers", "ripples the front of its foot in a slow give-and-take"), + V("extends its eyestalks while searching for a catch", "casts its head forward and recoils beneath its shell"), + V("sets its muscular foot against the haul and ripples backward", "anchors its shell while the broad foot pushes"), + V("lays a healing trail of mucus over {target}", "presses the soft rim of its foot against {target}"), + V("draws damp mucus over the flame", "swings its shell down in a slow smothering press"), + V("glides away on rapid foot ripples with feelers withdrawn", "pulls its head beneath the shell while sliding aside"), + V("seals its broad foot into a stable settling grip", "tests the boundary with fully extended eyestalks"), + V("rears beneath its shell with all feelers forward", "swings its shell from a firmly anchored warrior stance"), + V("traces each line with the tips of its eyestalks", "rasps lightly beneath the marks with its toothed tongue"), + V("draws a life-glow into the spiral of its shell", "gathers loose essence along its shining mucus trail"), + V("raises its shell and releases a soft waste pellet", "contracts its muscular foot and slowly releases waste"), + V("extends one eyestalk while withdrawing the other", "glides in a circle as its shell tilts the opposite way"), + V("rests half withdrawn as vigor ripples through its foot", "seals close while restorative moisture gathers beneath its shell"), + V("waves crossed feelers while its foot moves backward", "rasps at its own shell lip under a strange impulse"), + V("slides silently toward {target} with feelers tucked", "tries to arch its broad foot over {target}"), + V("twists beneath its shell as foreign pulses seize its foot", "lashes its feelers in movements outside its slow rhythm"), + V("sleeps sealed close while eyestalks twitch within", "rocks its shell slowly as spiral forms fill its dream")); + + AddExtended( + voices, + "lil_pumpkin", + V("rattles its hollow ribs beneath a vine-tip rhythm", "whistles through a curling stem in bouncing notes"), + V("twines receptive tendrils into a reproductive joining", "opens its crown as pollen reaches the seeded core"), + V("parts planting seams with forked tendril tips", "rolls its ribbed base over each planting point"), + V("catches pollen on curling vines around its crown", "flicks reproductive dust inward with springing tendrils"), + V("barters by looping and releasing two tendrils", "rocks its ribbed side in a measured give-and-take"), + V("uncurls a thin vine while searching for a catch", "snaps the tendril back into a tight coil"), + V("winds several tendrils around the haul and rolls backward", "braces its ribbed body while coiled vines pull"), + V("wraps a sap-rich tendril around {target}", "presses its soft inner vine gently against {target}"), + V("rolls its broad ribbed body over the flame", "lashes damp vine coils directly at the flame"), + V("bounds away on recoiling tendrils", "rolls rapidly with crown bent and vines tucked"), + V("spreads tendrils into a firm settling lattice", "sets its rounded base while the crown straightens"), + V("stiffens coiled vines around its ribbed body", "butts forward from a tendril-braced warrior stance"), + V("runs a forked vine tip along each line", "tilts its crown while tendrils trace the marks"), + V("draws life-light through its crown into the seeded hollow", "gathers loose essence along curling vine veins"), + V("lifts its base and releases spent fibrous pulp", "contracts its hollow body and expels dry fibers"), + V("rolls forward while every tendril pulls backward", "coils its crown vine around one rib repeatedly"), + V("rests round and still as sap fills each tendril", "pulses its hollow core in a slow restoring rhythm"), + V("ties two of its own vines into a tightening loop", "bounces on its base while the crown twists sideways"), + V("curls broad tendrils toward {target}", "tries to loop its vines around {target} before rolling away"), + V("rattles violently as foreign force plucks its vines", "rolls in broken arcs under an outside impulse"), + V("sleeps on one rib while tendrils curl and uncurl", "echoes soft dream-knocks inside its hollow body")); + + AddExtended( + voices, + "sand_spider", + V("drums eight feet in a dry intricate song", "rasps mouthparts beneath alternating leg taps"), + V("locks legs in a careful reproductive embrace", "transfers a mating pulse through paired front appendages"), + V("rakes planting lines with alternating front legs", "tamps planting points with four paired foot presses"), + V("combs pollen through the hairs of its legs", "steps reproductive dust onward across eight contact points"), + V("barters with measured front-foot taps", "alternates folded forelegs in a precise give-and-take"), + V("casts a fine silk line while searching for a catch", "feels along the silk with widely spread feet before jerking back"), + V("binds the haul in silk and pulls with all eight legs", "walks backward while paired feet drag"), + V("lays a sealing silk pad over {target}", "grooms {target} with fine mouthpart strokes"), + V("casts a dense silk sheet over the flame", "beats four pairs of legs in a smothering press"), + V("scuttles away sideways on low-splayed legs", "retracts its front pair and darts in an angular retreat"), + V("anchors silk before folding into a settled crouch", "reads surface tremors through eight feet before settling"), + V("rears on its hind pairs with front legs spread", "pivots sideways in a low fighting stance"), + V("follows each line with alternating front feet", "reads tiny tremors along a taut silk filament"), + V("wraps a life-glimmer in a pulsing silk knot", "draws gathered essence inward through all eight feet"), + V("raises its abdomen and releases a compact dropping", "holds on four feet as its rear briefly contracts"), + V("lifts the wrong leg in every paired sequence", "spins half a turn and freezes with feet crossed"), + V("settles low as vigor returns through eight joints", "flexes each paired leg in a slow restoring wave"), + V("ties a silk loop around its own forelegs", "drums three feet while the other five hold rigid"), + V("casts silk toward {target} with rapid rear pulses", "tries to fold its front legs around {target}"), + V("jerks on stiffened legs as alien tremors command it", "strikes with its front pair outside its usual rhythm"), + V("folds into sleep while feet answer phantom vibrations", "spins a tiny dream-thread beneath its resting body")); + + AddExtended( + voices, + "scorpion", + V("clacks both pincers in a hollow antiphonal song", "rattles its plated tail beneath measured claw beats"), + V("clasps pincers during a paired reproductive turning", "joins bodies beneath a carefully arched tail"), + V("shears planting seams with opposing claws", "presses each planting point with the flat of a pincer"), + V("brushes pollen onward between fine pincer hairs", "guides reproductive dust with alternating claw tips"), + V("barters between open pincers", "alternates one claw and the other in a measured give-and-take"), + V("holds one open claw while searching for a catch", "snaps both pincers inward after a tail-balanced pause"), + V("grips the haul with both claws and walks backward", "hooks underneath while eight legs pull"), + V("holds {target} steady in one pincer", "applies a minute regenerative sting to {target}"), + V("beats the flame with broad opposing claws", "presses its plated body low over the flame"), + V("sidesteps away with tail curled tight overhead", "retreats rapidly while both pincers guard its front"), + V("tests its footing with claw tips and walking legs", "lowers its plated body into a settled eight-foot brace"), + V("opens both pincers and poises its tail above", "advances sideways to battle with its plated guard raised"), + V("runs one claw tip beneath each line", "holds the markings between pincers while tail segments count"), + V("catches a life-spark between closing claws", "draws gathered essence down the arch of its tail"), + V("raises its rear plates and releases a compact dropping", "sets all eight feet as its abdomen pushes"), + V("circles its own tail while one claw opens and shuts", "sidesteps left as both pincers insist right"), + V("rests low as strength returns along its plated tail", "folds its claws beneath a slow restorative pulse"), + V("clasps its own tail tip between careful pincers", "walks backward beneath an involuntary claw rhythm"), + V("snaps one claw toward {target} while the other guards", "tries to pinch {target} before withdrawing sideways"), + V("strikes downward as foreign force arches its tail", "clacks its pincers in a rhythm it does not control"), + V("sleeps beneath a lowered tail while claw tips twitch", "dreams of a silent paired turn beneath its arched tail")); + + AddExtended( + voices, + "smore", + V("flaps broad layers in a soft stacked refrain", "pipes a thin note through clustered springy stalks"), + V("presses yielding layers into a reproductive joining", "braids ribbonlike leaves as pollen reaches the inner fold"), + V("parts planting seams with bundled stalk tips", "compresses its broad lower layer over each planting point"), + V("catches pollen between broad yielding layers", "flicks reproductive dust onward with ribbonlike leaves"), + V("barters by pinching and opening two soft layers", "alternates bending shoot tips in a gentle give-and-take"), + V("extends a ribbonlike leaf while searching for a catch", "snaps stacked layers shut after a trembling pause"), + V("clamps the haul between broad layers and shuffles backward", "bends bundled stalks into a springing push"), + V("presses a soft sap-filled layer over {target}", "wraps {target} between warm yielding folds"), + V("claps broad layers over the flame", "fans the flame with rapid stacked flaps"), + V("bounds away on compressed springy stalks", "folds its ribbonlike leaves and shuffles rapidly aside"), + V("spreads bundled shoots into a steady settling base", "aligns its stacked crown above a firm fibrous brace"), + V("compresses its layers into a dense springing guard", "raises ribbonlike leaves from a broad warrior stance"), + V("slides a leaf tip beneath each line", "tilts stacked layers as bundled shoots trace the marks"), + V("cups a life-glow between yielding inner folds", "draws gathered essence through its springy stalks"), + V("parts its lowest layers and expels spent fibrous residue", "compresses its crown and sheds soft fibers"), + V("tilts each layer in a different direction", "wraps one ribbonlike leaf around the entire stack"), + V("rests compressed while vigor fills its bending shoots", "slowly expands each layer with a restoring pulse"), + V("claps its upper layers without separating the lower ones", "braids its own leaves under an unbidden bounce"), + V("closes soft layers toward {target}", "tries to pinch {target} between yielding folds"), + V("buckles and springs as foreign force compresses its crown", "flaps unevenly under a pulse outside its body"), + V("settles into sleep while inner layers softly rise and fall", "bounces on folded shoots as muted dreams pulse within")); + } +} diff --git a/IdleSpectator/ActivitySpeciesVoices.Invertebrates.Specialized.cs b/IdleSpectator/ActivitySpeciesVoices.Invertebrates.Specialized.cs new file mode 100644 index 0000000..cabf02b --- /dev/null +++ b/IdleSpectator/ActivitySpeciesVoices.Invertebrates.Specialized.cs @@ -0,0 +1,207 @@ +using System.Collections.Generic; + +namespace IdleSpectator; + +public static partial class ActivitySpeciesVoiceCatalog +{ + private static void AddInvertebrateSpecializedVoices(Dictionary voices) + { + AddSpecialized( + voices, + "acid_blob", + V("kindles flame beneath a searing pseudopod", "spreads flame with a sweep of its acidic rim"), + V("smothers flame beneath a broad liquid fold", "suppresses flame with jets from its pulsing pores"), + V("pools against its kin in a ring of touching rims", "merges its outline into a visible cluster with kin"), + V("draws the observed life essence through a feeding film", "cups the observed life essence inside a contracting vacuole"), + V("probes for spoils with a hair-thin pseudopod", "reaches for spoils with an opening surface pocket"), + V("burbles as its membrane dimples in rapid waves", "spills a wavering gurgle through its trembling rim"), + V("raises a jagged lobe and spits a sharp wet hiss", "slaps its rim down as surface bubbles crackle")); + + AddSpecialized( + voices, + "ant_black", + V("kindles flame with rapid mandible strikes", "spreads flame with straight abdomen sweeps"), + V("smothers flame beneath stamping forefeet", "suppresses flame with rapid abdomen beats"), + V("packs into a straight-bodied cluster with kin", "locks antennae into a visible rank among kin"), + V("draws the observed life essence between closed mandibles", "pulls the observed life essence along both antennae"), + V("probes for spoils with brisk antenna taps", "reaches for spoils with narrowly opened mandibles"), + V("stridulates in clipped pulses as its antennae shiver", "folds low while its mandibles click unevenly"), + V("clacks its mandibles in a hard measured burst", "stamps all six feet beneath rigid antennae")); + + AddSpecialized( + voices, + "ant_blue", + V("kindles flame with alternating mandible scrapes", "spreads flame through precise abdomen pivots"), + V("smothers flame with paired forefoot presses", "suppresses flame beneath symmetrical abdomen fans"), + V("forms an angular cluster with evenly spaced kin", "crosses antennae in a visible lattice among kin"), + V("draws the observed life essence between parallel antennae", "channels the observed life essence through paired mouthparts"), + V("probes for spoils with mirrored antenna arcs", "reaches for spoils with both mandibles centered"), + V("ticks its mouthparts as both antennae droop", "draws uneven antenna spirals beneath a thin stridulation"), + V("clicks both mandibles in an exact descending pattern", "cuts rigid angles with its antennae while its feet stamp")); + + AddSpecialized( + voices, + "ant_green", + V("kindles flame with hooked foreleg scrapes", "spreads flame with bounding abdomen flicks"), + V("smothers flame beneath crossing forelegs", "suppresses flame with broad sweeps of its raised abdomen"), + V("arches its forelegs across a cluster of kin", "hooks antennae into a visible ring among kin"), + V("draws the observed life essence between uplifted feelers", "pulls the observed life essence down its hooked forelegs"), + V("probes for spoils with one raised foreleg", "reaches for spoils with both mandibles lifted"), + V("scrapes a skipping chirr as its forelegs curl", "bows beneath raised forelegs while its jaws rasp"), + V("flings both hooked forelegs overhead with a harsh chirr", "scrapes its mandibles while its abdomen snaps upward")); + + AddSpecialized( + voices, + "ant_red", + V("kindles flame with forceful mandible grinding", "spreads flame with charging abdomen sweeps"), + V("smothers flame beneath pounding forefeet", "suppresses flame with hard full-body swipes"), + V("wedges into a dense cluster with braced kin", "raises spread mandibles inside a visible knot of kin"), + V("draws the observed life essence through parted mandibles", "drags the observed life essence along rigid antennae"), + V("probes for spoils with forceful antenna thrusts", "reaches for spoils with mandibles spread wide"), + V("rattles its body plates as its jaws open and close", "crouches low beneath a broken stridulating rasp"), + V("clashes its mandibles and lashes both antennae", "rears on four feet with a hard abdominal rattle")); + + AddSpecialized( + voices, + "bee", + V("kindles flame with a rapid sting scrape", "spreads flame beneath beating wings"), + V("smothers flame with dense wingbeat pulses", "suppresses flame beneath sweeping abdomen fans"), + V("lands in a tight wing-to-wing cluster with kin", "locks legs into a visible hanging cluster with kin"), + V("draws the observed life essence along its unfurled tongue", "pulls the observed life essence between vibrating mouthparts"), + V("probes for spoils with antennae and tongue extended", "reaches for spoils with its forelegs spread"), + V("releases a wavering buzz as its abdomen contracts", "hangs its antennae beneath a broken wing hum"), + V("drives a harsh buzz through flared wings", "curls its stinger forward while its wingbeats rasp")); + + AddSpecialized( + voices, + "beetle", + V("kindles flame with scraping mandibles", "spreads flame beneath opening wing cases"), + V("smothers flame under its plated abdomen", "suppresses flame with repeated wing-case claps"), + V("presses wing cases into a plated cluster with kin", "interlocks hooked feet in a visible mound with kin"), + V("draws the observed life essence between its mandibles", "pulls the observed life essence beneath closed wing cases"), + V("probes for spoils with clubbed feelers", "reaches for spoils with hooked forefeet"), + V("rasps its feet along its plates as its feelers sag", "clicks its wing cases through a low uneven tremor"), + V("snaps its wing cases open with a hollow crack", "rakes hooked feet across its plates in a harsh rasp")); + + AddSpecialized( + voices, + "bioblob", + V("kindles flame with a hot contracting membrane", "spreads flame through bouncing membrane flicks"), + V("smothers flame beneath an expanding membrane pocket", "suppresses flame with pulsing jets from its pores"), + V("presses its membrane into a quivering cluster with kin", "stacks pulsing lobes in a visible mound among kin"), + V("draws the observed life essence through its translucent membrane", "pulls the observed life essence into a pulsing inner vesicle"), + V("probes for spoils with budding membrane nubs", "reaches for spoils with an expanding ingestion pocket"), + V("warbles through membrane pops as its body sags", "contracts around a low wobbling internal hum"), + V("pops its membrane in a sharp percussive chain", "thrusts a blunt lobe upward through a bubbling rasp")); + + AddSpecialized( + voices, + "butterfly", + V("kindles flame with rapid feeding-tube scrapes", "spreads flame beneath fanning wing scales"), + V("smothers flame beneath overlapping wings", "suppresses flame with downward wingbeat fans"), + V("folds wing edges into a visible cluster with kin", "links slender legs in a hanging cluster among kin"), + V("draws the observed life essence along its coiled feeding tube", "pulls the observed life essence between trembling mouthparts"), + V("probes for spoils with its feeding tube uncoiled", "reaches for spoils with its slender forelegs"), + V("flutters in broken pulses as its feeding tube curls", "bows its antennae beneath a thin wing-scale hiss"), + V("lashes its feeding tube through a burst of wingbeats", "claps its wings while its antennae snap outward")); + + AddSpecialized( + voices, + "flower_bud", + V("kindles flame with rasping rootlets", "spreads flame with quick petal fans"), + V("smothers flame beneath closing petals", "suppresses flame with broad leaf sweeps"), + V("weaves rootlets into a visible cluster with kin", "presses closed crowns together in a dense cluster of kin"), + V("draws the observed life essence through its root hairs", "pulls the observed life essence into its layered bud"), + V("probes for spoils with uncurling rootlets", "reaches for spoils with cupped lower leaves"), + V("bows its stalk as its petals rustle in broken pulses", "folds its crown inward beneath a papery keening"), + V("snaps its petals wide with a dry crackle", "whips its leaves while its closed crown rasps")); + + AddSpecialized( + voices, + "fly", + V("kindles flame with rasping mouthparts", "spreads flame beneath blurred wingbeats"), + V("smothers flame with hammering wing pulses", "suppresses flame beneath sweeping abdominal fans"), + V("hooks legs into a visible buzzing cluster with kin", "packs wing-to-wing inside a tight cluster of kin"), + V("draws the observed life essence through its sponging mouthparts", "pulls the observed life essence between rubbing forefeet"), + V("probes for spoils with forefeet and mouthparts", "reaches for spoils with its sponging tube extended"), + V("buzzes in broken drops as its forelegs cover its eyes", "folds its wings beneath a wavering high whine"), + V("grinds its forefeet beneath a piercing buzz", "flares its wings and spits a jagged wing whine")); + + AddSpecialized( + voices, + "garl", + V("kindles flame with fibrous root scrapes", "spreads flame through whipping leaf tips"), + V("smothers flame beneath layered bulb skins", "suppresses flame with dense leaf fans"), + V("braids roots into a visible cluster with kin", "packs layered bulbs into a rustling cluster of kin"), + V("draws the observed life essence through its fibrous roots", "pulls the observed life essence between layered bulb skins"), + V("probes for spoils with fine root fibers", "reaches for spoils with curling leaf tips"), + V("bows its stalk beneath a long papery rustle", "closes its leaves as its bulb layers creak"), + V("lashes its leaves through a dry cutting hiss", "shakes its layered bulb in a hard papery rattle")); + + AddSpecialized( + voices, + "grasshopper", + V("kindles flame with scraping hind legs", "spreads flame through forceful wing fans"), + V("smothers flame beneath stamping hind feet", "suppresses flame with downward wing pulses"), + V("folds hind legs into a visible cluster with kin", "crosses feelers inside a tight crouching cluster of kin"), + V("draws the observed life essence between side-working jaws", "pulls the observed life essence along its folded hind legs"), + V("probes for spoils with sweeping feelers", "reaches for spoils with both forefeet"), + V("scrapes a descending chirr as its hind legs fold", "crouches beneath a stuttering wing rattle"), + V("kicks both hind legs through a harsh chirr", "saws a jagged rasp from leg against wing")); + + AddSpecialized( + voices, + "lemon_snail", + V("kindles flame with rapid radula strokes", "spreads flame with broad sweeps of its muscular foot"), + V("smothers flame beneath its muscular foot", "suppresses flame with wet mantle contractions"), + V("presses shells into a visible spiral cluster with kin", "overlaps muscular feet in a close cluster of kin"), + V("draws the observed life essence along its rasping radula", "pulls the observed life essence beneath its mantle"), + V("probes for spoils with extended eyestalks", "reaches for spoils with the front of its muscular foot"), + V("withdraws its eyestalks beneath a low shell scrape", "ripples its foot beneath a wavering mantle hiss"), + V("whips both feelers through a wet rasp", "rocks its shell while its radula grates sharply")); + + AddSpecialized( + voices, + "lil_pumpkin", + V("kindles flame with rubbing tendril tips", "spreads flame through whipping vines"), + V("smothers flame beneath its ribbed body", "suppresses flame with coiling tendril sweeps"), + V("laces tendrils into a visible cluster with kin", "presses ribbed sides into a tight cluster of kin"), + V("draws the observed life essence through its curling tendrils", "pulls the observed life essence into its hollow core"), + V("probes for spoils with split tendril tips", "reaches for spoils with an uncoiling vine"), + V("droops its crown beneath a hollow internal knock", "curls every tendril as its ribbed body creaks"), + V("snaps its tendrils through a hollow body rattle", "jerks its crown upward while its vines whip")); + + AddSpecialized( + voices, + "sand_spider", + V("kindles flame with rasping mouthparts", "spreads flame through rapid foreleg sweeps"), + V("smothers flame beneath four paired leg presses", "suppresses flame with dense silk casts"), + V("interlaces eight legs in a visible cluster with kin", "packs low beneath a lattice of touching legs with kin"), + V("draws the observed life essence through its mouthparts", "pulls the observed life essence along taut silk"), + V("probes for spoils with lifted forelegs", "reaches for spoils with hooked front feet"), + V("folds all eight legs beneath a dry mouthpart tremor", "drums an uneven cadence as its body flattens"), + V("rears four forelegs through a cutting rasp", "strikes its hooked feet together in a hard dry burst")); + + AddSpecialized( + voices, + "scorpion", + V("kindles flame with grinding pincer tips", "spreads flame through arcing tail sweeps"), + V("smothers flame beneath closing pincers", "suppresses flame with broad plated-body sweeps"), + V("locks pincers into a visible cluster with kin", "arches tails over a tight cluster of kin"), + V("draws the observed life essence between its pincers", "pulls the observed life essence along its segmented tail"), + V("probes for spoils with open pincer tips", "reaches for spoils with one claw extended"), + V("lowers its tail beneath a wavering pincer clack", "folds its claws inward as its body plates rattle"), + V("snaps both pincers through a hard plated crackle", "lashes its tail overhead while its claws clack")); + + AddSpecialized( + voices, + "smore", + V("kindles flame with fibrous stalk scrapes", "spreads flame through flapping crown layers"), + V("smothers flame beneath compressing crown layers", "suppresses flame with broad ribbon-leaf fans"), + V("presses stacked crowns into a visible cluster with kin", "weaves springy stalks through a close cluster of kin"), + V("draws the observed life essence through its fibrous stalks", "pulls the observed life essence between yielding crown layers"), + V("probes for spoils with ribbonlike leaves", "reaches for spoils with opening crown layers"), + V("compresses its crown beneath a soft layered flap", "folds its stalks inward through a wavering rustle"), + V("claps its crown layers in a sharp dry burst", "whips its ribbonlike leaves while its stacked body rattles")); + } +} diff --git a/IdleSpectator/ActivitySpeciesVoices.Mammals.Extended.cs b/IdleSpectator/ActivitySpeciesVoices.Mammals.Extended.cs new file mode 100644 index 0000000..92ba879 --- /dev/null +++ b/IdleSpectator/ActivitySpeciesVoices.Mammals.Extended.cs @@ -0,0 +1,534 @@ +using System.Collections.Generic; + +namespace IdleSpectator; + +public static partial class ActivitySpeciesVoiceCatalog +{ + private static void AddMammalExtendedVoices(Dictionary voices) + { + AddExtended( + voices, + "alpaca", + V("hums through a raised muzzle in wavering notes", "sings a soft phrase while its long neck sways"), + V("courts with close humming and a lifted tail", "mates with long legs planted and neck extended"), + V("farms in light, padded steps with split lips busy", "plants and presses with its long neck lowered"), + V("brushes pollen onward through its trailing fleece", "carries pollen along its muzzle and wool"), + V("trades with ears upright and muzzle bobbing", "barters through soft hums and neck dips"), + V("fishes with neck stretched and split lips poised", "fishes with eyes lowered and padded feet held steady"), + V("hauls with fleece bunching above a straight back", "leans forward on padded feet and draws steadily"), + V("heals {target} through delicate split-lip nudges", "kneels and hums while licking {target} gently"), + V("stokes fire with its long neck drawn back", "fans the flames through quick muzzle dips"), + V("flees in long, rocking bounds with fleece flying", "gallops away on padded feet with neck extended"), + V("settles by folding long legs beneath thick fleece", "kneels carefully as padded joints fold under its chest"), + V("stands warrior-straight with neck high and ears fixed", "braces behind a spit and a forward kick"), + V("reads with long neck curved and ears still", "reads line by line through slow, precise head tilts"), + V("gathers life with split lips and careful foot placement", "gathers life with its long neck lowered"), + V("squats on folded hind legs with tail lifted", "relieves itself while balancing on padded feet"), + V("turns its long neck between conflicting directions", "steps sideways as its upright ears swivel unevenly"), + V("recharges kneeling beneath a curtain of fleece", "rests its weight low while its jaw rolls slowly"), + V("pivots stiff-legged as a strange urge takes hold", "stretches its neck forward and paws in short bursts"), + V("steals with soft-footed steps and mobile split lips", "snatches quickly, then retreats behind swaying fleece"), + V("jerks its long neck while its padded feet stamp", "moves in rigid bounds with ears pinned flat"), + V("dreams with folded legs twitching beneath its fleece", "hums faintly as its long neck shifts in sleep")); + + AddExtended( + voices, + "armadillo", + V("squeaks a dry tune beneath its plated brow", "sings in clipped chirps while armor bands flex"), + V("courts by circling low and touching pointed snouts", "mates with broad claws braced beneath overlapping armor"), + V("farms by raking in alternating foreclaw strokes", "plants with snout low and shell rocking"), + V("pushes pollen onward with its narrow snout", "carries pollen beneath its plated underside"), + V("trades with quick sniffs and foreclaw taps", "barters from beneath its armored brow"), + V("fishes with broad claws poised and snout extended", "fishes low while armor bands rise with each breath"), + V("hauls backward with digging claws locked down", "pushes steadily behind an armored shoulder"), + V("heals {target} through small snout touches", "heals {target} while keeping broad foreclaws tucked"), + V("stokes fire with short foreclaw scrapes", "fans the flames from beneath its plated brow"), + V("flees in a rapid armored scuttle", "scrambles away with armor bands pumping over short legs"), + V("settles by scraping with broad foreclaws", "turns in a low circle and tucks beneath its shell"), + V("faces battle behind overlapping plates and flexed claws", "holds a warrior crouch with pointed snout forward"), + V("reads with snout tracking side to side", "reads steadily beneath a motionless plated brow"), + V("gathers life through careful sniffs and shallow scrapes", "gathers life with broad claws opening lightly"), + V("raises its armored tail and crouches low", "relieves itself with foreclaws planted wide"), + V("scuttles in crossing circles with snout darting", "halts halfway into a curl and opens again"), + V("recharges curled around its soft underside", "rests low while overlapping bands loosen"), + V("scrabbles abruptly under a strange urge", "rises on hind feet and paddles broad claws"), + V("steals with pointed snout low and claws silent", "hooks away quickly beneath its plated body"), + V("bucks beneath its armor and rakes both claws forward", "uncurls in rigid jolts with snout snapping upward"), + V("dreams curled tightly as armor bands pulse", "scrapes faintly in sleep with one broad foreclaw")); + + AddExtended( + voices, + "bandit", + V("sings under the breath with one hand at the throat", "threads a low tune through quick measured breaths"), + V("courts through close gestures and deliberate body turns", "mates with hands braced and hips rocking steadily"), + V("farms in a crouch with quick, exact handwork", "plants through alternating reaches and fingertip presses"), + V("dusts pollen onward with nimble fingertips", "transfers pollen through quick turns of both wrists"), + V("trades through clipped words and counting fingers", "barters with one hand held close"), + V("fishes from a low stance with both hands poised", "fishes with narrowed eyes and still shoulders"), + V("hauls with bent knees and both arms drawing", "shifts its grip through compact hand-over-hand pulls"), + V("heals {target} with fast, precise fingers", "heals {target} with one hand braced and the other pressing"), + V("stokes fire with face turned and forearm raised", "fans the flames through quick wrist turns"), + V("flees through sharp turns and low sprinting steps", "retreats with shoulders tucked and hands close"), + V("settles by lowering one foot and then the other", "crouches with shoulders tucked and hands drawn close"), + V("takes a warrior stance with hands high and knees loose", "advances behind feints and a narrow profile"), + V("reads with one finger marking each line", "reads in quick jumps of narrowed eyes"), + V("gathers life with cupped hands and exact fingertips", "gathers life while shifting between knees and toes"), + V("squats with back turned and shoulders alert", "relieves itself while checking both sides"), + V("cycles through three interrupted gestures", "turns twice with hands hovering at different angles"), + V("recharges in a tight crouch with hands tucked", "rests lightly while breathing through closed lips"), + V("moves under a strange urge through repeated wrist flicks", "paces a tight loop while fingers flex in sequence"), + V("steals with a hooked finger and immediate retreat", "slips close, palms quickly, and turns away"), + V("moves in clipped angles with hands rigidly spread", "jerks upright as each shoulder pulls against the other"), + V("dreams with fingers twitching against folded arms", "makes silent feints while curled in shallow sleep")); + + AddExtended( + voices, + "bear", + V("sings in deep pulses through a broad muzzle", "rumbles a tune while massive shoulders sway"), + V("courts upright with muzzle rubbing and heavy huffs", "mates with broad hind paws planted and forepaws braced"), + V("farms through deep scoops of long curved claws", "plants with shoulders rolling behind both paws"), + V("smears pollen onward across its broad muzzle", "carries pollen through thick fur on wide paws"), + V("trades with low grunts and open forepaws", "barters upright on heavy haunches"), + V("fishes with muzzle low and one forepaw hovering", "fishes by swiping with long curved claws"), + V("hauls with jaws set and massive shoulders driving", "drags backward on broad plantigrade paws"), + V("heals {target} with small foreclaw presses", "heals {target} through close muzzle touches"), + V("stokes fire with muzzle lifted and forearms back", "fans the flames with broad furred paws"), + V("flees in a pounding four-pawed gallop", "lumbers away as heavy shoulders rise and fall"), + V("settles by turning its broad body and scraping once", "drops onto its haunches before curling muzzle to paws"), + V("rises warrior-tall with both forepaws spread", "charges behind a roar and rolling shoulders"), + V("reads upright with forepaws held against its chest", "reads through slow sweeps of its broad muzzle"), + V("gathers life between broad cupped paws", "gathers life with claw tips beneath a lowered muzzle"), + V("squats heavily with short tail lifted", "relieves itself on braced hind paws"), + V("swings its broad head through opposing arcs", "rises halfway, drops down, and turns again"), + V("recharges curled densely with paws over muzzle", "rests on its haunches while shoulders slowly slacken"), + V("rocks upright under a strange urge and bats above its chest", "paces heavily while rubbing both forepaws together"), + V("steals with one broad paw and a backward shuffle", "hooks away quickly beneath a lowered muzzle"), + V("rears in stiff jolts with foreclaws spread", "lurches on all fours as its broad head snaps sideways"), + V("dreams with paws kneading and muzzle rumbling", "paddles all four paws while twitching on its side")); + + AddExtended( + voices, + "buffalo", + V("sings in a chest-deep bellow beneath curved horns", "rolls a low tune through its beard and broad muzzle"), + V("courts by circling with horned head held broadside", "mates on planted hooves beneath a rising shoulder hump"), + V("farms with broad muzzle low and hooves pressing firmly", "plants through short, horn-guided pushes"), + V("brushes pollen onward through its hanging beard", "carries pollen across its broad muzzle"), + V("trades through deep grunts and measured horn dips", "barters broadside on four hooves"), + V("fishes with nostrils flared and horned brow low", "fishes motionless with beard hanging"), + V("hauls through its neck and massive shoulder hump", "leans forward as broad hooves dig in"), + V("nudges and licks {target} slowly", "heals {target} with curved horns angled aside"), + V("stokes fire with horned brow lowered", "fans the flames with short, heavy head sweeps"), + V("flees in a rolling gallop beneath tossing horns", "thunders away with shoulder hump surging"), + V("settles by folding thick legs under a massive chest", "turns broadside and lowers its horned head"), + V("holds a warrior line with horns level and hooves spread", "drives forward behind its heavy skull"), + V("reads with broad muzzle tracing each line", "reads through slow turns of its horned head"), + V("gathers life using careful muzzle sweeps", "gathers life low beneath its brushing beard"), + V("arches its heavy tail and spreads its hind hooves", "relieves itself beneath a level horned head"), + V("pivots its horned head while hooves step out of rhythm", "starts a charge, checks, and turns broadside"), + V("recharges chest-down with legs folded beneath", "stands ruminating while its shoulder hump settles"), + V("bucks under a strange urge and tosses both horns", "stamps in a tight square with beard swinging"), + V("steals by hooking quickly with its broad muzzle", "edges away behind a shield of curved horns"), + V("lurches in rigid surges with horns sweeping", "stamps unevenly as its heavy head jerks low"), + V("dreams with hooves kicking beneath a heaving chest", "bellows faintly while its horned head shifts")); + + AddExtended( + voices, + "capybara", + V("sings in soft whistles through a blunt muzzle", "purrs a bubbling tune with rounded ears flicking"), + V("courts through nose touches and close body circling", "mates on short legs with webbed toes spread"), + V("farms with broad incisors clipping and forefeet pressing", "plants low behind a blunt muzzle"), + V("pushes pollen onward with whiskers spread", "carries pollen across its bobbing blunt nose"), + V("trades through soft whistles and brief muzzle dips", "barters seated squarely on folded feet"), + V("fishes with webbed toes braced and whiskers forward", "fishes with blunt chin held low"), + V("hauls by gripping firmly with broad incisors", "pushes forward on short legs behind a broad chest"), + V("nibbles {target} lightly with broad incisors", "heals {target} with careful forefoot presses"), + V("stokes fire with blunt muzzle tilted away", "fans the flames through short head bobs"), + V("flees in compact bounds on short legs", "scampers away with webbed toes splayed wide"), + V("settles by folding its feet under a barrel body", "turns once and rests its blunt chin low"), + V("faces battle with incisors bared and chest low", "holds a compact warrior crouch on splayed toes"), + V("reads with whiskers brushing close to each line", "reads through small turns of its blunt muzzle"), + V("gathers life with incisors and careful forefeet", "gathers life with whiskers fanned around its muzzle"), + V("raises its short tail and squats on splayed hind toes", "relieves itself with barrel body held level"), + V("bobs between directions while rounded ears flick", "scampers a half-circle and freezes nose-first"), + V("recharges in a square loaf on folded feet", "rests chin-down while its barrel sides slow"), + V("hops repeatedly as a strange urge takes hold", "bobs its blunt head and paddles both forefeet"), + V("steals with a quick incisor grip and low retreat", "nudges close, snatches, and scampers away"), + V("jerks in compact hops with incisors exposed", "paddles stiff forefeet while its blunt head twists"), + V("dreams with webbed toes twitching beneath its body", "whistles faintly as its blunt muzzle bobs")); + + AddExtended( + voices, + "cat", + V("sings in rising yowls with whiskers pushed forward", "trills a tune while its tail curls and uncurls"), + V("courts through calling, circling, and cheek presentation", "mates with hind paws planted and tail held aside"), + V("farms with precise paw scrapes and close sniffing", "plants with tucked claws and twitching tail"), + V("brushes pollen onward on silent paws", "carries pollen across whiskers and cheek fur"), + V("trades with measured chirps and one careful paw", "barters seated behind a curling tail"), + V("fishes with body flattened and forepaw hovering", "fishes by striking with unsheathed claws"), + V("hauls backward with teeth set and paws braced", "hooks and draws with curved foreclaws"), + V("licks {target} roughly between gentle paw touches", "heals {target} with whiskers forward and claws tucked"), + V("stokes fire with whiskers drawn back", "fans the flames with its curling tail"), + V("flees in low, elastic bounds with tail streaming", "springs away as hind claws drive hard"), + V("settles by kneading twice and circling tightly", "folds paws beneath its chest and wraps its tail"), + V("takes a warrior crouch with back rippling", "advances sideways with ears flat and claws bare"), + V("reads with pupils tracking steadily across each line", "reads through tiny whiskered head turns"), + V("gathers life with delicate paw hooks", "gathers life while nose and whiskers pulse"), + V("squats with hind legs spread and tail lifted clear", "relieves itself before scraping with both forepaws"), + V("turns after its own tail, then freezes abruptly", "steps toward two directions with ears swiveling apart"), + V("recharges curled nose-to-tail with paws hidden", "rests in a compact loaf while whiskers slacken"), + V("chatters under a strange urge and paws repeatedly", "arches, sidesteps, and lashes its tail without pause"), + V("steals with a silent paw hook and backward spring", "closes its teeth quickly and slips away low"), + V("stalks in rigid steps with pupils stretched wide", "jerks its head sideways while claws open and close"), + V("dreams with paws kneading and tail tip flicking", "chirps asleep as hind legs make tiny pounces")); + + AddExtended( + voices, + "cow", + V("sings in long lowing notes through a broad muzzle", "rolls a slow tune beneath a swinging dewlap"), + V("courts with flank sniffing and chin resting across a back", "mates on cloven hooves with tail raised aside"), + V("farms with broad muzzle sweeping and hooves pressing", "plants in slow passes beneath a wide forehead"), + V("sweeps pollen onward across its broad muzzle", "carries pollen on its rough tongue and nose"), + V("trades through low calls and slow forehead dips", "barters while chewing between low signals"), + V("fishes with broad muzzle lowered and nostrils flaring", "fishes on quietly planted cloven hooves"), + V("hauls with broad chest forward and neck straight", "draws steadily as cloven hooves brace"), + V("licks {target} with a broad rough tongue", "heals {target} with its forehead angled aside"), + V("stokes fire with broad muzzle lifted", "fans the flames with slow tail switches"), + V("flees in a heavy gallop with dewlap swinging", "runs away on pounding cloven hooves"), + V("settles by folding its forelegs beneath a broad belly", "turns slowly and lowers its heavy body"), + V("holds a warrior stance with forehead low and hooves wide", "drives ahead behind a swinging horned head"), + V("reads with broad muzzle moving along each line", "reads through slow, square head turns"), + V("gathers life using tongue, muzzle, and careful hooves", "gathers life low beneath a broad forehead"), + V("raises its tail and spreads its hind hooves", "relieves itself while continuing a slow jaw roll"), + V("steps forward and back while its broad head swings", "turns from one side to the other with nostrils flaring"), + V("recharges belly-down while chewing in circles", "rests on folded legs with tail and ears barely moving"), + V("kicks its hind heels under a strange urge", "sidesteps repeatedly with forehead dipping"), + V("steals with a swift tongue curl and muzzle withdrawal", "edges close, closes its broad lips, and backs away"), + V("stamps in uneven beats as its head jerks", "lurches broadside with tail rigid and jaw still"), + V("dreams with cloven hooves twitching under its belly", "lows softly as its broad muzzle shifts")); + + AddExtended( + voices, + "dog", + V("sings in rising howls with muzzle lifted", "threads yips into a tune while its tail keeps time"), + V("courts through circling, sniffing, and close tail signals", "mates on braced paws with hindquarters aligned"), + V("farms by digging in alternating forepaw strokes", "plants nose-first with tail held level"), + V("pushes pollen onward with repeated nose passes", "carries pollen across its muzzle with ears forward"), + V("trades through short barks and alternating paw taps", "barters seated upright on its haunches"), + V("fishes with nose low and one forepaw raised", "fishes with a sudden snap after holding still"), + V("hauls with jaws firm and all four paws driving", "pulls backward while shoulders bunch"), + V("licks and nudges {target} carefully", "heals {target} with ears fixed forward"), + V("stokes fire with nose turned and tail lowered", "fans the flames through quick paw strokes"), + V("flees in long bounds with ears swept back", "sprints away as hind paws drive beneath its body"), + V("settles by circling twice and testing with its nose", "scrapes briefly, then folds nose beneath tail"), + V("stands warrior-alert with hackles raised and paws spread", "advances behind bared teeth and braced forelegs"), + V("reads with nose tracing beneath each line", "reads through quick head tilts"), + V("gathers life with nose close and forepaws moving", "gathers life with careful jaw grips and short sniffs"), + V("squats on bent hind legs with tail lifted", "relieves itself while forepaws hold steady"), + V("tilts its head from side to side and circles", "starts forward, wheels back, and sniffs again"), + V("recharges curled tightly with nose beneath tail", "rests flank-down while paws and ears slacken"), + V("chases a strange urge through tight, repeated circles", "bows, springs, and paws in quick succession"), + V("steals with a quick jaw grip and bounding retreat", "slips close nose-first, snatches, and trots away"), + V("moves in stiff lunges with hackles standing", "opens and closes its jaws while its head jerks sharply"), + V("dreams with paws running and muzzle softly yipping", "twitches on its side as its tail taps")); + + AddExtended( + voices, + "fox", + V("sings in clear yips through a pointed muzzle", "threads rasping notes while its brush sways"), + V("courts with gekker calls and brush-led circles", "mates on narrow paws with brush lifted aside"), + V("farms through neat forepaw scrapes and precise sniffs", "plants lightly with pointed muzzle low"), + V("brushes pollen onward with its trailing brush", "carries pollen across its narrow muzzle"), + V("trades through quick chirps and delicate paw gestures", "barters seated behind a curled brush"), + V("fishes from a still crouch with ears fixed", "fishes by pouncing forepaws-first"), + V("hauls with narrow jaws set and paws skimming backward", "draws in short pulls beneath a level brush"), + V("nibbles and licks {target} delicately", "heals {target} with pointed ears held forward"), + V("stokes fire with whiskers tucked and brush high", "fans the flames with quick brush sweeps"), + V("flees in light bounds with brush streaming", "darts away on narrow paws through abrupt turns"), + V("settles by circling tightly beneath its own brush", "scrapes with quick forepaws and tucks its muzzle"), + V("takes a warrior crouch with ears flat and brush level", "darts forward behind bared narrow teeth"), + V("reads with pointed muzzle tracking each line", "reads with ears pricked and brush curled close"), + V("gathers life using precise paw taps and muzzle touches", "gathers life lightly with whiskers fanned"), + V("arches its brush and crouches on narrow hind paws", "relieves itself with pointed muzzle held alert"), + V("pivots between sounds with ears pointing apart", "pounces one way, checks, and circles back"), + V("recharges curled beneath its sweeping brush", "rests with pointed muzzle tucked and paws hidden"), + V("springs vertically under a strange urge", "gekker-calls while whipping around after its brush"), + V("steals with a delicate bite and instant sidestep", "slips close on narrow paws and darts away"), + V("stalks in angular jolts with brush rigid", "snaps sideways as its pointed ears flatten"), + V("dreams with narrow paws paddling beneath its brush", "yips faintly while its pointed muzzle twitches")); + + AddExtended( + voices, + "goat", + V("sings in broken bleats beneath a lifted chin", "trills nasally while its beard quivers"), + V("courts through horn rubs, sniffs, and raised forequarters", "mates on hard cloven hooves with hind legs braced"), + V("farms with split lips clipping and hooves pressing", "plants through short, horn-guided pushes"), + V("pushes pollen onward with mobile split lips", "carries pollen along its beard and muzzle"), + V("trades through nasal calls and compact horn dips", "barters balanced squarely on hard hooves"), + V("fishes with horizontal pupils fixed and muzzle low", "fishes with forehooves planted close"), + V("hauls with forehead down and cloven hooves gripping", "draws in springing pulls through its narrow chest"), + V("licks {target} with careful lip and tongue strokes", "heals {target} with horns angled along its back"), + V("stokes fire with beard lifted and muzzle back", "fans the flames through compact head tosses"), + V("flees in steep, springing bounds", "scampers away with beard and short tail raised"), + V("settles by placing each hoof and folding narrow legs", "turns once with horns high before kneeling"), + V("stands warrior-ready on stiff legs with horns forward", "rears and drives down behind a compact headbutt"), + V("reads with horizontal pupils following each line", "reads through tiny bearded head tilts"), + V("gathers life with mobile lips and exact hoof placement", "gathers life close beneath its brushing beard"), + V("lifts its short tail and squats on bent hind legs", "relieves itself with forehooves planted together"), + V("hops between positions while horizontal pupils scan", "starts to rear, drops, and turns in place"), + V("recharges chest-down on folded narrow legs", "rests squarely while chewing with a sideways jaw"), + V("rears repeatedly under a strange urge", "twists stiff-legged while tapping its horns together"), + V("steals with split lips and a backward hop", "snatches quickly, then bounds clear on hard hooves"), + V("bucks in rigid bursts with beard snapping", "jerks its horned head while hooves stamp crosswise"), + V("dreams with stiff legs kicking beneath its chest", "bleats softly as its beard and muzzle twitch")); + + AddExtended( + voices, + "hyena", + V("sings in whooping pulses through heavy jaws", "cackles a jagged tune beneath rounded ears"), + V("courts through close sniffing and sloping-body circles", "mates with powerful forequarters braced and hindquarters aligned"), + V("farms with crushing jaws and alternating forepaw scrapes", "plants low beneath raised shoulders"), + V("pushes pollen onward with persistent muzzle passes", "carries pollen across its heavy muzzle"), + V("trades through whoops and measured jaw clacks", "barters from a high-shouldered stance"), + V("fishes with heavy head low and rounded ears fixed", "fishes by snapping from braced forequarters"), + V("hauls with jaws locked and shoulders driving", "drags backward as the sloping back tightens"), + V("nibbles {target} carefully with its front teeth", "heals {target} with massive jaws held still"), + V("stokes fire with heavy muzzle turned aside", "fans the flames through powerful forepaw strokes"), + V("flees in an endurance lope with back sloping", "runs away as high shoulders pump steadily"), + V("settles by circling on long forelegs and lowering its jaws", "folds belly-down beneath its raised shoulders"), + V("takes a warrior stance with crushing jaws open", "surges forward behind powerful forequarters"), + V("reads with heavy muzzle moving under each line", "reads while rounded ears remain still"), + V("gathers life with strong forepaws and controlled incisors", "gathers life beneath a lowered heavy neck"), + V("squats with short hindquarters lowered and tail raised", "relieves itself while forelegs stay nearly straight"), + V("lopes a crooked loop and snaps back around", "shifts between crouch and standing as ears swivel"), + V("recharges belly-down with jaws across both paws", "rests on one flank while high shoulders loosen"), + V("cackles under a strange urge and wheels repeatedly", "bounds crookedly while its heavy jaws open and close"), + V("steals with a crushing jaw grip and loping retreat", "creeps in high-shouldered, snatches, and wheels away"), + V("lurches behind rigid forequarters with jaws clacking", "twists its sloping body as the heavy head jerks"), + V("dreams with jaws opening and long forelegs twitching", "whoops faintly while curled beneath raised shoulders")); + + AddExtended( + voices, + "monkey", + V("sings in patterned hoots while both hands beat time", "threads chatter into a tune with tail balancing"), + V("courts through grooming gestures and close body displays", "mates with hands braced and long tail held clear"), + V("farms with nimble thumbs turning and pressing", "plants from a squat with both hands"), + V("moves pollen with careful finger-and-thumb pinches", "carries pollen on fingertips while its tail counterbalances"), + V("trades through rapid chatter and open-palmed gestures", "barters by counting across nimble fingers"), + V("fishes in a crouch with one hand hovering", "fishes by snatching while the other hand braces"), + V("hauls with both hands clasped and feet pushing", "draws backward with long tail held straight"), + V("heals {target} with precise fingertips", "heals {target} carefully with both hands while squatting"), + V("stokes fire with quick hands and face turned aside", "fans the flames with open palms"), + V("flees in four-limbed bounds with tail streaming", "scrambles away as hands and feet alternate rapidly"), + V("settles by patting and turning with both hands", "squats low and wraps its long tail close"), + V("takes a warrior crouch with hands spread and teeth bared", "leaps forward behind a slap and grappling reach"), + V("reads with one finger following each line", "reads through quick eye shifts and head tilts"), + V("gathers life through nimble two-handed sorting", "gathers life with precise thumb-and-finger pinches"), + V("squats deep with tail lifted clear", "relieves itself while balancing on feet and one hand"), + V("reaches three ways while its tail counters each turn", "rises on its hind feet, drops, and chatters in place"), + V("recharges curled with hands beneath its chin", "rests in a compact squat while tail wraps close"), + V("claps repeatedly under a strange urge", "leaps and lands while fingers spread and curl"), + V("steals with one quick hand and a tail-balanced retreat", "palms swiftly, then bounds away on all fours"), + V("jerks through broken gestures with fingers splayed", "scrambles in place as head and tail snap opposite ways"), + V("dreams with fingers grasping and tail slowly curling", "chatters softly while hands paddle beneath its chin")); + + AddExtended( + voices, + "rabbit", + V("sings in soft honks with nose pulsing rapidly", "chatters a tiny rhythm beneath upright ears"), + V("courts through circling, chin contact, and high leaps", "mates on powerful hind feet with ears laid back"), + V("farms with rapid forepaw scrapes and incisor clips", "plants crouched on folded hind legs"), + V("pushes pollen onward through quick nose-first hops", "carries pollen on its muzzle with ears upright"), + V("trades through nose touches and light forepaw taps", "barters sitting tall on long hind feet"), + V("fishes from a low crouch with ears fixed forward", "fishes with nose rapidly twitching"), + V("hauls with incisors gripping and hind feet pushing", "draws backward through quick, low hops"), + V("licks and nibbles {target} gently", "heals {target} with upright ears held still"), + V("stokes fire with short forepaw scrapes", "fans the flames through quick nose-first hops"), + V("flees in accelerating bounds on long hind feet", "darts away through sharp leaps with ears flattened"), + V("settles by scraping with both forepaws and turning", "folds hind legs beneath a compact loaf"), + V("takes a warrior posture tall on hind feet", "boxes forward with rapid forepaw strikes"), + V("reads with nose tracking beneath each line", "reads while one upright ear swivels"), + V("gathers life with incisors clipping and forepaws pressing", "gathers life from a low hind-leg crouch"), + V("raises its short tail over bent hind legs", "relieves itself in a compact crouch"), + V("hops toward one side while both ears point elsewhere", "freezes, turns, and launches into a second direction"), + V("recharges in a compact loaf with feet hidden", "rests stretched low while long ears settle"), + V("leaps and twists under a strange urge", "darts in tight circles before kicking both hind feet"), + V("steals with one incisor nip and a sudden bound", "edges close nose-first, snatches, and darts away"), + V("jerks through crooked hops with ears rigid", "boxes forward as its nose stops twitching"), + V("dreams with hind feet kicking beneath a compact body", "honks faintly while ears and whiskers twitch")); + + AddExtended( + voices, + "raccoon", + V("sings in raspy trills with black forepaws clasped", "chirrs a tune while its ringed tail keeps balance"), + V("courts through face sniffing and two-pawed grooming", "mates on plantigrade paws with ringed tail held aside"), + V("farms with sensitive fingers sifting and turning", "plants while crouched behind a masked face"), + V("moves pollen delicately with both black paws", "carries pollen on sensitive fingers with ringed tail trailing"), + V("trades through chirrs and quick finger counts", "barters sitting upright on plantigrade haunches"), + V("fishes with sensitive forepaws spread and hovering", "fishes by plunging both black paws together"), + V("hauls with fingers hooked and arched back pulling", "draws backward on nimble plantigrade paws"), + V("heals {target} through careful two-pawed touches", "heals {target} fingertip-first beneath its mask"), + V("stokes fire with black paws held back", "fans the flames with its raised ringed tail"), + V("flees in an arched-back gallop with tail streaming", "scampers away on nimble plantigrade paws"), + V("settles by patting around with both sensitive paws", "turns and curls masked muzzle against ringed tail"), + V("stands warrior-upright with black claws spread", "lunges from its haunches behind both grasping paws"), + V("reads with one black finger tracing each line", "reads beneath motionless dark facial markings"), + V("gathers life through two-pawed feeling and precise pinches", "gathers life with sensitive fingers spread"), + V("squats on plantigrade hind paws with ringed tail raised", "relieves itself while both forepaws stay planted"), + V("rubs its paws together, turns, and checks again", "reaches in opposite directions beneath a twitching mask"), + V("recharges curled around its ringed tail", "rests on its side with black forepaws folded"), + V("rubs its forepaws under a strange urge", "rolls and rights itself while ringed tail lashes"), + V("steals with both sensitive paws and a quick tuck", "palms swiftly beneath its chest and scampers away"), + V("jerks upright with black fingers rigidly spread", "paddles both forepaws as its masked head snaps"), + V("dreams with black paws rubbing and ringed tail twitching", "chirrs asleep while sensitive fingers flex")); + + AddExtended( + voices, + "rat", + V("sings in thin squeaks while whiskers keep rhythm", "chirps a quick tune between soft incisor bruxes"), + V("courts through whisker contact and rapid close circling", "mates on small hind feet with bare tail extended"), + V("farms by gnawing, scraping, and pressing with pink paws", "plants low behind chisel incisors"), + V("sweeps pollen onward with fanned whiskers", "carries pollen across its pointed muzzle"), + V("trades through rapid squeaks and clasped pink paws", "barters upright with bare tail balancing"), + V("fishes with pointed muzzle low and paws hovering", "fishes by snapping with chisel incisors"), + V("hauls with incisors locked and hind feet driving", "drags backward while bare tail braces each turn"), + V("licks {target} between tiny paw presses", "heals {target} beneath a fan of trembling whiskers"), + V("stokes fire with whiskers pulled back", "fans the flames through rapid forepaw strokes"), + V("flees in a low scurry with bare tail streaming", "darts away through tight turns on close-set feet"), + V("settles by scraping rapidly and curling around its tail", "turns in place before tucking pointed muzzle down"), + V("stands warrior-upright with incisors bared", "rushes low behind whiskers and chisel teeth"), + V("reads with pointed muzzle passing beneath each line", "reads while round ears hold still"), + V("gathers life using pink paws and precise incisor nips", "gathers life with whiskers sweeping both sides"), + V("squats on small hind feet with bare tail lifted", "relieves itself while forepaws hover at its chest"), + V("scurries in two crossing arcs and freezes upright", "turns with whiskers aimed one way and ears another"), + V("recharges curled tightly around its bare tail", "rests belly-down with pointed muzzle on pink paws"), + V("bruxes rapidly under a strange urge and wheels", "clasps its paws while bare tail lashes in circles"), + V("steals with a fast incisor grip and low retreat", "snatches between pink paws and scurries away"), + V("jerks upright with incisors chattering hard", "runs in broken circles as its bare tail stiffens"), + V("dreams with pink paws clasping and tail curling", "squeaks asleep while whiskers pulse rapidly")); + + AddExtended( + voices, + "rhino", + V("sings in rough squeals beneath a heavy horn", "rumbles a blunt tune through thick folded lips"), + V("courts through horn-side rubbing and close scenting", "mates on three-toed feet with massive shoulders braced"), + V("farms by pressing with broad lip and heavy feet", "plants through short, horn-led pushes"), + V("sweeps pollen onward with its square lip", "carries pollen across thick folded lips"), + V("trades through rough snorts and slow horn dips", "barters standing square on three-toed feet"), + V("fishes with small ears fixed and broad lip low", "fishes beneath a level horn"), + V("hauls with horn base low and shoulders driving", "leans its folded hide forward on stout legs"), + V("heals {target} through broad-lip nudges", "heals {target} with heavy horn angled aside"), + V("stokes fire with horn and muzzle lifted", "fans the flames through heavy head sweeps"), + V("flees in a pounding charge on three-toed feet", "runs away with folded hide shaking over thick shoulders"), + V("settles by folding stout legs beneath thick hide", "turns heavily and lowers horn and chin"), + V("holds a warrior line with horn level", "charges forward behind massive skull and shoulders"), + V("reads with square lip passing beneath each line", "reads through slow horned head sweeps"), + V("gathers life with broad lip and careful foot pressure", "gathers life low beneath its heavy horn"), + V("raises its short tail and bends thick hind legs", "relieves itself while three-toed feet stay spread"), + V("pivots heavily as small ears point opposite ways", "starts a charge, halts, and swings its horn aside"), + V("recharges flank-down on thick folded hide", "rests with stout legs tucked and horn angled low"), + V("bucks under a strange urge and tosses its horn", "stamps a tight pattern on three-toed feet"), + V("steals with a quick square-lip grip and shoulder turn", "edges close beneath its horn and tramps away"), + V("lurches in rigid charges as its horn snaps sideways", "stamps unevenly beneath twitching folded hide"), + V("dreams with three-toed feet pushing and horn shifting", "rumbles asleep while its thick lips pulse")); + + AddExtended( + voices, + "sheep", + V("sings in wavering bleats through a narrow muzzle", "threads soft nasal notes while dense fleece trembles"), + V("courts through woolly cheek rubs and close circling", "mates on narrow hooves with fleece pressed close"), + V("farms with split lip clipping and small hoof presses", "plants beneath a lowered woolly brow"), + V("brushes pollen onward through its fleece", "carries pollen on its muzzle and wool"), + V("trades through short baas and gentle forehead dips", "barters while standing square beneath its fleece"), + V("fishes with narrow muzzle low and ears angled forward", "fishes on close-planted hooves"), + V("hauls with fleece bunching over narrow shoulders", "draws steadily while small hooves brace"), + V("heals {target} through careful muzzle nudges", "heals {target} with woolly forehead angled aside"), + V("stokes fire with fleece held back", "fans the flames through quick muzzle dips"), + V("flees in stiff, bouncing strides with wool shaking", "runs away on narrow hooves beneath dense fleece"), + V("settles by folding slim legs beneath a round fleece", "turns once and tucks muzzle against wool"), + V("takes a warrior stance behind lowered woolly brow", "drives forward from braced hooves with forehead first"), + V("reads with narrow muzzle tracing below each line", "reads while ears angle from the fleece"), + V("gathers life with split lip and delicate hoof placement", "gathers life beneath a curtain of wool"), + V("raises its short tail over bent hind legs", "relieves itself with narrow forehooves together"), + V("steps in a tight square while ears angle apart", "lowers its forehead, checks, and turns again"), + V("recharges round-bodied on folded legs", "rests muzzle-deep against fleece while sides slow"), + V("springs stiff-legged under a strange urge", "thrusts its forehead forward and hops backward"), + V("steals with split lips and a quick woolly turn", "nudges close, grips briefly, and trots away"), + V("bucks in rigid hops with fleece shuddering", "jerks its woolly forehead down as hooves cross"), + V("dreams with narrow hooves twitching beneath fleece", "bleats faintly while its woolly cheek shifts")); + + AddExtended( + voices, + "unicorn", + V("sings in clear nickers beneath its spiral horn", "whinnies a bright tune while its long mane ripples"), + V("courts through arched-neck passes and muzzle touches", "mates on bright cloven hooves with horn held high"), + V("farms with precise hoof presses and horn-guided turns", "plants beneath a flowing mane"), + V("pushes pollen onward with mobile lips", "carries pollen along its muzzle beneath a lifted horn"), + V("trades through bell-like nickers and measured head dips", "barters with spiral horn upright"), + V("fishes with horn angled aside and muzzle low", "fishes on motionless cloven hooves"), + V("hauls with arched neck straightening into each pull", "draws steadily while bright hooves brace"), + V("heals {target} through gentle touches of mobile lips", "heals {target} with spiral horn angled past one shoulder"), + V("stokes fire with mane and tail drawn back", "fans the flames through high forehoof strokes"), + V("flees in a light canter with mane streaming", "gallops away beneath a level spiral horn"), + V("settles by folding bright legs and curving horn aside", "turns once before resting beneath its mane"), + V("stands warrior-tall with spiral horn aligned", "surges forward behind high forehooves and lowered horn"), + V("reads with muzzle following beneath each line", "reads through small, poised turns of its horn"), + V("gathers life with mobile lips and exact hoof placement", "gathers life with spiral horn lifted"), + V("raises its flowing tail and bends its hind legs", "relieves itself on balanced cloven hooves"), + V("steps high in crossing directions with ears flicking", "turns its arched neck twice and paws once"), + V("recharges on folded legs with mane draped close", "rests muzzle-low while its spiral horn angles aside"), + V("rears under a strange urge and paws in sequence", "canters a tight ring with mane and tail streaming"), + V("steals with mobile lips and a light backward step", "dips beneath its horn, grips quickly, and canters away"), + V("moves in rigid high steps as its horn jerks", "rears abruptly with mane snapping across its neck"), + V("dreams with bright hooves cantering against folded legs", "nickers asleep while spiral horn and ears shift")); + + AddExtended( + voices, + "wolf", + V("sings in a long howl with muzzle raised", "weaves yips into a tune while its chest expands"), + V("courts through muzzle licks, circling, and tail signals", "mates on long braced legs with bushy tail aside"), + V("farms with powerful forepaw scrapes and nose checks", "plants from an efficient, low stance"), + V("pushes pollen onward through steady nose-led passes", "carries pollen across its muzzle with tail level"), + V("trades through low whines and measured muzzle gestures", "barters seated tall on its haunches"), + V("fishes from a flattened crouch with ears fixed", "fishes with a sudden snap after holding still"), + V("hauls with jaws set and long legs driving", "draws backward while shoulders stay level"), + V("licks {target} and nibbles with careful teeth", "heals {target} with ears held forward"), + V("stokes fire with muzzle turned aside", "fans the flames with its bushy tail"), + V("flees in a long, fully extended lope", "runs away with level back and ears swept flat"), + V("settles by circling and scraping with strong forepaws", "folds chest-down with chin between extended paws"), + V("takes a warrior stance with ears forward and jaws open", "rushes ahead from a level-backed crouch"), + V("reads with muzzle tracking under each line", "reads while pointed ears remain fixed"), + V("gathers life with nose close and forepaws precise", "gathers life from a long-legged crouch"), + V("squats on bent hind legs with bushy tail raised", "relieves itself while forelegs remain straight"), + V("fans between directions with nose and ears angled apart", "starts a lope, checks sharply, and circles"), + V("recharges curled tightly beneath its bushy tail", "rests chest-down with chin over long forepaws"), + V("bows and springs repeatedly under a strange urge", "circles in an efficient lope while snapping upward"), + V("steals with a quick jaw grip and silent retreat", "stalks close nose-first, snatches, and lopes away"), + V("paces in rigid lines with hackles lifted", "jerks its muzzle sideways while jaws snap shut"), + V("dreams with long legs running beneath a curled body", "howls faintly while its bushy tail twitches")); + + AddExtended( + voices, + "worm", + V("sings as a faint rasp through contracting segments", "pulses a soft rhythm along its bristled underside"), + V("courts by aligning and rippling beside another body", "mates through close segment contact and coordinated contractions"), + V("farms by drawing its front segments forward", "plants through slow, bristle-anchored ripples"), + V("pushes pollen onward through looping body contact", "carries pollen along its segments in forward pulses"), + V("trades by curling close and tapping its tapered front", "barters through measured body pulses"), + V("fishes with its tapered front held motionless", "fishes through a sudden full-body contraction"), + V("hauls by anchoring bristles and shortening its body", "draws backward through wave after muscular wave"), + V("heals {target} through gentle front-segment contact", "heals {target} through tiny controlled contractions"), + V("stokes fire through short front-segment ripples", "fans the flames with its tapered front"), + V("flees through rapid contractions and flattened curves", "crawls away as bristles drive in quick succession"), + V("settles by coiling segment over segment", "sweeps its tapered front once before relaxing"), + V("takes a warrior coil with front segments lifted", "lashes forward from a bristle-anchored curve"), + V("reads by passing its tapered front along each line", "reads through tiny lateral ripples"), + V("gathers life with its mouth opening and controlled pulls", "gathers life through delicate front-segment contractions"), + V("contracts its rear segments and holds still", "relieves itself while the tapered front remains extended"), + V("crawls into a loop and reverses halfway", "points its tapered front one way as the body pulls another"), + V("recharges in a loose coil with bristles relaxed", "lies extended while faint pulses travel end to end"), + V("knots into repeated loops under a strange urge", "lashes and recoils while its rear segments stay fixed"), + V("steals by hooking its front segments and contracting away", "creeps close, grips briefly, and ripples back"), + V("writhes in broken waves with bristles scraping", "stiffens segment by segment before snapping into a coil"), + V("dreams as slow ripples pass along its resting body", "twitches its tapered front while loosely coiled")); + } +} diff --git a/IdleSpectator/ActivitySpeciesVoices.Mammals.Specialized.cs b/IdleSpectator/ActivitySpeciesVoices.Mammals.Specialized.cs new file mode 100644 index 0000000..d1bb80d --- /dev/null +++ b/IdleSpectator/ActivitySpeciesVoices.Mammals.Specialized.cs @@ -0,0 +1,240 @@ +using System.Collections.Generic; + +namespace IdleSpectator; + +public static partial class ActivitySpeciesVoiceCatalog +{ + private static void AddMammalSpecializedVoices(Dictionary voices) + { + AddSpecialized( + voices, + "alpaca", + V("blows through split lips until a small flame kindles", "breathes through split lips to spread the flame"), + V("presses padded feet over the flame", "snuffs flame beneath a dense fold of fleece"), + V("hums and folds into a shoulder-close herd", "threads its long neck among gathered kin"), + V("draws visible life essence up its long neck into parted lips", "pulls glowing life essence through its fleece toward its chest"), + V("probes for spoils with split lips and an extended neck", "reaches for spoils between careful padded feet"), + V("wails through a raised muzzle in wavering breaths", "hums in long pulses with its neck stretched high"), + V("pins its ears, stamps its padded feet, and spits", "jerks its long neck and grinds out a nasal rasp")); + + AddSpecialized( + voices, + "armadillo", + V("rakes broad foreclaws together until flame kindles", "fans flame outward with rapid flexes of its armor bands"), + V("curls its plated body over the flame to smother it", "scrapes flame flat beneath overlapping armor"), + V("tucks its plated flank into a shell-close cluster of kin", "presses its plated flank among gathered kin"), + V("draws visible life essence between its claws and under its plates", "pulls glowing life essence along its armor bands toward its chest"), + V("sniffs for spoils with its pointed snout", "hooks toward spoils with one broad foreclaw"), + V("squeals beneath a tightly folded plated brow", "chatters in dry bursts while its armor bands pulse"), + V("hunches behind its plates and rakes both foreclaws", "snaps its pointed snout and chatters through clenched jaws")); + + AddSpecialized( + voices, + "bandit", + V("rubs quick palms until flame kindles between them", "cups the flame and spreads it with flicking fingers"), + V("claps both palms over the flame to smother it", "pinches the flame down between quick fingertips"), + V("signals with two fingers and closes ranks with kin", "slips shoulder to shoulder among gathered kin"), + V("draws visible life essence into cupped hands", "pulls glowing life essence along spread fingers toward the chest"), + V("searches for spoils with quick eyes and probing fingers", "reaches toward spoils with one hand held low"), + V("cries out through cupped hands in a sharp broken call", "hunches with mouth open and breath pulsing audibly"), + V("jabs two fingers outward and spits clipped syllables", "sets the jaw, bares the teeth, and hisses through them")); + + AddSpecialized( + voices, + "bear", + V("rubs broad forepaws until flame kindles between the pads", "fans flame outward with heavy sweeps of both forepaws"), + V("smothers flame beneath crossed forepaws", "presses a broad muzzle over the flame and huffs it out"), + V("presses its heavy shoulder among gathered kin", "rises among gathered kin and draws them close with broad forepaws"), + V("draws visible life essence between its claws and into its chest", "pulls glowing life essence through its broad muzzle with deep breaths"), + V("sniffs for spoils with its broad muzzle sweeping", "reaches toward spoils with hooked foreclaws"), + V("roars with its muzzle lifted and forepaws spread", "huffs in deep pulses while its shoulders heave"), + V("bares its teeth and pounds both forepaws together", "rears with claws spread and growls in clipped bursts")); + + AddSpecialized( + voices, + "buffalo", + V("snorts through broad nostrils until flame kindles beneath its muzzle", "sweeps its horned head to spread the flame"), + V("stamps the flame beneath broad cloven hooves", "presses its heavy muzzle down and snorts the flame out"), + V("pushes shoulder to shoulder into a close herd", "bellows and joins the gathered herd flank-first"), + V("draws visible life essence along its horns into its brow", "pulls glowing life essence through its broad muzzle toward its chest"), + V("sniffs for spoils beneath its horned brow", "reaches toward spoils with its broad muzzle"), + V("bellows with its beard shaking beneath a raised muzzle", "moans in chest-deep pulses while its nostrils flare"), + V("drops its horned brow, stamps, and snorts sharply", "swings its beard and grinds out a deep nasal rumble")); + + AddSpecialized( + voices, + "capybara", + V("gnashes broad incisors until flame kindles", "fans flame outward with quick sweeps of its blunt muzzle"), + V("presses webbed forefeet over the flame", "snuffs flame beneath its broad wet muzzle"), + V("whistles and settles flank to flank among kin", "tucks its barrel-shaped body into a compact gathering of kin"), + V("draws visible life essence between its orange incisors", "pulls glowing life essence along its whiskers toward its chest"), + V("sniffs for spoils with whiskers spread", "reaches toward spoils with webbed forefeet"), + V("whistles through a long piercing note", "squeals with its blunt muzzle lifted"), + V("chatters its incisors and stamps both webbed forefeet", "bares broad incisors and barks in short bursts")); + + AddSpecialized( + voices, + "cat", + V("scrapes tucked claws until flame kindles", "lashes its tail to fan flame outward"), + V("pats the flame down with rapid sheathed paws", "covers the flame beneath crossed forepaws and snuffs it"), + V("trills and threads into a tail-close gathering of kin", "presses flank to flank among gathered kin"), + V("draws visible life essence along its whiskers into its chest", "pulls glowing life essence between curved claws"), + V("sniffs for spoils with whiskers thrust forward", "reaches toward spoils with one careful paw"), + V("yowls with its jaw wide and whiskers flared", "wails in rising notes with its tail held rigid"), + V("flattens its ears, lashes its tail, and spits", "arches its back and growls through bared teeth")); + + AddSpecialized( + voices, + "cow", + V("snorts through broad nostrils until flame kindles beneath its muzzle", "sweeps its broad muzzle to spread the flame"), + V("stamps flame beneath a cloven forehoof", "presses its broad muzzle down and snorts the flame out"), + V("lows and presses flank to flank into the herd", "presses its broad muzzle among gathered kin"), + V("draws visible life essence along its horns into its chest", "pulls glowing life essence through its broad muzzle"), + V("sniffs for spoils with its broad muzzle", "reaches toward spoils with a rough extended tongue"), + V("lows in a long resonant call with its muzzle raised", "moans in deep pulses while its broad throat vibrates"), + V("stamps a cloven hoof and bellows through flared nostrils", "swings its horned head and grinds out a rough lowing")); + + AddSpecialized( + voices, + "dog", + V("scrapes its foreclaws until flame kindles", "pants across the flame and fans it outward"), + V("pats the flame down with quick forepaws", "presses its muzzle close and huffs the flame out"), + V("barks and folds into a shoulder-close pack", "presses its nose among gathered kin until flanks touch"), + V("draws visible life essence along its whiskers into its chest", "pulls glowing life essence through its open jaws"), + V("sniffs for spoils with its nose sweeping", "reaches toward spoils with one extended forepaw"), + V("howls with its muzzle lifted and throat stretched", "whines in repeated pulses while its chest trembles"), + V("bares its teeth, stamps, and barks in clipped bursts", "bristles along the spine and growls through a fixed jaw")); + + AddSpecialized( + voices, + "fox", + V("scratches narrow claws together until flame kindles", "sweeps its brush to spread the flame"), + V("beats the flame down beneath quick forepaws", "wraps its broad brush over the flame and smothers it"), + V("gekker-calls and slips into a brush-close gathering of kin", "circles once and presses flank to flank among kin"), + V("draws visible life essence along its whiskers into its chest", "pulls glowing life essence through its pointed muzzle"), + V("sniffs for spoils with its pointed muzzle low", "reaches toward spoils with a narrow forepaw"), + V("screams through an open muzzle with its brush rigid", "yips in a rapid chain while its throat pulses"), + V("pins its ears, lashes its brush, and gekkers sharply", "bares narrow teeth and spits a rasping bark")); + + AddSpecialized( + voices, + "goat", + V("scrapes hard forehooves together until flame kindles", "snorts through split lips to spread the flame"), + V("stamps the flame beneath hard cloven hooves", "presses its split lips over the flame and snorts it out"), + V("bleats and shoulders into a horn-close herd", "presses its bearded chin among gathered kin"), + V("draws visible life essence along its horns into its brow", "pulls glowing life essence through its split lips toward its chest"), + V("sniffs for spoils beneath its beard", "reaches toward spoils with mobile split lips"), + V("bleats in a long broken call with its jaw trembling", "wails nasally while its beard shakes"), + V("stamps both forehooves and jerks its horns forward", "bares its lower teeth and snorts in clipped bursts")); + + AddSpecialized( + voices, + "hyena", + V("grinds heavy teeth until flame kindles", "pants over the flame and fans it outward"), + V("pounds the flame beneath powerful forepaws", "presses its heavy muzzle close and huffs the flame out"), + V("whoops and shoulders into a close clan of kin", "sets its high shoulders among gathered kin and presses flank to flank"), + V("draws visible life essence between massive premolars", "pulls glowing life essence through its broad muzzle into its chest"), + V("sniffs for spoils with its heavy muzzle low", "reaches toward spoils with one powerful forepaw"), + V("whoops in a rising cascade with jaws spread", "cackles in breathless bursts while its shoulders jolt"), + V("raises its shoulders, bares its teeth, and chatters", "snaps its jaws and growls in broken pulses")); + + AddSpecialized( + voices, + "monkey", + V("rubs nimble palms until flame kindles between them", "fans flame outward with quick alternating hands"), + V("claps both hands over the flame to smother it", "beats the flame down with flat rapid palms"), + V("hoots and presses shoulder to shoulder among kin", "reaches both arms into a gathering of kin and joins it"), + V("draws visible life essence into cupped hands", "pulls glowing life essence along curled fingers toward its chest"), + V("searches for spoils with quick eyes and probing fingers", "reaches toward spoils with one long arm"), + V("hoots with its mouth rounded and throat pulsing", "shrills in repeated notes while both hands clutch its chest"), + V("bares its teeth, slaps both palms, and chatters", "jabs one hand outward and barks in clipped syllables")); + + AddSpecialized( + voices, + "rabbit", + V("gnashes its incisors until flame kindles", "fans flame outward with rapid forepaw strokes"), + V("pats the flame down with quick forepaws", "presses both forepaws over the flame and smothers it"), + V("honks and settles into a flank-close cluster of kin", "tucks its long ears among gathered kin"), + V("draws visible life essence between its incisors", "pulls glowing life essence along its long ears toward its chest"), + V("sniffs for spoils with its nose pulsing", "reaches toward spoils with both small forepaws"), + V("squeals with its ears rigid and mouth open", "honks in repeated breaths while its hind feet tremble"), + V("thumps both hind feet and chatters its incisors", "pins its ears and grinds out a sharp nasal grunt")); + + AddSpecialized( + voices, + "raccoon", + V("rubs sensitive forepaws until flame kindles", "fans flame outward with quick sweeps of its ringed tail"), + V("claps black forepaws over the flame to smother it", "beats the flame down beneath nimble plantigrade paws"), + V("trills and presses into a ringed-tail cluster of kin", "feels along nearby flanks and joins gathered kin"), + V("draws visible life essence between sensitive fingers", "pulls glowing life essence along its ringed tail into its chest"), + V("feels and sniffs for spoils with spread black fingers", "reaches toward spoils with both nimble forepaws"), + V("screeches with its pointed muzzle lifted", "trills in broken pulses while its forepaws clutch together"), + V("arches its back, bares its teeth, and chatters", "slaps both forepaws down and growls in rasping bursts")); + + AddSpecialized( + voices, + "rat", + V("gnashes orange incisors until flame kindles", "lashes its bare tail to fan flame outward"), + V("pats the flame down with quick pink paws", "coils its bare tail over the flame and smothers it"), + V("squeaks and huddles into a whisker-close knot of kin", "presses its whiskered muzzle among gathered kin"), + V("draws visible life essence along its whiskers into its chest", "pulls glowing life essence between its orange incisors"), + V("sniffs for spoils with whiskers sweeping", "reaches toward spoils with both pink forepaws"), + V("squeals with whiskers flared and incisors bared", "chirps in rapid pulses while its bare tail coils tightly"), + V("bruxes its incisors and lashes its bare tail", "rears with pink paws spread and hisses through bared teeth")); + + AddSpecialized( + voices, + "rhino", + V("snorts through thick lips until flame kindles beneath its horn", "sweeps its massive horn to spread the flame"), + V("stamps the flame beneath a broad three-toed foot", "presses its thick muzzle down and snorts the flame out"), + V("grunts and presses thick shoulders into the herd", "presses its folded hide among gathered kin"), + V("draws visible life essence along its horn into its brow", "pulls glowing life essence through its thick lips toward its chest"), + V("sniffs for spoils beneath its heavy horn", "reaches toward spoils with its broad square lip"), + V("squeals with its horn raised and small ears spread", "moans in rough pulses while its thick throat vibrates"), + V("stamps a three-toed foot and blasts a hard snort", "swings its horn and grinds out a chest-deep rasp")); + + AddSpecialized( + voices, + "sheep", + V("scrapes narrow forehooves together until flame kindles", "snorts through split lips to spread the flame"), + V("stamps the flame beneath narrow cloven hooves", "presses dense fleece over the flame and smothers it"), + V("bleats and presses fleece to fleece into the flock", "tucks its woolly muzzle among gathered kin"), + V("draws visible life essence along its curled horns", "pulls glowing life essence through its fleece toward its chest"), + V("sniffs for spoils through its woolly muzzle", "reaches toward spoils with a mobile split lip"), + V("bleats in a long wavering call with its jaw trembling", "wails nasally while its dense fleece quivers"), + V("stamps narrow hooves and jerks its curled horns", "bares its lower teeth and grinds out a broken baa")); + + AddSpecialized( + voices, + "unicorn", + V("draws a spark down its spiral horn until flame kindles", "sweeps its spiral horn to spread the flame"), + V("presses the flame flat beneath bright cloven hooves", "touches its spiral horn to the flame and snuffs it"), + V("nickers and joins a mane-close herd of kin", "arches its neck among gathered kin until flanks touch"), + V("draws visible life essence along its spiral horn into its brow", "pulls glowing life essence through its flowing mane toward its chest"), + V("searches for spoils with its horn angled low", "reaches toward spoils with mobile lips"), + V("whinnies with its spiral horn raised and throat stretched", "cries in clear ringing notes while its mane trembles"), + V("strikes a cloven forehoof and tosses its spiral horn", "pins its ears and snorts through bared teeth")); + + AddSpecialized( + voices, + "wolf", + V("scrapes strong foreclaws until flame kindles", "pants over the flame and fans it outward"), + V("pounds the flame beneath broad forepaws", "presses its muzzle close and huffs the flame out"), + V("howls and folds shoulder to shoulder into the pack", "sets its long-legged flank among gathered kin"), + V("draws visible life essence along its muzzle into its chest", "pulls glowing life essence between its strong jaws"), + V("sniffs for spoils with its nose sweeping low", "reaches toward spoils with one broad forepaw"), + V("howls with its muzzle lifted and throat extended", "whines in repeated breaths while its chest pulses"), + V("raises its hackles, bares its teeth, and growls", "snaps its jaws and barks in hard clipped bursts")); + + AddSpecialized( + voices, + "worm", + V("rasps its bristled underside until flame kindles", "whips its front segments to spread the flame"), + V("coils its segmented body over the flame to smother it", "presses contracting segments across the flame and suppresses it"), + V("twines into a close knot of gathered kin", "threads its tapered front between kin and presses segmented bodies together"), + V("draws visible life essence along contracting segments toward its mouth opening", "pulls glowing life essence through rippling body bands"), + V("probes for spoils with its tapered front", "reaches toward spoils by extending its front segments"), + V("rasps in long pulses through contracting segments", "rustles in repeated dry ripples with its front raised"), + V("coils tightly, lashes its front segments, and rasps", "braces its tiny bristles and whips forward with a dry hiss")); + } +} diff --git a/IdleSpectator/ActivityVerbMap.cs b/IdleSpectator/ActivityVerbMap.cs index 0d0886d..f7d2e10 100644 --- a/IdleSpectator/ActivityVerbMap.cs +++ b/IdleSpectator/ActivityVerbMap.cs @@ -6,21 +6,67 @@ namespace IdleSpectator; /// Maps every live task shape to an action concept; no creature voice logic. public static class ActivityVerbMap { + private static readonly string[] BehaviorBeatKeys = + { + "BehUnloadResources", + "BehThrowResources", + "BehSocializeTalk", + "BehTryToSocialize", + "BehPlantCrops", + "BehCityActorFertilizeCrop", + "BehBuildTarget", + "BehPoopOutside", + "BehPoopInside", + "BehBoatFishing", + "BehBoatCollectFish", + "BehClaimZoneForCityActorBorder" + }; + public static string Resolve(string key) { if (string.IsNullOrEmpty(key)) return ""; string k = key.ToLowerInvariant(); + if (ActivitySpeciesVoice.IsAuthoredVerb(k)) return k; if (k.Contains("laugh")) return "laugh"; if (k.Contains("sing") || k.Contains("just_sang")) return "sing"; + if (k == "start_fire") return "ignite"; + if (k == "put_out_fire" || k.Contains("extinguish") || k.Contains("fireman")) return "extinguish"; + if (k.Contains("family_group")) return "group"; + if (k.Contains("soul_harvested")) return "harvest_life"; + if (k.Contains("loot")) return "loot"; + if (k.Contains("crying") || k.Contains("just_cried")) return "cry"; + if (k.Contains("swore") || k.Contains("swear")) return "swear"; + if (k.Contains("madness")) return "confused"; + if (k == "follow_desire_target" || k == "task_unit_weird_desire") return "strange_urge"; + if (k == "task_unit_follow_family" || k == "child_follow_parent") return "group"; + if (k == "possessed_following") return "possessed"; + if (k == "poop_inside" || k == "poop_outside" || k == "try_to_poop" + || k == "behpoopinside" || k == "behpoopoutside") return "relieve"; + if (k == "status_confused" || k == "task_unit_confused") return "confused"; + if (k == "replenish_energy" || k == "task_unit_replenish_energy") return "recharge"; + if (k == "strange_urge_finish" || k == "task_strange_urge_finish") return "strange_urge"; + if (k == "try_to_steal_money" || k == "try_to_take_city_item") return "steal"; + if (k == "possessed") return "possessed"; + if (k == "try_affect_dreams") return "dream"; + if (k == "behthrowresources") return "haul"; + if (k.StartsWith("diet_")) return "eat"; + if (k == "city_walking_to_danger_zone" || k == "farmer_random_move" + || k == "random_move_towards_civ_building") return "move"; + if (k == "warrior_army_captain_idle_walking_city" + || k == "warrior_army_leader_move_random") return "warrior"; + if (k == "boat_transport_check_taxi") return "settle"; + if (k == "punch_a_building") return "fight"; + if (k == "run_to_water_when_on_fire") return "flee"; + if (k == "try_to_launch_fireworks") return "play"; + if (k == "type_bonfire") return "work"; + if (k == "random_house_building") return "settle"; if ((k.Contains("play") && !k.Contains("display")) || k.Contains("fun_move") || k.Contains("frolic") || k.StartsWith("child_")) return "play"; if (k.Contains("hunt") || k == "behattackactorhuntingtarget") return "hunt"; if (k.Contains("fight") || k.Contains("attack") || k.Contains("tantrum")) return "fight"; - if (k.Contains("social") || k.Contains("talk") || k.Contains("trysocialize") - || k.Contains("crying") || k.Contains("just_cried") || k.Contains("swore") - || k.Contains("madness")) return "social"; + if (k.Contains("social") || k.Contains("talk") || k.Contains("trysocialize")) return "social"; if (k.Contains("lover") || k.Contains("breed") || k.Contains("reproduction") - || k.Contains("desire")) return "lover"; + || k.Contains("reproduc") || k.Contains("desire")) return "lover"; if (k.Contains("farm") || k.Contains("plant") || k.Contains("fertiliz") || k.Contains("harvest") || k.Contains("hoe")) return "farm"; if (k == "work" || k.Contains("mine") || k.Contains("woodcut") || k.Contains("chop") @@ -33,43 +79,62 @@ public static class ActivityVerbMap if (k.Contains("trade") || k.Contains("barter") || k.Contains("tax") || k.Contains("boat_trading")) return "trade"; if (k.Contains("fish")) return "fish"; - if (k.Contains("unload") || k.Contains("throw_resource") || k.Contains("carrying")) return "haul"; + if (k.Contains("unload") || k.Contains("throw_resource") || k.Contains("carrying") + || k.Contains("store_resource") || k.Contains("boat_load_units")) return "haul"; if (k.Contains("heal") || k.Contains("cure")) return "heal"; - if (k.Contains("fire") || k.Contains("fireman") || k.Contains("blaze")) return "fire"; + if (k.Contains("fire") || k.Contains("blaze")) return "fire"; if (k.Contains("sleep") || k.Contains("wakeup") || k.Contains("burrow")) return "sleep"; if (k.Contains("eat") || k.Contains("food") || k.Contains("meal") || k.StartsWith("diet_")) return "eat"; if (k.Contains("run_away") || k.Contains("flee") || k.Contains("retreat") || k.Contains("danger_check") || k.Contains("banish") || k.Contains("kill_unruly")) return "flee"; + if (k == "task_unit_run_to_water") return "flee"; if (k.Contains("job") || k.Contains("employ") || k.Contains("find_house") - || k.Contains("claim") || k.Contains("king_") || k.Contains("leader_") + || k.Contains("claim") || k.StartsWith("king_") || k.StartsWith("leader_") || k.Contains("citizen") || k.Contains("join_city") || k.Contains("check_city") || k.Contains("check_plot") || k.Contains("family_check") || k.Contains("embark") || k.Contains("boat_return") || k.Contains("force_into_a_boat") - || k.Contains("boat_transport") || k.Contains("boat_check") || k.Contains("investigate")) + || k.Contains("boat_transport") || k.Contains("boat_check") || k.Contains("investigate") + || k == "check_join_empty_nearby_city" || k.Contains("progress_plot") + || k == "task_unit_plot" || k.Contains("return_to_dock") + || k == "try_new_plot" || k == "try_to_return_to_home_city" + || k == "try_to_start_new_civilization" || k == "type_house" || k == "type_well") return "settle"; if (k.Contains("warrior") || k.Contains("army") || k.Contains("formation") - || k.Contains("invincible")) return "warrior"; + || k.Contains("invincible") || k == "type_barracks" + || k == "type_training_dummies") return "warrior"; if (k.Contains("wait") || k == "reflection" || k.Contains("hold_still") - || k.Contains("make_decision") || k.Contains("think") || k.Contains("stuck")) return "wait"; + || k.Contains("make_decision") || k.Contains("think") || k.Contains("stuck") + || k == "nothing" || k == "sit_inside_boat" || k.StartsWith("stay_in_") + || k == "task_unit_nothing") return "wait"; if (k.Contains("idle") || k.Contains("random_move") || k.Contains("walking") || k.EndsWith("_move") || k.Contains("wander") || k == "move" || k.Contains("dragon_") || k.Contains("godfinger") || k.Contains("follow_") || k.StartsWith("ant_") || k.StartsWith("ufo_") || k.StartsWith("worm_") - || k.Contains("slide") || k.Contains("land") || k.Contains("fly")) return "move"; + || k.Contains("slide") || k.Contains("land") || k.Contains("fly") + || k.StartsWith("move_") || k == "random_swim" || k.Contains("teleport") + || k == "task_unit_walk" || k == "possessed_following") return "move"; if (k.Contains("read")) return "read"; - if (k.Contains("loot") || k.Contains("family_group")) return "gather_life"; + if (k == "pickaxe" || k.StartsWith("print_") || k == "punch_a_tree" + || k.Contains("repair_equipment") || k == "ruins" + || k == "type_fruits" || k == "type_poop" || k == "type_tree" + || k == "type_vegetation" || k == "type_bonfire") return "work"; + if (k == "type_flower" || k == "type_hive") return "pollinate"; + if (k == "type_crops") return "farm"; return ""; } public static bool HasActionCore(string key) { - return !string.IsNullOrEmpty(Resolve(key)) - || !string.IsNullOrEmpty(ActivityProse.PatternActionPhrase(key, false)) - || !string.IsNullOrEmpty(key); + return !string.IsNullOrEmpty(Resolve(key)); } public static List EnumerateLiveTaskIds() { return ActivityAssetCatalog.EnumerateLiveTaskIds(); } + + public static string[] EnumerateBehaviorBeatKeys() + { + return (string[])BehaviorBeatKeys.Clone(); + } } diff --git a/IdleSpectator/ActivityVoiceHarness.cs b/IdleSpectator/ActivityVoiceHarness.cs index 7c0e180..944c7c0 100644 --- a/IdleSpectator/ActivityVoiceHarness.cs +++ b/IdleSpectator/ActivityVoiceHarness.cs @@ -15,11 +15,7 @@ public sealed class ActivityVoiceAuditResult /// Exhaustive live-library gates for voice classification and prose fingerprints. public static class ActivityVoiceHarness { - private static readonly string[] FingerprintKeys = - { - "move", "wait", "task_unit_play", "task_eat", "task_sleep", - "task_hunt", "task_attack", "social", "laugh", "work" - }; + private static readonly string[] FingerprintKeys = ActivitySpeciesVoice.AuthoredVerbs; private static readonly string[] AwkwardProseFragments = { @@ -57,7 +53,15 @@ public static class ActivityVoiceHarness "eagerly", "contentedly", "stubborn focus", - "stubborn persistence" + "stubborn persistence", + "pollinating work", + "fishing task", + "healing task", + "hauling task", + "stealing motion", + "tends the healing", + "works the farm", + "waits over the fishing" }; private static readonly string[] UngroundedTerrainFragments = @@ -72,7 +76,16 @@ public static class ActivityVoiceHarness "close to the ground", "nose to the ground", "damp play", - "wet quiet" + "wet quiet", + " in water", + " through water", + " underwater", + " on the shore", + " across the field", + " in the field", + " tests the ground", + " gaining ground", + " grounded " }; public static ActivityVoiceAuditResult RunAudit(string outputDirectory) @@ -96,6 +109,9 @@ public static class ActivityVoiceHarness int terrainLeaks = 0; int variantBaseFail = 0; int authoredPhraseFail = 0; + int unmappedTasks = 0; + int missingTaskBags = 0; + int routedTasks = 0; string sample = ""; string vehicleFingerprint = null; var fingerprints = new Dictionary(StringComparer.Ordinal); @@ -245,6 +261,38 @@ public static class ActivityVoiceHarness } } + List taskKeys = ActivityVerbMap.EnumerateLiveTaskIds(); + string[] beatKeys = ActivityVerbMap.EnumerateBehaviorBeatKeys(); + for (int source = 0; source < 2; source++) + { + int count = source == 0 ? taskKeys.Count : beatKeys.Length; + for (int i = 0; i < count; i++) + { + string taskKey = source == 0 ? taskKeys[i] : beatKeys[i]; + string verb = ActivityVerbMap.Resolve(taskKey); + routedTasks++; + if (string.IsNullOrEmpty(verb)) + { + unmappedTasks++; + AddSample(ref sample, taskKey + ":unmapped-task"); + continue; + } + + foreach (string baseId in liveBases) + { + string[] bag = ActivitySpeciesVoiceCatalog.GetBag( + baseId, + verb, + ActivityTerrain.Unknown); + if (bag == null || bag.Length < 2) + { + missingTaskBags++; + AddSample(ref sample, baseId + ":" + taskKey + ":missing-bag=" + verb); + } + } + } + } + int pairFail = PairwiseFailures(ref sample); bool liveContextOk = VerifyLiveContext(ref sample); try @@ -273,6 +321,8 @@ public static class ActivityVoiceHarness && terrainLeaks == 0 && variantBaseFail == 0 && authoredPhraseFail == 0 + && unmappedTasks == 0 + && missingTaskBags == 0 && pairFail == 0 && liveContextOk; return new ActivityVoiceAuditResult @@ -294,6 +344,9 @@ public static class ActivityVoiceHarness + " terrainLeaks=" + terrainLeaks + " variantBaseFail=" + variantBaseFail + " authoredPhraseFail=" + authoredPhraseFail + + " routedTasks=" + routedTasks + + " unmappedTasks=" + unmappedTasks + + " missingTaskBags=" + missingTaskBags + " pairFail=" + pairFail + " liveContextOk=" + liveContextOk + " sample='" + sample + "'" @@ -304,9 +357,9 @@ public static class ActivityVoiceHarness { int failures = 0; string label = ActivityAssetCatalog.SpeciesDisplayLabel(baseSpeciesId); - for (int i = 0; i < ActivitySpeciesVoice.CoreVerbs.Length; i++) + for (int i = 0; i < ActivitySpeciesVoice.AuthoredVerbs.Length; i++) { - string verb = ActivitySpeciesVoice.CoreVerbs[i]; + string verb = ActivitySpeciesVoice.AuthoredVerbs[i]; string[] bag = ActivitySpeciesVoiceCatalog.GetBag( baseSpeciesId, verb, diff --git a/IdleSpectator/AgentHarness.cs b/IdleSpectator/AgentHarness.cs index 06aaf7e..27f9c4d 100644 --- a/IdleSpectator/AgentHarness.cs +++ b/IdleSpectator/AgentHarness.cs @@ -1857,6 +1857,20 @@ public static class AgentHarness detail = $"hist='{hist}' needle='{needle}' act={WatchCaption.LastActivityShown} life={WatchCaption.LastLifeShown}"; break; } + case "dossier_history_not_contains": + { + string needle = string.IsNullOrEmpty(cmd.value) ? cmd.label : cmd.value; + string hist = WatchCaption.LastHistoryJoined ?? ""; + if (string.IsNullOrEmpty(hist)) + { + hist = WatchCaption.LastHistoryPreview ?? ""; + } + + pass = !string.IsNullOrEmpty(needle) + && hist.IndexOf(needle, System.StringComparison.OrdinalIgnoreCase) < 0; + detail = $"hist='{hist}' excludes='{needle}' act={WatchCaption.LastActivityShown} life={WatchCaption.LastLifeShown}"; + break; + } case "activity_count": { long id = WatchCaption.CurrentUnitId; diff --git a/IdleSpectator/HarnessScenarios.cs b/IdleSpectator/HarnessScenarios.cs index 8bdae65..7b4ed77 100644 --- a/IdleSpectator/HarnessScenarios.cs +++ b/IdleSpectator/HarnessScenarios.cs @@ -487,7 +487,7 @@ internal static class HarnessScenarios Step("act13e", "assert", expect: "activity_prose_library"), Step("act13f", "assert", expect: "activity_taxonomy_audit"), Step("act14", "activity_force", asset: "laughing", label: "Laughing", count: 1, value: "angle"), - Step("act14b", "assert", expect: "activity_log_contains", value: "chime"), + Step("act14b", "assert", expect: "activity_log_contains", value: "celestial"), Step("act14c", "activity_force", asset: "eating", label: "Taking a meal", count: 1), Step("act15", "activity_force", asset: "farm", label: "Tends the fields", count: 1), Step("act16", "activity_force", asset: "hunt", label: "Hunts", count: 1, expect: "Barkley"), @@ -507,7 +507,7 @@ internal static class HarnessScenarios Step("act20b", "assert", expect: "activity_names_colored"), Step("act20c", "assert", expect: "activity_log_contains", value: "Barkley"), Step("act21", "assert", expect: "dossier_history_shown", value: "1", label: "min", tier: "activity"), - Step("act22", "assert", expect: "dossier_history_contains", value: "Harness pollen"), + Step("act22", "assert", expect: "dossier_history_not_contains", value: "Harness pollen"), Step("act23", "assert", expect: "caption_layout_ok"), Step("act24", "screenshot", value: "hud-activity_idle_smoke.png"), Step("act25", "wait", wait: 0.55f), diff --git a/IdleSpectator/mod.json b/IdleSpectator/mod.json index f68a1c2..45c4c85 100644 --- a/IdleSpectator/mod.json +++ b/IdleSpectator/mod.json @@ -1,7 +1,7 @@ { "name": "IdleSpectator", "author": "dazed", - "version": "0.12.79", + "version": "0.12.84", "description": "AFK Idle Spectator (I) + Lore (L). Detailed living activity prose by default.", "GUID": "com.dazed.idlespectator" }