SGP Cgen HOWTO-Character Sheets: 110901 ---------------------------------------------------------------------- To begin making character sheets, you first have to define how many different types of characters that you have and what kinds of data the sheet needs to display for them. There are two schools of thought as to how to approach this task. One is to create a large command that calls all the various strings, stats, and list, using switches to determine what data is shown according to some factor like race, character class, or some other virtue. This is likely advantageous on systems where there are very few different types of characters or there isn't much difference between the types of sheets needed to display. ie, if your game has fighters, magicians, and clerics, and there isn't a lot of other stuff to consider about the races that might be playing those classes, then certainly one big command makes sense. However, as the relationship between various factors involved in dis- playing a character sheet become more numerous or complex, it is often better to create different sheets for different things. A fighter might be a dwarf or a human. A magic user might be a vampire or an elf. Both situations can possibly require you to design dis- plays that take those variations into account. ((You will have to also account for these complexities and restrictions in the way that you build the display conditions in the +stats commands themselves. For instance, in some systems, a single factor such as race determines the look and properties of character sheet(WoD). Others look at something like race and then have a character class or faction affiliation to consider(Triniy or D&D).)) For the purposes of discussion, this HOWTO covers the second method. The words of the day are 'simplicity' and 'readability'. In general, readable code is best. It is not always true, but in most cases, it serves the coder and the user better at the end of the day. Large, clumsy, complicated switches in code are hard to debug, and can also hit invokation and recursion limits -very- quickly. Modular design is also very good for systems with multiple sheet display attributes. That said, you need to look at your system and decide what is best. Now is the time that you look at the game system and play with a text editor to design how your sheet will look overall. Decide where you want the strings, stats, and lists to appear, put the in order and then sit back with it. Sections of the sheet should be seperated by headings that say what the section is. Each of the major sections of the sheet should be made so they live inside an @pemit statement, strung together into a cohesive whole with semicolons ';'. This way, it is harder for the code to bottom out on one of the hard limits of the server itself(4k/8k buffer limits, invokation, recursion, etc...). ---------------------------------------------------------------------- &CMD-STATS SGP Cgen: WoD Support Code=$+stats:@trigger #140/SHEET-[get(%#/string-race)]=%#,%# The above is an example of a player-level sheet command. The code uses @trigger and the results of get(/string-race) to choose appropriate &SHEET- to display. This code returns nothing if the race attribute is unset(and note that it isn't a particulary great command because it lacks adequate error checking). Joe is a mortal and the code finds and emits the contents of &SHEET-MORTAL back to him. This is but one way to deal with selecting which sheet to use and certainly not the only one. The staff command takes an argument, and provides more error checking. &SHEET-MORTAL SGP Cgen: WoD Support Code=@pemit %1=[center(<%b%b[name(%0)]%b%b>,78,=)]%R[u(fn-display-strings,%0,Race:STRING-RACE|Birthday:STRING-BIRTHDAY|Nature:STRING-NATURE|Demeanor:STRING-DEMEANOR|Concept:STRING-CONCEPT|XP:XP)]%r[u(#140/fn_attributes,*%0)]%r[u(#140/fn_abilities,*%0)]%r[center(%bMiscellaneous%b,78,~)]%r[u(#140/FN_3LISTSCOL,get(*%0/statlist-backgrounds),get(*%0/statlist-virtues),get(*%0/statlist-pools))]; @pemit %1=[u(#140/fn_common-lists,*%0)];@pemit %1=%r[u(#140/FN_HEALTH,%0)]%R[repeat(=,78)] The code @pemit to %1, not %0 or %# in this case. Through the magic of MUSHCode, %1 becomes %# in the command itself. Isn't that nice and confusing? Now, look at the section from the beginning of the first @pemit to the first ';'. This part of the code displays the name of the character, centered in the middle of a line 78 spaces long, padded with '='. It is then followed by invokation of FN-DISPLAY-STRINGS to call a list of &STRING attributes on the character object as specified. FN-DISPLAY-STRINGS creates a two column display as seen below. It is more than possible to create string manipulation functions that use as few as 1 and 3 or more columns of display. Example: ==================================< Joe >=================================== Race: Mortal Birthday: Jan 1, 2000 Nature: Loner Demeanor: Crabby Concept: Computer Geek XP: The rest of the first @pemit uses two special utility functions, FN_ATTRIBUTES and FN_ABILITIES. FN_ATTRIBUTES creates the header line and then uses the more general FN_3VCOL to produce the display from a single list of stats. It doesn't actually pick the order of how things are displayed, but lets the order of the stats on the attribute decide. FN_ABILITIES uses FN_3LISTSCOL to produce an alphabetically sorted, 3 column listing based on the contents of as many as 6 attributes on the character object. Example: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Strength 2 Charisma 2 Perception 2 Dexterity 2 Manipulation 2 Intelligence 2 Stamina 2 Appearance 2 Wits 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Abilities ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Acting 2 Animal ken 2 Bureaucracy 2 Alertness 2 Drive 2 Computer 8 Athletics 2 Etiquette 2 Finance 4 Brawl 2 Investigation 2 Dodge 2 Science 3 Finally, the first section is completed with the making of a new header line and a listing of miscellaneous stats using FN_3LISTSCOL. Example: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Miscellaneous ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Contacts 4 Conscience 4 Blood 10 Fame 2 Courage 3 Willpower 7 Resources 5 The second @pemit calls the utility function, FN_COMMON-LISTS, and checks the character object for specialties, merits, flaws, equip- ment. Joe has Merits and Flaws, but no specialties or equipment that needs to be listed on his sheet. FN_COMMON-LISTS can be customized by changing the content and the order of the listtypes in the code. Example: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Merits ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ stuff and stuff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Flaws ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ stuffed The last @pemit calls another utility function called FN_HEALTH, that lists out wounds, bloodpool and tracks if someone is blood bound to a vampire or not. It ends with a line of '=' 78 characters long Example: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Health ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Wounds / Agg Wounds : 0 / 0 Blood: 10 / 10 ============================================================================== The value of specialized utility functions can't be overstated. In cases where you have multiple sheets that have sections that will be identical, being able to display those sections in a less spammy way is useful, probably vital to the maintenance of both the code and your sanity. The other advantage of creating such specialized functions is that if you want to do a mass change to the way a part of the display looks, you can change it in one place and have it take effect for all your different sheet types. The &SHEET is this case is very simple, and a mix of both explicit function calls, and more specialitize utility functions. In truth, a sheet the size of Joe's could be displayed in a single @pemit statement. However, because other sheets are much more complex, and have the potential to have a lot more information on them, we broke the data into multiple statements to avoid hitting server limits. Other races in this genre(WoD), have a lot more stuff on them, so they are broken up even further. The best thing to do is to study the way the code in other libraries works, as well as read the cgen helpfiles on various topics.