Skip to main content

System creation

Contribute on GitHub License: CC BY-NC-SA 4.0

Prerequisites

In order to create systems for the app, you will need a couple things. These might seem technical, but if you need help a quick Google (or question to your AI of choice) might help a lot:

  1. A copy of the RPG Companion App (you can download it from here).
  2. A cool text editor (any text editor will work, but Visual Studio Code is recommended as you will be able to use some special snippets that we've created for you, to make your task easier).
  3. The RPG Companion App dev tool, which will help you test your system with the app. a. You need to have the app in "Developer Mode" to be able to develop systems. You can toggle this in the app's settings.
  4. A USB cable to plug your phone/laptop to your computer.
  5. If developing with an Android device, make sure you have the Android adb program installed and correctly mapped in your PATH. a. You will need to enable USB Debugging on the device for the tool to work. b. For Mac OS, you might need to add one of these two to your bashrc or zshrc file:
    export PATH=~/Library/Android/sdk/tools:$PATH
    export PATH=~/Library/Android/sdk/platform-tools:$PATH

That's it! I know it seems complicated, but this was the hardest part.

Prefer starting from a template?

You can clone a working folder structure and example system.rpg.json from the Open Systems Repository: github.com/blastervla/rpg-companion-app-systems

If you choose to use Visual Studio Code, optionally, you can go through the following steps to make your development experience a bit better:

  1. Open up the editor
  2. Use the command palette (cmd + option + p) to and choose the option Preferences: Open Keyboard Shortcuts (JSON).
  3. Insert the following block within the brackets:
    {
    "key": "shift+cmd+i",
    "command": "editor.action.insertSnippet",
    "when": "!editorReadonly"
    },
  4. Once again, open up the command palette and choose Snippets: Configure Snippets. Choose New Global Snippets file.
  5. Name the file rpg.json.
  6. Copy and paste the contents of the following json to the new created file.
    rpg.json snippets file content
    {
    // Place your global snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
    // description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
    // is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
    // used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
    // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
    // Placeholders with the same ids are connected.
    // Example:
    // "Print to console": {
    // "scope": "javascript,typescript",
    // "prefix": "log",
    // "body": [
    // "console.log('$1');",
    // "$2"
    // ],
    // "description": "Log output to console"
    // }
    "statStat": {
    "prefix": "stat",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"stat\",",
    "\t\"stat\": \"\"",
    "}"
    ]
    },
    "definedStat": {
    "prefix": "statDefined",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"defined\",",
    "\t\"stat\": \"\"",
    "}"
    ]
    },
    "metaStatStat": {
    "prefix": "metaStat",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"metaStat\",",
    "\t\"meta_stat\": {}",
    "}"
    ]
    },
    "defaultIfNullStat": {
    "prefix": "statdefaultIfNull",
    "body": [
    "{",
    "\t\"type\": \"defaultIfNull\",",
    "\t\"components\": {},",
    "\t\"default_components\": {}",
    "}"
    ]
    },
    "mapperStat": {
    "prefix": "statmap",
    "body": [
    "{",
    "\t\"type\": \"map\",",
    "\t\"components\": {},",
    "\t\"mapper\": {}",
    "}"
    ]
    },
    "flatMapStat": {
    "prefix": "statFlatMap",
    "body": [
    "{",
    "\t\"type\": \"flatMap\",",
    "\t\"components\": {},",
    "\t\"mapper\": {}",
    "}"
    ]
    },
    "filterStat": {
    "prefix": "statfilter",
    "body": [
    "{",
    "\t\"type\": \"filter\",",
    "\t\"components\": {},",
    "\t\"filter\": {}",
    "}"
    ]
    },
    "findFirstStat": {
    "prefix": "statfindFirst",
    "body": [
    "{",
    "\t\"type\": \"findFirst\",",
    "\t\"components\": {},",
    "\t\"filter\": {}",
    "}"
    ]
    },
    "sortByStat": {
    "prefix": "statsortby",
    "body": [
    "{",
    "\t\"type\": \"sortBy\",",
    "\t\"order\": ?\"asc|desc\",",
    "\t\"sort_by_value_key\": ?\"\\$sortByValue\",",
    "\t\"components\": {},",
    "\t\"sort_by_selector\": {}",
    "}"
    ]
    },
    "enumeratedNameStat": {
    "prefix": "statEnumeratedName",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"enumeratedName\",",
    "\t\"enumerated_type\": \"\",",
    "\t\"id\": {}",
    "}"
    ]
    },
    "enumeratedAbbreviationStat": {
    "prefix": "statEnumeratedAbbreviation",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"enumeratedAbbreviation\",",
    "\t\"enumerated_type\": \"\",",
    "\t\"id\": {}",
    "}"
    ]
    },
    "joinToStringStat": {
    "prefix": "statJoinToString",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"joinToString\",",
    "\t\"separator\": \"\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "splitStat": {
    "prefix": "statSplit",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"split\",",
    "\t\"separator\": \"\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "concatStat": {
    "prefix": "statConcat",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"concat\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "isEmptyStat": {
    "prefix": "statIsEmpty",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"isEmpty\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "lengthStat": {
    "prefix": "statLength",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"length\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "trimStat": {
    "prefix": "statTrim",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"trim\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "containsStat": {
    "prefix": "statContains",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"contains\",",
    "\t\"haystack\": {},",
    "\t\"needle\": {}",
    "}"
    ]
    },
    "maxStat": {
    "prefix": "statMax",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"max\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "minStat": {
    "prefix": "statMin",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"min\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "copyResourceStat": {
    "prefix": "statCopyResource",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"copyResource\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "addStat": {
    "prefix": "statAdd",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"add\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "subtractStat": {
    "prefix": "statSubtract",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"subtract\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "multiplyStat": {
    "prefix": "statMultiply",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"multiply\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "divideStat": {
    "prefix": "statDivide",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"divide\",",
    "\t\"rounding_method\": \"down|up|closest|none\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "equalsStat": {
    "prefix": "statEquals",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"equals\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "andStat": {
    "prefix": "statAnd",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"and\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "orStat": {
    "prefix": "statOr",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"or\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "notEqualsStat": {
    "prefix": "statNotEquals",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"notEquals\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "notNullStat": {
    "prefix": "statNotNull",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"notNull\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "isNullStat": {
    "prefix": "statIsNull",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"isNull\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "notStat": {
    "prefix": "statNot",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"not\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "greaterThanEqualsStat": {
    "prefix": "statGTE",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"greaterThanEquals\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "greaterThanStat": {
    "prefix": "statGT",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"greaterThan\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "lessThanEqualsStat": {
    "prefix": "statLTE",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"lessThanEquals\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "lessThanStat": {
    "prefix": "statLT",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"lessThan\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "statToNum": {
    "prefix": "statToNum",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"toNum\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "statToSignedString": {
    "prefix": "statToSignedString",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"toSignedString\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "statToLowerCase": {
    "prefix": "statToLowerCase",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"toLowerCase\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "statToUpperCase": {
    "prefix": "statToUpperCase",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"toUpperCase\",",
    "\t\"components\": {}",
    "}"
    ]
    },
    "statReplace": {
    "prefix": "statreplace",
    "body": [
    "{",
    "\t\"type\": \"replace\",",
    "\t\"string\": {},",
    "\t\"occurrence\": {},",
    "\t\"replace\": {}",
    "}"
    ]
    },
    "statRoll": {
    "prefix": "statRoll",
    "body": [
    "{",
    "\t\"type\": \"roll\",",
    "\t\"formula\": {}",
    "}"
    ]
    },
    "statRollable": {
    "prefix": "statRollable",
    "body": [
    "{",
    "\t\"type\": \"rollable\",",
    "\t\"formulas\": {},",
    "\t\"text\": {}",
    "}"
    ]
    },
    "statList": {
    "prefix": "statlist",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"list\",",
    "\t\"components\": []",
    "}"
    ]
    },
    "statFlatAppend": {
    "prefix": "statFlatAppend",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"flatAppend\",",
    "\t\"components\": []",
    "}"
    ]
    },
    "statConstant": {
    "prefix": "statconst",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"constant\",",
    "\t\"value\": ,",
    "\t\"value_type\": ",
    "}"
    ]
    },
    "statWhen": {
    "prefix": "statwhen",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"when\",",
    "\t\"clauses\": [",
    "\t\t{",
    "\t\t\t\"condition\": {},",
    "\t\t\t\"components\": {}",
    "\t\t},",
    "\t\t{",
    "\t\t\t\"condition\": {",
    "\t\t\t\t\"type\": \"constant\",",
    "\t\t\t\t\"value\": true,",
    "\t\t\t\t\"value_type\": \"bool\"",
    "\t\t\t},",
    "\t\t\t\"components\": {}",
    "\t\t}",
    "\t]",
    "},"
    ]
    },
    "whenClause": {
    "prefix": "wclause",
    "scope": "json",
    "body": [
    "{",
    "\t\"condition\": {},",
    "\t\"components\": {}",
    "},"
    ]
    },
    "baseStat": {
    "prefix": "base",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"name\": \"\",",
    "\t\"type\": \"base\",",
    "\t\"value_type\": \"\",",
    "\t\"default_value\": ",
    "},"
    ]
    },
    "calcStat": {
    "prefix": "calc",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"name\": \"\",",
    "\t\"type\": \"calculated\",",
    "\t\"value_type\": \"\",",
    "\t\"components\": {}",
    "},"
    ]
    },
    "textView": {
    "prefix": "vtext",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"text\",",
    "\t\"text\": ?{},",
    "\t\"edit_stat\": ?,",
    "\t\"style\": \"text|title|section|subhead|headline|caption\",",
    "\t\"max_length\": ?,",
    "\t\"signed\": ?false,",
    "\t\"hint\": ?{},",
    "\t\"label\": ?{},",
    "\t\"bold\": ?,",
    "\t\"color\": ?{},",
    "\t\"resource_id\": ?,",
    "\t\"resource_instance_ids_stat\": ?,",
    "\t\"resource_display_stat\": ?",
    "},"
    ]
    },
    "diffTextView": {
    "prefix": "vdiffText",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"diffText\",",
    "\t\"original_text\": {},",
    "\t\"new_text\": {},",
    "\t\"added_color\": ?\"\",",
    "\t\"deleted_color\": ?\"\"",
    "},"
    ]
    },
    "listView": {
    "prefix": "vlist",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"list\",",
    "\t\"padding\": ?,",
    "\t\"alignment\": ?\"start|center|end\",",
    "\t\"subviews\": []",
    "},"
    ]
    },
    "statView": {
    "prefix": "vStat",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"stat\",",
    "\t\"stat\": \"\",",
    "\t\"edit_stat\": ?\"\",",
    "\t\"change_amount\": ?1,",
    "\t\"min_value_allowed\": ?0,",
    "\t\"max_value_allowed\": ?999999,",
    "\t\"calculated_min_value_allowed\": ?{},",
    "\t\"calculated_max_value_allowed\": ?{},",
    "\t\"on_tap_event\": ?{},",
    "\t\"on_long_tap_event\": ?{},",
    "\t\"bottom_sheet_view\": ?{},",
    "\t\"bottom_sheet_in_edit_mode\": ?false,",
    "\t\"sheet_title\": {}",
    "\t\"stat_color\": ?{}",
    "\t\"name_color\": ?{}",
    "\t\"style\": ?\"block|list\"",
    "\t\"always_show_sign\": ?false",
    "}"
    ]
    },
    "resourceSectionView": {
    "prefix": "vResSection",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"resourceSection\",",
    "\t\"resource_stat\": \"\",",
    "\t\"resource_id\": \"\",",
    "\t\"header_view\": ?{},",
    "\t\"resource_set_stat\": ?\"\",",
    "\t\"contentItemMinWidth\": ?1,",
    "\t\"alignment\": ?\"start|center|end\",",
    "\t\"read_only\": ?false,",
    "\t\"tap_displays_resource\": ?true",
    "},"
    ]
    },
    "sectionView": {
    "prefix": "vSection",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"section\",",
    "\t\"header\": [],",
    "\t\"content\": [],",
    "\t\"show_divider\": false,",
    "\t\"content_item_min_width\": ?100,",
    "\t\"collapsible\": ?false,",
    "\t\"start_collapsed\": ?false,",
    "\t\"always_show_collapse_icon\": ?false,",
    "\t\"alignment\": ?\"start|center|end\"",
    "}"
    ]
    },
    "avatarSectionView": {
    "prefix": "vAvatarSection",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"avatarSection\",",
    "\t\"bottom_left_stack\": ?[],",
    "\t\"bottom_right_stack\": ?[],",
    "\t\"center_content\": [],",
    "\t\"bottom_left_button_title\": ?{},",
    "\t\"bottom_left_button_event\": ?{},",
    "\t\"bottom_right_button_title\": ?{},",
    "\t\"bottom_right_button_event\": ?{}",
    "}"
    ]
    },
    "avatarView": {
    "prefix": "vAvatar",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"avatar\",",
    "\t\"photo_stat\": \"\",",
    "\t\"name_stat\": \"\",",
    "\t\"size\": \"massive|medium|small\",",
    "\t\"interactable\": ?false",
    "}"
    ]
    },
    "selectView": {
    "prefix": "vselect",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"select\",",
    "\t\"stat\": \"\",",
    "\t\"options\": ?\"\",",
    "\t\"allowed_options\": ?{},",
    "\t\"resource_options\": ?{},",
    "\t\"max_selection_amount\": ?{},",
    "\t\"options_display_stat\": ?\"\",",
    "\t\"multi_select\": ?false",
    "\t\"style\": ?\"dropdown|list\"",
    "},"
    ]
    },
    "checkboxView": {
    "prefix": "vcheck",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"checkbox\",",
    "\t\"stat\": \"\",",
    "\t\"label\": ?,",
    "\t\"label_alignment\": ?\"left|right\",",
    "\t\"style\": ?\"checkbox|switcher\",",
    "\t\"should_auto_save\": ?false",
    "},"
    ]
    },
    "compositeView": {
    "prefix": "vcomp",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"composite\",",
    "\t\"row_only\": ?true,",
    "\t\"alignment\": ?\"start|center|end\",",
    "\t\"subviews\": []",
    "},"
    ]
    },
    "resourceArrayView": {
    "prefix": "vresarr",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"resourceArray\",",
    "\t\"resource_id\": \"\",",
    "\t\"stat\": \"\",",
    "\t\"view_type\": \"list|display|edit\",",
    "\t\"auto_add_first\": ?true|false,",
    "\t\"left_view\": ?,",
    "\t\"pop_up_type\": ?\"bottomSheet|window\",",
    "\t\"pop_up_button_text\": ?{},",
    "\t\"hide_line\": ?false",
    "},"
    ]
    },
    "iconView": {
    "prefix": "vIcon",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"icon\",",
    "\t\"name\": \"\",",
    "\t\"size\": \"massive|xLarge|large|medium|small|xSmall\",",
    "\t\"color\": ?\"\"",
    "},"
    ]
    },
    "menuButtonView": {
    "prefix": "vMenuButton",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"menuButton\",",
    "\t\"icon_name\": \"\",",
    "\t\"icon_size\": \"massive|xLarge|large|medium|small|xSmall\",",
    "\t\"icon_color\": ?\"\",",
    "\t\"options\": \"\",",
    "\t\"allowedoptions\": ?{}",
    "},"
    ]
    },
    "resourceView": {
    "prefix": "vreso",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"resource\",",
    "\t\"view_type\": \"display|edit|list\",",
    "\t\"resource_id\": \"\",",
    "\t\"stat\": \"\",",
    "\t\"create_if_empty\": ?false",
    "},"
    ]
    },
    "popUpButtonView": {
    "prefix": "vPopUp",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"popUpButton\",",
    "\t\"text\": ?{},",
    "\t\"icon\": ?{},",
    "\t\"pop_up_view\": {},",
    "\t\"pop_up_type\": \"bottomSheet|alert\",",
    "\t\"dismissible\": ?true|false,",
    "\t\"pop_up_title\": {},",
    "\t\"display_cancel_button\": ?true,",
    "\t\"cancel_text\": ?{},",
    "\t\"display_save_button\": ?false,",
    "\t\"save_text\": ?{},",
    "\t\"should_persist_on_save\": ?false,",
    "\t\"extra_buttons\": ?[{\"text\": {}, \"event\": {}}],",
    "\t\"in_edit_mode\": ?false",
    "},"
    ]
    },
    "selectResourcesView": {
    "prefix": "vselres",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"selectResources\",",
    "\t\"stat\": \"\",",
    "\t\"resource_id\": \"\",",
    "\t\"view_type\": ?\"list|icon\",",
    "\t\"should_append\": ?false,",
    "\t\"should_save_on_selection\": ?false,",
    "\t\"create_in_place\": ?false,",
    "\t\"creation_pop_up_type\": ?\"bottomSheet|window\",",
    "\t\"filters\": ?{}",
    "}"
    ]
    },
    "tickerView": {
    "prefix": "vtick",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"ticker\",",
    "\t\"stat\": \"\",",
    "\t\"style\": ?\"text|title|section|subhead|headline|caption\",",
    "\t\"button_location\": ?\"left|right|sideToSide\",",
    "\t\"button_look\": ?\"plusMinus|upDown\",",
    "\t\"should_auto_save\": ?false,",
    "\t\"change_amount\": ?1,",
    "\t\"min_value_allowed\": ?-99999,",
    "\t\"max_value_allowed\": ?99999,",
    "\t\"label\": ?{},",
    "\t\"label_alignment\": ?\"left|right\",",
    "\t\"edit_bottom_sheet_title\": ?{}",
    "},"
    ]
    },
    "chipView": {
    "prefix": "vChip",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"chip\",",
    "\t\"text\": {},",
    "\t\"on_tap_event\": ?{},",
    "\t\"background_color\": ?\"\",",
    "\t\"border_color\": ?\"\",",
    "\t\"style\": ?\"compact|fullSize\",",
    "\t\"resource_id\": ?\"\",",
    "\t\"resource_instance_ids_stat\": ?\"\",",
    "\t\"resource_display_stat\": ?\"\"",
    "},"
    ]
    },
    "buttonView": {
    "prefix": "vbutt",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"button\",",
    "\t\"text\": {},",
    "\t\"event\": ?{},",
    "\t\"event_names\": ?{}",
    "},"
    ]
    },
    "collapsibleView": {
    "prefix": "vCollapsible",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"collapsible\",",
    "\t\"title\": {},",
    "\t\"subtitle\": ?{},",
    "\t\"start_expanded\": ?false,",
    "\t\"subviews\": []",
    "}"
    ]
    },
    "viewPagerView": {
    "prefix": "vviewpager",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"viewPager\",",
    "\t\"names\": {returns list[string]},",
    "\t\"color\": ?{returns string},",
    "\t\"subviews\": []",
    "}"
    ]
    },
    "listItemView": {
    "prefix": "vlistItem",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"listItem\",",
    "\t\"title\": {},",
    "\t\"title_color\": {},",
    "\t\"subtitle\": {},",
    "\t\"subtitle_color\": {},",
    "\t\"first_line_extra\": {},",
    "\t\"first_line_extra_color\": {},",
    "\t\"second_line_extra\": {},",
    "\t\"second_line_extra_color\": {},",
    "\t\"chips\": {}",
    "}"
    ]
    },
    "spacerView": {
    "prefix": "vSpacer",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"spacer\"",
    "},"
    ]
    },
    "dividerView": {
    "prefix": "vDivider",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"type\": \"divider\",",
    "\t\"vertical\": ?false",
    "},"
    ]
    },
    "addToStatEffect": {
    "prefix": "eAddToStat",
    "body": [
    "{",
    "\t\"type\": \"addToStat\",",
    "\t\"stat\": ?\"\",",
    "\t\"meta_stat\": ?{},",
    "\t\"value\": {},",
    "\t\"aggregation_type\": ?\"min|max|sum|set|none\",",
    "\t\"calculated_aggregation_type\": ?{}",
    "}"
    ]
    },
    "setStatEffect": {
    "prefix": "eSetStat",
    "body": [
    "{",
    "\t\"type\": \"setStat\",",
    "\t\"stat\": ?\"\",",
    "\t\"meta_stat\": ?{},",
    "\t\"new_value\": {},",
    "\t\"aggregation_type\": ?\"min|max|sum|set|none\",",
    "\t\"calculated_aggregation_type\": ?{}",
    "}"
    ]
    },
    "whenEffect": {
    "prefix": "eWhen",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"when\",",
    "\t\"clauses\": [",
    "\t\t{",
    "\t\t\t\"condition\": {},",
    "\t\t\t\"effect\": {}",
    "\t\t},",
    "\t\t{",
    "\t\t\t\"condition\": {},",
    "\t\t\t\"effect\": {}",
    "\t\t}",
    "\t]",
    "}"
    ]
    },
    "eWhenClause": {
    "prefix": "ewclause",
    "scope": "json",
    "body": [
    "{",
    "\t\"condition\": {},",
    "\t\"effect\": {}",
    "},"
    ]
    },
    "delayedEffect": {
    "prefix": "eDelayed",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"delayed\",",
    "\t\"millis\": 100,",
    "\t\"effect\": {}",
    "}"
    ]
    },
    "dismissResourceEffect": {
    "prefix": "eDismissResource",
    "scope": "json",
    "body": [
    "{",
    "\t\"type\": \"dismissResource\",",
    "\t\"id\": ?{}",
    "}"
    ]
    },
    "fireEventEffect": {
    "prefix": "efire",
    "body": [
    "{",
    "\t\"type\": \"fireEvent\",",
    "\t\"event\": ?{},",
    "\t\"event_names\": ?{return list}",
    "}"
    ]
    },
    "forwardEventEffect": {
    "prefix": "eforward",
    "body": [
    "{",
    "\t\"type\": \"forwardEvent\",",
    "\t\"new_event_names\": ?{return list}",
    "}"
    ]
    },
    "sequenceEffect": {
    "prefix": "eseq",
    "body": [
    "{",
    "\t\"type\": \"sequence\",",
    "\t\"effects\": []",
    "}"
    ]
    },
    "forEachEffect": {
    "prefix": "eforEach",
    "body": [
    "{",
    "\t\"type\": \"forEach\",",
    "\t\"components\": {},",
    "\t\"apply\": {},",
    "\t\"for_each_value_key\": ?\"\"",
    "}"
    ]
    },
    "showResourceEffect": {
    "prefix": "eShowResource",
    "body": [
    "{",
    "\t\"type\": \"showResource\",",
    "\t\"resource\": {}",
    "}"
    ]
    },
    "showMessageEffect": {
    "prefix": "eShowMessage",
    "body": [
    "{",
    "\t\"type\": \"showMessage\",",
    "\t\"message\": {},",
    "\t\"message_type\": ?\"info|error|success\"",
    "}"
    ]
    },
    "showPopUpEffect": {
    "prefix": "eshowPopUp",
    "body": [
    "{",
    "\t\"type\": \"showPopUp\",",
    "\t\"pop_up_view\": {},",
    "\t\"pop_up_type\": \"bottomSheet|alert\",",
    "\t\"dismissible\": ?true|false,",
    "\t\"pop_up_title\": {},",
    "\t\"display_cancel_button\": ?true,",
    "\t\"cancel_text\": ?{},",
    "\t\"display_save_button\": ?false,",
    "\t\"save_text\": ?{},",
    "\t\"should_persist_on_save\": ?false,",
    "\t\"extra_buttons\": ?[{\"text\": {}, \"event\": {}}],",
    "\t\"in_edit_mode\": ?false",
    "}"
    ]
    },
    "rollEffect": {
    "prefix": "eRoll",
    "body": [
    "{",
    "\t\"type\": \"roll\",",
    "\t\"rolls\": {},",
    "\t\"on_result_effect\": ?{}",
    "}"
    ]
    },
    "mechanic": {
    "prefix": "mech",
    "body": [
    "{",
    "\t\"id\": \"\",",
    "\t\"name\": ?\"\",",
    "\t\"description\": ?\"\",",
    "\t\"event_names\": ?\"\",",
    "\t\"calculated_event_names\": ?{returns list},",
    "\t\"revert_event_names\": ?\"\",",
    "\t\"calculated_revert_event_names\": ?{returns list},",
    "\t\"revert_on_remove\": ?{returns bool},",
    "\t\"effects\": {}",
    "}"
    ]
    },
    "searchFilters": {
    "prefix": "searchFilter",
    "body": [
    "{",
    "\t\"name\": \"\",",
    "\t\"stat\": \"\",",
    "\t\"true_name\": ?\"\",",
    "\t\"false_name\": ?\"\",",
    "\t\"options\": ?\"\",",
    "\t\"options_display_stat\": ?\"\"",
    "}"
    ]
    },
    }
  7. You can utilize the Snippets: Configure Snippets option and choose the rpg.json.json.code-snippets option whenever you want to update / enhance these if needed.

