-
Notifications
You must be signed in to change notification settings - Fork 3
Authoring Patterns
This is a collection of interesting authoring patterns that arise from StoryAssembler's capabilities. Use it for inspiration!
{
"id": "fightStart",
"content": "What did you say? Care to repeat that?",
"conditions": ["establishDinnerWithFriend eq true"],
"effects": ["addWishlist { 'condition': 'fightResolved eq true' }"]
}
If this fragment is chosen, adds a new wishlist item fightResolved eq true
. This means that StoryAssembler, if this fragment is visited, will start prioritizing to find a path that leads to fragments to satisfy that, in addition to the items set in the scene-config file.
Features
- Allows groupings of fragments to maintain internal consistency, without cluttering up the main wishlist with items that are too-specific
- In other words, allows nested hierarchies of wants, connected / initiated by effects that satisfy the main scene wishlist items
wishlist: [
{ condition: "provokeArgument eq {getStateVar|argumentMode}"},
{ condition: "{getMainCharTrait|protagonist} gt 4" }
]
When the scene begins, whatever argumentMode
is set to in State will become what StoryAssembler tries to set provokeArgument
to. For the second item, will seek to increment whatever the main character's trait is past 4
Features
- Allows insertion of state variables into wishlist items, allowing subsequent scenes to be affected by state modifications in previous ones.
For example, if the player makes a choice to be pacifist, thenargumentMode
can be set tofalse
. Then in a subsequent scene, as illustrated above, the scene will prioritize to make sureprovokeArgument
is set tofalse
. However, if they’d decided to be aggressive and that variable was set to true, the next scene would play out in the opposite manner.
{
"id": "optionalChoiceLabel",
"choiceLabel": "I know, right?",
"request": {"gotoId": "mainContent"}
},
{
"id": "mainContent",
"content": "You would not believe how much of this stuff I ate in Spain.",
"choices" : [
{"gotoId": "quals"},
],
"conditions": ["establishDinnerWithFriend eq true"],
"effects": ["set establishFriendBackstory true"]
}
Features Allows mainContent to appear both as a choice on a node, and as a stand-alone node (bypassing the optionalChoiceLabel fragment). This is important because during normal “Continue” fragment searches it won’t consider fragments that have choiceLabel fields. Essentially this is how you say a choiceLabeled fragment can be considered for a “Continue” search--by separating out the choiceLabel field into another fragment.
Caveats The limitation of state evaluation in the system means that sometimes it will incorrectly say that conditions are not met for the mainContent fragment even though those effects are run in the optionalChoiceLabel. Essentially one should never mix effects / conditions for these combos: either you put both in the labels, or in the mainContent fragment. Never split between the two. However, conditions in one and effects in the other (or vice-versa) should be fine.
{
"id": "choiceLabel1",
"choiceLabel": "I know, right?",
"request": {"gotoId": "mainContent"}
},
{
"id": "choiceLabel2",
"choiceLabel": "Are you kidding me?",
"request": {"gotoId": "mainContent"}
},
{
"id": "mainContent",
"content": "You would not believe how much of this stuff I ate in Spain.",
"choices" : [
{"gotoId": "quals"},
],
"conditions": ["establishDinnerWithFriend eq true"],
"effects": ["set establishFriendBackstory true"]
}
Features
- Allows multiple pathways into one node, with different choiceLabels.
- Allows you to run different grammars on the choiceLabels
- Allows you to add different entry effects to the same fragment
Caveats
Conditions should never appear in both. You have to put them in one or the other