{ "name": "English", "_id": "pBOyeBDuTeowuDOE", "pages": [ { "sort": 100000, "name": "Getting Started", "type": "text", "category": "mrZHFR2i0MYp7aaY", "_id": "xcR48pakEm49hbc2", "system": {}, "title": { "show": true, "level": 1 }, "image": {}, "text": { "format": 1, "content": "
Thank you for installing Stat Tracker!
This module aims to provide a clean way of keeping track of any data points you want within Foundry, whether that be dice rolls, or other things like how many natural 1s to natural 20s you get.
I was inspired by the dicestats module, however it only allows tracking dice statistics, which is something I found myself needing to work around and struggle against, so I decided to make this module to fill that gap while improving upon the graph rendering.
You've already done the hardest part of set up for this module to work on the basic level, installing it! However if you want a more advanced set up for the module, this Journal is your go-to for information.
This module makes use of multiple key terms which are important for your understanding, the main terms you need to understand are:
@UUID[Compendium.stat-tracker.docs.JournalEntry.pBOyeBDuTeowuDOE.JournalEntryPage.S7Z6mZ0JablJVQJu]{Row}
@UUID[Compendium.stat-tracker.docs.JournalEntry.pBOyeBDuTeowuDOE.JournalEntryPage.ugzCCxQskUSYMZR4]{Table}
and, @UUID[Compendium.stat-tracker.docs.JournalEntry.pBOyeBDuTeowuDOE.JournalEntryPage.e9FYKidbfFnnTspO]{Bucket}
You can find information about what each of those terms mean within the \"Key Concepts\" section of the documentation or by clicking the above links.
If you just want the module to track dice stats, then it's probably already done for you! All you need to do is start playing your game.
The only situation in which you need to do additional configuration for your game is if you are playing a game which doesn't use the standard dice sizes (d4, d6, d8, d10, d12, d20, d100), however you can add any dice size you want by creating a new table named Dice/dX where X is the number of sides the dice should have (e.g. for a 3-sided dice you would make the table name be Dice/d3). By adding a table in this way, it's configuration will be locked for editing and the only way to change it will be to delete the table entirely.
Currently this module does not support system-specific implementations, however in the future I am planning on adding support for systems as desired by users (the dnd5e system will be the first one supported once I can).
All feature requests and bug reports can go the module's GitHub page : https://github.com/Oliver-Akins/Foundry-Stat-Tracker/issues/new/choose
" }, "video": { "controls": true, "volume": 0.5 }, "src": null, "ownership": { "default": -1, "t2sWGWEYSMFrfBu3": 3 }, "flags": {}, "_stats": { "compendiumSource": null, "duplicateSource": null, "exportSource": null, "coreVersion": "13.344", "systemId": "empty-system", "systemVersion": "0.0.0", "createdTime": 1748328891633, "modifiedTime": 1748583825340, "lastModifiedBy": "t2sWGWEYSMFrfBu3" }, "_key": "!journal.pages!pBOyeBDuTeowuDOE.xcR48pakEm49hbc2" }, { "sort": 300000, "name": "Table", "type": "text", "category": "ZPAbuPbVOLWh75hL", "_id": "ugzCCxQskUSYMZR4", "system": {}, "title": { "show": true, "level": 1 }, "image": {}, "text": { "format": 1, "content": "Tables are quite close to being a \"container\" for every piece of data within the module, every @UUID[Compendium.stat-tracker.docs.JournalEntry.pBOyeBDuTeowuDOE.JournalEntryPage.S7Z6mZ0JablJVQJu]{row} within the module must be associated with a particular table. The table is responsible for maintaining all of the @UUID[Compendium.stat-tracker.docs.JournalEntry.pBOyeBDuTeowuDOE.JournalEntryPage.e9FYKidbfFnnTspO]{bucket} and @UUID[Compendium.stat-tracker.docs.JournalEntry.pBOyeBDuTeowuDOE.JournalEntryPage.IXZpEBEJsvOpY3OL]{graph} configurations, controlling what data is allowed to be saved and how to represent that data.
Subtables are a concept used to group multiple tables together in a logical way, taking the Dice/d10 table as an example, the \"table ID\" is the full \"Dice/d10\", while the table name is \"Dice\" and the subtable name is \"d10\". This allows the module to group all of the \"Dice\" tables together in the user interfaces.
Subtables can only go one level deep (e.g. Table/SubTable/SubSubTable is an invalid table ID and the module will reject it)
Subtables within the \"Dice\" table cannot be edited, they are required to use a @UUID[Compendium.stat-tracker.docs.JournalEntry.pBOyeBDuTeowuDOE.JournalEntryPage.e9FYKidbfFnnTspO#range-buckets]{Range Bucket} and the settings are locked. This is because the module makes certain assumptions about the subtables within that space adhering to those requirements and making changes to them causes some issues. If you want to make a table that doesn't conform to those requirements, you can make a new table for your own purposes though!
Rows make up the vast majority of data that the stat tracker stores. Every dice roll, or custom entry, is saved as a single row.
Each row consists of the following data:
The value (e.g. the result of a single dice roll)
A timestamp of when it was added to the database
A privacy mode (one for each of the Foundry-provided roll modes, see @UUID[Compendium.stat-tracker.docs.JournalEntry.pBOyeBDuTeowuDOE.JournalEntryPage.WYaZPgSRDx8L7Zmq#privacy-modes]{Privacy Modes})
An identifier
" }, "video": { "controls": true, "volume": 0.5 }, "src": null, "ownership": { "default": -1, "t2sWGWEYSMFrfBu3": 3 }, "flags": {}, "_stats": { "compendiumSource": null, "duplicateSource": null, "exportSource": null, "coreVersion": "13.344", "systemId": "empty-system", "systemVersion": "0.0.0", "createdTime": 1748329454864, "modifiedTime": 1748497975724, "lastModifiedBy": "t2sWGWEYSMFrfBu3" }, "_key": "!journal.pages!pBOyeBDuTeowuDOE.S7Z6mZ0JablJVQJu" }, { "sort": 400000, "name": "Bucket", "type": "text", "category": "ZPAbuPbVOLWh75hL", "_id": "e9FYKidbfFnnTspO", "system": {}, "title": { "show": true, "level": 1 }, "image": {}, "text": { "format": 1, "content": "This combination of data can end up becoming a lot of data to load when opening Foundry, if you don't think you'll be resetting the data very often, please consider checking out the different @UUID[Compendium.stat-tracker.docs.JournalEntry.pBOyeBDuTeowuDOE.JournalEntryPage.PcdmuLgNM15h0in1]{Database Adapters} and picking one of them that is more suitable for your campaign.
A bucket is the term used to identify a group of allowed values within a @UUID[Compendium.stat-tracker.docs.JournalEntry.pBOyeBDuTeowuDOE.JournalEntryPage.ugzCCxQskUSYMZR4]{table}, each bucket must have a type, and a number of additional settings depending on what type it is.
This is the most simple type of bucket, it allows a string to be added as the row's value. The only additional configuration for this type of bucket is restricting what strings can be added be added.
e.g. you can limit each row to only have a value of \"Critical Success\", or \"Critical Failure\" and if someone tries to add \"Apple Sauce\" into the table, it will reject that row.
This type of bucket is likely the one you will utilize the most, it allows storing any number. It accepts an set of additional options described below, all of which are optional.
Setting | Description |
Minimum | The minimum allowed value |
Maximum | The maximum allowed value, must be greater than Minimum |
Step | Requires Minimum When a step is set it requires each number to be a \"step\" away from the lower one. So if you have a minimum of 2 and a step of 4, the allowed values are: 2, 6, 10, 14, 18, etc. |
The range bucket is what is used by the auto-generated dice tables, these bucket types use the same options as the @UUID[Compendium.stat-tracker.docs.JournalEntry.pBOyeBDuTeowuDOE.JournalEntryPage.e9FYKidbfFnnTspO#number-buckets]{Number Buckets} but the Minimum/Maximum/Step options are required when the type is range.
" }, "video": { "controls": true, "volume": 0.5 }, "src": null, "ownership": { "default": -1, "t2sWGWEYSMFrfBu3": 3 }, "flags": {}, "_stats": { "compendiumSource": null, "duplicateSource": null, "exportSource": null, "coreVersion": "13.344", "systemId": "empty-system", "systemVersion": "0.0.0", "createdTime": 1748329573212, "modifiedTime": 1748499573438, "lastModifiedBy": "t2sWGWEYSMFrfBu3" }, "_key": "!journal.pages!pBOyeBDuTeowuDOE.e9FYKidbfFnnTspO" }, { "sort": 500000, "name": "The Sidebar Tab", "type": "text", "category": "mrZHFR2i0MYp7aaY", "_id": "ZI6rVlgXYnZGZ3MS", "system": {}, "title": { "show": true, "level": 1 }, "image": {}, "text": { "format": 1, "content": "This stat tracker comes with a custom sidebar tab that provides a general overview of the module's state as well as short-cuts for opening and controlling settings of the module.
The primary actions within the sidebar are:
Viewing the data in graphs
Creating a new @UUID[Compendium.stat-tracker.docs.JournalEntry.pBOyeBDuTeowuDOE.JournalEntryPage.ugzCCxQskUSYMZR4]{table} (Gamemasters only)
Managing existing @UUID[Compendium.stat-tracker.docs.JournalEntry.pBOyeBDuTeowuDOE.JournalEntryPage.ugzCCxQskUSYMZR4]{tables} (Gamemasters only)
The module provides a bunch of settings to be able to control how it interacts with Foundry in various ways. Each setting has a description provided in the settings configuration window, but these descriptions will go more in depth than the ones in there. This will not include all settings, just the ones that would be more beneficial to have additional clarification for.
This tells the module to automatically track rolls that are sent to the chat, this includes systems, modules, and other rolls like RollTables. As long as it gets sent to the chat, this will allow that roll to automatically be tracked.
By default, this only tracks the standard dice sizes (d4, d6, d8, d10, d12, d20, d100), however you can add any dice size you want by creating a new table named Dice/dX where X is the number of sides the dice should have (e.g. for a 3-sided dice you would make the table name be Dice/d3). By adding a table in this way, it's configuration will be locked for editing and the only way to change it will be to delete the table entirely.
For most systems you will want to leave this setting enabled, because otherwise there is a chance that no dice rolls will be tracked at all unless the system has specifically implemented an integration with the module.
This setting is primarily targeted at users who would like to integrate stats tracking into macros, as it exposes a globally available stats variable with references to all of the exposed methods and utility helpers of the module. This can sometimes cause conflicts with systems or other modules, so make sure that there isn't already another a global variable named stats before enabling this setting.
Below is an example of how to retrieve the module's API both with and without this setting enabled:
// with it enabled:\nconst statViewer = new stats.Apps.StatsViewer;\nstatViewer.render({ force: true });\n\n// with it disabled\nconst api = game.modules.get(`stat-tracker`)?.api;\nconst statViewer = new api.Apps.StatsViewer;\nstatViewer?.render({ force: true });"
},
"video": {
"controls": true,
"volume": 0.5
},
"src": null,
"ownership": {
"default": 0,
"t2sWGWEYSMFrfBu3": 3
},
"flags": {},
"_stats": {
"compendiumSource": null,
"duplicateSource": null,
"exportSource": null,
"coreVersion": "13.344",
"systemId": "empty-system",
"systemVersion": "0.0.0",
"createdTime": 1748330762378,
"modifiedTime": 1748658920308,
"lastModifiedBy": "t2sWGWEYSMFrfBu3"
},
"_key": "!journal.pages!pBOyeBDuTeowuDOE.UuAWTQtd3QMKOWvU"
},
{
"sort": 900000,
"name": "Utilities",
"type": "text",
"category": "KGdeJUfatQ9v0raI",
"_id": "TQzWrVTEz4oQhLPD",
"system": {},
"title": {
"show": true,
"level": 1
},
"image": {},
"text": {
"format": 1,
"content": "The module provides a multitude of utility functions through it's API for usage however desired. This will go over them and describe their purpose.
This method is intended to take @UUID[Compendium.stat-tracker.docs.JournalEntry.pBOyeBDuTeowuDOE.JournalEntryPage.S7Z6mZ0JablJVQJu]{rows} provided by the database and filter out any that the user would not be able to see normally. This is usually called by the database adapters so there's unlikely to be any reason to use it externally.
Available under <api>.utils.filterPrivateRows.
Available under <api>.utils.validateValue.
Available under <api>.utils.validateBucketConfig.
This is a list of all available database adapters and how they're configured.
This database adapter isn't a full adapter, this is an abstract class that is used by the other database adapters to enforce a consistent method / interface specification. The general interface includes implementation details for storing the table data in a world setting as well as adding/removing any applications that are rendered as part of the module's operations.
Available under <api>.databases.Database.
This database adapter uses Foundry's flag system in order to store the row data in the User document, leveraging Foundry's automatic database update propagation to other clients. The application handling and table storage utilizes the abstract implementations.
Available under <api>.databases.UserFlagDatabase.
This is unimplemented at the moment. But it will be a database that makes long-term campaign storage more viable, at the tradeoff of not being able to filter data as granularly.
This database adapter should not be used in any actual games, it is intended for development only.
Available under <api>.databases.MemoryDatabase.
Right now all graphs are bar graphs and non-configurable. This is coming in a later update.
" }, "video": { "controls": true, "volume": 0.5 }, "src": null, "ownership": { "default": -1, "t2sWGWEYSMFrfBu3": 3 }, "flags": {}, "_stats": { "compendiumSource": null, "duplicateSource": null, "exportSource": null, "coreVersion": "13.344", "systemId": "empty-system", "systemVersion": "0.0.0", "createdTime": 1748393806045, "modifiedTime": 1748499640505, "lastModifiedBy": "t2sWGWEYSMFrfBu3" }, "_key": "!journal.pages!pBOyeBDuTeowuDOE.IXZpEBEJsvOpY3OL" }, { "sort": 1100000, "name": "Table Manager", "type": "text", "category": "mrZHFR2i0MYp7aaY", "_id": "Z31C8BPl4ZXDn3R6", "system": {}, "title": { "show": true, "level": 1 }, "image": {}, "text": { "format": 1, "content": "Documentation Coming Soon
" }, "video": { "controls": true, "volume": 0.5 }, "src": null, "ownership": { "default": -1, "t2sWGWEYSMFrfBu3": 3 }, "flags": {}, "_stats": { "compendiumSource": null, "duplicateSource": null, "exportSource": null, "coreVersion": "13.344", "systemId": "empty-system", "systemVersion": "0.0.0", "createdTime": 1748393919924, "modifiedTime": 1748583846540, "lastModifiedBy": "t2sWGWEYSMFrfBu3" }, "_key": "!journal.pages!pBOyeBDuTeowuDOE.Z31C8BPl4ZXDn3R6" }, { "sort": 850000, "name": "Enums", "type": "text", "category": "KGdeJUfatQ9v0raI", "_id": "WYaZPgSRDx8L7Zmq", "system": {}, "title": { "show": true, "level": 1 }, "image": {}, "text": { "format": 1, "content": "All of these enums are available within <api>.enums, they are read-only and cannot be modified by other plugins.
This enum is used by the module to specify all of the privacy levels that it uses.
The valid values are:
GM - Representing that only gamemasters and assistant gamemasters will be able to see this data entry. This mode is similar to the \"Blind GM Roll\" roll mode.
PRIVATE - Indicating that this is a piece of private data, that only gamemasters, assistant gamemasters, and the user who owns the piece of data will be able to see it.
SELF - Similar to the \"GM\" level, but instead of gamemasters, it's only the user who owns the piece of data that's able to see it.
PUBLIC - Everyone can see it.
This module was designed from the ground up with the desire to be able to be used within macros, because of this it has first-class Macro support through the entire API.
The primary API that you will interact with inside of macros is held within CONFIG.stats, this is the core API which allows interacting with the stored data however the user wants it to be stored, it allows accessing the apps to view stats, manage the tables, and create new tables.
Each of the items within CONFIG.stats has a different purpose, but most of the programmatic interactions for the module are most likely to be interested in the CONFIG.stats.db part of the API, which handles all of the data within the module in your configured preference.
This is the interface which all @UUID[Compendium.stat-tracker.docs.JournalEntry.pBOyeBDuTeowuDOE.JournalEntryPage.PcdmuLgNM15h0in1]{Database Adapters} must conform to in order for the module to function. If they do not conform to this a warning will be thrown and the module will override the provided database with a database adapter which does nothing, so that the existing data will be protected from errors.
The best way to learn about the required database interface is to read the implementation of the interface that all database adapters are required to extend.
" }, "video": { "controls": true, "volume": 0.5 }, "src": null, "ownership": { "default": -1, "t2sWGWEYSMFrfBu3": 3 }, "flags": {}, "_stats": { "compendiumSource": null, "duplicateSource": null, "exportSource": null, "coreVersion": "13.344", "systemId": "empty-system", "systemVersion": "0.0.0", "createdTime": 1748408916163, "modifiedTime": 1748656904440, "lastModifiedBy": "t2sWGWEYSMFrfBu3" }, "_key": "!journal.pages!pBOyeBDuTeowuDOE.PlKHrrb61Uc1sGbN" } ], "folder": null, "categories": [ { "name": "Overview", "sort": 100000, "_id": "mrZHFR2i0MYp7aaY", "flags": {}, "_stats": { "compendiumSource": null, "duplicateSource": null, "exportSource": null, "coreVersion": "13.344", "systemId": "empty-system", "systemVersion": "0.0.0", "createdTime": 1748328842906, "modifiedTime": 1748328842906, "lastModifiedBy": "t2sWGWEYSMFrfBu3" }, "_key": "!journal.categories!pBOyeBDuTeowuDOE.mrZHFR2i0MYp7aaY" }, { "name": "API", "sort": 300000, "_id": "KGdeJUfatQ9v0raI", "flags": {}, "_stats": { "compendiumSource": null, "duplicateSource": null, "exportSource": null, "coreVersion": "13.344", "systemId": "empty-system", "systemVersion": "0.0.0", "createdTime": 1748328851997, "modifiedTime": 1748328851997, "lastModifiedBy": "t2sWGWEYSMFrfBu3" }, "_key": "!journal.categories!pBOyeBDuTeowuDOE.KGdeJUfatQ9v0raI" }, { "name": "Key Concepts", "sort": 200000, "_id": "ZPAbuPbVOLWh75hL", "flags": {}, "_stats": { "compendiumSource": null, "duplicateSource": null, "exportSource": null, "coreVersion": "13.344", "systemId": "empty-system", "systemVersion": "0.0.0", "createdTime": 1748329482648, "modifiedTime": 1748329482648, "lastModifiedBy": "t2sWGWEYSMFrfBu3" }, "_key": "!journal.categories!pBOyeBDuTeowuDOE.ZPAbuPbVOLWh75hL" } ], "sort": 0, "ownership": { "default": 0, "t2sWGWEYSMFrfBu3": 3 }, "flags": { "core": { "locked": false } }, "_stats": { "compendiumSource": null, "duplicateSource": null, "exportSource": null, "coreVersion": "13.344", "systemId": "empty-system", "systemVersion": "0.0.0", "createdTime": 1748328832096, "modifiedTime": 1748393668194, "lastModifiedBy": "t2sWGWEYSMFrfBu3" }, "_key": "!journal!pBOyeBDuTeowuDOE" }