- Python 100%
Shoggoth
THe Shoggoth Project is intended to be a suite of support programes for the Cthulhu Eternal RPG. So far it consists of the file format specifications, the character sheet engine, and a random character generator.
You will need Typst to use the character sheet engine, and Python3 to use the random generator.
Why did you do this?
Adobe
The form-fillable character sheets supplied by Dean as part of Cthulhu Eternal have a problem: they're that special new sort of Adboe PDF, I think with embedded JavaScript, which only works in Adobe's own renderer. If you try to load them elsewhere, you get a stub page:
"If this message is not eventually replaced by the proper contents of the document, your PDF viewer may not be able to display this type of document."
Adobe has not released a version of Acrobat Reader for Linux this century. These sheets are completely unusable to me.
And the rest
When I was using Chaosium's form-fillable sheets, I could extract characters' information and from the form fields and use it elsewhere. So why not turn that round, and make the definitive character file something in a structured data format, then render the character sheet from that?
This also lets me potentially do other things too—most obviously a character generator, which I'm thinking about writing in JavaScript. But there's also the possibility of a GM cheat sheet, not to mention keeping the files in version control to track a character's progress through a campaign.
My focus here is on a playable sheet with the things you need during a game: stats, skills, trackers for HP and sanity, and since there was room a weapon list. Space down the side shows bonds and resources. But I'm not trying to include investigation notes, equipment that doesn't have special stats, or other things of that sort; for me that's best suited to a separate and more freeform page, maintained separately and perhaps printed on the back of the main sheet.
File Formats
These are given in the json_spec document. In outline, a character is defined by a JSON file, which includes a reference to their Era (Cold War, Jazz Age, Future, etc.); that indicates which era file should be loaded, to bring in things like skill and weapon lists.
Era files
Current status:
- Future, Modern, Cold War, World War II, Jazz Age, World War I, Victorian Era: all complete
Others will follow as time allows.
character_sheet.typst
This is a Typst program to convert a character JSON file to a playable sheet.
If you don't have the Myriad Pro font, which is the one I tend to
favour for sans-serif text, change the set text definition to
something else. Or leave it out.
To run from the command line on a CHARACTER.json file:
typst compile --input char=CHARACTER.json character_sheet.typst CHARACTER.pdf
Probably this will work on Typst's web editor too, but I don't use it.
This program will try to show the "Re-Animated By Cthulhu Eternal" Logo, which to be on the safe side I'm not including in this archive but you can get from here. Or you can cut out that bit of code.
cheat_sheet.typst
Give this a party list:
typst compile --input party=PARTY.json cheat_sheet.typst
It will produce a cheat sheet in a format I find useful: characters across the top, stats and skills down the side. It autoloads an era file (for the first character listed, if they differ, but they really shouldn't), and includes rows for any skill that at least one character has, or that has a non-zero default.
improvement.typst
This one will work out character improvements. Since typst has neither a random number generator nor the ability to write out a json file, this is quite fiddly. (But if you're using this at all, typst is the one language I'm fairly sure you have access to.)
Here's how I do it on Linux with bash (note that this won't give different results if you run it more than once in the same clock second):
typst query improvement.typst '<char>' --input char=CHARACTER.json --input seed=$(date +%s) --one --field value --pretty >NEWCHARACTER.json
That will do the improvements (+d4 to each skill listed in checks),
remove checks, and spit out a new character file.
generate
This Python program will randomly generate a character.
Parameters:
-
-e ERA_FILENAMESpecify the JSON era file you're using. The program will do nothing without this. -
-a ARCHETYPESpecify the archetype to use. If you do not include this parameter, the program will list the available archetypes. -
-c CHARACTER_NAMESpecify the character's name. (Optional.) -
-p PLAYER_NAMESpecify the player's name. (Optional.) -
-H HARSHNESSSpecify the level of harshness of the character's upbringing (1 for Harsh, 2 for Very Harsh). -
-s SKILLS_WEIGHTSpecify the weighting of bonus picks towards improving Skills. (See below.) -
-r RESOURCES_WEIGHTSpecify the weighting of bonus picks towards improving Resources. (See below.) -
-b BONDS_WEIGHTSpecify the weighting of bonus picks towards improving Community Bonds. (See below.)
The program will produce a JSON character file on standard output. The steps it goes through are:
-
Generate statistics. 4d6 drop low; highest go into the archetype's Recommended Stats, others are assigned randomly.
-
Penalise stats for harsh upbringing.
-
Generate initial sanity, including modifiers for harsh upbringing.
-
Apply fixed archetype skills.
-
Add variable archetype skills.
-
Apply adversity skills for harsh upbringing.
-
Generate Individual and Community bonds.
-
Add Bonus Picks. This will select randomly from skills (weighted with "-s", default 40, then picks a random skill), resources (weighted with "-r", default 5) and community bonds (weighted with "-c", default 10, then picks a random bond if any community bonds have been generated at all).
To get the character to a playable state, you will need to edit the JSON further to:
-
Check any skills for "(choose)"; replace this with a specialisation such as "(Jungle)". Unless there's a specialisation mentioned in the archetype (e.g. the Cold War Criminal's "Craft (Locksmith)"), every skill that needs specialisation will be marked in this way. You may want to split a "(choose)" into multiple specialisations, but note that a very few skills have both a non-zero base and specialisation: for example "Survival (choose)" has a base of 10, so if you split it a skill of 40 into two specialisations each of them would be at
10 + (40-10)/2 = 25. -
Specify the Individual and Community Bonds (generated as A, B, C, etc.)
-
Add age, birthplace, pronouns.
-
Add equipment.
Errors
There are some things the system doesn't cope with.
Age of Revolutions
Artist/Craftsperson, Scientist/Scholar: you may change an Art to a Craft or vice versa.
Clergy/Spiritual Leader: you must have at least one Community Bond at level 14.
I have not included the various field guns on the equipment list as they seem unlikely to be personal equipment.
Victorian
Artist / Craftsperson: you may change an Art to a Craft or vice versa.
Landed Gentry: you are required to take at least one pick on Resources. If your Resources aren't at least 7, re-generate.
Clergy/Spiritual Leader and Landed Gentry: you must have at least one Community Bond at level 14.
Doctor/Nurse, Landed Gentry and Military Officer: your standard Empire Lore is British, but you may change this.
Scientist: you may end up with "Science (A Different One)". Pick a Science, as with "(choose)".
Thief/Smuggler: you may change your Craft (Locksmith) to a different specialisation.