Wildermyth accomplishes Dynamic Writing by using Tags to control what text is inserted into a passage.
Tags use <angle brackets> and allow a fairly wide variety of functionality.
Note: mostly case insensitive, comma and slash as separators, most of the time!
(Related: You'll almost always be using tags via the Comic Editor)
These are simple tags that work in any context and insert names of interesting things.
|tag||example||might render as||explanation|
|Town||<town>||Ninesprings||Finds either the nearest town, or the origin town for the heroes.|
|Company||<company>||The Fellowship of the Eagle||Gives the name of the player's company, which they get a chance to choose at the end of the introduction.|
|Site||<site>||Moosetunnel||Finds the relevant site in a situation, if there is one, or falls back to the nearest interesting site.|
|Tower||<tower>||Cranespire||Finds the name of the Heroes' main base, their home tower, which they gain control of during the introduction.|
|random||<random:I love the woods!/These trees are huge!>||These trees are huge!||Chooses randomly between any number of options. Useful if you want to add variety to an event players might see a lot that might otherwise be the same each time.|
|randomA / randomB / randomC||"Want some <randomA:pasta/bugs>?" "<randomA:Oh, yum! Sure!/Ew, gross.>"||"Want some bugs?" "Ew, gross."||Chooses randomly but deterministically (based on roles in the Effect) between any number of options. If you use several instances of one of these tags with the same number of choices within the same Effect, the same option will be chosen in each instance. This can be useful if you want to randomize a conversation that spans multiple panels.|
|int||<int:2+5>||7||Calculates a given expression as an integer. This is generally useful when used together with variables, ex: "It costs <int:2+RECRUIT_COST_ADJUSTMENT> Legacy Points to recruit this hero."|
|test||<test:foes.THREAT_STRENGTH_FROM_INFESTATION:There are infested tiles/There are no infested tiles>||There are infested tiles||In the form of <test:expression:pass> or <test:expression:pass/fail>. Calculates a given expression as an integer, and shows the pass branch if the expression evaluates to >= 1, and the fail branch (or nothing) otherwise.|
Most tags (and the most useful tags) rely on Story Roles. A role is used to refer to a particular target, usually a hero, and then select text depending on properties of the target.
Role tags use this form:
- <roleName> gives the short name of the target
- <roleName.tag...> most tags work like this, has a variety of effects depending.
- <roleName.#.tag...> where # is a number like 1,2,3,4... Which is useful if more than one entity is assigned to a role.
Numbered roles are not generally recommended because they're a bit awkward to think about, but sometimes they're convenient if, for example, you know there are 2 heroes in the party and you just need to list them or something.
Names and Specials
Use these tags to insert names.
|tag||example||might render as||explanation|
|<leader>||Barlox||Use a plain role tag to show the short name, which, for heroes, is always their first name.|
|shortName||<leader.shortName>||Barlox||Short name. Same as unadorned role.|
|firstName||<leader.firstName>||Barlox||First name. Same as short name.|
|name||<leader.name>||Barlox||Same as short name and first name.|
|lastName||<leader.lastName>||Spidermusk||If the entity has a two-part name, return the last part.|
|fullName||<leader.fullName>||Barlox Spidermusk||The whole name. Very formal.|
|nameCAPS||<leader.nameCAPS>||BARLOX||BARLOX ARE YOU SERIOUS.|
|namelower||<leader.namelower>||barlox||stream of consciousness, mumbling..|
|fullNameCAPS||<leader.fullNameCAPS>||BARLOX SPIDERMUSK||Gah! What'd I do Ma?!|
|fullnamelower||<leader.fullnamelower>||barlox spidermusk||was a strange fellow i'd say|
|lastnamelower||<leader.lastnamelower>||spidermusk||no one will use this tag. go ahead prove me wrong.|
|singular||<foes.singular>||Gorgon||Useful for monsters, if you want the singular version of the monster group name.|
|plural||<foes.plural>||Gorgons||Gives the plural version of the name of a group of monsters.|
|biome||<overlandTile.biome>||forest||the short name of the biome. forest, field, hills, or swamp. If the first letter of the tag is capitalized, the first letter of the result will be as well.|
|biomeLong||<overlandTile.biomeLong>||pine forest||The longer and more specific name of the biome if any. Broadleaf forest, grassland, foothills, pine forest, wetlands. If the first letter of the tag is capitalized, the first letter of the result will be as well.|
|station||<site.station>||windmill||the station type. earthworks, quarry, hunter's blind, outfitter, threshery, etc. If the first letter of the tag is capitalized, the result will be as well.|
|weaponType||<coward.weaponType>||axe||If the first letter of the tag is capitalized (coward.WeaponType), the first letter of the result will be as well.|
|weaponTier||<weapon.weaponTier>||2||The tier of the given item, or the tier of the current main hand weapon of a given individual.|
|element||<weapon.element>||Fire||The element of a given item (Fire, Water, Leaf, Stone), or nothing if the item isn't elemental. (Can also be used to get the element of a spirit)|
|elementSpaceAfter||A <weapon.elementSpaceAfter>Bow||A Fire Bow||Same as element, but puts a space after the element if it's not null. This is to prevent the awkward double-space that would occur if you used the element tag in a line of text and the element was null. (When using this, don't put a space after the tag, only before it)|
|link||<leader.link>||Barlox||Creates a clickable link?? Might not function?? what.|
|eventRoll||<hook.eventRoll:roll_one|difficulty_one>||47%||If there is a dice roll defined in the event, you can use this tag to preview your chance of success. The New Option dialog creates this tag automatically when you define a roll, so you don't need to understand all the ins and outs.|
Selector tags select between alternatives, depending on some aspect or stat of the target. They usually take this form:
- <roleName.selector:option1/option2/option3> options separated by /
- <roleName.selector:option1,option2,option3> options separated by ,
|selector||example||might render as||explanation|
|mf||<bookish.mf:his/her> towel.||her towel.||male/female. if the target is a male, the first option, otherwise the second option.|
|mf||<bookish.mf:his/her/their> towel.||their towel.||male/female. if the target is a male, the first option. If the target is a female, the second option. If neither, the third option is used.|
|awm||I hope to find <romantic.awm:some fine vixen/some wily fox>.||I hope to find some fine vixen.||Attracted to women/men. If the target is attracted to women, the first option. If attracted to men, the second option. If no attraction can be determined, one is picked randomly (but consistently for that character.)|
|town OR hometown||Oh no I can't go back to <goofball.hometown>!||Oh no I can't go back to Markvale!||Finds the hometown of the character, or maybe the origin town if no hometown can be determined.|
|whm||Let me grab my <hothead.whm:shield/cloak/robe/pitchfork>!||Let me grab my cloak!||warrior/hunter/mystic/none returns different text depending on the class of the target. If none, an optional fourth clause is used. if no fourth clause is present, pretend to be a warrior.|
|cdgmt||This place stinks of <foes.cdgmt:mushrooms and mold and muckdwellers./Drauv and doom and death./oozing flesh and miscellanious gorgonous gases./gear-oil and rotting bones./spells and spiderfarts.>||This place stinks of gear-oil and rotting bones.||cultist/drauven/gorgon/morthagi/trhixl - give different text depending on the flavor of a threat.|
|exists||<hook.exists:<hook> looks suspicious.../Nobody knows...>||Aryssa looks suspicious...||if this role exists, i.e. there is one or more match, return the first option, otherwise the second option if any.|
|sp||<party.sp:I'm all alone out here!,I am sure am glad you're with me.>||I sure am glad you're with me.||If the role has zero or one matches, return the first option, otherwise the second option. NOTE: bug, can't use / to separate, must use ,|
|maimal||<hook.maimal:my lost arm/my lost leg/my aching bones>||my lost arm||Maimed? arm, leg, other/none. used to talk about a lost limb.|
|bghps||<overlandTile.bghps:that oak tree/this meadow/that cliffside/that redwood/that pond>||that redwood||different text per tile biome: broadleaf forest (deciduous) / grassland / hills / pine forest (coniferous) / swamp.|
|station||<site.station:earthworks/quarry/hunter' blind/outfitter/...>||quarry||24-way split for each site station: earthworks/quarry/huntersBlind/outfitter/threshery/ tannery/mine/lumberyard/weaverworks/ forestShrine/henge/primalAltar/dreamloom/ library/cavern/laboratory/distillery/font/ forge/windmill/waterwheel/tower/grove/none|
|weaponType||<hook.weaponType:swing your sword at it/axe it a question/bonk it one/stick the pointy end in its face/fire a shot across its nose/stick a bolt in it/sneak up on it real quiet like/wave your big stick around/wave your magic wand/get up in its grill>||axe it a question||different text depending on target's main weapon type: sword/axe/mace/spear/bow/crossbow/dagger/staff/wand/other (or none).|
|personality||<hook.personality:bookish/cowardly/goofy/greedy/gentle/angry/serious/detached/dreamy/horny/smart>||cowardly||quickly create an 11 way personality split: bookish/coward/goofball/greedy/healer/hothead/leader/loner/poet/romantic/snark|
|personality2||<hook.personality2:bookish/cowardly/goofy/greedy/gentle/angry/serious/detached/dreamy/horny/smart>||cowardly||quickly create an 11 way personality split based on the second-highest personality stat of a hero: bookish/coward/goofball/greedy/healer/hothead/leader/loner/poet/romantic/snark|
Relational tags test some relationship between two people, and let you write different text depending on how they relate.
|selector||example||might render as||explanation|
|rfln.OTHER_ROLE||<hook.rfln.hook2:It's been a while since we sang anything together./I always did love that song./Song always broke my heart a little, when we sang it together./--->||Song always broke my heart a little, when we sang it together.||rival/friend/lover/none. If hook and hook2 in this example are rivals, friends, or lovers, they say different things about the song. There's no line for if they don't have a relationship, because in this context (a relationship quest) we know they have one.|
|krfln.OTHER_ROLE||<hook.krfln.hook2:Remember when used to sing around the kitchen?/It's been a while since we sang anything together./I always did love that song./Song always broke my heart a little, when we sang it together./Oh you like to sing?>||Song always broke my heart a little, when we sang it together.||kin/rival/friend/lover/none. If hook and hook2 in this example are family (kin), rivals, friends, or lovers, they say different things about the song.|
|shipWith.OTHER_ROLE||<volunteer.shipWith.volunteer2:Yeah!/No...>||No...||If the first role has a relationship with the second role, returns the first option. Otherwise, the second option.|
|rivalOf.OTHER_ROLE||<hook.rivalOf.bookish:You're the worst./Hm.>||You're the worst.||If the first role is the rival of the second role, returns the first option. Otherwise, the second option.|
|friendOf.OTHER_ROLE||<volunteer.friendOf.friend:Hey friend!/Oh, hi.>||Hey friend!||If the first role is a friend of the second role, returns the first option. Otherwise, the second option.|
|loverOf.OTHER_ROLE||<volunteer.loverOf.volunteer2:lover/none>||lover||If the first role is the lover of the second role, returns the first option. Otherwise, the second option.|
|shipLevel.OTHER_ROLE||<volunteer.shipLevel.volunteer2:No../Maybe./Yes!>||No...||relationshipLevel with OTHER_ROLE. Relationships between heroes have tiers. The first option is tier 0, if they don't have any relationship. next is 1, if they do, then 2. Any number of options can be provided, up to the full 5 relationship tiers.|
|rivalLevel.OTHER_ROLE||<hook.rivalLevel.bookish:<bookish>/<bookish>/stinker/slug-lips/supernose>...!||stinker...!||rivalry level with OTHER_ROLE. If these two are not rivals, the first option. If they are rivals, depending on the tier, additional options, up to the full 5 relationship tiers.|
|friendLevel.OTHER_ROLE||<volunteer.friendLevel.friend:Well,/Well,/Being honest,/Being honest,/<friend>, you know/<friend>, you know> I'd prefer to be elsewhere.||Being honest, I'd prefer to be elsewhere.||friendship level with OTHER_ROLE. Relationships have a flavor. Right now that can be, rival, friend, or lover. If these two are not friends, the first option is returned. If they are friends, depending on the tier, additional options, up to the full 5 relationship tiers.|
|loverLevel.OTHER_ROLE||<volunteer.loverLevel.volunteer2:/crush/flame/sweetheart/lover/soulmate>||lover||lover level with OTHER_ROLE. If these two are not lovers, the first option. If they are, depending on the tier, additional options, up to the full 5 relationship tiers.|
|pcfn.OTHER_ROLE||<loner.pcfn.leader:Alright bossypants./Fine, <leader.mf:Dad/Mom>./Ok <leader.mf:bro/sis>/Alright.>||Fine, Dad.||isParentOf/isChildOf/isFamilyWith/none. If loner and leader are family, use a specific family relationship to flavor the line.|
|childOf.OTHER_ROLE||I'm their <hook.childOf.hook2:child/friend>.||I'm their child.||If the first role is a child of the second role, returns the first option. Otherwise, the second option.|
|parentOf.OTHER_ROLE||I'm their <hook.parentOf.hook2:parent/friend>.||I'm their parent.||If the first role is a parent of the second role, returns the first option. Otherwise, the second option.|
|familyWith.OTHER_ROLE||They're my <hook.familyWith.hook2:family/friend>.||They're my family.||If the first role is family with the second role (child, parent, sibling, grandchild/parent, etc...), returns the first option. Otherwise, the second option.}|
|directionTo.OTHER_ROLE||They're somewhere <leader.directionTo.target:north of us/northeast of us/east of us/southeast of us/south of us/southwest of us/west of us/northwest of us/nearby>.||They're somewhere southeast of us.||The compass direction from one hero or tile to another on the overland: N/NE/E/SE/S/SW/W/NW/Same Position(Optional)|
|XXyoungerThan.OTHER_ROLE||<volunteer.8youngerThan.volunteer2:gosh you're old!/I'm not intimidated.>||gosh you're old!||is XX years younger than OTHER_ROLE. Can use whatever number you want.|
|XXolderThan.OTHER_ROLE||<volunteer.12olderThan.volunteer2:You're too little to help./You're too dumb to help.>||You're too little to help.||is XX years older than OTHER_ROLE. Can use whatever number you want.|
|XXysoThan.OTHER_ROLE||<volunteer.7ysoThan.volunteer2:nope!/we could date./creepy.>||creepy.||younger/same/older. is younger by XX years, roughly the same age, or older by XX years, than OTHER_ROLE. Can use whatever number you want.|
Generic selector tags allow you to pick different text depending on stat values, or depending on which stat is higher, or aspect values. They're very flexible!
<roleName.STAT.##:statIsHigh/statIsLow> test a stat against a value, and give different text depending on the outcome.
|example||might render as||explanation|
|<leader.bookish.50:Let's calculate the odds./Let's think it over.>||Let's calculate the odds.||If leader is bookish, he'll say something more precise and scientificish.|
|<coward.injury.1:Argghh. Let's rest a bit./Can we hold up a sec?>||Argghh. Let's rest a bit.||If coward is injured, they will use their injury as an excuse to take a break before facing more danger.|
|<romantic.charisma.30:Let me just fix my hair.../Do I look alright?>||Do I look alright?||If romantic his a high charisma, they will use a line that's more confident, otherwise they will be more unsure.|
<roleName.STAT_1/STAT_2/STAT_3:stat1IsBest/stat2IsBest/stat3IsBest> test any number of stats against eachother, return text depending on which one is highest.
<roleName.2nd/STAT_1/STAT_2/STAT_3:stat1IsBest/stat2IsBest/stat3IsBest> test any number of stats against eachother, return text depending on which one is SECOND highest.
|example||might render as||explanation|
|<poet.loner/leader:The vanity of our years is in thinking we are more than time, more than the tree or flower, doomed to expire/Though we press on against the teeth of time, we all break eventually, consumed by history>.||Though we press on against the teeth of time, we all break eventually, consumed by history.||Poet is trying to make a point about mortality, and it comes out differently if they are more concerned about the individual, or more social and group-oriented.|
|<healer.goofball/peacemaker/poet:A spooky blue stone,A glowing crystal,A luminous crystal that calls to me>.||A spooky blue stone.||We're talking about the same object, but we describe it differently depending on our personality.|
|<target.bookish/snark/poet/50:a bookish line/a snarky line/a poetic line/a neutral line>.||a neutral line||You can add a fallback case, which will be picked if none of the stats are above 50.|
|<target.bookish.80/snark/poet/40:a very bookish line/a fairly snarky line/a fairly poetic line/a fallback line>.||a very bookish line||you can mix thresholds, bare stats, and fallbacks freely. Play around!|
|<hook3.coward/leader/peacemaker/snark:It's funny to think <legend.mf:he/she> used to scare me when I was little, and there I was.../There were times I thought I would disappear in the night. But./I suppose I understood <legend.name>, better than other people... That was <legend.mf:his,her> name. <legend>./Old cussheart wouldn't just die early and let me get on with my life, but.>||I suppose I understood Borna, better than other people... That was her name. Borna.||hook3 is describing someone she used to know, a bugbear from his childhood, and uses different words depending on his personality.|
|<hook.2nd/poet/bookish/40:I also like poetry../I also like to read.../and that's about it.>||I also like to read...||hook is making a comment based on their second highest stat from this group. Good for following up or modifying a previous stat-based line.|