The system

You will be mainly working on a single file, called system.rpg.json. Once you create it, you can open it in your text editor and start working. This file is going to represent the System, so following that documentation page will be crucial.

The system file structure

A system is, mainly, the system.rpg.json file. However, you might want to also include pre-made resources with your system, and you might even want to be able to host several different systems in the same place. That is why, you should work with this file structure:

systems
|—system1
| |—system.rpg.json
| |—resources
| |—resource1.rpg.json
| |—resource2.rpg.json
| |—...
|—system2
|—...

As you can see, we will be working inside a "global" systems folder, and then you should follow the file structure for your systems.

Where do I get the resourceX.rpg.json files?

Once you create your system and run it in your copy of the RPG Companion App, you will be able to use the app itself to create your pre-made resources. Once you are done, you should be able to use the share button on the top-left of the resources screen (orange section of the app) to create a gzip file of all the resources you created it. Simply unzip that file and copy-paste the contents into the resources folder for your system, and you're done!

How do I test the system?

If you have enabled "Developer Mode" in the app, you can use the RPG Companion App dev tool to get your system to your app and try it out. Just select the input folder to be your systems folder, click on "Start server" and wait for the system to build, then tap on the "Update systems" button in either the app's home page or the app's settings.

I see pop-ups with problems in my system.

A lot of the information in the pop up will help you diagnose what the issue is. However, if you still need help and are feeling lost, please feel free to contact Vlad (the app developer) if you need any help or run into issues. He's always happy to help. You can reach him at feedback@blastervla.com.

What next?

Once you're done working with your system, you can host it by following the instructions in Hosting a system

Contributing your system

If you’d like to share your system with the community:

  1. Ensure it builds locally and loads in the app (using the Dev Tool).
  2. Follow the folder structure in this guide.
  3. Open a Pull Request to the Open Systems Repository: github.com/blastervla/rpg-companion-app-systems

Your contributions will be shared under CC BY-NC-SA 4.0 so everyone can improve and remix non-commercially.