# Character Sheet Development/Pattern Libraries

Jump to: navigation, search

Character Sheet Development
Getting Started

General

Reference

Tools & Tips

Git/GitHub

Other

Main Page: Building Character Sheets

Pattern Libararies useful for creating your own character sheets.

## Examples

### Helpful Functions

```//Convert Integers to be Negative
const convertIntegerNegative = number => number > 0 ? -Math.abs(number) : number

//Convert an object with negative numbers
const convertIntegersNegatives = numbers => {
numbers => {
for (let [key, value] of Object.entries(numbers)) {
numbers[key] = convertIntegerNegative(value);
}
return numbers
}
}

//Pass in eventinfo.triggerName
const findRepeatingField = trigger => trigger.split('_')[1]

//Pass in eventinfo.triggerName
const getReprowid = trigger => {
const split = trigger.split('_');
return `\${split[0]}_\${split[1]}_\${split[2]}`
}

//Pass in an object keep that has the repeating section
//Example repeating_weapon_-m1czg68yzicwhfdpyys_name
const getReprowAttribute = key => {
const getReprowid = processingFunctions.getReprowid(key)
return key.split(`\${getReprowid}_`)[1]
}

//Provide the function with an array of keys to find translations for
//Example ['strength', 'agility', 'willpower']
const getTranslations = translationKeys => {
let translations = {}
translationKeys.forEach(key => translations[`\${key}`] = getTranslationByKey(key))
return translations
}

const parseInteger = string => parseInt(string) || 0

//Use for converting the result of getAttrs from strings into integers
const parseIntegers = numbers => {
for (let [key, value] of Object.entries(numbers)) {
numbers[key] = parseInt(value) || 0
}
return numbers
}

const setAttributes = (update, silent) => silent && typeof update === 'object' ? setAttrs(update, {silent:true}) : typeof update === 'object' ? setAttrs(update) : console.error(`\${update} is not an object`)

//returns strength from @{strength}
const sliceAttr = attribute => attribute.slice(2, -1)

const sumIntegers = numbers => numbers.reduce((a,b) => a + b, 0)
```

### Sheet Versioning

It can be beneficial to use a visible sheet version on a sheet, so people know when the sheet have updated. Also using sheet version will make it easier for you and others to track the state of the sheet and possible changelog.

If you have complex stat & sheetworkers in you sheet and make changes to them, it can be beneficial to add sheet versioning sheetworker that updates things for character using older version of the sheet to a new one.

An example would be to update an attribute name with a typo, to one with the correct spelling. The sheet versioning would next time a sheet is opened notice it is a older version, and then perform the sheet update transferring the attribute values of the old attribute to the new one, while it would do nothing on sheet that are already the latest version.

See also the MigrateAttributes sheetworker examples, both show a simple method for sheet versioning alongside migrating attributes to new names.

### Improved Sheetworker diagnostics

TheAaronSheet contains a number of helpful sheetworker functions like simplifying repeating sections, but it also has a improved debugging settings that can help making various dev console messages more distinct.

### Documentation

The "Instructions"-section of the sheet.json is a bit unwieldy to fill out and structure(mix of normal Markdown-syntax, and using `/n` for line breaks), so it might be easier to place any larger documentation here on the Roll20 Community Wiki.

If the character sheet have several tabs or is long, the wiki could better fit more preview images of the sheet, rather than having something complicated on GitHub/the Sheet Template Preview.

Alternatively, add a `Readme.md`-file in the same folder with the sheet code, and then write sheet instructions using Markdown on it.

Link to the sheet's wiki page/readme in the "Instructions" (e.g. `For sheet instructions, go to [ExampleRPG](https://wiki.roll20.net/ExampleRPG).`.

### Using REGEX

One method of saving time with sheet dev is to use regex to find & replace more complex things in code.

Example:

Using REGEX to add `title=`(i.e. hover descriptions) for all attributes and roll buttons
Many sheets do not tell users the different attribute names. The easiest method is to include a `title="@{attrname}"` in each input/select. Buttons could also benefit from adding a `title="%{buttonname}"` but isn't as big of a deal.
It's possible to create a regex or some other syntax/replace command that could be run on any sheet that already doesn't have them, and add these attribute name tooltips for all attributes.
This same example could be used as a base for creating `i18n` attributes for sheet translations
Basic syntax to add Attribute titles:
find all: name="attr_REGEX"
replace with: name="attr_REGEX" title="@{REGEX}"
REGEX is replaced with regex commands or some other search syntax that search/accepts alphanumerals, -, _ (in essence, anything that's a valid attribute name)
Basic syntax to add Roll buttons titles:
find all: name="roll_REGEX"
replace with: name="roll_REGEX" title="%{REGEX}"
Attribute example:
```find regex: name="attr_([A-Za-z0-9_-]{1,50})"
replace regex: name="attr_\$1" title="@{\$1}"
```
Buttons example:
```find regex: name="roll_([A-Za-z0-9_-]{1,50})"
replace regex: name="roll_\$1" title="%{\$1}"
```
(Arbitrarily chose "50" as the max-length of possible `attr` names, use a larger number if you might have longer names.)