R P G Generator

949 views

Published on

This is my Python Role Player Game Generator toolkit. It can be used to create multiple RPG\'s by simply creating the story and the logic, it will then create random characters and place them in the game.

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
949
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

R P G Generator

  1. 1. The Python RPG Generator This tool set which is a series of programs, has been designed for a person with Python programming experience so that they may build multiple computer based role playing games without having to re- invent or re-code the fundamental parts of the RPG. This tool set includes the following programs which will be discussed in greater detail later. The pyDie.py program was designed separately from the RPG Generator and is used to create dice using a preset pattern. This program allows for the creation of multiple dice with varying characteristics. The namegen.py program was adapted from source found on http://www.uselesspython.com/download.php?script_id=32. It allows for the random generation of a avatar's name. The charGen.py program has been designed solely with the RPG Generator in mind. This program allows for the creation of avatars and create some fundamental characteristics of each. This program uses pyDie for dice rolls and namegen for avatar name generation. The storyWriter.py program can be used to read in a file that uses a specific format, that can then be used to create the story for the RPG. This program accepts shortcuts in the text file that it reads so that various attributes of the avatar can be placed into the story. Finally, the rpgGenerator.py is the main part of this tool set as it does the work of pulling the story together with the characters. Any individual program or combination or programs can be used to create the RPG, or by using the rpgGenerator program, the RPG developer can create a game by creating a story text file with shortcuts included and then a wrapper program that contains the logic for the sequences following the presentation of each scene/location/plot of the story (explained in further detail later). pyDie To begin with let us look at the pyDie program in further detail. The pyDie program contains two classes (die and cup). For this tool set we will only address the die class itself. A single die can be created by calling this class and providing at least one parameter. The parameters and their defaults are (sides, starting point = 1, maximum = 6, increment = 1). By calling the die class and passing the number six (6), a standard six sided die is created. This die can then be rolled by calling the roll method. Additional die can be created and made unique for the purposes required by altering the default parameters (see pyDie documentation for details). namegen The namegen program came with no documentation or license. In fact it didn't even have a name just simply the code. This program was used solely to prevent re-inventing the wheel, but it is the least documented program and the one part of the tool suite that does not follow good coding standards, so at some point this may be replaced.
  2. 2. charGen The charGen program is the avatar (or character) generator for the RPG Generator tool set. It is made up of a single class called character. The program uses five files located one directory back from the script itself in the lib directory. Thus if the charGen.py file is located in RPG_Gen/etc, these files can be found in RPG_Gen/lib. These files are used for controlling the various attributes of the randomly generated character. They are (race.txt, specialty.txt, powers.txt, skills.txt, tools.txt). Let us look at each of these files in order. 1. The race.txt file is a text file that contains all the races you want to use for character generation in your game. By default these include (Human, Dwarf, Giant, Alien, Creature, and Organism) all on individual lines. 2. The specialty.txt file is a | delimited file with the format of (specialty|sex[m,f,a]|race). This file is used to determine the various specialties for a race. The sex field is can contain one or more of m = male, f = female, a = no sex or asexual separated by commas, and the race field can contain one or more races separated by commas. Thus the line “Servant|m,f| Human,Dwarf,Alien” tells us that the “Servant” specialty can belong to any character that is male or female of the Human, Dwarf, or Alien race. 3. The powers.txt file defines the powers that a specialty or race can be assigned. It is a | delimited file in the format of (power|specialty/race). The specialty/race field is comma delimited and limits the power assigned to a list of specialties and/or races. Thus the line “Invisibility| Sorcerer,Alien” tells us that Invisibility can be given to the Sorcerer specialty or the Alien race. At creation time, only one power is given by default, but others can be added as the rule in the powers.txt file dictates. 4. The skills.txt file defines the skills that each specialty is allocated the time of character creation. This is a | delimited file in the format of (skill|specialty). The specialty field is comma delimited and limits the skill assigned to a list of specialties. Also the * symbol may be used to specify all specialties. Thus the line “Fight|*” means all specialties are given the Fight skill while the line “Heal|Physician,Mage” tells us that only the Physician and Mage specialties can Heal. 5. The tools.txt file defines the tools that each specialty or race can be assigned. It is a | delimited file in the format of (tool|specialty/race). The specialty/race field is comma delimited and limits the power assigned to a list of specialties and/or races. Thus the line (Laser| Alien,Hacker) tells us that the Laser tool can be assigned to the Alien race or the Hacker specialty. Like powers only one tool is given by default at the creation of a character, but others may be added as the rule in tools.txt dictates. The use of these five files allows the RPG developer to specify characteristics and tools that are allowed for each character, and thus additional characteristics can be added without changing the code of the game itself. The next thing to note about the charGen program is the methods (attack, defend, learn, isDead, addTool, and addPower). We will look at each of these one at a time. 1. If the character using the attack method is still alive, it will add the character values for strength, wisdom, and experience together, it then performs integer division upon this result by adding the result of the roll of a six sided die to 10. Thus the formula used is (strength + wisdom + experience)//(die value + 10). This result is then returned to the calling program.
  3. 3. 2. If the character using the defend method is still alive, it will use the same logic in determining a defense value as the attack method, with the resulting value returned to the calling program. 3. If the character using the learn method is still alive, it will roll an eight sided die that starts at two and increments by twos add this value to the character's wisdom value and return this number to the calling program. Thus a character with a wisdom of 11 that calls the learn method that gets a roll value of 8 would have the value 19 returned to the calling program. It is up to the RPG developer how to handle this value. They may simply change the learn value or use it in some other fashion as their program logic dictates. 4. The isDead method looks at the character's strength and if it is < 1 then the character's strength, wisdom, experience, skills, powers, and tools are cleared and True is returned to the calling program. Otherwise False is returned to the calling program. This method can be used to determine if the character died during battle. 5. The addTool and addPower methods are used to add another random tool or power to the character (if one is available as defined in the corresponding text files). storyWriter The storyWriter program is used to read in and process the story file. It has a single class called story which has one method called open. It is used simply by creating a storyWriter.story object and then calling the open method. The story class has one mandatory argument which is the name of the file to be read. This file must be stored in the RPG_Gen/share directory. The story file itself is made up of four sections labeled as Intro, Scene, Location, and Plot (see below). <Intro> Introduction lines ... </Intro> <Scene> Text inside here is ignored. <Location> Location lines ... <Plot> Plot lines ... </Plot> </Location> </Scene> There are shortcuts which can be included in the text of each section (except for Scene which is ignored) that allow the RPG Developer to specify where various aspects (such as name, experience, race, etc) are to be displayed for each character as the story is played out. The following is a list of allowed shortcuts.
  4. 4. Within the plot line use the &# shortcut to represent your character as it corresponds to the list #. For instance if you use a list avatars = [] that you populate with 10 characters then <5> would be the 6th character since lists begin with 0. Thus think of 0 as your main character. Shortcuts include: &# = character description (name the race specialty) &#.nam = character name (text) &#.rac = character race (text) &#.spe = character specialty (text) &#.sex = character sex (text m,f,a = male, female, asexual) &#.evi = character trait (text evil or good) &#.exp = character experience (number) &#.str = character strength (number) &#.wis = character wisdom (number) &#.skl$ = character skill where $ represents the list number for the skill in question starting with 0 (text) &#.pow$ = character power where $ represents the list number for the skill in question starting with 0 (text) &#.tol$ = character tool where $ represents the list number for the skill in question starting with 0 (text) So to access the 3rd tool for the 6th character the shortcut would be &5.to2 The line “This player is &1.evi.” within the story text file causes storyWriter to replace &1.evi with Evil or Good for character 1. Keep in mind that this uses list processing within Python thus 0 is the actual first character in the list. rpgGenerator The main tool within the RPG Generator tookit is the rpgGenerator itself. It pulls in all the previously mentioned programs and incorporates them into a functioning tool that can then be used to create your game based upon the lib and share files mentioned above. It is made up of three classes (player, opponent, and game). The player class simply inherits the charGen.character class for creating the game's initial player, while the opponent class changes the inheritance slightly by forcing all opponents to be on the opposite of the player. Thus if player is created as “Good”, then all opponents are “Evil”. The game class is used to create the story and populate the shortcuts used in the storyWriter file. It assumes that &0 is always the player and any &# > 0 is an enemy. The following is a very simplistic example for using rpgGenerator.
  5. 5. import rpgGenerator fn = 'setup.txt' me = rpgGenerator.player(False) myGame = rpgGenerator.game(me, 4, fn) print 'Characters are:' for i in myGame.characters: print ' %s'%(i.name) print 'Intro:' print myGame.intro print for s in range(0, len(myGame.scenes)): print 'Scene: %i'%s loca = 0 for l in range(0, len(myGame.locations)): sid, location = myGame.locations[l] if sid == s: print 'Location %i'%l print location for p in range(0, len(myGame.plots)): sid2, lid, plot = myGame.plots[p] if sid2 == s and lid == loca: print 'Plot %i'%p print plot loca += 1 First you import rpgGenerator. Then you have to create your initial player and tell it whether it is evil or not (in this case the player is good so all enemies will be evil). Next you have to create your game, by specifying the name of your player object, how many opponents you want to create, (this should match the number used in your story file. It is acceptable to have too many but too few and you will get weird results.), and your story file name. From that point it is up to the RPG Developer how they want their game to flow, but the above example shows how to access the various elements of the story. The following is an example of the output using the default files included with the RPG Generator.
  6. 6. Characters are: Einckae Yulemziu Iuoi Goi Yujrei Intro: This is a setup for a story file. It doesn't really do anything. But it does demonstrate the setup of the story file. Scene: 0 Location 0 Coolsville - Einckae the Dwarf Duke is Good Plot 0 I want to do something here. I will display Yulemziu's name. The oponenet Yulemziu is Evil. Plot 1 Now I want to do something else. I can even use multiple lines. Einckae can battle Yulemziu with Knife. Einckae has [] powers while Yulemziu has ['Teleportation'] powers. Location 1 My House Plot 2 Not much happening here... The character has these skills. ['Fight', 'Speak', 'Build', 'Read', 'Ride'] And the first enemy has these tools. ['Shield'] … etc As you can see the tool kit allows for a great deal of flexibility for the RPG Developer to create a tailor made game again and again, without having to rewrite much of the mundane code required for character and plot line development. This allows them to focus on the story itself. Sample Game The following is a simple (incomplete) game designed using the RPG toolkit, but it is included to
  7. 7. provide an example of the power and flexibility when using the toolkit. First let us look at the story itself. <Intro> You are &0.nam and you are a &0.rac &0.spe. You have awakened to find yourself in the cargo hold of &5.nam's ship. How did you let this happen to yourself. If you don't find a way out of here and back home you know that &5.nam will kill you. </Intro> <Scene> Text inside here is ignored. <Location> &5.nam's Cargo Hold <Plot> It is dark in here! You stumble across the room till you trip ove a box. The contents of the box spill out across the floor. </Plot> <Plot> You begin to search the contents of the box and find a light. </Plot> <Plot> You turn on the light and begin to search for anything useful. </Plot> <Plot> You have found a medkit, a ceremonial dagger, and an empty satchel. </Plot> <Plot> As you pick up the last remaining items you hear someone entering the cargo hold. You must hide, or prepare to fight. What will you do? </Plot> <Plot> &1.nam the &1.evi &1.rac &1.spe has discovered you are awake. As &1.nam approaches you have only seconds to decide what to do next. </Plot> </Location> </Scene> Now let us look at the program that controls the flow of the story and characters.
  8. 8. import rpgGenerator fn = 'firstGame.txt' me = rpgGenerator.player(False) myGame = rpgGenerator.game(me, 5, fn) myItems = [] def action(actions, msg='Choose what you will do'): act = '' while act not in actions: act = raw_input('%s %s '%(msg, str(actions).lower())) if act not in actions: print 'You cannot do that' return act def incrExp(): myGame.characters[0].experience = myGame.characters[0].experience + 1 print 'Characters are:' for i in myGame.characters: print ' %s'%(i.name) print 'Intro:' print myGame.intro print # Location 0 sid, loca = myGame.locations[0] print loca # Plot 0 sid2, lid, plot = myGame.plots[0] print plot actions = ['fight', 'flee', 'search', 'talk'] again = True while again: act = action(actions) if act == 'fight': print 'Just what are you going to fight with?' elif act == 'flee': print 'There is nowhere to go.' elif act == 'search': incrExp() print 'Your experience is now: %d'%myGame.characters[0].experience again = False elif act == 'talk': print 'Surely you are not crazy enough to start that.' This first section of the code creates some modules that we will use and then creates the story and the characters. It then begins plot 0.
  9. 9. # Plot 1 sid2, lid, plot = myGame.plots[1] print plot actions = ['search', 'grab'] again = True while again: act = action(actions) if act == 'search': print 'You are unable to find anything else in the dark.' elif 'grab' in act: # Plot 2 myItems.append('light') sid2, lid, plot = myGame.plots[2] print plot again = False Next we do plot 1 and 2.
  10. 10. # Plot 3 sid2, lid, plot = myGame.plots[3] print plot actions = ['search', 'take'] again = True items = 0 act = '' while again and items < 3: if act == 'search': print 'There is nothing else to find.' elif act == 'take': again = False msg = 'What will you pick up?' list = ['satchel', 'dagger', 'medkit'] satchel = False while items < 3: item = action(list, msg) if item == 'satchel': print 'satchel' satchel = True list.remove('satchel') myItems.append('satchel') items += 1 elif item == 'dagger' and satchel: print 'dagger' list.remove('dagger') myItems.append('dagger') items += 1 elif item == 'medkit' and satchel: print 'medkit' list.remove('medkit') myItems.append('medkit') items += 1 elif not satchel: print 'Don't you need something to put your stuff in?' else: print 'else' else: act = action(actions) incrExp() print 'Your experience is now: %d'%myGame.characters[0].experience In the third plot we are gathering some items we will use.
  11. 11. # Plot 4 msg = '' sid2, lid, plot = myGame.plots[4] print plot actions = ['hide', 'run', 'talk'] again = True while again: act = action(actions) if act == 'hide': sid2, lid, plot = myGame.plots[5] msg = '%s is not pleased to find you awake.'%myGame.characters[1].name print plot again = False elif act == 'run': print 'Seriously, where are you going to run from a %s'%myGame.characters[1].race elif act == 'talk': sid2, lid, plot = myGame.plots[5] print plot msg = '%s was not interested in talking.'%myGame.characters[1].name again = False actions = ['attack', 'talk'] again = True while again: if msg == '': act = action(actions) else: act = action(actions, msg) if act == 'attack': medkit = True dagger = True me = myGame.characters[0].name you = myGame.characters[1].name
  12. 12. At the start of plot 4 we are preparing for the battle that will take place following. while not myGame.characters[0].isDead() and not myGame.characters[1].isDead(): attack = myGame.characters[0].attack() defend = myGame.characters[1].defend() print 'You attacked %s with %d and %s defended with %d'%(you, attack, you, defend) if attack < defend and dagger: print 'You use your dagger, but it breaks as you plunge it into %s's belly.'%myGame.characters[1].name temp = attack attack = defend defend = temp dagger = False myItems.remove('dagger') myGame.characters[1].strength -= (attack - defend) if not myGame.characters[0].isDead() and not myGame.characters[1].isDead(): attack = myGame.characters[1].attack() defend = myGame.characters[0].defend() print '%s attacked you with %d and you defended with %d'%(you, attack, defend) if attack > defend and medkit: myGame.characters[0].strength -= (attack - defend) print 'You use your medkit.' myGame.characters[0].strength += 5 medkit = False myItems.remove('medkit') myGame.characters[0].strength -= (attack - defend) again = False elif act == 'talk': msg = '%s was not interested in talking.'%myGame.characters[1].name if myGame.characters[1].isDead(): print 'You have killed %s'%myGame.characters[1] if myGame.characters[0].isDead(): print 'You have died!' After the battle sequence we determine who has died. Here is what this short program looks like as it is ran.
  13. 13. As we continue through our story...
  14. 14. And finally...
  15. 15. Thus as you can see a very suitable story line can be developed and then random characters generated and placed into the story, without having to recreate the story processor or character generation routines each time a new story is created.

×