{"tab":"mechanics","section":"successLevelSettings","title":"Success Levels","summary":"The outcome bands an action's skill check can land in. Each tier is a score range with a player-facing name, narration instructions and an optional image, and one tier marks where success begins. Voyage rejects a world that leaves the section out.","kind":"schema","uiLocation":"Files → Mechanics → Success Levels","editor":"Edit in Studio + View JSON","related":[{"section":"triggers","note":"action-success-level reads the tier an action landed in, matching on its name"},{"section":"skillSettings","note":"the skill check that produces the score a tier covers"},{"section":"relationshipStages","note":"the same score-band shape, applied to NPC relationships"}],"wikiUrl":"/mechanics/successLevelSettings","filePath":["successLevelSettings"],"schema":{"_type":"intersection","parts":[{"_type":"required","fields":{"firstSuccessfulTierId":"string","tiers":{"_type":"array","of":{"_type":"intersection","parts":[{"_type":"partial","fields":{"id":"string","name":"string","minScore":{"_type":"union","of":["number","undefined"]},"maxScore":{"_type":"union","of":["number","undefined"]},"prompt":"string"}},{"_type":"partial","fields":{"imageUrl":{"_type":"union","of":["string","undefined"]}}}]}}}}]},"sizeLimits":[],"blocks":[{"type":"example","lang":"json","caption":"Example: Voyage's default success tiers, which every new world starts from","code":"{\n  \"successLevelSettings\": {\n    \"firstSuccessfulTierId\": \"mixed-results\",\n    \"tiers\": [\n      {\n        \"id\": \"critical-failure\",\n        \"name\": \"Critical Failure\",\n        \"minScore\": null,\n        \"maxScore\": -66,\n        \"imageUrl\": \"\",\n        \"prompt\": \"[Note: {{characterName}} tries to do the action, but it fails in a dramatic, catastrophic way - if enemies are present, consider framing the failure as partly the result of an enemy's cleverness, tactics, or intervention that thwarts the attempt, rather than the player merely being inept.]\"\n      },\n      {\n        \"id\": \"failure\",\n        \"name\": \"Failure\",\n        \"minScore\": -65,\n        \"maxScore\": -51,\n        \"imageUrl\": \"\",\n        \"prompt\": \"[Note: {{characterName}} tries to do the action, but it fails - if enemies are present, consider framing the failure as partly the result of an enemy's cleverness, tactics, or intervention that thwarts the attempt, rather than the player merely being inept.]\"\n      },\n      {\n        \"id\": \"mixed-results\",\n        \"name\": \"Mixed Results\",\n        \"minScore\": -50,\n        \"maxScore\": -26,\n        \"imageUrl\": \"\",\n        \"prompt\": \"[Note: {{characterName}} does the action, but it is only partially successful with mixed results.]\"\n      },\n      {\n        \"id\": \"basic-success\",\n        \"name\": \"Basic Success\",\n        \"minScore\": -25,\n        \"maxScore\": -1,\n        \"imageUrl\": \"\",\n        \"prompt\": \"[Note: {{characterName}}'s action is successful.]\"\n      },\n      {\n        \"id\": \"success\",\n        \"name\": \"Success\",\n        \"minScore\": 0,\n        \"maxScore\": 24,\n        \"imageUrl\": \"\",\n        \"prompt\": \"[Note: {{characterName}}'s action is quite successful.]\"\n      },\n      {\n        \"id\": \"great-success\",\n        \"name\": \"Great Success\",\n        \"minScore\": 25,\n        \"maxScore\": 49,\n        \"imageUrl\": \"\",\n        \"prompt\": \"[Note: {{characterName}}'s action is very successful.]\"\n      },\n      {\n        \"id\": \"critical-success\",\n        \"name\": \"Critical Success\",\n        \"minScore\": 50,\n        \"maxScore\": null,\n        \"imageUrl\": \"\",\n        \"prompt\": \"[Note: {{characterName}}'s action is amazingly successful in an awesome way.]\"\n      }\n    ]\n  }\n}"},{"type":"prose","md":"## How it works\n\nAn action the engine resolves with a skill check produces a score, and `successLevelSettings` decides which outcome band that score falls in. The band it lands on names the outcome for the player and hands the narrator that band's `prompt` as guidance for describing it.\n\n- A tier is `{ id, name, minScore, maxScore, prompt }` with an optional `imageUrl`. A world defines between 2 and 20 of them.\n- The bands are read in score order rather than file order, so rearranging the list changes nothing. They must tile the range exactly: each band begins one point above the previous band's `maxScore`, leaving no gaps and no overlaps.\n- The two ends are open: the lowest band sets `minScore` to `null` and the highest sets `maxScore` to `null`. Exactly one band may do each, and it must be the band at that end of the ladder.\n- `firstSuccessfulTierId` names the `id` of the lowest tier that counts as a success. That tier and every band above it succeed, everything below it fails. How far above the threshold a tier sits is what makes its success read as a stronger one, so a ladder with a single successful tier treats that tier as the strongest.\n- `id` must be unique and non-empty. `name` must be unique as well, compared ignoring case and surrounding spaces, so `Great Success` and `great success` collide.\n- Voyage rejects a world that leaves this section out, so unlike an optional settings section it cannot simply be omitted. The defaults above are the starting point.\n- Triggers read the outcome with the `action-success-level` condition, which matches a tier's **`name`** rather than its `id`, again ignoring case and surrounding spaces. The values are an ordered ladder, so the comparison operators rank them. A value matching no tier name leaves the condition permanently false. The engine also refuses to judge `action-success-level` in the same trigger as a `story` or `story-text` condition; put the story check on its own trigger (see [Triggers](/mechanics/triggerDefinitions))."},{"type":"fields","fields":[{"name":"firstSuccessfulTierId","required":true,"tooltip":"Id of the lowest tier that counts as a success.","md":"The `id` of the lowest tier that counts as a success. That tier and every higher band succeed; the bands below it fail. It must name a tier in `tiers`."},{"name":"tiers","required":true,"tooltip":"The outcome bands, between 2 and 20 of them.","md":"The outcome bands, between 2 and 20 of them. They are read in score order and must tile the range with no gaps or overlaps, so the list's own order carries no meaning."},{"name":"id","required":true,"tooltip":"Stable identifier for this tier.","md":"A stable identifier for this tier, unique within `tiers` and non-empty. `firstSuccessfulTierId` points at one of these."},{"name":"name","required":true,"tooltip":"Player-facing name for this outcome.","md":"The player-facing name for this outcome, and the value an `action-success-level` trigger condition matches against. It must be unique, compared ignoring case and surrounding spaces."},{"name":"minScore","required":true,"tooltip":"Lowest score in this band, or null on the lowest band.","md":"The lowest score this band covers, inclusive, as a whole number. Set it to `null` on the lowest band to leave that end open; on every other band it must be one point above the band below's `maxScore`."},{"name":"maxScore","required":true,"tooltip":"Highest score in this band, or null on the highest band.","md":"The highest score this band covers, inclusive, as a whole number. Set it to `null` on the highest band to leave that end open. It must be at or above this band's `minScore`."},{"name":"prompt","required":true,"tooltip":"Narration instructions for this outcome.","md":"The instruction handed to the narrator when an action lands in this band. `{{characterName}}` is replaced with the acting character's name."},{"name":"imageUrl","required":false,"tooltip":"Optional image shown with this outcome.","md":"An optional image shown with the outcome. Voyage limits which hosts it will load, so use the https URL Voyage gives you when the image is uploaded, or leave it blank for no image."}]}],"body":"> **How to read this page.** Only what it says Voyage requires, rejects or enforces is a rule, and `POST /validate` is what settles those. Everything else is authoring guidance: one worked way of doing it, not a specification. Do not apply guidance to a world unless the human asks for it.\n\n## Example: Voyage's default success tiers, which every new world starts from\n\n```json\n{\n  \"successLevelSettings\": {\n    \"firstSuccessfulTierId\": \"mixed-results\",\n    \"tiers\": [\n      {\n        \"id\": \"critical-failure\",\n        \"name\": \"Critical Failure\",\n        \"minScore\": null,\n        \"maxScore\": -66,\n        \"imageUrl\": \"\",\n        \"prompt\": \"[Note: {{characterName}} tries to do the action, but it fails in a dramatic, catastrophic way - if enemies are present, consider framing the failure as partly the result of an enemy's cleverness, tactics, or intervention that thwarts the attempt, rather than the player merely being inept.]\"\n      },\n      {\n        \"id\": \"failure\",\n        \"name\": \"Failure\",\n        \"minScore\": -65,\n        \"maxScore\": -51,\n        \"imageUrl\": \"\",\n        \"prompt\": \"[Note: {{characterName}} tries to do the action, but it fails - if enemies are present, consider framing the failure as partly the result of an enemy's cleverness, tactics, or intervention that thwarts the attempt, rather than the player merely being inept.]\"\n      },\n      {\n        \"id\": \"mixed-results\",\n        \"name\": \"Mixed Results\",\n        \"minScore\": -50,\n        \"maxScore\": -26,\n        \"imageUrl\": \"\",\n        \"prompt\": \"[Note: {{characterName}} does the action, but it is only partially successful with mixed results.]\"\n      },\n      {\n        \"id\": \"basic-success\",\n        \"name\": \"Basic Success\",\n        \"minScore\": -25,\n        \"maxScore\": -1,\n        \"imageUrl\": \"\",\n        \"prompt\": \"[Note: {{characterName}}'s action is successful.]\"\n      },\n      {\n        \"id\": \"success\",\n        \"name\": \"Success\",\n        \"minScore\": 0,\n        \"maxScore\": 24,\n        \"imageUrl\": \"\",\n        \"prompt\": \"[Note: {{characterName}}'s action is quite successful.]\"\n      },\n      {\n        \"id\": \"great-success\",\n        \"name\": \"Great Success\",\n        \"minScore\": 25,\n        \"maxScore\": 49,\n        \"imageUrl\": \"\",\n        \"prompt\": \"[Note: {{characterName}}'s action is very successful.]\"\n      },\n      {\n        \"id\": \"critical-success\",\n        \"name\": \"Critical Success\",\n        \"minScore\": 50,\n        \"maxScore\": null,\n        \"imageUrl\": \"\",\n        \"prompt\": \"[Note: {{characterName}}'s action is amazingly successful in an awesome way.]\"\n      }\n    ]\n  }\n}\n```\n\n## How it works\n\nAn action the engine resolves with a skill check produces a score, and `successLevelSettings` decides which outcome band that score falls in. The band it lands on names the outcome for the player and hands the narrator that band's `prompt` as guidance for describing it.\n\n- A tier is `{ id, name, minScore, maxScore, prompt }` with an optional `imageUrl`. A world defines between 2 and 20 of them.\n- The bands are read in score order rather than file order, so rearranging the list changes nothing. They must tile the range exactly: each band begins one point above the previous band's `maxScore`, leaving no gaps and no overlaps.\n- The two ends are open: the lowest band sets `minScore` to `null` and the highest sets `maxScore` to `null`. Exactly one band may do each, and it must be the band at that end of the ladder.\n- `firstSuccessfulTierId` names the `id` of the lowest tier that counts as a success. That tier and every band above it succeed, everything below it fails. How far above the threshold a tier sits is what makes its success read as a stronger one, so a ladder with a single successful tier treats that tier as the strongest.\n- `id` must be unique and non-empty. `name` must be unique as well, compared ignoring case and surrounding spaces, so `Great Success` and `great success` collide.\n- Voyage rejects a world that leaves this section out, so unlike an optional settings section it cannot simply be omitted. The defaults above are the starting point.\n- Triggers read the outcome with the `action-success-level` condition, which matches a tier's **`name`** rather than its `id`, again ignoring case and surrounding spaces. The values are an ordered ladder, so the comparison operators rank them. A value matching no tier name leaves the condition permanently false. The engine also refuses to judge `action-success-level` in the same trigger as a `story` or `story-text` condition; put the story check on its own trigger (see [Triggers](/mechanics/triggerDefinitions)).\n\n## Fields\n\n### firstSuccessfulTierId\n\nThe `id` of the lowest tier that counts as a success. That tier and every higher band succeed; the bands below it fail. It must name a tier in `tiers`.\n\n### tiers\n\nThe outcome bands, between 2 and 20 of them. They are read in score order and must tile the range with no gaps or overlaps, so the list's own order carries no meaning.\n\n### id\n\nA stable identifier for this tier, unique within `tiers` and non-empty. `firstSuccessfulTierId` points at one of these.\n\n### name\n\nThe player-facing name for this outcome, and the value an `action-success-level` trigger condition matches against. It must be unique, compared ignoring case and surrounding spaces.\n\n### minScore\n\nThe lowest score this band covers, inclusive, as a whole number. Set it to `null` on the lowest band to leave that end open; on every other band it must be one point above the band below's `maxScore`.\n\n### maxScore\n\nThe highest score this band covers, inclusive, as a whole number. Set it to `null` on the highest band to leave that end open. It must be at or above this band's `minScore`.\n\n### prompt\n\nThe instruction handed to the narrator when an action lands in this band. `{{characterName}}` is replaced with the acting character's name.\n\n### imageUrl\n\nAn optional image shown with the outcome. Voyage limits which hosts it will load, so use the https URL Voyage gives you when the image is uploaded, or leave it blank for no image."}