Skip to content

Instantly share code, notes, and snippets.

@marijnvdwerf
Last active April 2, 2025 11:37
Show Gist options
  • Save marijnvdwerf/b506b0d6c942b51b6c2c2d0055af5067 to your computer and use it in GitHub Desktop.
Save marijnvdwerf/b506b0d6c942b51b6c2c2d0055af5067 to your computer and use it in GitHub Desktop.
Emotracker schemas

Add the following code to .vscode/settings.json:

{
  "files.associations": {
    "*.json": "jsonc"
  },
  "json.schemas": [
    {
      "fileMatch": ["manifest.json"],
      "url": "https://gist.githubusercontent.com/marijnvdwerf/b506b0d6c942b51b6c2c2d0055af5067/raw/manifest.json"
    },
    {
      "fileMatch": ["maps.json"],
      "url": "https://gist.githubusercontent.com/marijnvdwerf/b506b0d6c942b51b6c2c2d0055af5067/raw/maps.json"
    },
    {
      "fileMatch": ["items/*.json"],
      "url": "https://gist.githubusercontent.com/marijnvdwerf/b506b0d6c942b51b6c2c2d0055af5067/raw/items.json"
    },
    {
      "fileMatch": ["locations.json"],
      "url": "https://gist.githubusercontent.com/marijnvdwerf/b506b0d6c942b51b6c2c2d0055af5067/raw/locations.json"
    },
    {
      "fileMatch": ["settings.json"],
      "url": "https://gist.githubusercontent.com/marijnvdwerf/b506b0d6c942b51b6c2c2d0055af5067/raw/settings.json"
    },
    {
      "fileMatch": ["layouts/*.json"],
      "url": "https://gist.githubusercontent.com/marijnvdwerf/b506b0d6c942b51b6c2c2d0055af5067/raw/layout.json"
    }
  ]
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "EmoTracker Items Definition Schema",
"description": "Defines the trackable items used by the package.",
"type": "array",
"items": {
"$ref": "#/definitions/item"
},
"definitions": {
"item": {
"description": "Represents any trackable item.",
"oneOf": [
{ "$ref": "#/definitions/toggleItem" },
{ "$ref": "#/definitions/progressiveItem" },
{ "$ref": "#/definitions/consumableItem" },
{ "$ref": "#/definitions/staticItem" },
{ "$ref": "#/definitions/progressiveToggleItem" },
{ "$ref": "#/definitions/toggleBadgedItem" },
{ "$ref": "#/definitions/compositeToggleItem" },
{ "$ref": "#/definitions/sectionChestsProxyItem" },
{ "$ref": "#/definitions/blankItem" }
// LuaItem cannot be defined via JSON
]
},
"itemBaseSchema": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "The type identifier for the item."
},
"name": {
"type": "string",
"description": "Optional unique name/identifier for this specific item instance."
},
"capturable": {
"type": "boolean",
"description": "Can this item be captured in notes/sections?",
"default": true
},
"mask_input": {
"type": "boolean",
"description": "Should this item obscure input to items behind it?",
"default": false
},
"ignore_user_input": {
"type": "boolean",
"description": "Should user clicks on this item be ignored?",
"default": false
},
"disabled_image_filter": {
"type": "string",
"description": "Item-specific override for the disabled image filter."
},
"disabled_img_mods": { // Legacy/Alternative name
"type": "string",
"description": "Item-specific override for the disabled image filter."
}
},
"required": ["type"]
},
"toggleItem": {
"description": "An item that can be toggled on or off.",
"allOf": [
{ "$ref": "#/definitions/itemBaseSchema" },
{
"properties": {
"type": { "const": "toggle" },
"img": { "type": "string", "description": "Image path when active." },
"img_mods": { "type": "string", "description": "Image filter when active." },
"disabled_img": { "type": "string", "description": "Optional image path when inactive. Defaults to filtered active image." },
"disabled_img_spec": { "type": "string", "description": "Legacy filter name" },
"initial_active_state": { "type": "boolean", "default": false },
"codes": { "type": "string", "description": "Comma-separated list of codes provided when active." },
"consume": { "type": "string", "description": "Code of a consumable item to decrement/increment when toggled." },
"loop": { "type": "boolean", "description": "If true, left/right click both toggle. If false, left=on, right=off.", "default": false }
}
// img is implicitly required if not purely logical
}
]
},
"progressiveStage": {
"type": "object",
"properties": {
"img": { "type": "string", "description": "Image path for this stage." },
"img_mods": { "type": "string", "description": "Image filter for this stage." },
"inherit_codes": { "type": "boolean", "description": "If false, resets code inheritance from previous stages.", "default": true },
"codes": { "type": "string", "description": "Comma-separated codes provided *by* this stage (added to inherited codes)." }
},
"required": ["img"]
},
"progressiveItem": {
"description": "An item that progresses through multiple stages.",
"allOf": [
{ "$ref": "#/definitions/itemBaseSchema" },
{
"properties": {
"type": { "const": "progressive" },
"loop": { "type": "boolean", "description": "If true, loops from last stage back to first.", "default": false },
"allow_disabled": { "type": "boolean", "description": "If true, adds an initial 'disabled' stage automatically.", "default": true },
"stages": {
"type": "array",
"items": { "$ref": "#/definitions/progressiveStage" }
},
"initial_stage_idx": { "type": "integer", "description": "Zero-based index of the starting stage.", "default": -1 }
},
"required": ["stages"]
}
]
},
"consumableItem": {
"description": "An item with a quantity that can be acquired and consumed.",
"allOf": [
{ "$ref": "#/definitions/itemBaseSchema" },
{
"properties": {
"type": { "const": "consumable" },
"codes": { "type": "string", "description": "Comma-separated codes provided when available count > 0." },
"img": { "type": "string", "description": "Image path when count > 0 or acquired > 0." },
"img_mods": { "type": "string" },
"disabled_img": { "type": "string", "description": "Image path when never acquired (acquired_count = 0)." },
"max_quantity": { "type": "integer", "default": 2147483647 },
"min_quantity": { "type": "integer", "default": 0 },
"initial_quantity": { "type": "integer", "default": 0 },
"increment": { "type": "integer", "default": 1 },
"swap_actions": { "type": "boolean", "description": "If true, right-click increments, left-click decrements.", "default": false },
"display_as_fraction_of_max": { "type": "boolean", "description": "Show badge as 'X/Max' instead of just 'X'.", "default": false }
}
}
]
},
"staticItem": {
"description": "A non-interactive item, often used as a logical provider or display element.",
"allOf": [
{ "$ref": "#/definitions/itemBaseSchema" },
{
"properties": {
"type": { "const": "static" },
"img": { "type": "string" },
"img_mods": { "type": "string" },
"codes": { "type": "string", "description": "Codes always provided by this item." },
"capturable": {"type": "boolean", "default": false } // Overrides base default
}
}
]
},
"progressiveToggleStage": {
"type": "object",
"properties": {
"img": { "type": "string", "description": "Image when active at this stage." },
"img_mods": { "type": "string" },
"disabled_img": { "type": "string", "description": "Image when inactive at this stage." },
"disabled_img_mods": { "type": "string" },
"codes": { "type": "string", "description": "Codes provided when active at this stage." },
"secondary_codes": { "type": "string", "description": "Codes checked for AdvanceToPrivateCode." }
},
"required": ["img"]
},
"progressiveToggleItem": {
"description": "Combines progressive stages with an active/inactive toggle.",
"allOf": [
{ "$ref": "#/definitions/itemBaseSchema" },
{
"properties": {
"type": { "const": "progressive_toggle" },
"swap_actions": { "type": "boolean", "description": "If true, left toggles, right advances stage.", "default": false },
"stages": {
"type": "array",
"items": { "$ref": "#/definitions/progressiveToggleStage"}
},
"initial_stage_idx": { "type": "integer", "default": 0 },
"initial_active_state": { "type": "boolean", "default": false }
},
"required": ["stages"]
}
]
},
"toggleBadgedItem": {
"description": "Adds an active/inactive badge toggle to another base item.",
"allOf": [
{ "$ref": "#/definitions/itemBaseSchema" },
{
"properties": {
"type": { "const": "toggle_badged" },
"base_item": { "type": "string", "description": "Code of the item this badge is attached to." },
"disabled_img": { "type": "string", "description": "Badge image when inactive." },
"disabled_img_spec": { "type": "string" },
"img": { "type": "string", "description": "Badge image when active." },
"img_mods": { "type": "string" },
"initial_active_state": { "type": "boolean", "default": false },
"codes": { "type": "string", "description": "Codes provided when this badge is active." }
},
"required": ["img"] // Active image seems required
}
]
},
"compositeImageCondition": {
"type": "object",
"properties": {
"img": { "type": "string" },
"img_mods": { "type": "string" },
"left": { "type": "boolean", "description": "Condition for item_left's state.", "default": false },
"right": { "type": "boolean", "description": "Condition for item_right's state.", "default": false }
},
"required": ["img"]
},
"compositeToggleItem": {
"description": "Displays a different image based on the active state of two other ToggleItems.",
"allOf": [
{ "$ref": "#/definitions/itemBaseSchema" },
{
"properties": {
"type": { "const": "composite_toggle" },
"codes": { "type": "string", "description": "Codes always provided by this item." },
"item_left": { "type": "string", "description": "Code of the first ToggleItem to monitor." },
"item_right": { "type": "string", "description": "Code of the second ToggleItem to monitor." },
"images": {
"type": "array",
"items": { "$ref": "#/definitions/compositeImageCondition" }
}
},
"required": ["item_left", "item_right", "images"]
}
]
},
"sectionChestsProxyItem": {
"description": "Displays the chest count and icon for a specific location section.",
"allOf": [
{ "$ref": "#/definitions/itemBaseSchema" },
{
"properties": {
"type": { "const": "sectionchests" },
"codes": { "type": "string", "description": "Optional codes provided by this proxy (usually not needed)." },
"section": { "type": "string", "description": "Code of the location section (e.g., 'LocationName/SectionName')." }
},
"required": ["section"]
}
]
},
"blankItem": {
"description": "An empty, non-interactive item, used for layout spacing.",
"allOf": [
{ "$ref": "#/definitions/itemBaseSchema" },
{
"properties": {
"type": { "const": "blank" },
"capturable": { "type": "boolean", "default": false } // Overrides base
}
}
]
}
}
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "EmoTracker Layout Schema",
"description": "Describes the structure of EmoTracker layout files (e.g., layouts/some_layout.json, tracker_layout.json's 'layouts' object)",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9_\\-]+$": {
"$ref": "#/definitions/layoutItem",
"description": "A named layout definition, keyed by its unique name/identifier."
}
},
"additionalProperties": false,
"definitions": {
"layoutItem": {
"description": "Represents any valid layout item.",
"oneOf": [
{ "$ref": "#/definitions/arrayPanel" },
{ "$ref": "#/definitions/buttonPopup" },
{ "$ref": "#/definitions/canvasPanel" },
{ "$ref": "#/definitions/container" }, // Also handles "grid" type
{ "$ref": "#/definitions/dockPanel" },
{ "$ref": "#/definitions/groupBox" },
{ "$ref": "#/definitions/image" },
{ "$ref": "#/definitions/item" },
{ "$ref": "#/definitions/itemGrid" },
{ "$ref": "#/definitions/lastClearedLocation" },
{ "$ref": "#/definitions/layoutReference" },
{ "$ref": "#/definitions/mapPanel" },
{ "$ref": "#/definitions/recentPinnedLocations" },
{ "$ref": "#/definitions/scrollPanel" },
{ "$ref": "#/definitions/tabPanel" },
{ "$ref": "#/definitions/textBlock" },
{ "$ref": "#/definitions/viewBox" }
]
},
"layoutItemBase": {
"description": "Base properties common to all layout items.",
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "The type identifier for the layout item."
},
"uid": {
"type": "string",
"description": "Optional unique identifier for referencing this item."
},
"background": {
"type": "string",
"description": "Background color (hex or name)."
},
"foreground": {
"type": "string",
"description": "Foreground color (hex or name)."
},
"dock": {
"type": "string",
"description": "Docking position within a DockPanel (e.g., 'left', 'right', 'top', 'bottom', 'fill')."
},
"margin": {
"type": "string",
"description": "Margin around the item. Single value or 'left,top,right,bottom'.",
"default": "0",
"pattern": "^\\d+(\\.\\d+)?(,\\s*\\d+(\\.\\d+)?){0,3}$"
},
"h_alignment": {
"type": "string",
"enum": ["Left", "Center", "Right", "Stretch"],
"default": "Stretch"
},
"v_alignment": {
"type": "string",
"enum": ["Top", "Center", "Bottom", "Stretch"],
"default": "Stretch"
},
"scale": {
"type": "number",
"description": "Scaling factor.",
"default": -1.0
},
"width": {
"type": "number",
"description": "Explicit width.",
"default": -1.0
},
"height": {
"type": "number",
"description": "Explicit height.",
"default": -1.0
},
"min_width": {
"type": "number",
"description": "Minimum width.",
"default": -1.0
},
"min_height": {
"type": "number",
"description": "Minimum height.",
"default": -1.0
},
"max_width": {
"type": "number",
"description": "Maximum width.",
"default": -1.0
},
"max_height": {
"type": "number",
"description": "Maximum height.",
"default": -1.0
},
"canvas_left": {
"type": "number",
"description": "Left position within a CanvasPanel.",
"default": -1.0
},
"canvas_top": {
"type": "number",
"description": "Top position within a CanvasPanel.",
"default": -1.0
},
"canvas_depth": {
"type": "number",
"description": "Z-index within a CanvasPanel.",
"default": -1.0
},
"dropshadow": {
"type": "boolean",
"description": "Enable drop shadow.",
"default": false
},
"broadcast_shadow": {
"type": "boolean",
"description": "Enable drop shadow for broadcast.",
"default": false
},
"hit_test_visible": {
"type": "boolean",
"description": "Is the item interactive.",
"default": true
}
},
"required": ["type"]
},
"itemGrid": {
"description": "Displays a grid of trackable items.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "itemgrid" },
"item_margin": {
"type": "string",
"description": "Margin around individual items within the grid.",
"default": "5",
"pattern": "^\\d+(\\.\\d+)?(,\\s*\\d+(\\.\\d+)?){0,3}$"
},
"item_size": {
"type": "number",
"description": "Default size (width and height) for items.",
"default": 32.0
},
"item_width": {
"type": "number",
"description": "Overrides item_size for width."
},
"item_height": {
"type": "number",
"description": "Overrides item_size for height."
},
"badge_font_size": {
"type": "number",
"description": "Font size for item badges.",
"default": 12.0
},
"rows": {
"type": "array",
"description": "Array of rows, where each row is an array of item codes (strings).",
"items": {
"type": "array",
"items": { "type": "string" }
}
},
"margin": { // Legacy property
"type": "string",
"description": "Legacy margin property used only if LayoutEngineVersion < 1.0. Controls item spacing.",
"default": "5",
"pattern": "^\\d+(\\.\\d+)?(,\\s*\\d+(\\.\\d+)?){0,3}$"
}
},
"required": ["rows"]
}
]
},
"container": {
"description": "A basic container that holds other layout items. Used for 'container' and 'grid' types.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "enum": ["container", "grid"] },
"content": {
"description": "The child layout item(s). Can be a single item or an array.",
"oneOf": [
{ "$ref": "#/definitions/layoutItem" },
{
"type": "array",
"items": { "$ref": "#/definitions/layoutItem" }
}
]
}
}
}
]
},
"arrayPanel": {
"description": "Arranges child items vertically or horizontally, potentially wrapping.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "array" },
"orientation": {
"type": "string",
"enum": ["Vertical", "Horizontal"],
"default": "Vertical"
},
"style": {
"type": "string",
"enum": ["Stack", "Wrap"],
"default": "Stack"
},
"content": {
"type": "array",
"description": "List of child layout items.",
"items": { "$ref": "#/definitions/layoutItem" }
}
}
}
]
},
"buttonPopup": {
"description": "A button that displays a layout in a popup when clicked.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "button_popup" },
"style": {
"type": "string",
"enum": ["Settings", "Solid", "Image"],
"default": "Settings"
},
"image": {
"type": "string",
"description": "Path to the image for 'Image' style button."
},
"image_filter": {
"type": "string",
"description": "Filter spec (img_mods) for the image."
},
"layout": {
"type": "string",
"description": "The key/name of the layout to show in the popup."
},
"popup_background": {
"type": "string",
"description": "Background color of the popup.",
"default": "#FF212121"
},
"mask_input": {
"type": "boolean",
"description": "Whether the popup masks input to elements behind it.",
"default": false
}
},
"required": ["layout"]
}
]
},
"canvasPanel": {
"description": "Positions child items using explicit canvas_left/canvas_top coordinates.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "canvas" },
"content": {
"type": "array",
"description": "List of child layout items.",
"items": { "$ref": "#/definitions/layoutItem" }
}
}
}
]
},
"dockPanel": {
"description": "Arranges child items based on their 'dock' property.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "dock" },
"content": {
"type": "array",
"description": "List of child layout items.",
"items": { "$ref": "#/definitions/layoutItem" }
}
}
}
]
},
"groupBox": {
"description": "A container with an optional header.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "group" },
"header": {
"type": "string",
"description": "Text for the group header."
},
"header_background": {
"type": "string",
"description": "Background color for the header.",
"default": "#212121"
},
"header_content": {
"$ref": "#/definitions/layoutItem",
"description": "Layout item to use as the header content instead of text."
},
"content": { // From Container base
"description": "The child layout item(s) inside the group box.",
"oneOf": [
{ "$ref": "#/definitions/layoutItem" },
{
"type": "array",
"items": { "$ref": "#/definitions/layoutItem" }
}
]
},
"background": { // Override default from base
"type": "string",
"default": "#66212121"
}
}
}
]
},
"image": {
"description": "Displays a static image.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "image" },
"image": {
"type": "string",
"description": "Path to the image file relative to the pack."
},
"image_filter": {
"type": "string",
"description": "Optional filter specification (img_mods)."
}
},
"required": ["image"]
}
]
},
"item": {
"description": "Displays a single trackable item.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "item" },
"item": {
"type": "string",
"description": "The code of the trackable item to display."
}
},
"required": ["item"]
}
]
},
"lastClearedLocation": {
"description": "Displays the last location that was cleared.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "last_cleared_location" },
"compact": {
"type": "boolean",
"description": "Use compact display format.",
"default": true
}
}
}
]
},
"layoutReference": {
"description": "Embeds another named layout.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "layout" },
"key": {
"type": "string",
"description": "The name/key of the layout to embed."
}
},
"required": ["key"]
}
]
},
"mapPanel": {
"description": "Displays the game map(s) with location markers.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "map" },
"orientation": {
"type": "string",
"enum": ["Auto", "Horizontal", "Vertical"],
"default": "Auto"
},
"maps": {
"type": "array",
"description": "Optional list of specific map names (from maps.json) to display. Defaults to all.",
"items": { "type": "string" }
}
}
}
]
},
"recentPinnedLocations": {
"description": "Displays a list of recently pinned locations.",
"allOf": [
// Inherits ArrayPanel structure implicitly via C# inheritance
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "enum": ["recentpins", "recent_pins"] },
"orientation": { // From ArrayPanel base
"type": "string",
"enum": ["Vertical", "Horizontal"],
"default": "Vertical"
},
"style": { // From ArrayPanel base
"type": "string",
"enum": ["Stack", "Wrap"],
"default": "Stack"
},
"compact": {
"type": "boolean",
"description": "Use compact display format for locations.",
"default": true
},
"num_items": {
"type": "integer",
"description": "Maximum number of locations to show (0 for all).",
"default": 0,
"minimum": 0
}
// Does not explicitly define 'content', inherits from ArrayPanel base implicitly
}
}
]
},
"scrollPanel": {
"description": "A container that provides scrolling for its content.",
"allOf": [
// Inherits Container structure implicitly via C# inheritance
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "scroll" },
"horizontal_scrollbar_visibility": {
"type": "string",
"enum": ["Disabled", "Auto", "Hidden", "Visible"],
"default": "Auto"
},
"vertical_scrollbar_visibility": {
"type": "string",
"enum": ["Disabled", "Auto", "Hidden", "Visible"],
"default": "Auto"
},
"content": { // From Container base
"description": "The child layout item(s) inside the scroll panel.",
"oneOf": [
{ "$ref": "#/definitions/layoutItem" },
{
"type": "array",
"items": { "$ref": "#/definitions/layoutItem" }
}
]
}
}
}
]
},
"tabPanel": {
"description": "Displays content within selectable tabs.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "tabbed" },
"tabs": {
"type": "array",
"description": "List of tabs to display.",
"items": {
"type": "object",
"properties": {
"title": { "type": "string", "description": "Text displayed on the tab." },
"icon": { "type": "string", "description": "Path to icon image for the tab."},
"icon_image_spec": { "type": "string", "description": "Filter spec (img_mods) for icon." },
"content": { "$ref": "#/definitions/layoutItem", "description": "The layout item displayed when this tab is active." }
},
"required": ["content"] // Title or icon is usually needed too
}
}
},
"required": ["tabs"]
}
]
},
"textBlock": {
"description": "Displays a block of text.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "text" },
"text": {
"type": "string",
"description": "The text content to display."
}
},
"required": ["text"]
}
]
},
"viewBox": {
"description": "Scales its single child item to fit available space.",
"allOf": [
// Inherits Container structure implicitly via C# inheritance
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "viewbox" },
"content": { // From Container base
"description": "The single child layout item to scale.",
"oneOf": [
{ "$ref": "#/definitions/layoutItem" },
{ // Allow array, but typically only one item is useful
"type": "array",
"items": { "$ref": "#/definitions/layoutItem" },
"maxItems": 1
}
]
}
}
}
]
}
}
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "EmoTracker Layout Schema",
"description": "Describes the structure of EmoTracker layout files (e.g., layouts/some_layout.json, tracker_layout.json's 'layouts' object)",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9_\\-]+$": {
"$ref": "#/definitions/layoutItem",
"description": "A named layout definition, keyed by its unique name/identifier."
}
},
"additionalProperties": false,
"definitions": {
"layoutItem": {
"description": "Represents any valid layout item.",
"oneOf": [
{ "$ref": "#/definitions/arrayPanel" },
{ "$ref": "#/definitions/buttonPopup" },
{ "$ref": "#/definitions/canvasPanel" },
{ "$ref": "#/definitions/container" }, // Also handles "grid" type
{ "$ref": "#/definitions/dockPanel" },
{ "$ref": "#/definitions/groupBox" },
{ "$ref": "#/definitions/image" },
{ "$ref": "#/definitions/item" },
{ "$ref": "#/definitions/itemGrid" },
{ "$ref": "#/definitions/lastClearedLocation" },
{ "$ref": "#/definitions/layoutReference" },
{ "$ref": "#/definitions/mapPanel" },
{ "$ref": "#/definitions/recentPinnedLocations" },
{ "$ref": "#/definitions/scrollPanel" },
{ "$ref": "#/definitions/tabPanel" },
{ "$ref": "#/definitions/textBlock" },
{ "$ref": "#/definitions/viewBox" }
]
},
"layoutItemBase": {
"description": "Base properties common to all layout items.",
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "The type identifier for the layout item."
},
"uid": {
"type": "string",
"description": "Optional unique identifier for referencing this item."
},
"background": {
"type": "string",
"description": "Background color (hex or name)."
},
"foreground": {
"type": "string",
"description": "Foreground color (hex or name)."
},
"dock": {
"type": "string",
"description": "Docking position within a DockPanel (e.g., 'left', 'right', 'top', 'bottom', 'fill')."
},
"margin": {
"type": "string",
"description": "Margin around the item. Single value or 'left,top,right,bottom'.",
"default": "0",
"pattern": "^\\d+(\\.\\d+)?(,\\s*\\d+(\\.\\d+)?){0,3}$"
},
"h_alignment": {
"type": "string",
"enum": ["Left", "Center", "Right", "Stretch"],
"default": "Stretch"
},
"v_alignment": {
"type": "string",
"enum": ["Top", "Center", "Bottom", "Stretch"],
"default": "Stretch"
},
"scale": {
"type": "number",
"description": "Scaling factor.",
"default": -1.0
},
"width": {
"type": "number",
"description": "Explicit width.",
"default": -1.0
},
"height": {
"type": "number",
"description": "Explicit height.",
"default": -1.0
},
"min_width": {
"type": "number",
"description": "Minimum width.",
"default": -1.0
},
"min_height": {
"type": "number",
"description": "Minimum height.",
"default": -1.0
},
"max_width": {
"type": "number",
"description": "Maximum width.",
"default": -1.0
},
"max_height": {
"type": "number",
"description": "Maximum height.",
"default": -1.0
},
"canvas_left": {
"type": "number",
"description": "Left position within a CanvasPanel.",
"default": -1.0
},
"canvas_top": {
"type": "number",
"description": "Top position within a CanvasPanel.",
"default": -1.0
},
"canvas_depth": {
"type": "number",
"description": "Z-index within a CanvasPanel.",
"default": -1.0
},
"dropshadow": {
"type": "boolean",
"description": "Enable drop shadow.",
"default": false
},
"broadcast_shadow": {
"type": "boolean",
"description": "Enable drop shadow for broadcast.",
"default": false
},
"hit_test_visible": {
"type": "boolean",
"description": "Is the item interactive.",
"default": true
}
},
"required": ["type"]
},
"itemGrid": {
"description": "Displays a grid of trackable items.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "itemgrid" },
"item_margin": {
"type": "string",
"description": "Margin around individual items within the grid.",
"default": "5",
"pattern": "^\\d+(\\.\\d+)?(,\\s*\\d+(\\.\\d+)?){0,3}$"
},
"item_size": {
"type": "number",
"description": "Default size (width and height) for items.",
"default": 32.0
},
"item_width": {
"type": "number",
"description": "Overrides item_size for width."
},
"item_height": {
"type": "number",
"description": "Overrides item_size for height."
},
"badge_font_size": {
"type": "number",
"description": "Font size for item badges.",
"default": 12.0
},
"rows": {
"type": "array",
"description": "Array of rows, where each row is an array of item codes (strings).",
"items": {
"type": "array",
"items": { "type": "string" }
}
},
"margin": { // Legacy property
"type": "string",
"description": "Legacy margin property used only if LayoutEngineVersion < 1.0. Controls item spacing.",
"default": "5",
"pattern": "^\\d+(\\.\\d+)?(,\\s*\\d+(\\.\\d+)?){0,3}$"
}
},
"required": ["rows"]
}
]
},
"container": {
"description": "A basic container that holds other layout items. Used for 'container' and 'grid' types.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "enum": ["container", "grid"] },
"content": {
"description": "The child layout item(s). Can be a single item or an array.",
"oneOf": [
{ "$ref": "#/definitions/layoutItem" },
{
"type": "array",
"items": { "$ref": "#/definitions/layoutItem" }
}
]
}
}
}
]
},
"arrayPanel": {
"description": "Arranges child items vertically or horizontally, potentially wrapping.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "array" },
"orientation": {
"type": "string",
"enum": ["Vertical", "Horizontal"],
"default": "Vertical"
},
"style": {
"type": "string",
"enum": ["Stack", "Wrap"],
"default": "Stack"
},
"content": {
"type": "array",
"description": "List of child layout items.",
"items": { "$ref": "#/definitions/layoutItem" }
}
}
}
]
},
"buttonPopup": {
"description": "A button that displays a layout in a popup when clicked.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "button_popup" },
"style": {
"type": "string",
"enum": ["Settings", "Solid", "Image"],
"default": "Settings"
},
"image": {
"type": "string",
"description": "Path to the image for 'Image' style button."
},
"image_filter": {
"type": "string",
"description": "Filter spec (img_mods) for the image."
},
"layout": {
"type": "string",
"description": "The key/name of the layout to show in the popup."
},
"popup_background": {
"type": "string",
"description": "Background color of the popup.",
"default": "#FF212121"
},
"mask_input": {
"type": "boolean",
"description": "Whether the popup masks input to elements behind it.",
"default": false
}
},
"required": ["layout"]
}
]
},
"canvasPanel": {
"description": "Positions child items using explicit canvas_left/canvas_top coordinates.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "canvas" },
"content": {
"type": "array",
"description": "List of child layout items.",
"items": { "$ref": "#/definitions/layoutItem" }
}
}
}
]
},
"dockPanel": {
"description": "Arranges child items based on their 'dock' property.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "dock" },
"content": {
"type": "array",
"description": "List of child layout items.",
"items": { "$ref": "#/definitions/layoutItem" }
}
}
}
]
},
"groupBox": {
"description": "A container with an optional header.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "group" },
"header": {
"type": "string",
"description": "Text for the group header."
},
"header_background": {
"type": "string",
"description": "Background color for the header.",
"default": "#212121"
},
"header_content": {
"$ref": "#/definitions/layoutItem",
"description": "Layout item to use as the header content instead of text."
},
"content": { // From Container base
"description": "The child layout item(s) inside the group box.",
"oneOf": [
{ "$ref": "#/definitions/layoutItem" },
{
"type": "array",
"items": { "$ref": "#/definitions/layoutItem" }
}
]
},
"background": { // Override default from base
"type": "string",
"default": "#66212121"
}
}
}
]
},
"image": {
"description": "Displays a static image.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "image" },
"image": {
"type": "string",
"description": "Path to the image file relative to the pack."
},
"image_filter": {
"type": "string",
"description": "Optional filter specification (img_mods)."
}
},
"required": ["image"]
}
]
},
"item": {
"description": "Displays a single trackable item.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "item" },
"item": {
"type": "string",
"description": "The code of the trackable item to display."
}
},
"required": ["item"]
}
]
},
"lastClearedLocation": {
"description": "Displays the last location that was cleared.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "last_cleared_location" },
"compact": {
"type": "boolean",
"description": "Use compact display format.",
"default": true
}
}
}
]
},
"layoutReference": {
"description": "Embeds another named layout.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "layout" },
"key": {
"type": "string",
"description": "The name/key of the layout to embed."
}
},
"required": ["key"]
}
]
},
"mapPanel": {
"description": "Displays the game map(s) with location markers.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "map" },
"orientation": {
"type": "string",
"enum": ["Auto", "Horizontal", "Vertical"],
"default": "Auto"
},
"maps": {
"type": "array",
"description": "Optional list of specific map names (from maps.json) to display. Defaults to all.",
"items": { "type": "string" }
}
}
}
]
},
"recentPinnedLocations": {
"description": "Displays a list of recently pinned locations.",
"allOf": [
// Inherits ArrayPanel structure implicitly via C# inheritance
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "enum": ["recentpins", "recent_pins"] },
"orientation": { // From ArrayPanel base
"type": "string",
"enum": ["Vertical", "Horizontal"],
"default": "Vertical"
},
"style": { // From ArrayPanel base
"type": "string",
"enum": ["Stack", "Wrap"],
"default": "Stack"
},
"compact": {
"type": "boolean",
"description": "Use compact display format for locations.",
"default": true
},
"num_items": {
"type": "integer",
"description": "Maximum number of locations to show (0 for all).",
"default": 0,
"minimum": 0
}
// Does not explicitly define 'content', inherits from ArrayPanel base implicitly
}
}
]
},
"scrollPanel": {
"description": "A container that provides scrolling for its content.",
"allOf": [
// Inherits Container structure implicitly via C# inheritance
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "scroll" },
"horizontal_scrollbar_visibility": {
"type": "string",
"enum": ["Disabled", "Auto", "Hidden", "Visible"],
"default": "Auto"
},
"vertical_scrollbar_visibility": {
"type": "string",
"enum": ["Disabled", "Auto", "Hidden", "Visible"],
"default": "Auto"
},
"content": { // From Container base
"description": "The child layout item(s) inside the scroll panel.",
"oneOf": [
{ "$ref": "#/definitions/layoutItem" },
{
"type": "array",
"items": { "$ref": "#/definitions/layoutItem" }
}
]
}
}
}
]
},
"tabPanel": {
"description": "Displays content within selectable tabs.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "tabbed" },
"tabs": {
"type": "array",
"description": "List of tabs to display.",
"items": {
"type": "object",
"properties": {
"title": { "type": "string", "description": "Text displayed on the tab." },
"icon": { "type": "string", "description": "Path to icon image for the tab."},
"icon_image_spec": { "type": "string", "description": "Filter spec (img_mods) for icon." },
"content": { "$ref": "#/definitions/layoutItem", "description": "The layout item displayed when this tab is active." }
},
"required": ["content"] // Title or icon is usually needed too
}
}
},
"required": ["tabs"]
}
]
},
"textBlock": {
"description": "Displays a block of text.",
"allOf": [
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "text" },
"text": {
"type": "string",
"description": "The text content to display."
}
},
"required": ["text"]
}
]
},
"viewBox": {
"description": "Scales its single child item to fit available space.",
"allOf": [
// Inherits Container structure implicitly via C# inheritance
{ "$ref": "#/definitions/layoutItemBase" },
{
"properties": {
"type": { "const": "viewbox" },
"content": { // From Container base
"description": "The single child layout item to scale.",
"oneOf": [
{ "$ref": "#/definitions/layoutItem" },
{ // Allow array, but typically only one item is useful
"type": "array",
"items": { "$ref": "#/definitions/layoutItem" },
"maxItems": 1
}
]
}
}
}
]
}
}
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "EmoTracker Package Manifest Schema",
"description": "Defines the core metadata for an EmoTracker package.",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The display name of the package."
},
"uid": {
"type": "string",
"description": "The unique identifier for this package (required)."
},
"package_uid": {
"type": "string",
"description": "Legacy unique identifier field (use 'uid' instead)."
},
"version": {
"type": "string",
"description": "The version of this package (e.g., '1.2.3'). Required.",
"pattern": "^\\d+\\.\\d+(\\.\\d+)?(\\.\\d+)?$"
},
"package_version": {
"type": "string",
"description": "Legacy version field (use 'version' instead).",
"pattern": "^\\d+\\.\\d+(\\.\\d+)?(\\.\\d+)?$"
},
"layout_engine_version": {
"type": "string",
"description": "The minimum EmoTracker Layout Engine version required (e.g., '1.0.0').",
"pattern": "^\\d+\\.\\d+(\\.\\d+)?(\\.\\d+)?$"
},
"platform": {
"type": "string",
"description": "The target game platform.",
"enum": [
"Unknown", "NES", "SNES", "N64", "Gameboy", "GBA", "Gamecube", "Genesis"
],
"default": "Unknown"
},
"game_name": {
"type": "string",
"description": "The name of the game this package is for."
},
"game_variant": {
"type": "string",
"description": "Specific variant or mod name (e.g., 'Randomizer', 'Open World')."
},
"author": {
"type": "string",
"description": "The author(s) of the package."
},
"enable_unsafe_scripting": {
"type": "boolean",
"description": "Allows the package to use potentially unsafe Lua functions (like file I/O). Requires user opt-in.",
"default": false
},
"variants": {
"type": "object",
"description": "Defines different variations within this package.",
"additionalProperties": {
"$ref": "#/definitions/variantEntry"
}
}
},
"required": [
"name"
// Technically uid or package_uid and version or package_version are required,
// but handling the fallback logic is complex in pure schema.
// Add ["uid", "version"] here if enforcing the modern fields.
],
"definitions": {
"variantEntry": {
"type": "object",
"properties": {
"display_name": {
"type": "string",
"description": "The user-friendly name for this variant."
},
"flags": {
"type": "array",
"description": "Flags associated specifically with this variant.",
"items": {
"type": "string",
"enum": [
"None", "Official", "Featured", "Map", "Pins", "ChatHUD", "AutoTracker", "Unsafe"
]
}
}
},
"required": ["display_name"]
}
}
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "EmoTracker Maps Definition Schema",
"description": "Defines the base map images and their default properties.",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Unique name used to identify this map (in locations.json map_locations)."
},
"location_size": {
"type": "number",
"description": "Default size (diameter) for location pins placed on this map.",
"default": 70.0
},
"location_border_thickness": {
"type": "number",
"description": "Default border thickness for location pins on this map.",
"default": 8.0
},
"img": {
"type": "string",
"description": "Path to the map image file relative to the package root."
},
"img_mods": {
"type": "string",
"description": "Optional image filter spec applied to the map image."
}
},
"required": ["name", "img"],
"additionalProperties": false
}
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "EmoTracker Package Settings Schema",
"description": "Defines package-specific settings like UI behavior and default visuals.",
"type": "object",
"properties": {
"allow_resize": {
"type": "boolean",
"description": "Whether the tracker window should be user-resizable for this package.",
"default": true
},
"disabled_image_filter": {
"type": "string",
"description": "Default image filter spec applied to disabled items (e.g., 'grayscale, dim'). Overrides application default.",
"examples": ["grayscale", "dim", "grayscale, dim"]
},
"chest_opened_img": {
"type": "string",
"description": "Path to the default image for an opened chest (for location visuals)."
},
"chest_unopened_img": {
"type": "string",
"description": "Path to the default image for a closed/unopened chest (for location visuals)."
},
"always_allow_chest_manipulation": {
"type": "boolean",
"description": "Default setting for whether chests in locations can always be clicked regardless of accessibility.",
"default": false
},
"auto_unpin_on_clear": {
"type": "boolean",
"description": "Default setting for whether locations should automatically unpin when fully cleared.",
"default": false // Note: The C# code defaults the root to false, but user settings override.
},
"enable_accessibility_rule_caching": {
"type": "boolean",
"description": "Whether to enable caching for accessibility rule evaluations (improves performance).",
"default": true
}
},
"additionalProperties": false // Generally settings files have a fixed structure
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment