Quick "Character Builder" Python script

17 posts / 0 new
Last post
golan2072
Patreon SupporterBarbarian Conquerors of Kanahu AuthorPlayer's Companion BackerDwimmermount BackerSinister Stone of Sakkara BackerLairs And Encounters BackerBarbarian Conquerors of Kanahu BackerACKS Heroic Fantasy Handbook Backer
Joined: 2012-01-14 14:14
Quick "Character Builder" Python script

I've made my own offline Python3 version of the "ACKS Character Builder" from the main Autarch site. Instead of sending you the character stats by e-mail, it lets you save them into a TXT file.

You need Python3 installed to run this (included in some operating systems and free for download otherwise)

Get it here:

https://app.box.com/s/p6cv9gxysda1hq8imexi2zy57n5aak0a

nike air thea cobalt blue cross shield federal , Nike Air Force 1 Shadow Pale Ivory/Celestial Gold-Tropical Twist
AlexM
Joined: 2017-01-21 00:28

Cool!  I've also written one recently that's here: https://github.com/AlexMooney/ACKS.  Feel free to make a pull request or just mention here if you think of something to improve it.  Currently, I'd just run chargen.py > file.txt to save a file to the disk.

golan2072
Patreon SupporterBarbarian Conquerors of Kanahu AuthorPlayer's Companion BackerDwimmermount BackerSinister Stone of Sakkara BackerLairs And Encounters BackerBarbarian Conquerors of Kanahu BackerACKS Heroic Fantasy Handbook Backer
Joined: 2012-01-14 14:14

I'll have to get a closer look at the Click library you used.

I am working on adding classes to the generator, based on which attribute is the highest.

This is the Method I started writing for the character class (so to speak :-)) -

def charclass(self): #choses character class based on attributes
        profession="Fighter"
        if self.strength==max(self.attribute_list):
            profession="Fighter"
        if self.dexterity==max(self.attribute_list):
            profession="Thief"
        if self.intelligence==max(self.attribute_list):
            profession="Mage"
        if self.wisdom==max(self.attribute_list):
            profession="Cleric"
        return profession #returns chosen class        

golan2072
Patreon SupporterBarbarian Conquerors of Kanahu AuthorPlayer's Companion BackerDwimmermount BackerSinister Stone of Sakkara BackerLairs And Encounters BackerBarbarian Conquerors of Kanahu BackerACKS Heroic Fantasy Handbook Backer
Joined: 2012-01-14 14:14

My next two projects are a better treasure generator and an NPC hireling/torchbearer generator in the vein of "Meatshields". The altter is far more complex.

The existing Autarch page treasure generator sometimes yields disorganized results, and I want to get a text I can simply copy into an adventure or setting as-is as a treasure without having to re-organize it into a readable paragraph.

jedavis
Patreon SupporterPlayer's Companion BackerDomains At War BackerSinister Stone of Sakkara Backer
Joined: 2012-03-08 01:21

I had some stuff for henchman generation a la meatshields at https://github.com/jedavis-rpg/ackstools ; it used to be up on my website, but seems to have stopped working (not sure why yet).

AlexM
Joined: 2017-01-21 00:28

You may want to introduce the possiblity that someone picks a non-optimal class.

def charclass(self):
    #choses character class based on attributes
    professions = []
    if self.strength >= 9:
        professions += ['Fighter']*(self.strength-8)
    if self.dexterity >= 9:
        professions += ['Thief']*(self.dexterity-8)
    if min(self.dexterity, self.strength) >= 9:
        professions += ['Assassin']*(min(self.dexterity, self.strength)-8)
    # etc. with all classes
    if professions == []:
        professions = ['Normal man']
    return random.choice(professions)

You could make this better by, say, only considering the prime requisite bonues rather than the absolute score.  

golan2072
Patreon SupporterBarbarian Conquerors of Kanahu AuthorPlayer's Companion BackerDwimmermount BackerSinister Stone of Sakkara BackerLairs And Encounters BackerBarbarian Conquerors of Kanahu BackerACKS Heroic Fantasy Handbook Backer
Joined: 2012-01-14 14:14

Thanks for the share! So much for me to dissect and learn from :-)

My previous learning project was a Traveller world and subsector/sector generator:

https://github.com/makhidkarun/worldgen

I might try my hand in Traveller character generation as well. Traveller is PERFECT for beginner programmers to experiment on as everything is procedurally generated. ACKS is quite similar, again much procedural generation.

golan2072
Patreon SupporterBarbarian Conquerors of Kanahu AuthorPlayer's Companion BackerDwimmermount BackerSinister Stone of Sakkara BackerLairs And Encounters BackerBarbarian Conquerors of Kanahu BackerACKS Heroic Fantasy Handbook Backer
Joined: 2012-01-14 14:14

AlexM - wonderful! Thanks.

golan2072
Patreon SupporterBarbarian Conquerors of Kanahu AuthorPlayer's Companion BackerDwimmermount BackerSinister Stone of Sakkara BackerLairs And Encounters BackerBarbarian Conquerors of Kanahu BackerACKS Heroic Fantasy Handbook Backer
Joined: 2012-01-14 14:14

 

I was thinking of writing a treasure generator script in Python which will be better suited for my needs than the one provided by the Autarch site.
 
The one thing which has been keeping me awake last night (literally!) was how to streamline "weighted" choice. That is, I know how to randomly chose an item from a list, but then all items have equal "weight" (i.e. equal chance to get chosen. On the other hand, sometimes I want an item to have a higher chance than others to get chosen in the random choice function. Right now I am using too many if/elif statements and it isn't pretty. I am looking for a more elegant way to do this. This is very important for a treasure generator.
 
For example, here is a function of mine from my henchman generator (the "dice" function called here generates random numbers emulating dice):
 
def armor_gen():
"""
generates character armor
"""
roll=dice(2, 6)
if roll <= 6:
armor="Clothes"
elif roll == 7:
armor="Hide/Fur"
elif roll == 8:
armor="Leather"
elif roll in [9, 10]:
armor="Scalemail"
elif roll in [11, 12]:
armor="Chainmail"
else:
armor="Clothes only (AC 0)"
return armor
 
How can I streamline and simplify such weighted random choice?
golan2072
Patreon SupporterBarbarian Conquerors of Kanahu AuthorPlayer&#039;s Companion BackerDwimmermount BackerSinister Stone of Sakkara BackerLairs And Encounters BackerBarbarian Conquerors of Kanahu BackerACKS Heroic Fantasy Handbook Backer
Joined: 2012-01-14 14:14

(note that the Autarch forums do not show indentation correctly)

Aryxymaraki
Aryxymaraki's picture
Patreon SupporterDomains At War BackerSinister Stone of Sakkara BackerLairs And Encounters BackerBarbarian Conquerors of Kanahu ContributorACKS Heroic Fantasy Handbook Contributor
Joined: 2014-01-04 02:20

I don't know Python specifically but would it be easier/better to just put items in the list more than once?

That is, if you want there to be a 40% chance of leather, 40% mail, 20% plate, your list would be Leather, Leather, Mail, Mail, Plate. A random unweighted selection from this list would then give you the chances you wanted.

golan2072
Patreon SupporterBarbarian Conquerors of Kanahu AuthorPlayer&#039;s Companion BackerDwimmermount BackerSinister Stone of Sakkara BackerLairs And Encounters BackerBarbarian Conquerors of Kanahu BackerACKS Heroic Fantasy Handbook Backer
Joined: 2012-01-14 14:14

This is what I do in simple cases, but some treasure tables have widely varying probability ranges and thus will end up with LONG lists.

Weron
Patreon SupporterSinister Stone of Sakkara BackerLairs And Encounters BackerBarbarian Conquerors of Kanahu BackerACKS Heroic Fantasy Handbook Backer
Joined: 2013-10-07 06:44
You could write some code to create this long list for you based on the table with probabilities.
jedavis
Patreon SupporterPlayer&#039;s Companion BackerDomains At War BackerSinister Stone of Sakkara Backer
Joined: 2012-03-08 01:21

I ended up rolling an accidentally-context-free grammar for such tables, a loader that parsed/read them from config into memory, and a thing to randomly walk down them.

In my format, your armor-type conditionals (in a config file) would look like

ArmorType
2d6
6: Clothes
7: Hide/Fur
8: Leather
10: Scalemail
12: Chainmail

(see https://github.com/jedavis-rpg/ackstools/blob/master/treasuretables#L202 for more)

And then, much like https://github.com/jedavis-rpg/ackstools/blob/master/treasuregen.py ,

import tables
tables.loadtables("path/to/file/with/table")
print tables.evaltable("ArmorType")

It's not great (if I were to do it again, I would not be using global state in the tables module, might consider adding ability to call out to code from the grammar for eg intelligent weapons, and would add some #include or equivalent ability to split config files up more) but it is aimed at the problem you are trying to solve and might serve as a starting point. If this approach is of interest, I can roll some better documentation for the grammar I ended up with (I may have prioritized brevity over intuitive readability in some cases). It is also true that there is some irreducible complexity in modeling the treasure tables faithfully, and you're going to end up with a lot of text no matter how you slice it.

Arman
Joined: 2016-04-12 14:19

I put together a full party generator in Google Sheets, for NPC encounters and hiring situations; I realize that my generator has some extra classes, and understanding it requires an advanced degree in insanity... but, just in case it helps anyone, have a look:

https://docs.google.com/spreadsheets/d/1RWOxlYVnUfDUk_r3XPkoJ2bIgw1N3jkz1qqPJX02660

You'll have to make a copy to get it to actally generate anything. Also, in case you're interested, a quick summary of pages:

Select: this has the drop-down selectors to choose what kind of party you want, and how many.

Class: the list of classes, and how often they show up (ie, Barbarians have a 3/108 chance of showing up in a random party, or 2/35 in a party of fighters)

ClassInfo: a list of main stats, seconday stats, HD, and what equipment each class can use.

Builder: takes each piece of info and builds it into a lsit of stuff the character is carrying.

Stuff: list of weapons, equipment, and other stuf

Magic items: a list of each magic item, and wich (if any) a character will have. Doesn't take into account class at all.

Stats: generates and tweaks stats and HP

Profs: generates class and general proficiencies; "+1" means "and one more"; as GM, I usually pick a stats that matches the character. I'll automate this someday, probably.

Names: A list of first and last names for various cultures.

Eventually, I plan on making this into an online generator... but this works really well for now. It's not python, or even a real programming language, but hopefully some of the methods I used will be helpful!

Aryxymaraki
Aryxymaraki's picture
Patreon SupporterDomains At War BackerSinister Stone of Sakkara BackerLairs And Encounters BackerBarbarian Conquerors of Kanahu ContributorACKS Heroic Fantasy Handbook Contributor
Joined: 2014-01-04 02:20

It is also true that there is some irreducible complexity in modeling the treasure tables faithfully, and you're going to end up with a lot of text no matter how you slice it.


-jedavis

This is the summary, yeah.

Mine in C# doesn't use config files, though it should (for some reason magic items were the only thing I chose not to make a config file, I don't remember why but I assume I had some reason), but the fact is just that there are a lot of options available on the magic item table.

If there are a hundred unique options, it's going to take a lot of text to express that, there's just no way around it.

golan2072
Patreon SupporterBarbarian Conquerors of Kanahu AuthorPlayer&#039;s Companion BackerDwimmermount BackerSinister Stone of Sakkara BackerLairs And Encounters BackerBarbarian Conquerors of Kanahu BackerACKS Heroic Fantasy Handbook Backer
Joined: 2012-01-14 14:14

Thanks for the input!