97b49d4145
Skill list grows from 18 → 30 so every ability has 5 skills tied to it. New skills appended at SkillId byte indices 18–29 to preserve save-game compat with pre-M6.18 characters. STR (+4): Brawl, Build-Read, Force, Haulage DEX (+2): Driving, Marksmanship CON (+5): Endurance, Fortitude, Hardiness, Lung-Craft, Pain Tolerance CHA (+1): Scent-Speak Endurance covers applied effort over time; Hardiness covers external condition tolerance (temperature, smoke, altitude); Fortitude is ingestion-only (poison, spoiled food, ritual draughts). Pain Tolerance is function-while-wounded. Lung-Craft is breath/voice discipline. Class skill_options updated across all 8 callings so every new skill has 3+ class homes (Muzzle-Speaker remains the universal pick of all 30). Backgrounds left untouched — their skill grants are doc-canon and would benefit from a separate balancing pass. CharacterBuilder.SkillToJsonName extended with explicit cases for the new skills so compound enum names like BuildRead serialize as "build_read" rather than the fallback "buildread" — caught by CharacterBuilderTests. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
103 lines
8.4 KiB
C#
103 lines
8.4 KiB
C#
namespace Theriapolis.GodotHost.UI;
|
|
|
|
/// <summary>
|
|
/// All 30 skills with display labels, governing ability, and codex
|
|
/// flavor descriptions. Entries are keyed by their snake_case JSON id —
|
|
/// the same string that appears in <c>class.skill_options</c> and
|
|
/// <c>background.skill_proficiencies</c> in <c>Content/Data</c>.
|
|
///
|
|
/// Labels and ability mapping mirror Theriapolis.Core.Rules.Stats.SkillId.
|
|
/// The 18 d20-baseline descriptions are ported from the React prototype's
|
|
/// <c>SKILL_DESC</c> table; the 12 M6.18 expansions (5 per ability total)
|
|
/// are Theriapolis-specific and authored against the design canon.
|
|
/// </summary>
|
|
public static class SkillsCatalog
|
|
{
|
|
public record SkillEntry(string JsonId, string Label, string Ability, string Description);
|
|
|
|
public static readonly SkillEntry[] All =
|
|
{
|
|
new("acrobatics", "Acrobatics", "DEX",
|
|
"Tumbling, balance, and the kind of footwork that keeps you upright on a coliseum sand-floor or a warren-rope. Body-cunning under pressure."),
|
|
new("animal_handling", "Animal Handling", "WIS",
|
|
"Reading and steering non-sentient beasts — feral hounds, draft-kine, the wild cousins of your own clade. Calming, herding, riding."),
|
|
new("arcana", "Arcana", "INT",
|
|
"Knowledge of the older magics: scent-sorcery, blood-sigil, the half-forgotten rites that pre-date the Covenant of Claws."),
|
|
new("athletics", "Athletics", "STR",
|
|
"Raw physical effort. Climbing scaffold, swimming the foul canal, hauling a packmate from the pit, breaking a hold."),
|
|
new("brawl", "Brawl", "STR",
|
|
"Bare-fanged unarmed violence — claws, teeth, horns, hooves. The coliseum tradition and the back-alley one. Distinct from Athletics (the running body) and Intimidation (the threat unspoken) — this is the application of natural-weapon force."),
|
|
new("build_read", "Build-Read", "STR",
|
|
"Sizing up another creature's physical capabilities at a glance. Cross-clade body diversity makes this nontrivial — a Mustelid's frame lies about its strength, a Cervid's stillness lies about its speed. The dockside boxer's eye for who can fight."),
|
|
new("deception", "Deception", "CHA",
|
|
"Speaking convincingly past your scent. The art of the false posture, the planted rumor, the answer that is technically true."),
|
|
new("driving", "Driving", "DEX",
|
|
"Vehicle and mount control under pressure. Caravan-work, Hare-courier carts, riding a clademorphic beast over broken ground, navigating a contested street at speed."),
|
|
new("endurance", "Endurance", "CON",
|
|
"Sustained applied effort. The act of doing hard work for a long time — forced marches, all-night hauls, rowing the canal-shift, the long chase. What you put out, hour after hour."),
|
|
new("force", "Force", "STR",
|
|
"Applied violence on objects. Doors, chains, shutters, locked chests, walls that shouldn't be there anymore. The Bulwark's quiet talent and the Claw-Wright's last resort."),
|
|
new("fortitude", "Fortitude", "CON",
|
|
"Resisting what you swallow. Ingested poison and contagion, spoiled rations, foreign cuisine, the Goat-Folk welcome of rotted cheese, the dockside whiskey flight, the ritual draught you cannot politely refuse."),
|
|
new("hardiness", "Hardiness", "CON",
|
|
"Withstanding external conditions. Temperature extremes, smoke and dust, thin mountain air, the slow attrition of weather. The Polar Bear-Folk's cold tolerance, the Coyote-Folk's heat-of-the-day shift, the herd-wall holding under blizzard."),
|
|
new("haulage", "Haulage", "STR",
|
|
"Bearing weight under distance. Porter discipline, stretcher-craft, shouldering an unconscious packmate up a switchback. The Bovid wagon-train's daily reality and the battlefield medic's quiet requirement."),
|
|
new("history", "History", "INT",
|
|
"The long memory of Theriapolis — the Imperium's fall, the Compact's ratification, which clade owes which other a centuries-old debt."),
|
|
new("insight", "Insight", "WIS",
|
|
"Reading another's true posture beneath their words. Catching the off-note in a snarl, the held breath, the lie in a friendly tail."),
|
|
new("intimidation", "Intimidation", "CHA",
|
|
"Bared-teeth diplomacy. The threat made plain enough that violence is not required to extract compliance."),
|
|
new("investigation", "Investigation", "INT",
|
|
"Methodical search and inference: scene-reading, document-sifting, the patient accumulation of small facts into a verdict."),
|
|
new("lung_craft", "Lung-Craft", "CON",
|
|
"Sustained vocalization and breath-control. The physical basis of Muzzle-Speaker oratory, the diver's stillness underwater, the smoke-tolerant veteran's projection across a coliseum without shredding the throat."),
|
|
new("marksmanship", "Marksmanship", "DEX",
|
|
"Accurate ranged weapon use — bow, crossbow, sling, javelin, thrown blade. The skill that lets prey-clade militias hold a wall against predator charge, and the Shadow-Pelt's clean answer at distance."),
|
|
new("medicine", "Medicine", "WIS",
|
|
"Field surgery, poultice-craft, knowing which clade tolerates which tincture. Stabilizing the dying without finishing them."),
|
|
new("nature", "Nature", "INT",
|
|
"Knowledge of the wild outside the city wall — terrain, weather, plant-lore, and the unsigned beasts that observe no Covenant."),
|
|
new("pain_tolerance", "Pain Tolerance", "CON",
|
|
"Function while wounded. Holding the line bleeding, finishing the sentence with a knife in your shoulder, performing surgery on yourself. The hybrid medical-mistrust skill — the one you use when the doctor isn't an option."),
|
|
new("perception", "Perception", "WIS",
|
|
"Awareness through every sense your clade gives you: ear-cock, scent-prickle, the half-glimpsed shape at the edge of vision."),
|
|
new("performance", "Performance", "CHA",
|
|
"Holding an audience — coliseum crowd, courtroom gallery, market square. Song, oratory, the body that compels watching."),
|
|
new("persuasion", "Persuasion", "CHA",
|
|
"Open-handed argument. The case made on its merits, the appeal to mutual benefit, the patient construction of agreement."),
|
|
new("religion", "Religion", "INT",
|
|
"The hymn-cycles of the Cervid liturgy, the Compact's sacred clauses, the small household rites your clade keeps without thinking."),
|
|
new("scent_speak", "Scent-Speak", "CHA",
|
|
"Deliberate pheromone communication — the unspoken half of every Theriapolis conversation. Broadcasting calm, threat, deference, lineage, trust. The Scent-Broker's craft, the passer's nightmare, the perfumer's living. Distinct from Insight (which reads the scent) — this is the active emission."),
|
|
new("sleight_of_hand", "Sleight of Hand", "DEX",
|
|
"Quiet fingers — pickpocketing, palmed coins, the swap performed under another's nose. Useful in markets and courtrooms alike."),
|
|
new("stealth", "Stealth", "DEX",
|
|
"Movement unseen and unsmelled. Wind-checking, scent-suppression, the slow weight-shift on a creaking floor."),
|
|
new("survival", "Survival", "WIS",
|
|
"Field-craft beyond the wall: tracking, foraging, fire-making, knowing which run-off is safe to drink and which carries the upstream butcher's leavings."),
|
|
};
|
|
|
|
public static readonly string[] Abilities = { "STR", "DEX", "CON", "INT", "WIS", "CHA" };
|
|
|
|
public static readonly System.Collections.Generic.Dictionary<string, string> AbilityFullName = new()
|
|
{
|
|
{ "STR", "Strength" },
|
|
{ "DEX", "Dexterity" },
|
|
{ "CON", "Constitution" },
|
|
{ "INT", "Intellect" },
|
|
{ "WIS", "Wisdom" },
|
|
{ "CHA", "Charisma" },
|
|
};
|
|
|
|
public static SkillEntry? Get(string jsonId) =>
|
|
System.Array.Find(All, s => s.JsonId == jsonId);
|
|
|
|
public static System.Collections.Generic.IEnumerable<SkillEntry> ByAbility(string ability)
|
|
{
|
|
foreach (var s in All)
|
|
if (s.Ability == ability) yield return s;
|
|
}
|
|
}
|