MER-c |
4 people marked this as a favorite. |
Greetings everyone.
Let's see if we can model a complete Player Character in an Object Oriented format for PF2 and Compare it to PF1.
Here's my attempt at modeling PF1 human fighter.
PF1 Assumptions
Player is a Class that contains two objects. Object PlayerClass (Fighter in this case) and Object PlayerRace(Human in this case)
Player also holds Player Attributes (Stats)
Thus the basic structure looks like this
Class Player {
Int Level
Array PlayerStats
Object PlayerClass = Fighter
Object PlayerRace = Human
Array PlayerTraits
Array PlayerFeats
Array Inventory
Int HitDie = PlayerClass.HitDie
Call hpCalc(HitDie, Level)
Array PlayerSkills [[,],[,]]
Int SKillPoints
Call skillPointCalc(Class.SkillPoints, Race.Features, Player.Playerstats[4])
}
Class Fighter{
Object ClassHitDie = 'd10'
Array ClassSkills
Array WeaponProfs
Array ArmorProfs
Int SKillPoints
Array BonusFeats
Object Bravery
Object WeaponTraining
Object ArmorTraining
ObjectCapstone
}
Class Human {
Array LanguageOptions
String Type
String Subtype
Object BonusSkill
Object BonusFeat
}
Basically I assume PF1 bases everything off the player as the central object, rather than a class based Players must have both Race and Class, and Store their own stats.
Anyway, how would we model a PF2 Player Character in relation to this? Given what we know now, can we say for sure what interacts differently or has different attributes?
This is more of a food for thought exercise than anything serious
PF2 Assumptions,
Everything is an Object with the Level attribute
Feats, players, classes, inherit form object.
Ancestries are also objects and have Feats that inherit from the base Feat Class.
Proficiency is not an object but a concept within the system. Skills are thus an attribute.
Objects can change attributes.
Mathmuse |
1 person marked this as a favorite. |
A good pseudocode describing the characters and their actions would provide clear answers to rules questions, so I applaud the effort.
However, "Player" seems a poor name for the class that defines a character. Do we need to differentiate between player characters and non-player characters at such a basic level? Furthermore, in this pseudocode, Class means a class of objects, but in Pathfinder, Class means the class of a character. Perhaps the pseudocode should use a different name for class of objects, such as Category.
We will also want some pseudocode for actions, such as casting a spell or making an attack. Or will that be another project?
MER-c |
I think for PF2 you'd break it down as follows
Objects have levels, Characters, Feats, Items and Monsters inherit from object and thus have levels. Characters also have Classes, however classes can be looked at as an implementation of character, though for Clarity we would make Class and Object with the name Catogry which has a generic Features, skills and constructor for Class Feats.
Going on to Feats, Ancestry, Skill, General, Archetype, and Class feats all inherit the basic Feat class and extend it.
In implementation you'd actually have Character as the main object, a Character has Classes, Ancestry, Backgrounds and General Feats, A Character also can have Items and take Actions.
Generically that would look something like
class Character > Object [
Int Level
Array Attributes []
Array Ancestry
Array Background
Object AdventurereClass = Fighter(Level)
Array Skills
Array GeneralFeats[]
Call ActionTypes(ClassObject.ClassActions,GenericActions)
Array Actions[ActionTypes]
Array Inventory
Call Calc AC_TAC
Int HD
Int HP
Int MoveSpeed
]
It's a bit much but the idea is that Character can represent any given character in the game.
I figure all the core classes are their own objects which inherit a base template. That Template could look like this
class Category > Object{
Int Level
Int Hit Dice
Int SkillProfs
Array SignatureSkills
Array WeaponProficiency
Array ArmorProficiency
Array ClassFeats
}
This basic class covers the most basic structure of a class, however special featues like Combos, Spells, Domains, etc should be defined in the specific class.
Fighter for example would probably look like this
class Fighter > Catagory{
Int Level
Int Hit Dice
Int SkillProfs
Array SignatureSkills
Array WeaponProficiency
Array ArmorProficiency
Array ClassFeats
Array FighterStances
Array FighterCombos
}
What do you all think? Could we make this simpler, more clear? I have a much better idea on how Clases work in PF2, how that relates to players is I think where I start to fall a bit.
sadie |
The unfortunate conflation of "class" (in a roleplaying sense) and "class" (in a programming sense) can't really be avoided. Anybody who writes code related to RPGs has hit it, and just ends up calling it something like 'CharacterClass' instead.
Real code would make a distinction between the Fighter class itself, which defines eg how many hit points per level a Fighter gets, and the fact that a given character has X levels in Fighter.
MER-c |
The unfortunate conflation of "class" (in a roleplaying sense) and "class" (in a programming sense) can't really be avoided. Anybody who writes code related to RPGs has hit it, and just ends up calling it something like 'CharacterClass' instead.
Real code would make a distinction between the Fighter class itself, which defines eg how many hit points per level a Fighter gets, and the fact that a given character has X levels in Fighter.
It would, however that does not mean that CharacterClass would not be defined as a parent for the actual classes. It's easier and saves space.
As a note on HP, since Pathfinder does not use rolled HP all you need to do is list an HP per Level in the Class as it will override the HP defined in the parent class.
Also modeling monster is actually easy as well. You just have to extend Character with a Monster object.
NielsenE |
I have to ask first what's the goal:
1) How to model a PC in a character creator?
2) How to model a PC in a at-the-table digital aid?
3) How to model a PC for a experiment/trial simulation runner?
4) How to model a PC for say a full computer game?
The way I would build out my abstractions would vary greatly for each of those.
MER-c |
That would work for PF1, however I think PF2 is different enough to warrant a different structure, reading in class data is a real possibility as it saves on upfront processing, however if the data does not match the internal structure then you have to spend resources to process it and make it fit within the class structure. Really though this isn't about the practical aspects of it, this project is done with the goal of clarifying how things work together in the new edition in a format that is easy to understand.
A nice side benefit is if we can come to a similar result bar plugging in the math then we can use it as a model to better understand the new edition and maybe clear up some long running confusion on it.
mrianmerry |
I'm gonna ask a whole bunch of questions aimed at trying to understand your PF2 pseudocode. I hope you don't take offence, as I really am just trying to understand your reasoning!
I'm also interested in what language you usually use, as there is definitely a particular influence in what you've written....
Character:
- I wonder why you have both HD and Level properties?
From what I've read, we're completely scrapping HD in favour of using Level.
- Is there a reason you list AC as the result of some method that also calculates TAC?
I think it would be better to have a simple int representing these values, where the getter for the property computes the values instead of storing them.
- I think you can probably represent the AdventurerClass object better
Some kind of list of Key-Value pairs (such as a dictionary, map, or hashmap, as your chosen language prefers) would likely be better, to accommodate multi-classed characters
- I don't see a reason to have separate arrays - at the Character level - for General Feats.
Feats should be a single array, where the type is some kind of abstract superclass or interface, which the specific feat types can inherit?
Category:
- I presume the repetition of the properties of the superclass are repeated for verbosity's sake, but would not actually be redefined?
- I like word-choice here, instead of Class, but I think it might be a keyword for some languages!
- Hit Dice for this level is presumably in regards to HP per level?
- What do you expect the Class Feats array to hold?
- No Class Features Array?
Fighter:
- FighterStances and FighterCombos could likely be considered part of my proposed Class Features in the superclass.
MER-c |
Long and detailed comment...
Hello, so first I should mention that I am by no means a developer, it's a thought experiment at the least. The language I understand the best is Ruby followed by Powershell.
That said for simplicity let's assume one of the typeless languages, either Ruby or Python, they can define their types if needed, but in this case language should not mean anything outside of specifics in how things are handled, hence why I don't actually call anything.
I list Hit Dice mostly because I'm still unsure if it has been removed, it's more for legacy than actual use, though HP could be a valid replacement.
AC and TAC should be calculated based on the same math, unless there is another wholly separate formula for it. As I am unsure I toss them together. It's lazy but frankly I don't know enough yet.
I call the Class Character because it's intended to be a parent class for every character, NPC and monster.
I do see your point in keeping Feats down to a single array, however I do think that it should be a multi denominational array, as keeping track of every feat that isn't a class feat on a single array would be a hard task at best.
As for Category, I think this is where I'd call it AdventureClass. Since this is intended mostly for PC's
Class feats are listed here because a base character does not have class feats, a class has them, a base character does get pretty much every other type of feat.
I just noticed I missed ClassFeatures, maybe it can be replaced with a dictionary object since class features are fixed, Though I would have to make them mutable somehow.
I agree on the fighter.
sadie |
There are two approaches to this. The first is, as MER-c describes, to write pseudocode describing the fields and types you'd use to represent a character.
I've been working on this, and have a bit of pseudocode here: pf2-character-pseudocode.txt. It's not written in any specific language, though it borrows liberally from Scala, Java, Go, Ruby and modern JavaScript.
- I used `type` rather than `class` to avoid confusion.
- `var` indicates a variable that's stored locally. Types are listed after variable names.
- `def` is a function that's calculated. For example, dexterity modifier is calculated from dexterity score.
Regarding Pathfinder 2e itself, there's a lot we still don't know, or that I haven't fully grasped. For example, how to calculate saving throw proficiencies when multiclassing. A lot of things should become clearer when the full playtest comes out.
---
The second approach is to consider it from a data standpoint instead, and write example data in eg JSON describing an actual character. Unlike pseudocode, this approach needs to be shaped by the real technologies used and have valid syntax. I have a practical need for this for my own character sheets project, so it's something I've been working on for longer.
Have a look at this as a rough starting point: pf2-character.json. This is a JSON document, and there is a JSON Schema defining the format.
- It's wrapped in a JSON-API structure, which provides a convenient way of handling multiple payload objects in a single document. In this case, there are two attachments: a character portrait image and a play object.
- Every character must have `type: "character"`, an `id`, and the `game`. In the case of Pathfinder 2e, it would be `game: "pathfinder2"`.
- Data is divided between universal fields, such as `language`; game-specific fields, such as ancestry; and dynamic values such as hit points.
- To avoid conflict, game-specific parameters are all wrapped in an object named for that game. So in the case of a Pathfinder 2e character, there would be a `pathfinder2: {}` object parameter.
- Dynamic values - any that change as you level up - are separated into an object of type `"play"`.
There's a lot of work still to do here, as much of it's still empty, but it's a framework for filling in.
mrianmerry |
Why do you have dictionaries for the ancestry, background, and classes entries? Are you intending to have more data in those places? (Such as rules text, etc)
I looked through your pseudocode, and it's a lot more developed than you indicated! it looks pretty solid, too. I'll have a closer look another time when I get the chance.
---------
Also: nice work with the character sheets! I had a look at the Pathfinder one, and never have I seen a more pleasantly laid out sheet than the one generated by (I presume here that you're one of the main people behind the site) whatever API you've set up.
(And that's especially true for Monks!)