Skills
skills
Skills are the rolled actions characters attempt. Each skill connects to one attribute (which contributes to the check total), has a type string for difficulty bonuses, and a description that defines what it covers.
"Available skills and their mechanics"
- Editor location
- Mechanics → Skills
- Editor type
- JSON + ADD ITEM
- API endpoint
-
/api/sections/skills.json/api/sections/skills.md - Size limits
-
No character-length caps for this section. See the validation reference for the complete table.
Schema
{
"skills": {
"<key>": {
"name": "string",
"attribute": "string",
"type": "string",
"description": "string",
"startingItems": [
"(recursive)"
]
}
}
}
Example
{
"acrobatics": {
"name": "acrobatics",
"type": "utility",
"attribute": "dexterity",
"description": "Tumbling, balancing, escaping restraints. DC 10: basic balance. DC 15: combat tumbling. DC 20: acrobatic attacks. DC 25: impossible-seeming feats of agility.",
"startingItems": [
{ "item": "leather boots", "quantity": 1 }
],
"abilities": ["Tumble", "Recover Footing"]
},
"athletics": {
"name": "athletics",
"type": "combat",
"attribute": "strength",
"description": "Melee combat, climbing, swimming, grappling. DC 10: basic attacks and physical tasks. DC 20: powerful strikes, scaling walls. DC 30: exceptional feats of strength. DC 40+: legendary physical achievements.",
"startingItems": [
{ "item": "Shortsword", "quantity": 1 }
],
"abilities": ["Precision Strike", "Whirlwind"]
}
}
Fields
type
Must match a key in skillTypeDifficultyBonus. Types are entirely world-defined — only "none" (with a bonus of 0) is a documented default; any other type strings you use must be defined in skillTypeDifficultyBonus. Conventional values are "combat" (anything that deals damage) and "utility" (everything else). “Only use utility if you never plan to deal damage with it. If it’s a hybrid skill, make it combat.” Note acrobatics above is utility — it describes movement and escape, but if a player wanted to deal damage with an acrobatic maneuver, they’d roll athletics instead.
Note (
"combat"is mechanically special): Beyond the difficulty bonus, the exact type string"combat"is the only type that adds damage. When an attack uses atype: "combat"skill, it gains a flat bonus scaling with that skill’s linkedattribute:max(0, floor((effectiveAttribute - 6) / 2))added to damage — i.e. +1 per 2 attribute points above 6, so an attribute of 14 adds +4. Skills of any other type deal no attribute-scaled damage. Give an attack skilltype: "combat"if you want it to scale damage with its attribute. This is the per-skill bonus referenced under Attributes → attributeDamageModifiers; the globalattributeDamageModifierspercentage stacks on top of it.
attribute
Governs the attribute contribution to the check total. Must match a name in attributeSettings.attributeNames
— the validator enforces this cross-reference. Recommend a fairly even mix of skills per attribute; 1–3 attributes per character class is a good target. A D&D-style scenario typically maps to strength, dexterity, intelligence, wisdom, and charisma.
description
The primary AI guidance for this skill. Include: what actions it covers, difficulty thresholds for specific tasks, how powerful effects are. This is the field the AI reads as its primary reference for this skill during play. DC thresholds serve dual purpose: as the target numbers for resolving checks, and as narrative scaling guidance — a roll of 12 on a skill with “DC 10: basic success, DC 20: powerful strike” produces a solid functional outcome described as clearly short of the masterful tier.
startingItems
items given to players who start with this skill at character creation. “If you give someone the swordsmanship skill, it’s nice to give them a sword too.” Use [] if no starting gear is attached.
abilities (extra-codec)
Array of ability name strings associated with this skill. The editor displays these to show which abilities are unlockable through this skill. Strings should match keys in abilities
. Does not replace the requirements field on individual abilities — this is a display association, not the unlock gate.
Task resolution
Skill check formula
total = baseRoll
+ (skillLevel * skillBonusModifier)
+ ((attributeValue - 10) * attributeBonusModifier)
+ skillTypeDifficultyBonus[skillType]
+ earlyGameBonus // +10 if gameTick < 50, else 0
+ contextModifiers
Compare total against the difficulty target. The bands of success (critical / success / partial / failure / critical failure) are determined by how far the total exceeds or falls short of the target.
baseRoll is a finite deck
Voyage does not use a D20-style dice system. The engine draws one card without replacement from a fixed pool, modulated by global difficulty. At medium difficulty the pool is [-40, -20, -10, 0, 10, 20, 20, 40] (8 cards). Easier difficulties add positive cards (very easy adds [15, 20, 25, 30], easy adds [10, 15, 20]); harder difficulties add negatives (hard adds [-20, -15, -10], very hard adds [-30, -25, -20, -15]). When the pool empties it refills to the full set, so streaks of bad luck are bounded and the distribution averages out over a handful of checks. Each drawn card is also clamped to ± maxSkillSuccessLevel. Practically: tune DC thresholds against this specific distribution, and expect occasional swings of ±40 (or larger at extreme difficulties) rather than uniform variance.
maxSkillSuccessLevel cap
skillSettings.maxSkillSuccessLevel (engine default 25) caps the absolute contribution any single skill, attribute, ability, random roll, or context modifier can add to a check. Most authored worlds raise this to 80–100 to give skill investment headroom; the default of 25 keeps swings tight in tutorial-style scenarios.
Progression
Skill XP rewards
In skillSettings.skillXPRewards:
| Size | Balanced XP |
|---|---|
small
|
40 |
medium
|
60 |
large
|
100 |
huge
|
150 |
XP to next skill level
xpToNextLevel = startingXPToLevelUpSkill + (currentLevel * additionalXPRequiredPerSkillLevel)
With balanced settings (startingXPToLevelUpSkill: 100, additionalXPRequiredPerSkillLevel: 40): level 1 = 100 XP, level 10 = 460 XP, level 30 = 1,260 XP. skillSettings.maxSkillLevel (engine default 25) caps how high any skill can climb; most authored worlds raise this to 100 for deeper progression.
Learning new skills
When a character uses a skill they don’t have:
chanceToLearn = baseChanceToLearnNewSkill + (attributeValue * skillLearningBonusModifier)
If the roll succeeds, the skill is added at level 0, the character gains xpFromNewSkill (balanced 200) character XP, and the skill’s startingItems are added to inventory. Set baseChanceToLearnNewSkill: 1 and skillLearningBonusModifier: 1 to allow learning new skills, or both 0 to lock the skill set at character creation.
Training
Players can train skills between uses, with cooldown skillSettings.trainingCooldown (balanced 10) ticks between sessions. Training adds skill XP directly.
Authoring tips
Balance advice
- Don’t create multiple overlapping skills (e.g., 4 sword-fighting styles). Skills level through use — spreading XP across many similar skills weakens all of them.
- XP rewards: use
skillXPRewardssize buckets (small/medium/large/huge) to weight skills used in combat vs. skills used rarely.
Attribute distribution
Aim for 1–3 primary attributes per class. A good distribution avoids any single attribute dominating every class, and gives utility skills (social, knowledge) roughly equal representation to combat skills. The complete skill list for your scenario should be documented in your scenario’s registry.