Wayfinder - gem for the Pathfinder roleplaying game.
What it does
Wayfinder fills the gap between the raw data describing your Pathfinder character and nicely formatted templates, it manages the bookeeping of your character so you don't have to do the number crunching yourself. Every feat, item, skill, temporary buff and whatever other condition affecting your character is aggregated passed on to a customizable template so your character is both easy to maintain - by manipulating the source files - and easy to use in your epic aventures by looking at beautiful ouput that you can generate using html, markdown or whatever else you choose.
The chosen format for the source files of the chacracters is Yaml, the internal Wayfinder::Character
class is agnostic from the source files though, so it should
be really easy to add other serialization strategies to it. Yaml is easy to read and write though, making it ideal for you to store and edit your character data
on the fly.
What it doesn't do
Better programmers than me have tried and failed to build something that could take care of their bookkeeping for them, the problem is that Pathfiner - and pretty much all other roleplayin games, really - is incredibly complex. Trying to emulate the whole rulebook including classes and races is hard but everything just becomes plain impossible when trying to account for every possible feat, magical effect, weird class feature and random modifiers.
Wayfinder errs on the side of simplicity: your character doesn't have a class but it's composed of some extremely basic stuff: everything in the game is considered to be a modifier
and is treated equally simply as stuff that modifies your character final stats in one way or another.
Don't expect wayfinder to help you to level up your character or stick to the rules of Pathfinder, it aims only to be a simple way to add up all your numbers and fill a template with data, the rest my fellow adventurer, is up to you.
Usage
As expected, you can install wayfinder via rubygems typing gem install wayfinder
in your terminal.
Wayfinder assumes you'll have a set of files describing your character and a template file where to pass the aggregated data. By default the source files are expected to be in the source
directory, and the template used is source/template.md
, you can change this using the appropriate flags.
$ tree
├── README.md
└── source
├── main.yml #=> Contains basic character stuff, such as ability scores, saving throws, current hit points, etc.
├── modifiers.yml #=> Anything and everything that affects your character, gear, feats, spells and more.
├── skills.yml #=> Skill ranks and associated stat are described here.
└── template.mote #=> Template file.
Tests
You can run rests with the following command:
$ make test
Example
Take a look at the example
directory in this repo, it contains a sample template.mote
file that you might want to use as well as the source files for my character (Edward Di Blasi, Duelist extraordinaire!) and a README.md
file generated by wayfinder.
The main.yml
file
The main file is used for most basic info in your character: the base ability scores, saving throws, max and current hit points and so on, any and all information in this file is exposed by Wayfinder::Character#source_data.main
in the character object.
Ability scores and saving throws are must haves, everything else is optional, this is how your file might look like:
name: 'Edward Di Blasi'
alignment: 'Chaotic/Good'
xp: 255000
hp: 104
received_damage: 36
bab: 12
classes:
bard: 4
fighter: 3
duelist: 6
saving_throws:
fortitude: 6
reflex: 8
will: 7
ability_scores:
strength: 16
dexterity: 14
constitution: 14
intelligence: 12
wisdom: 8
charisma: 16
The modifiers.yml
file
Modifiers are things that affect your final bonus for actions (such as attacks, or skill checks), they can be active or inactive - and thus ignored when crunching numbers - so you can keep all possible effects your character usually goes through in your source files without them necessarily affecting the final outcome. It's important to note that any modifiers are considered to be active by default, this means the active
field is redundant more often than not, but I think it's nice to keep it there for clarity.
Modifiers can also have a type
, this is relevant because more often than not bonus of the same type will not stack and only the greater one is used, wayfinder takes this into account so you don't have to, but for that it's important that modifiers have their appropriate type
when relevant.
This is how your modifiers.yml
file might look like:
## Equipped gear
- name: 'Ring of Protection'
active: true
type: 'deflection'
modifiers:
ac: 2
- name: 'Cloak of Elvenkind'
active: true
type: 'competence'
modifiers:
stealth: 5
## Feats
- name: 'Weapon Focus (Rapier)'
active: true
modifiers:
to_hit: 1
- name: 'Power Attack'
active: true
modifiers:
to_hit: -3
damage: 6
## Magical Effects
- name: 'Heroism'
active: true
type: 'morale'
modifiers:
to_hit: 2
fortitude: 2
reflex: 2
will: 2
In case you want to do things programatically with your stack in your template files you'll find these methods to be useful:
Wayfinder::Character#stack_for(attribute)
For example, character.stack_for('to_hit') will return an array of modifiers that will affect your final
to_hitbonus, you can do the same with
strength, or
escape_artist, or
ac`.
Wayfinder::Character#modifier_for(attribute)
Goes one step beyond: will take the character.stack_for
the given attribute and output the final modifier for that
Both of these methos might be useful if you want your template file to create breakdown tables of everything that's at play, it's up to you. :)
The skills.yml
file
The skills file simply describes which skills you have and how many ranks have you spent on them, unlike modifiers they are entered in the form of a dictionary, this happens because their key in the dictionary is also used to look for modifiers that might affect each skill.
Skills must have a stat
associated with them, which is the ability score that affects how well you perform them and they can optionally be tagged with class: true
, signifying that this skill is a class skill for your character (which in practice gives you a +3 bonus to the final score)
Your skills file might look something like this:
stealth:
class: true
stat: 'dexterity'
ranks: 9
survival:
stat: 'wisdom'
ranks: 1
use_magic_device:
class: true
stat: 'charisma'
ranks: 13
The template file.
The template file (usually template.mote
, but can be changed) is a mote template file which has your character exposed in a variable named c
, this means you can just go nuts on your character programatically and do all kinds of interesting things with it, my template file output is usually markdown (so I can just push it and have a nice view of my character online, from GitHub) but this too can also be changed into whatever you want.
Your template file might look like this:
## {{ c.name }}
### General
| | |
|-------------|-------------------|
| XP | {{ c.xp }} |
| Alignment | {{ c.alignment }} |
#### Classes
| Class | Level |
|---------|-------|
% c.source_data.main.classes.each do |klass, level|
| {{ klass.capitalize }} | {{ level }} |
% end
### Stats
| Stat | Score | Modifier |
|--------------|:------------------:|:-------------------------------:|
| Strength | {{ c.strength }} | {{ c.strength_modifier }} |
| Dexterity | {{ c.dexterity }} | {{ c.dexterity_modifier }} |
| Constitution | {{ c.constitution }} | {{ c.constitution_modifier }} |
| Intelligence | {{ c.intelligence }} | {{ c.intelligence_modifier }} |
| Wisdom | {{ c.wisdom }} | {{ c.wisdom_modifier }} |
| Charisma | {{ c.strength }} | {{ c.strength_modifier }} |
### Saves
| Fortitude | Reflex | Will |
|:-----------------:|:--------------:|:------------:|
| {{ c.fortitude }} | {{ c.reflex }} | {{ c.will }} |
### Combat
| | |
|-------------|-----------------------------------------------|
| Hit Points | {{ c.hp }} |
| DR/CHP | {{ c.received_damage }} / {{ c.current_hp }} |
| Initiative | {{ c.initiative }} |
| Armor Class | {{ c.ac }} |
| BAB | {{ c.bab }} |
| CMD | {{ c.cmd }} |
| CMB | {{ c.cmb }} |
| To Hit Bonus | Damage | Critical |
|:-------------------------------:|:---------------------:|:---------:|
| {{ c.full_attack.join('/') }} | 1d6 + {{ c.damage }} | 15-20 x 2 |
### Skills
| Skill | Final Score |
|-------------------|:-----------:|
% c.skills.each do |name, score|
| {{ name.split('_').map(&:capitalize).join(' ') }} | {{ score }} |
% end