This is a preview release for people who want to see what my framework does and how it does it. I've had a lot of people asking me about this since I wrote a general overview on my blog ( https://medium.com/so-forth/maptool-a-v ... 7d41219688 ) a few weeks ago. Since then I've been working on trying to make it a little more robust and shareable. It's still not what I'd call a good beginner framework, since it's not thoroughly tested enough and is far from complete in terms of its 5e offerings.
I call this a preview, but there's plenty of handy functionality that should work right "out of the box" and should give adventurous GMs and macro scripters plenty of room to customize and expand upon.
I've only play-tested in my own games so far, and while that's many tens of hours, I've been adding to it and building as I go, so there are certainly going to be bugs.
I'd be grateful, if you find a bug, if you could post it here. That's the best chance I have of getting it fixed for a later release.
Hopefully anyone interested enough can take the parts of this framework they like and use them elsewhere or build out from this foundation and customize their own versions.
I plan to update this, though infrequently. I cannot promise to support this on any regular timeline as yet. Hopefully this documentation is enough to you get started.
Note: This is not a complete framework for 5e, meaning the majority of spells and special abilities are not completed and you either need to create them yourself from templates or manually adjudicate these things in play. I've tried to give a good list of what things you can expect the framework to handle for you and what it won't.
PURPOSE
Spoiler
I haven't used a lot of other MT frameworks for more than must playing around to see how they did different things. I quickly found that I wanted to change things, so many things, just because of my own personal tastes, and found it easier to start building the whole framework out from scratch instead.
I generally only create the monsters, spells, attacks, and macros that I plan on using in my campaign. This is only a hobby after all. The example PCs and monsters included in the campaign file are slightly modified versions from my own game. I did however create most of the major functions to be highly customizable so that most spells and attacks and special abilities could be created or approximated with just a little customization of the function arguments.
I'm sure there are many inefficient or poorly structured blocks of code throughout the code base, though I've tried to be pretty reasonable and have refactored many of the major functions several times over. If you see something specific that could be improved, I'm happy to hear your thoughts and will consider making the change.
I realize my window layout for MapTool may be nonstandard or different from the implied layout of other popular frameworks. I'm including a screenshot of how I have my windows setup to show you what the framework "interface" was designed for. If you use a much wider, shorter Chat window, some of the output is bound to look much uglier than it was intended.
Also, there's two important houserules hard-coded into this framework that you should know about:
Vitality Points Houserule
The purpose of this change is to limit the miraculous effects of non-natural healing, and short-circuit any potential exploitation of cheap but plentiful sources of healing.
Your body can only be pushed so far in a day. Your maximum vitality points is equal to your constitution score. Each time you are healed by non-natural healing (a potion or spell), you lose a vitality point. While you have zero vitality points, you cannot receive non-natural healing. Healing, in the sense of VP, means recovering HP, not the removal of poison or disease or other harmful conditions. After each long rest you recover VP back to your maximum.
If you have zero VP and you are knocked to zero HP, any source of healing will stabilize you, but you will not recover HP until 1d4 hours later when you recover 1 HP. After that, you can recover VP after a long rest as usual.
You can work around this houserule by never using VP whenever you have a healing effect, either by adjusting the options spl of the heal() function or making sure to uncheck "use VP" whenever using the healing dialog macro. It should rarely impact your game either way, however, unless your high level PCs are hoarding (relatively) cheap low-level healing scrolls, potions, wands, etc.
Bloodied Houserule
There's also a bloodied houserule. When a character is reduced to half or fewer of its max HP, a big red slash appears across its token. This doesn't do anything mechanically, it just lets everyone know how wounded you are. You could remove this feature by swapping in a blank image for the appropriate wound level state.
Spoiler
The GM has a special GM Notes button which shows him and only him a nicely formatted version of the GM Notes for the selected token along with showing what the token currently has equipped in its hands. Sometimes this will be silly, you may have a horse that has "hoof" equipped to both "hands". All tokens have a defaultAtk, eqMain, and eqOff property even if the creature doesn't actually have any hands. These properties are mostly managed behind the scenes with defaultAtk = eqMain by default (whatever weapon is equipped in the main hand will be the default weapon used by the attack() function).
In general, players interact with the macro buttons in the Selection window for their characters. They should never need to use global or campaign macro buttons. The GM generally uses the campaign macro buttons to perform common tasks with NPC tokens such as rolling ability checks, but each token has its own set of defined attacks and spells which the GM uses the Selection window to interact with.
Many of the campaign macro buttons can be used on a selection of multiple tokens: Rest, Damage, Heal, Roll Init, and the Condition toggle buttons.
Suggested Player Screen Layout
Suggested GM Screen Layout
The default setup assumes a 100 pixel wide square grid. This is good for the size of tokens and states I use, but you can modify this. I set my maps up for 1 square = 1 unit, and try to use squares instead of feet as much as possible within the framework and in output. So, when specifying the range for a bow or a spell, for example, use the number of squares, not the number of feet.
I typically start a fresh campaign file by loading the template campaign file.cmpgn into MapTool and then adding new maps to that campaign and saving the campaign under a new name.
Spoiler
If a function has options, they will be documented at the top of the function definition within its macro on the Lib:main token.
The attack(), spellAttack(), attackWithSave(), and spellWithSave() functions can cover most attacks and spells with some careful tweaking of the [spl options]. Look at some of the attacks and spells as defined on the example character and monster tokens for some examples.
Here's the top 24 lines of the attack() function, for example
Code: Select all
// args: attackingTokenName, specialPropertiesList
[numArgs = argCount()]
[contextToken = arg(0)]
[switchToken(contextToken)]
// a string property list
//
// validTargets = Any // 'Any', 'NPCs', or 'PCs'
// strike = default // 'default', 'wpn0' through 'wpn9'
// vantage = 0
// damageOnly=0
// noDamage=0
// miscDamageMod=0
// miscAttackMod=0
// isOppAttack=0
// rollOverride=0
// conditionOnHit=0
// conditionOnMiss=0
// onHitEffectStr=0
// onMissEffectStr=0
// showMessage=1
// gmOnly=0
//
Code: Select all
<!--
[attack( getName(), 'validTargets=NPCs' )]
-->
[abort(0)]
Code: Select all
<!--
[attack( getName(), 'validTargets=NPCs;strike=wpn3;noDamage=1' )]
-->
[abort(0)]
Code: Select all
<!--
[attack( getName(), 'validTargets=NPCs;damageOnly=1' )]
-->
[abort(0)]
Note: In general, I rarely depend on MapTool to interpret truthiness and prefer to always use 1 for "true" and 0 for "false" and make all logic comparisons refer to the actual values 1 or 0.
Damage Types
Many functions and dialog modals in the framework refer to damage dice expressions. In many cases, these are described with examples within the dialog, but for easy reference, here are the recognized damage types and their two-character abbreviations for use in damage expressions when needed:
Code: Select all
un = untyped
ac = acid,
bl = bludgeoning,
co = cold,
fi = fire,
fo = force,
li = lightning,
ne = necrotic,
pi = piercing,
po = poison,
ps = psychic,
ra = radiant,
sl = slashing,
th = thunder
Code: Select all
1d6sl
Code: Select all
1d6sl,1d6fi
These two-character damage type abbreviations are used in the Edit Stats dialog also to define damage immunities, vulnerabilities, resistances, etc.
Combat
Spoiler
Note: I use the term "vantage" instead of "advantage / disadvantage" for brevity.
Modifiers and vantage from conditions on you and your target are applied automatically, if possible (see Conditions, below).
If you use a ranged attack against an adjacent target or your target is in long range, your attack roll suffers disadvantage automatically.
If your target has vulnerability, resistance, immunity (or DR, or ablative protection) to any of the damage dealt, it's automatically modified before being applied.
If you have the sneak attack ability, you'll be given the option to toggle whether your attack qualifies for sneak attack damage or not (but only if you are attacking with a finesse weapon or a ranged attack).
If you have vantage, two d20s are rolled and the proper result is used. Dark gray d20s are shown for disadvantage.
If there is ever any amount of disadvantage AND advantage, both are canceled out automatically.
The option to choose advantage or disadvantage before you make an attack is only for the rare cases when the system cannot automatically determine vantage for you, in any case, it will simply treat this another source of vantage, not an overrule.
You can type in a d20 roll overrule for an attack roll and it will show up that you did so (so no one can cheat).
Basic equippability and customization of weapons, armor, shields, and ammo. If your armor causes a stealth penalty, it will be inlcuded automatically when you attempt a Dexterity (Stealth) ability check. If you equip a shield, your AC is adjusted automatically. If you weild a sword, your default attack action will use that sword and check your reach when determining potential targets, etc.
Automatic tracking of equipped ammo. If you equip a weapon that requires ammo, whatever ammo you have equipped will be depleted automatically and used when you attack. If your ammo does extra damage, for example, it will also automatically be applied on a successful hit in addition to the damage from your weapon.
Weapons and ammo (and spells and other attacks) can have multiple different dice and types of damage. You generally specify damage in string lists with a two character suffix (for example: "1d6pi,1d4fi" for 1d6 piercing plus 1d4 fire damage).
On hit or miss and On save failed or successful conditions can be set automatically, along with descriptive text.
Automated dying and death-save rolls. Most NPCs die instantly at 0 HP, but you can set any character to "Makes death saves" instead.
Spoiler
If the showMessage=1 argument is passed to setCondition() a description of the condition will be broadcast when the condition is enabled, in this description each item is bulleted with a plus or minus sign, a plus sign indicates the framework automatically handles this part of the condition (for example: "+ You suffer disadvantage on attack rolls."). A minus sign indicates something the framework either cannot ever adjuticate or does not yet handle and you'll have to remember to handle that rule manually (for example: "- You cannot willingly move closer to the source of your fear.")
Most attacks and spells can enable or disable a condition on a hit or a miss or a failed or successful saving throw. For example, adding "conditionOnHit=prone" to an attack's options spl will cause the target to automatically be set to prone upon a successful hit.
Code: Select all
<!--
[attack( getName(), 'validTargets=NPCs;conditionOnHit=prone' )]
-->
[abort(0)]
Code: Select all
<!--
[attack( getName(), 'validTargets=NPCs;conditionOnHit=prone;onHitEffectStr=Target is knocked <i>prone</i>.' )]
-->
[abort(0)]
Spoiler
Edit Stats is the core and first button for defining basics about a character like his ability scores, alignment, hit dice, class levels, and any damage immunities, resistances, etc.
Edit Special Abilities allows you to setup various class and racial features like a fighter's superiority dice or a monk's ki points. The features here are limited right now and far from exhaustive.
Edit Skills and Edit Tools allows you to grand proficiency or expertise to skills or tools and add static modifiers to these ability check rolls.
Edit Spell class allows you to setup one or more spell classes for the character and determine spell slots, spells known, casting attribute. Prep Spells allows you to set which spells the character currently has prepared. Names of spells should be lower case and use no dashes or underscores or apostraphes (ex: "mordenkainens magnificent mansion").
Edit Weapon allows you define up to 10 different weapons (or natural attacks). This macro basically edits the token properties wpn0 through wpn9. Edit Ammo works similarly, allowing you to setup multiple different pools of different types of ammo for a character. If the character uses an attack that "Requires Ammo", then whatever ammo he currently has equipped will be used also, as long as he has any remaining.
PC tokens have Equip, Equip Armor, and Equip Ammo buttons so they can swap out their weapons and shields and ammo as needed. You'll see a message when this happens, so they can't cheat. The GM generally uses the campaign macro Equip buttons to manage equpment on NPCs instead of copying these buttons to each NPC token individually (though that works too, if you prefer).
Edit Armor allows you to customize armor, but it also comes prepoluated with all of the standard 5e armor options to make it easier for charactes to swap out different types of armor on the fly as needed.
Spoiler
Treasure
5e DMG Individual Treasure and Treasure Hoard generation. In the campaign macros there's a Treasure Hoard and Treasure Individual button that give you options for generating 100% 5e DMG based treasure. Bigger hoards will spit out a lot of information, so be prepared for that. The output is a labor of love, each line shows a small image of a coin or gem or art object or an image appropriate to the magic item type. It's really pretty and fun and took many many hours to create.
If a gem result has an 'or' descriptive property as its described in the DMG, that's also randomly determined.
Weapons and armor are randomly chosen for the appropriate magic items, with only appropriate results returned for certain items (a vorpal sword must be slashing, so you can't get a vorpal rapier).
Scroll spells are randomly selected from all spells of the given scroll level, including the new spells in the Elemental Evil player's guide.
There are also buttons for instantly rolling up various gems, art objects, magic items from the charts A through I in the DMG, and the DMG charts for magic item history, creator, minor properties, and quirks. Currently these buttons all simply push output to everyone in the game, so if you're trying to generate a secret magic item, don't use them while your players are connected.
Light State Toggles
There are special buttons to toggle lights on and off of tokens, while the light is on a special state image will appear to make it obvious just in case you're not on a map with vision and darkness enabled. For example, clicking the Candle button will toggle a candle icon on each selected token and toggle on the candle light source automatically.
Dynamic Objects
Several dynamic object tokens are included for light sources with lit/unlit states and doors with opened/closed states. These should be dragged onto your map on the Object or Background or Hidden layers and sized and positioned appropriately, then you can set them to the Token layer if you like. Characters making attacks will not be able to target these special tokens either way. When you select one of these dynamic tokens, it will have a button allowing you to toggle its state. The light source tokens like the torch, lantern, and campfire have active light sources on them that are toggled on and off by their buttons which also swaps in a lit or unlit version of the graphic as appropriate.
Special Abilities
The special abilities in the Edit Special Abilities dialog are implemented throughout the system already.
For example, if a token has "Halfling Luck" checked, anytime it rolls a 1 for an ability check, saving throw, or attack roll, it'll automatically be re-rolled and a note will appear in the results to show a 1 was originally rolled.
Similarly, if a token has "Relentless Endurance" checked it'll automatically be knocked to 1 HP instead of killed or dying the first time after a long rest when it would be reduced to 0 HP.
Spoiler
There is no encumbrance checking or calculation at all currently. This is a feature I may add later.
If an effect calls for a creature to be pushed, pulled, or otherwise moved X feet, that needs to be done manually.
If you use the DMG Flanking rules for grid-play, like we do, this framework will not automatically determine flanking and apply vantage. The way we play, if the player knows he should get advantage from flanking, he checks the Advantage option in the attack dialog.
If you have a feature that lets you add some modifier before or after a roll, but "before the results of the roll has been determined", you're gonna have trouble with that last part in this framework. Most rolls are setup with a dialog and then executed fully. That's part of the downside of having the attacks automatically determine hit or miss and apply damage, etc. You can kind of fake it a little by say, attacking, then rolling the attack again but using the d20 override to attack with an adjusted d20 result, but then, of course, you've already seen the result of the first roll and that's not by the book. It's not been a major problem for us in play so far, but it's a potential area where we may make houserules to amp up those sorts of abilities a little in order to compensate for their lesser utility within this framework.