I love the flexibility offered by tabletop RPGs. When we involve a computer in gaming, the limitations of the technology impose limitations on what we can do in the game world. This code was designed specifically to be as minimal and lightweight as possible so as to not restrict what people can do in the game world.\n
This application is more defined by what it does not do than by what it does do. Small is beautiful. Less is more. Just as describing something limits it, providing scaffolding and mechanism in a computer program limits what one can do to what the program can do. This is very much a philosophical decision for this application.\n
I want the freedom to let my players do whatever they want. This means leaving things simple and light. I don't run Windows. It's not an option. I'm a minimalist and I love Unix. Seriously. I live in a terminal all day every day. I have about 50 panes in tmux across all the machines I have logins on. Each one has a purpose. Text is beautiful. Go read ESR's Art of Unix Programming and replace all the jibes at Perl with 'fnord'.\n
This is a simplified model, of course, which doesn't account for environmental hazards or other more creative things. It also glosses over the ways different RPG systems \n
POE::NFA is not really what I want; my use case is very deterministic.\nFSA::Rules, well, frankly I'm not sure how I missed it. metacpan bug maybe? I very probably would have used this if I knew about it.\nFSA::Engine is a Moose role that adds FSA capabilities to a class. It's also what we'll be talking about today.\n
There's a lot left to do here, but the basic groundwork is laid and can be built upon.\n
Whats This About?Having funRPGs are funPerl is funHow can we use one to make the othermore fun?
RPGsI like tabletop RPGs and will play mostsystemsHowever, running combats takes toomuch time and effortI want to pay attention to my players,not logistics
PerlPerl is really, really good at automatingthingsRPG combats are simple and defined bydeterministic statesDont we have something to handledeterministic states?
FSAFinite State AutomatonHuh?An FSA is a set of rules defining eachstate and how to move to other states
FSAs, ContdAn FSA models a system that movesfrom one state to the next by a specific,limited set of rulesGiven an initial state and some data,you can tell which state youll end up in... and where to go from there
Yet More FSAsFSAs have multiple possible destinationstates when transitioningEach transition is tested; the first onethats true is the destination stateOrder transitions by priority
Perl + RPGs == <3So, what do we have here?A way of keeping track of whose turn itis in an RPG combat, and some othersmall things like condition expirationsNote that only the Pathfinder/d20system uses FSA::Engine; its not arequirement
What Isnt It?It doesnt track creature healthIt doesnt record what actions one takesIts not a virtual tabletopIt does not replace the GMComplete or pretty (right now)
What Is It?It tracks who goes whenIt tracks simple statuses... and if a status precludes someonefrom acting, it skips themThats itAnything more is a bug
Why Is It?Every other tool does too much(Almost) Every other tool needsWindowsEvery other tool requires a GUI
Why an FSA?Why not just use a REPL and somevariables?Lets think about how RPG combatsworkThe model fits really well
Why an FSA?What happens in an RPG combat?Different creatures take their turnsThe order matters but what that orderis doesntTheres some state that affects whodoes what when
Why an FSA?Turns are grouped into rounds, roundsare grouped into a combatLoop over the combatants turns everyround until theres no combatants fromone side leftEvery step of the way is determined bythe state of the system at the time
Why an FSA?Therefore, we need something thatmoves from one of a finite list of statesto another based upon the existingstateIt turns out FSAs are really good at that
Automata in PerlWeve got a few automata in Perl: POE::NFA FSA::Rules FSA::Engine
FSA::EngineMoose roleAdds some attributes and methodsThese attributes and methods controlthe automatonThe docs are good, I wont repeat themhere
Using FSA::EngineIts a Moose role, so you compose it intoyour class as you would any other roleThen there are some attributes andmethods you need to write which tellthe FSA how to transition statesReally easy, seriously
The App ItselfIts simple, reallyStart it, it asks for a list of combatants(PCs and NPCs)Then it runs a combat until one sidewins
Poking Under The Cover Each different game system is supported by a ruleset class This ruleset class is actually the brain of the app It determines who goes when and most everything else
Undo SupportWhen thinking about this feature, Iinvestigated various undo frameworkson CPANThey do what they say on the tin...... but they require me to write lots ofboring codeIsnt there an easier way?
Undo SupportIt turns out there isThe FSA runs various coderefs todetermine which state to advance toThese coderefs use attributes andvariables in scope for the transitionsubs
Therefore...All we need for undo support is to find away to snapshot the object attributesand lexicals and a way to roll back thatto that snapshot and then tell the statemachine to go to the next state
The MagicThe trick here is realizing that its notreally undo that we needIts just moving the FSA to anotherstateIf we can fake that, then it doesntreally matter that its fake undo
How?If this was just package variables itd beeasyBut its modern Perl and that meanslexicalsThankfully, Perl is awesomeWe have tools for that, like PadWalker
PadWalker?Every so often, take a snapshot of thelexical padPush it onto a stackWhen requested, unwind the stack, tellthe FSA to go to the next stateUndo support!
But...It *is* a bit of a hackIts simpleBut its cheatingPatches welcome
Future DirectionsOther RPG systemsSerialize state to disk for resumingsessions laterAdd support for holding/delayingactions and other things of that sort
Questions?Code is on github at http://bit.ly/LlqIcRSlides at http://slidesha.re/LSTqT4
A particular slide catching your eye?
Clipping is a handy way to collect important slides you want to go back to later.