Adds import support from our other project.

This commit is contained in:
2026-09-07 21:57:59 -07:00
parent a3d1a139e9
commit a3dace36de
150 changed files with 17716 additions and 21 deletions

View File

@@ -0,0 +1,57 @@
{
"$schema": "../../../schema/entity-definition.json",
"id": "armor",
"name": "Armor",
"description": "Armor entity extending base item schema with AC base, dex cap, strength requirement, and stealth penalties.",
"ruleset_id": "open5e",
"version": "1.0.0",
"schema": {
"type": "object",
"required": ["name", "armor_category", "ac_base"],
"allOf": [
{
"$ref": "item.json#/schema"
},
{
"type": "object",
"properties": {
"armor_category": {
"type": "string",
"enum": ["light", "medium", "heavy"],
"description": "Classification of armor determining weight class and dexterity application."
},
"ac_base": {
"type": "integer",
"minimum": 0,
"description": "Base Armor Class provided by this armor (e.g. 11 for Leather, 14 for Breastplate, 18 for Plate)."
},
"ac_modifier": {
"type": "integer",
"description": "Armor Class modifier over the base 10 (e.g. +1 for Leather, +4 for Breastplate, +8 for Plate)."
},
"dex_cap": {
"type": ["integer", "null"],
"description": "Maximum dexterity modifier bonus allowed. null = uncapped (light armor), 2 = medium armor cap (+2), 0 = heavy armor (no dex bonus)."
},
"strength_requirement": {
"type": ["integer", "null"],
"description": "Minimum Strength score needed to wear without speed penalty. null or 0 if none."
},
"stealth_disadvantage": {
"type": "boolean",
"default": false,
"description": "Whether wearing this armor imposes disadvantage on Dexterity (Stealth) checks."
}
}
}
]
},
"default_values": {
"weight": 10,
"quantity": 1,
"equipped": false,
"rarity": "common",
"stealth_disadvantage": false,
"strength_requirement": null
}
}

View File

@@ -0,0 +1,375 @@
{
"$schema": "../../../schema/entity-definition.json",
"id": "character",
"name": "Player Character",
"description": "5e Player Character entity with ability scores, proficiencies, hit points, and inventory.",
"ruleset_id": "open5e",
"version": "1.0.0",
"default_template": "character_sheet",
"allowed_templates": [
"character_sheet",
"character_sheet_alt",
"spellcasting_sheet",
"stat_block",
"character_card",
"character_list_item"
],
"schema": {
"type": "object",
"required": ["level", "abilities", "hit_points"],
"properties": {
"level": {
"type": "integer",
"minimum": 1,
"maximum": 20,
"description": "Total character level."
},
"class": {
"type": "string",
"description": "Primary class of the character."
},
"race": {
"type": "string",
"description": "Character race / species."
},
"background": {
"type": "string",
"description": "Character background."
},
"alignment": {
"type": "string",
"description": "Ethical and moral alignment."
},
"experience_points": {
"type": "integer",
"minimum": 0
},
"armor_class": {
"type": ["integer", "object"],
"description": "Armor class value or extended property with shield/dex/item modifiers."
},
"equipped_armor": {
"type": ["object", "null"],
"description": "Currently equipped body armor item snapshot or reference. null if unarmored.",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"armor_category": {
"type": "string",
"enum": ["light", "medium", "heavy"]
},
"ac_base": { "type": "integer" },
"dex_cap": { "type": ["integer", "null"] },
"stealth_disadvantage": { "type": "boolean" },
"strength_requirement": { "type": ["integer", "null"] }
}
},
"equipped_shield": {
"type": ["object", "null"],
"description": "Currently equipped shield item snapshot or reference. null if no shield is equipped.",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"ac_bonus": { "type": "integer", "default": 2 },
"stealth_disadvantage": { "type": "boolean" },
"strength_requirement": { "type": ["integer", "null"] }
}
},
"speed": {
"type": "integer",
"description": "Base walking speed in feet."
},
"hit_points": {
"type": "object",
"required": ["current", "max"],
"properties": {
"current": { "type": "integer" },
"max": { "type": "integer" },
"temp": { "type": "integer", "default": 0 }
}
},
"abilities": {
"type": "object",
"description": "Core 5e ability scores.",
"required": [
"strength",
"dexterity",
"constitution",
"intelligence",
"wisdom",
"charisma"
],
"properties": {
"strength": { "type": ["integer", "object"] },
"dexterity": { "type": ["integer", "object"] },
"constitution": { "type": ["integer", "object"] },
"intelligence": { "type": ["integer", "object"] },
"wisdom": { "type": ["integer", "object"] },
"charisma": { "type": ["integer", "object"] }
}
},
"player_name": {
"type": "string",
"description": "Name of the player controlling this character."
},
"subclass": {
"type": "string",
"description": "Character archetype or subclass (e.g. Hunter, Champion, Evoker)."
},
"inspiration": {
"type": ["boolean", "integer"],
"default": false,
"description": "Heroic inspiration state or count."
},
"initiative": {
"type": ["integer", "object"],
"description": "Initiative modifier (typically dexterity modifier plus bonuses)."
},
"hit_dice": {
"type": "object",
"properties": {
"total": { "type": ["integer", "string"] },
"current": { "type": ["integer", "string"] },
"dice": { "type": "string" }
}
},
"death_saves": {
"type": "object",
"properties": {
"successes": {
"type": "integer",
"minimum": 0,
"maximum": 3,
"default": 0
},
"failures": {
"type": "integer",
"minimum": 0,
"maximum": 3,
"default": 0
}
}
},
"saving_throws": {
"type": ["array", "object"],
"description": "Saving throw proficiencies and bonuses."
},
"skills": {
"type": ["array", "object"],
"description": "Skill proficiencies and bonuses across the 18 standard 5e skills."
},
"passive_perception": {
"type": ["integer", "object"],
"description": "Passive Wisdom (Perception) score: typically 10 + perception bonus."
},
"other_proficiencies_and_languages": {
"type": "object",
"properties": {
"armor": { "type": "array", "items": { "type": "string" } },
"weapons": { "type": "array", "items": { "type": "string" } },
"tools": { "type": "array", "items": { "type": "string" } },
"languages": { "type": "array", "items": { "type": "string" } }
}
},
"attacks": {
"type": "array",
"description": "Weapons and spell attacks for the Attacks & Spellcasting section.",
"items": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string" },
"atk_bonus": { "type": ["string", "integer"] },
"damage": { "type": "string" },
"damage_type": { "type": "string" },
"range": { "type": "string" },
"notes": { "type": "string" }
}
}
},
"currency": {
"type": "object",
"properties": {
"cp": { "type": "integer", "default": 0 },
"sp": { "type": "integer", "default": 0 },
"ep": { "type": "integer", "default": 0 },
"gp": { "type": "integer", "default": 0 },
"pp": { "type": "integer", "default": 0 }
}
},
"personality_traits": { "type": ["string", "array"] },
"ideals": { "type": ["string", "array"] },
"bonds": { "type": ["string", "array"] },
"flaws": { "type": ["string", "array"] },
"features_and_traits": {
"type": "array",
"description": "Class, racial, and background features.",
"items": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string" },
"source": { "type": "string" },
"desc": { "type": "string" }
}
}
},
"character_details": {
"type": "object",
"properties": {
"age": { "type": ["integer", "string"] },
"height": { "type": "string" },
"weight": { "type": "string" },
"eyes": { "type": "string" },
"skin": { "type": "string" },
"hair": { "type": "string" },
"appearance": { "type": "string" },
"backstory": { "type": "string" },
"allies_and_organizations": { "type": ["string", "array"] },
"treasure": { "type": ["string", "array"] }
}
},
"spellcasting": {
"type": "object",
"properties": {
"class": { "type": "string" },
"ability": { "type": "string" },
"save_dc": { "type": ["integer", "object"] },
"attack_bonus": { "type": ["integer", "object"] },
"cantrips": {
"type": "array",
"items": { "type": ["string", "object"] }
},
"slots": {
"type": "object",
"description": "Spell slot counts per spell level 1-9.",
"additionalProperties": {
"type": "object",
"properties": {
"total": { "type": "integer" },
"expended": { "type": "integer", "default": 0 }
}
}
},
"spells": {
"type": "array",
"items": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string" },
"level": { "type": "integer", "minimum": 0, "maximum": 9 },
"prepared": { "type": "boolean", "default": false },
"desc": { "type": "string" }
}
}
}
}
},
"inventory": {
"type": "array",
"description": "List of carried items.",
"items": {
"type": "object",
"required": ["id", "name"],
"properties": {
"id": { "type": "string" },
"entity_ref": {
"type": "string",
"description": "Optional relative path or identifier of the base item entity."
},
"name": { "type": "string" },
"quantity": { "type": "integer", "default": 1 },
"weight": { "type": "number", "default": 0 },
"equipped": { "type": "boolean", "default": false },
"ac_base": { "type": "integer" },
"dex_cap": { "type": ["integer", "null"] },
"ac_bonus": { "type": "integer" },
"grants_modifiers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"target": { "type": "string" },
"value": { "type": ["number", "string"] },
"type": { "type": "string" },
"source": { "type": "string" }
}
}
}
},
"additionalProperties": true
}
}
}
},
"calculated_properties": {
"armor_class": {
"expr": "10 + (equipped_armor ? (equipped_armor.ac_modifier !== undefined ? equipped_armor.ac_modifier : equipped_armor.ac_base - 10) : 0) + (equipped_armor && equipped_armor.dex_cap !== null ? (equipped_armor.dex_cap === 0 ? min(0, abilities.dexterity.modifier) : min(equipped_armor.dex_cap, abilities.dexterity.modifier)) : abilities.dexterity.modifier) + (equipped_shield ? equipped_shield.ac_bonus : 0) + sum(filter(armor_class.modifiers, m => m.active && m.type !== 'armor' && m.type !== 'ability'))",
"type": "integer",
"dependencies": [
"equipped_armor",
"equipped_shield",
"abilities.dexterity.modifier",
"armor_class.modifiers"
],
"description": "5e Armor Class calculation: base 10 + armor modifier (e.g. +1 for leather, +8 for plate) + dexterity modifier (capped by armor; heavy armor caps positive dex to 0 but allows negative penalties) + shield bonus + active external modifiers."
},
"proficiency_bonus": {
"expr": "floor((level - 1) / 4) + 2",
"type": "integer",
"dependencies": ["level"],
"description": "Standard 5e proficiency bonus calculation."
},
"ability_modifiers.strength": {
"expr": "floor((abilities.strength - 10) / 2)",
"type": "integer",
"dependencies": ["abilities.strength"]
},
"ability_modifiers.dexterity": {
"expr": "floor((abilities.dexterity - 10) / 2)",
"type": "integer",
"dependencies": ["abilities.dexterity"]
},
"ability_modifiers.constitution": {
"expr": "floor((abilities.constitution - 10) / 2)",
"type": "integer",
"dependencies": ["abilities.constitution"]
},
"ability_modifiers.intelligence": {
"expr": "floor((abilities.intelligence - 10) / 2)",
"type": "integer",
"dependencies": ["abilities.intelligence"]
},
"ability_modifiers.wisdom": {
"expr": "floor((abilities.wisdom - 10) / 2)",
"type": "integer",
"dependencies": ["abilities.wisdom"]
},
"ability_modifiers.charisma": {
"expr": "floor((abilities.charisma - 10) / 2)",
"type": "integer",
"dependencies": ["abilities.charisma"]
}
},
"default_values": {
"level": 1,
"equipped_armor": null,
"equipped_shield": null,
"abilities": {
"strength": 10,
"dexterity": 10,
"constitution": 10,
"intelligence": 10,
"wisdom": 10,
"charisma": 10
},
"hit_points": {
"current": 10,
"max": 10,
"temp": 0
},
"speed": 30,
"inventory": []
}
}

View File

@@ -0,0 +1,100 @@
{
"$schema": "../../../schema/entity-definition.json",
"id": "item",
"name": "Item / Gear",
"description": "Base entity schema for generic items, equipment, and gear in 5e.",
"ruleset_id": "open5e",
"version": "1.0.0",
"schema": {
"type": "object",
"required": ["name"],
"properties": {
"name": {
"type": "string",
"description": "The name of the item."
},
"description": {
"type": "string",
"description": "A description of the item."
},
"cost": {
"description": "The market value or cost of the item.",
"type": "object",
"properties": {
"quantity": { "type": "number", "minimum": 0 },
"unit": {
"type": "string",
"enum": ["cp", "sp", "ep", "gp", "pp"],
"default": "gp"
}
}
},
"weight": {
"type": "number",
"minimum": 0,
"description": "Weight in pounds (lbs)."
},
"rarity": {
"type": "string",
"enum": [
"common",
"uncommon",
"rare",
"very rare",
"legendary",
"artifact"
],
"default": "common"
},
"attunement": {
"type": "boolean",
"default": false,
"description": "Whether this item requires attunement."
},
"equipped": {
"type": "boolean",
"default": false,
"description": "Whether this item is currently equipped or worn."
},
"quantity": {
"type": "integer",
"minimum": 1,
"default": 1,
"description": "Number of copies carried in inventory."
},
"grants_modifiers": {
"type": "array",
"description": "Modifiers applied to the character when this item is equipped.",
"items": {
"type": "object",
"required": ["target", "value"],
"properties": {
"target": {
"type": "string",
"description": "The property path modified on the wearer (e.g. 'armor_class', 'saving_throws.all')."
},
"value": {
"type": ["number", "string"],
"description": "Modifier bonus value or expression."
},
"type": {
"type": "string",
"description": "Modifier type (e.g. 'bonus', 'base', 'override', 'advantage')."
},
"source": {
"type": "string",
"description": "Name or origin of the bonus."
}
}
}
}
}
},
"default_values": {
"weight": 0,
"quantity": 1,
"equipped": false,
"rarity": "common",
"attunement": false
}
}

View File

@@ -0,0 +1,45 @@
{
"$schema": "../../../schema/entity-definition.json",
"id": "shield",
"name": "Shield",
"description": "Shield entity extending base item schema with AC bonus and strength/stealth properties.",
"ruleset_id": "open5e",
"version": "1.0.0",
"schema": {
"type": "object",
"required": ["name", "ac_bonus"],
"allOf": [
{
"$ref": "item.json#/schema"
},
{
"type": "object",
"properties": {
"ac_bonus": {
"type": "integer",
"default": 2,
"description": "Armor Class bonus granted by wielding this shield (standard 5e shield is +2)."
},
"strength_requirement": {
"type": ["integer", "null"],
"description": "Minimum Strength score required to use without penalty."
},
"stealth_disadvantage": {
"type": "boolean",
"default": false,
"description": "Whether wielding this shield imposes disadvantage on Dexterity (Stealth) checks."
}
}
}
]
},
"default_values": {
"ac_bonus": 2,
"weight": 6,
"quantity": 1,
"equipped": false,
"rarity": "common",
"stealth_disadvantage": false,
"strength_requirement": null
}
}

View File

@@ -0,0 +1,92 @@
{
"$schema": "../../../schema/entity-definition.json",
"id": "spell",
"name": "Spell",
"description": "5e Spell entity definition declaring level, school, casting time, range, components, duration, and spell description.",
"ruleset_id": "open5e",
"version": "1.0.0",
"schema": {
"type": "object",
"required": [
"level",
"school",
"casting_time",
"range",
"duration",
"description"
],
"properties": {
"level": {
"type": "integer",
"minimum": 0,
"maximum": 9,
"description": "Spell level from 0 (cantrip) up to 9."
},
"school": {
"type": "string",
"enum": [
"abjuration",
"conjuration",
"divination",
"enchantment",
"evocation",
"illusion",
"necromancy",
"transmutation"
]
},
"casting_time": {
"type": "string",
"description": "e.g. 1 action, 1 bonus action, 1 reaction, 10 minutes."
},
"range": {
"type": "string",
"description": "e.g. Self, Touch, 30 feet, 60 feet, 120 feet."
},
"components": {
"type": "object",
"properties": {
"verbal": { "type": "boolean", "default": true },
"somatic": { "type": "boolean", "default": true },
"material": { "type": "boolean", "default": false },
"material_specified": { "type": "string" }
}
},
"duration": {
"type": "string",
"description": "e.g. Instantaneous, 1 round, 1 hour, Concentration up to 1 minute."
},
"concentration": {
"type": "boolean",
"default": false
},
"ritual": {
"type": "boolean",
"default": false
},
"description": {
"type": "string",
"description": "Rules text of the spell effect."
},
"higher_levels": {
"type": "string",
"description": "Rules text for casting at higher slot levels."
}
}
},
"default_values": {
"level": 0,
"school": "evocation",
"casting_time": "1 action",
"range": "60 feet",
"components": {
"verbal": true,
"somatic": true,
"material": false
},
"duration": "Instantaneous",
"concentration": false,
"ritual": false,
"description": ""
}
}

View File

@@ -0,0 +1,82 @@
{
"$schema": "../../../schema/entity-definition.json",
"id": "weapon",
"name": "Weapon",
"description": "5e Weapon entity definition inheriting from base item, specifying damage dice, damage type, and weapon properties.",
"ruleset_id": "open5e",
"version": "1.0.0",
"schema": {
"allOf": [
{
"$ref": "item.json#/schema"
},
{
"type": "object",
"required": ["damage_dice", "damage_type"],
"properties": {
"weapon_category": {
"type": "string",
"enum": ["simple", "martial"]
},
"weapon_range": {
"type": "string",
"enum": ["melee", "ranged"],
"default": "melee"
},
"damage_dice": {
"type": "string",
"description": "Damage formula e.g. 1d6, 1d8, 2d6."
},
"damage_type": {
"type": "string",
"enum": ["bludgeoning", "piercing", "slashing"]
},
"properties": {
"type": "array",
"description": "Standard 5e weapon properties.",
"items": {
"type": "string",
"enum": [
"ammunition",
"finesse",
"heavy",
"light",
"loading",
"range",
"reach",
"special",
"thrown",
"two-handed",
"versatile"
]
}
},
"range_normal": {
"type": ["integer", "null"],
"description": "Standard effective range in feet."
},
"range_long": {
"type": ["integer", "null"],
"description": "Long range with disadvantage in feet."
},
"versatile_dice": {
"type": ["string", "null"],
"description": "Two-handed damage dice when used versatile (e.g. 1d10 for a longsword)."
}
}
}
]
},
"default_values": {
"cost": {
"quantity": 10,
"unit": "gp"
},
"weight": 2.0,
"weapon_category": "simple",
"weapon_range": "melee",
"damage_dice": "1d6",
"damage_type": "slashing",
"properties": []
}
}

View File

@@ -0,0 +1,51 @@
{
"$schema": "../../../../schema/entity.json",
"uuid": "f6a83d72-b94e-4e5c-a5c2-f39b6b52d202",
"ruleset_id": "open5e",
"entity_type": "character",
"display_name": "Acolyte",
"description": "Medium humanoid (any race), any alignment.",
"version": "1.0.0",
"template_id": "stat_block",
"tags": ["npc", "humanoid", "spellcaster", "cr-1/4"],
"properties": {
"size": "medium",
"type": "Humanoid",
"subtype": "any race",
"alignment": "any alignment",
"armor_class": 10,
"hit_points": {
"current": 9,
"max": 9,
"formula": "2d8 + 0",
"hit_dice": "2d8"
},
"speed": 30,
"speed_desc": "30 ft.",
"challenge_rating": "1/4 (50 XP)",
"cr": "1/4",
"abilities": {
"strength": 10,
"dexterity": 10,
"constitution": 10,
"intelligence": 10,
"wisdom": 14,
"charisma": 11
},
"skills": ["medicine +4", "religion +2"],
"senses": "passive Perception 12",
"languages": ["any one language (usually Common)"],
"traits": [
{
"name": "Spellcasting",
"desc": "The acolyte is a 1st-level spellcaster. Its spellcasting ability is Wisdom (spell save DC 12, +4 to hit with spell attacks). The acolyte has following cleric spells prepared:\n\n* Cantrips (at will): _light, sacred flame, thaumaturgy_\n* 1st level (3 slots): _bless, cure wounds, sanctuary_"
}
],
"actions": [
{
"name": "Club",
"desc": "_Melee Weapon Attack:_ +2 to hit, reach 5 ft., one target. _Hit:_ 2 (1d4) bludgeoning damage."
}
]
}
}

View File

@@ -0,0 +1,99 @@
{
"$schema": "../../../../schema/entity.json",
"uuid": "b8a91c34-d07f-4f8a-92c1-d41a8a91e404",
"ruleset_id": "open5e",
"entity_type": "character",
"display_name": "Adult Black Dragon",
"description": "Huge dragon, chaotic evil.",
"version": "1.0.0",
"template_id": "stat_block",
"tags": ["monster", "dragon", "legendary", "cr-14"],
"properties": {
"size": "huge",
"type": "Dragon",
"alignment": "chaotic evil",
"armor_class": 19,
"armor_description": "natural armor",
"hit_points": {
"current": 196,
"max": 196,
"formula": "17d12 + 85",
"hit_dice": "17d12"
},
"speed": 40,
"speed_desc": "40 ft., fly 80 ft., swim 40 ft.",
"challenge_rating": "14 (11,500 XP)",
"cr": "14",
"abilities": {
"strength": 23,
"dexterity": 14,
"constitution": 21,
"intelligence": 14,
"wisdom": 13,
"charisma": 17
},
"saving_throws": [
"Dexterity +7",
"Constitution +10",
"Wisdom +6",
"Charisma +8"
],
"skills": ["perception +16", "stealth +11"],
"damage_immunities": ["acid"],
"senses": "darkvision 120 ft., blindsight 60 ft., passive Perception 11",
"languages": ["Common", "Draconic"],
"traits": [
{
"name": "Amphibious",
"desc": "The dragon can breathe air and water."
},
{
"name": "Legendary Resistance (3/Day)",
"desc": "If the dragon fails a saving throw, it can choose to succeed instead."
}
],
"actions": [
{
"name": "Multiattack",
"desc": "The dragon can use its Frightful Presence. It then makes three attacks: one with its bite and two with its claws."
},
{
"name": "Bite",
"desc": "_Melee Weapon Attack:_ +11 to hit, reach 10 ft., one target. _Hit:_ 17 (2d10 + 6) piercing damage plus 4 (1d8) acid damage."
},
{
"name": "Claw",
"desc": "_Melee Weapon Attack:_ +11 to hit, reach 5 ft., one target. _Hit:_ 13 (2d6 + 6) slashing damage."
},
{
"name": "Tail",
"desc": "_Melee Weapon Attack:_ +11 to hit, reach 15 ft., one target. _Hit:_ 15 (2d8 + 6) bludgeoning damage."
},
{
"name": "Frightful Presence",
"desc": "Each creature of the dragon's choice that is within 120 feet of the dragon and aware of it must succeed on a DC 16 Wisdom saving throw or become frightened for 1 minute. A creature can repeat the saving throw at the end of each of its turns, ending the effect on itself on a success. If a creature's saving throw is successful or the effect ends for it, the creature is immune to the dragon's Frightful Presence for the next 24 hours."
},
{
"name": "Acid Breath (Recharge 5-6)",
"desc": "The dragon exhales acid in a 60-foot line that is 5 feet wide. Each creature in that line must make a DC 18 Dexterity saving throw, taking 54 (12d8) acid damage on a failed save, or half as much damage on a successful one."
}
],
"legendary_actions": {
"description": "The dragon can take 3 legendary actions, choosing from the options below. Only one legendary action option can be used at a time and only at the end of another creature's turn. The dragon regains spent legendary actions at the start of its turn.",
"actions": [
{
"name": "Detect",
"desc": "The dragon makes a Wisdom (Perception) check."
},
{
"name": "Tail Attack",
"desc": "The dragon makes a tail attack."
},
{
"name": "Wing Attack (Costs 2 Actions)",
"desc": "The dragon beats its wings. Each creature within 10 ft. of the dragon must succeed on a DC 19 Dexterity saving throw or take 13 (2d6 + 6) bludgeoning damage and be knocked prone. The dragon can then fly up to half its flying speed."
}
]
}
}
}

View File

@@ -0,0 +1,261 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "4c8f3824-3453-48bf-9a0e-a4c336b3bcf2",
"ruleset_id": "open5e",
"entity_type": "character",
"display_name": "Arannis",
"description": "Elven Ranger exploring ancient ruins.",
"version": "1.0.0",
"created_at": "2026-09-06T14:00:00Z",
"updated_at": "2026-09-06T18:00:00Z",
"tags": ["pc", "ranger", "elf"],
"properties": {
"player_name": "Tom",
"level": 3,
"class": "Ranger",
"subclass": "Hunter",
"race": "Elf",
"size": "medium",
"type": "Humanoid",
"subtype": "Elf",
"background": "Outlander",
"alignment": "Chaotic Good",
"experience_points": 900,
"inspiration": true,
"proficiency_bonus": 2,
"initiative": 3,
"speed": 35,
"speed_desc": "35 ft.",
"hit_points": {
"current": 24,
"max": 24,
"formula": "3d10 + 6",
"temp": 0
},
"hit_dice": {
"total": 3,
"current": 3,
"dice": "1d10"
},
"death_saves": {
"successes": 0,
"failures": 0
},
"saving_throws": ["Strength +3", "Dexterity +5"],
"advantages": ["wis"],
"skills": ["Athletics +3", "Perception +5", "Stealth +5", "Survival +5"],
"passive_perception": 15,
"senses": "darkvision 60 ft., passive Perception 15",
"languages": ["Common", "Elvish", "Sylvan"],
"other_proficiencies_and_languages": {
"armor": ["Light armor", "Medium armor", "Shields"],
"weapons": ["Simple weapons", "Martial weapons"],
"tools": ["Herbalism kit", "Flute"],
"languages": ["Common", "Elvish", "Sylvan"]
},
"attacks": [
{
"name": "Longbow",
"atk_bonus": "+7",
"damage": "1d8 + 3",
"damage_type": "Piercing",
"range": "150/600 ft."
},
{
"name": "Shortsword",
"atk_bonus": "+5",
"damage": "1d6 + 3",
"damage_type": "Piercing",
"range": "5 ft."
}
],
"currency": {
"cp": 15,
"sp": 40,
"ep": 0,
"gp": 25,
"pp": 0
},
"personality_traits": "I feel far more comfortable among the ancient trees and wild beasts than in bustling cities.",
"ideals": "Nature: The natural world is more important than the constructs of civilization.",
"bonds": "An ancient ruined shrine in the northern forest holds a secret I have sworn to protect.",
"flaws": "I am slow to trust others and prefer solitude even in times of danger.",
"features_and_traits": [
{
"name": "Favored Enemy (Undead)",
"source": "Ranger 1",
"desc": "You have advantage on Wisdom (Survival) checks to track your favored enemies, as well as on Intelligence checks to recall information about them."
},
{
"name": "Natural Explorer (Forest)",
"source": "Ranger 1",
"desc": "When making an Intelligence or Wisdom check related to your favored terrain, your proficiency bonus is doubled if you are using a skill you're proficient in."
},
{
"name": "Colossus Slayer",
"source": "Hunter Archetype",
"desc": "Your tenacity can wear down the most potent foes. Once per turn when you hit a creature with a weapon attack, the creature takes an extra 1d8 damage if it's below its hit point maximum."
}
],
"spellcasting": {
"class": "Ranger",
"ability": "WISDOM",
"save_dc": 13,
"attack_bonus": 5,
"cantrips": [],
"slots": {
"1": {
"total": 3,
"expended": 1
}
},
"spells": [
{
"name": "Hunter's Mark",
"level": 1,
"prepared": true,
"desc": "You choose a creature you can see within range and mystically mark it as your quarry."
},
{
"name": "Cure Wounds",
"level": 1,
"prepared": true,
"desc": "A creature you touch regains a number of hit points equal to 1d8 + your spellcasting ability modifier."
}
]
},
"traits": [
{
"name": "Fey Ancestry",
"desc": "Arannis has advantage on saving throws against being charmed, and magic cannot put her to sleep."
},
{
"name": "Natural Explorer",
"desc": "Difficult terrain does not slow Arannis's group while traveling."
}
],
"actions": [
{
"name": "Longbow",
"desc": "_Ranged Weapon Attack:_ +7 to hit, range 150/600 ft., one target. _Hit:_ 7 (1d8 + 3) piercing damage."
},
{
"name": "Shortsword",
"desc": "_Melee Weapon Attack:_ +5 to hit, reach 5 ft., one target. _Hit:_ 6 (1d6 + 3) piercing damage."
}
],
"equipped_armor": {
"id": "armor_leather",
"name": "Leather Armor",
"armor_category": "light",
"ac_base": 11,
"ac_modifier": 1,
"dex_cap": null,
"stealth_disadvantage": false,
"strength_requirement": null
},
"equipped_shield": null,
"armor_class": {
"value": 15,
"base": 10,
"expr": "base + sum(modifiers)",
"modifiers": [
{
"source": "Leather Armor",
"value": 1,
"type": "armor"
},
{
"source": "Dexterity Modifier",
"value": 3,
"type": "ability"
},
{
"source": "Ring of Protection +1",
"value": 1,
"type": "bonus",
"active": true
}
]
},
"abilities": {
"strength": 12,
"dexterity": {
"value": 16,
"base": 14,
"modifier": 3,
"modifiers": [
{
"source": "Elven Agility",
"value": 2,
"type": "bonus"
}
]
},
"constitution": 14,
"intelligence": 10,
"wisdom": 15,
"charisma": 8
},
"inventory": [
{
"id": "armor_leather",
"entity_ref": "entities/armor.json",
"name": "Leather Armor",
"quantity": 1,
"weight": 10.0,
"equipped": true,
"ac_base": 11,
"dex_cap": null
},
{
"id": "ring_protection",
"entity_ref": "entities/item.json",
"name": "Ring of Protection +1",
"quantity": 1,
"weight": 0.1,
"equipped": true,
"grants_modifiers": [
{
"target": "armor_class",
"value": 1,
"type": "bonus",
"source": "Ring of Protection +1"
}
]
},
{
"id": "longbow",
"entity_ref": "entities/weapon.json",
"name": "Longbow",
"quantity": 1,
"weight": 2.0,
"equipped": true
},
{
"id": "shortsword",
"entity_ref": "entities/weapon.json",
"name": "Shortsword",
"quantity": 1,
"weight": 2.0,
"equipped": true
},
{
"id": "arrow",
"entity_ref": "entities/item.json",
"name": "Arrow",
"quantity": 20,
"weight": 1.0,
"equipped": false
},
{
"id": "potion_healing",
"entity_ref": "entities/item.json",
"name": "Potion of Healing",
"quantity": 2,
"weight": 1.0,
"equipped": false
}
]
}
}

View File

@@ -0,0 +1,56 @@
{
"$schema": "../../../../schema/entity.json",
"uuid": "e5b72e61-a83d-4c3d-b4b1-e28a5a41c101",
"ruleset_id": "open5e",
"entity_type": "character",
"display_name": "Goblin",
"description": "Small humanoid (goblinoid), neutral evil.",
"version": "1.0.0",
"template_id": "stat_block",
"tags": ["monster", "goblinoid", "humanoid", "cr-1/4"],
"properties": {
"size": "small",
"type": "Humanoid",
"subtype": "goblinoid",
"alignment": "neutral evil",
"armor_class": 15,
"armor_description": "leather armor, shield",
"hit_points": {
"current": 7,
"max": 7,
"formula": "2d6 + 0",
"hit_dice": "2d6"
},
"speed": 30,
"speed_desc": "30 ft.",
"challenge_rating": "1/4 (50 XP)",
"cr": "1/4",
"abilities": {
"strength": 8,
"dexterity": 14,
"constitution": 10,
"intelligence": 10,
"wisdom": 8,
"charisma": 8
},
"skills": ["stealth +6"],
"senses": "darkvision 60 ft., passive Perception 9",
"languages": ["Common", "Goblin"],
"traits": [
{
"name": "Nimble Escape",
"desc": "The goblin can take the Disengage or Hide action as a bonus action on each of its turns."
}
],
"actions": [
{
"name": "Scimitar",
"desc": "_Melee Weapon Attack:_ +4 to hit, reach 5 ft., one target. _Hit:_ 5 (1d6 + 2) slashing damage."
},
{
"name": "Shortbow",
"desc": "_Ranged Weapon Attack:_ +4 to hit, range 80/320 ft., one target. _Hit:_ 5 (1d6 + 2) piercing damage."
}
]
}
}

View File

@@ -0,0 +1,492 @@
# Open5e Ruleset — Import & Export Specification Guide
This document is the technical integration and schema guide for third-party applications, services, and developers who want to **import** or **export** Open5e (D&D 5th Edition SRD) entities—including **Player Characters / Creatures**, **Weapons**, **Armor**, **Shields**, **Spells**, and **Generic Items**.
---
## Table of Contents
1. [Overview & Architecture](#1-overview--architecture)
2. [What Files to Distribute to External Apps](#2-what-files-to-distribute-to-external-apps)
3. [The Universal Entity Envelope (`entity.json`)](#3-the-universal-entity-envelope-entityjson)
4. [Entity Specifications & Payloads](#4-entity-specifications--payloads)
- [4.1 Character (`character.json`)](#41-character-entity-characterjson)
- [4.2 Base Item (`item.json`)](#42-base-item-entity-itemjson)
- [4.3 Weapon (`weapon.json`)](#43-weapon-entity-weaponjson)
- [4.4 Armor (`armor.json`)](#44-armor-entity-armorjson)
- [4.5 Shield (`shield.json`)](#45-shield-entity-shieldjson)
- [4.6 Spell (`spell.json`)](#46-spell-entity-spelljson)
5. [Validation & Conformance Rules](#5-validation--conformance-rules)
6. [Import & Export Implementation Checklist](#6-import--export-implementation-checklist)
---
## 1. Overview & Architecture
In our system, all data entities (characters, items, spells, etc.) follow a two-tier JSON architecture:
1. **The Universal Envelope (`entity.json`)**: Provides standard metadata required across all rulesets and systems (`uuid`, `ruleset_id`, `entity_type`, `display_name`, `version`, `tags`, etc.).
2. **The Entity Properties Payload (`properties`)**: Houses ruleset-specific and entity-specific fields defined by the entity schema (e.g. ability scores, spell slots, armor classes, damage dice).
```
┌─────────────────────────────────────────────────────────────┐
│ Universal Envelope (schema/entity.json) │
│ ├─ uuid: "4c8f3824-3453-48bf-9a0e-a4c336b3bcf2" │
│ ├─ ruleset_id: "open5e" │
│ ├─ entity_type: "character" | "weapon" | "spell" | ... │
│ ├─ display_name: "Arannis" │
│ └─ properties: { ... } <── Validated by Entity Schema │
└─────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Entity-Specific Schema (entities/{type}.json) │
│ ├─ character.json │
│ ├─ weapon.json (inherits from item.json) │
│ ├─ armor.json (inherits from item.json) │
│ ├─ shield.json (inherits from item.json) │
│ ├─ spell.json │
│ └─ item.json │
└──────────────────────────────────────────────────┘
```
---
## 2. What Files to Distribute to External Apps
To give an external application complete import and export capability, package and provide the following files:
### A. Root Schemas (`schema/`)
1. **[`schema/entity.json`](../../schema/entity.json)**: The universal envelope schema. Every exported file must validate against this schema.
2. **[`schema/entity-definition.json`](../../schema/entity-definition.json)**: The meta-schema describing how entity types and schemas are declared.
### B. Ruleset Manifest (`rulesets/open5e/`)
3. **[`rulesets/open5e/manifest.json`](manifest.json)**: Identifies the ruleset (`open5e`), version, author, and all registered entities and templates.
### C. Entity Property Schemas (`rulesets/open5e/entities/`)
4. **[`character.json`](entities/character.json)**: 5e Character and creature schema (attributes, vitals, proficiencies, attacks, spells, inventory).
5. **[`item.json`](entities/item.json)**: Base schema for equipment, gear, and magic items.
6. **[`weapon.json`](entities/weapon.json)**: Weapon schema (damage dice, damage types, ranges, weapon properties; inherits from `item.json`).
7. **[`armor.json`](entities/armor.json)**: Armor schema (AC base, Dex caps, stealth penalty, strength requirement; inherits from `item.json`).
8. **[`shield.json`](entities/shield.json)**: Shield schema (AC bonus, stealth penalty; inherits from `item.json`).
9. **[`spell.json`](entities/spell.json)**: Spell schema (spell level 0–9, school, casting time, range, components, duration).
> **Integration Note on `$ref` Resolution**:
> `weapon.json`, `armor.json`, and `shield.json` use JSON Schema `$ref: "item.json#/schema"`. When integrating with schema validators (such as Ajv, jsonschema, or Newtonsoft.Json), ensure all schema files are preloaded in the schema registry or resolved relative to their folder.
---
## 3. The Universal Entity Envelope (`entity.json`)
Every exported file **must** include these top-level fields:
| Field | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| `$schema` | `string` | Recommended | URI or relative path to schema (`"../../../schema/entity.json"`). |
| `uuid` | `string` | **Yes** | Unique identifier (standard UUID v4 format recommended). |
| `ruleset_id` | `string` | **Yes** | Must be `"open5e"` for this ruleset. |
| `entity_type` | `string` | **Yes** | One of: `"character"`, `"item"`, `"weapon"`, `"armor"`, `"shield"`, `"spell"`. |
| `display_name` | `string` | **Yes** | Human-readable primary label (e.g. `"Arannis"`, `"Longsword +1"`). |
| `description` | `string` | No | Short synopsis or narrative summary. |
| `version` | `string` | No | Data version format (default `"1.0.0"`). |
| `created_at` | `string` | No | ISO 8601 timestamp (e.g. `"2026-09-07T12:00:00Z"`). |
| `updated_at` | `string` | No | ISO 8601 timestamp of last modification. |
| `tags` | `array<string>`| No | Filter and categorization tags (e.g. `["pc", "ranger", "elf"]`). |
| `template_id` | `string` | No | Optional UI template override (e.g. `"character_sheet"`). |
| `properties` | `object` | **Yes** | The entity's payload data (detailed below). |
---
## 4. Entity Specifications & Payloads
### 4.1 Character Entity (`character.json`)
Used for **Player Characters (PCs)**, **Non-Player Characters (NPCs)**, and **Monsters / Creatures**.
#### Required Fields in `properties`:
- `level` (`integer`, 1–20)
- `abilities` (`object` containing `strength`, `dexterity`, `constitution`, `intelligence`, `wisdom`, `charisma`)
- `hit_points` (`object` containing `current` and `max`)
#### Full Property Breakdown:
| Group | Field | Type | Description / Example |
| :--- | :--- | :--- | :--- |
| **Identity** | `player_name` | `string` | Player name (optional for NPCs/monsters). |
| | `class` | `string` | Primary class (e.g. `"Ranger"`). |
| | `subclass` | `string` | Archetype / subclass (e.g. `"Hunter"`). |
| | `race` | `string` | Character race (e.g. `"Elf"`). |
| | `background` | `string` | Background (e.g. `"Outlander"`). |
| | `alignment` | `string` | Moral alignment (e.g. `"Chaotic Good"`). |
| | `experience_points` | `integer` | Current total XP. |
| | `inspiration` | `boolean` | Inspiration point toggle. |
| **Abilities** | `abilities` | `object` | 6 scores. Can be raw integers or score objects: `{"strength": 12, "dexterity": 16, "constitution": 14, "intelligence": 10, "wisdom": 15, "charisma": 8}`. |
| | `proficiency_bonus` | `integer` | Bonus added to proficient rolls (auto-calculated from level or explicit). |
| | `saving_throws` | `array<string>` | Formatted saves (e.g. `["Strength +3", "Dexterity +5"]`). |
| | `skills` | `array<string>` | Formatted skill proficiencies (e.g. `["Athletics +3", "Stealth +5"]`). |
| | `passive_perception` | `integer` | Passive Wisdom (Perception) score (e.g. `15`). |
| **Combat** | `hit_points` | `object` | `{"current": 24, "max": 24, "temp": 0, "formula": "3d10 + 6"}`. |
| | `hit_dice` | `object` | `{"total": 3, "current": 3, "dice": "1d10"}`. |
| | `death_saves` | `object` | `{"successes": 0, "failures": 0}` (0–3 each). |
| | `speed` | `integer` | Walking speed in feet (e.g. `35`). |
| | `speed_desc` | `string` | Display string including flight/swim (e.g. `"30 ft., fly 60 ft."`). |
| | `initiative` | `integer` | Initiative modifier (usually Dex modifier). |
| | `armor_class` | `integer\|object` | Total AC (e.g. `15`). |
| | `equipped_armor` | `object\|null` | Snapshot: `{"name": "Studded Leather", "ac_base": 12, "dex_cap": null}`. |
| | `equipped_shield` | `object\|null` | Snapshot: `{"name": "Shield", "ac_bonus": 2}`. |
| | `attacks` | `array<object>` | Weapon/spell attack rows: `[{"name": "Longbow", "atk_bonus": "+7", "damage": "1d8 + 3", "damage_type": "Piercing", "range": "150/600 ft."}]`. |
| **Inventory & Wealth** | `currency` | `object` | `{"cp": 15, "sp": 40, "ep": 0, "gp": 25, "pp": 0}`. |
| | `inventory` | `array<object>` | Carried items matching `item.json` schema. |
| **Roleplay** | `personality_traits` | `string` | Personality trait text. |
| | `ideals` | `string` | Character ideals. |
| | `bonds` | `string` | Character bonds. |
| | `flaws` | `string` | Character flaws. |
| | `features_and_traits` | `array<object>` | Class/racial features: `[{"name": "Colossus Slayer", "source": "Hunter Archetype", "desc": "..."}]`. |
| **Spellcasting** | `spellcasting` | `object` | `{"class": "Ranger", "ability": "Wisdom", "save_dc": 13, "attack_bonus": 5, "cantrips": [], "slots": {"1": {"total": 3, "expended": 1}}, "spells": [...]}`. |
| **NPC / Monster** | `challenge_rating` | `number\|string` | CR (e.g. `0.25`, `"1/4"`, `14`). |
| | `actions` | `array<object>` | Monster stat block actions: `[{"name": "Scimitar", "desc": "Melee Weapon Attack..."}]`. |
| | `reactions` | `array<object>` | Creature reactions. |
| | `legendary_actions` | `array<object>` | Creature legendary actions. |
#### Complete Export/Import Example (`character`):
```json
{
"$schema": "../../../schema/entity.json",
"uuid": "4c8f3824-3453-48bf-9a0e-a4c336b3bcf2",
"ruleset_id": "open5e",
"entity_type": "character",
"display_name": "Arannis",
"description": "Elven Ranger exploring ancient ruins.",
"version": "1.0.0",
"tags": ["pc", "ranger", "elf"],
"properties": {
"player_name": "Tom",
"level": 3,
"class": "Ranger",
"subclass": "Hunter",
"race": "Elf",
"background": "Outlander",
"alignment": "Chaotic Good",
"experience_points": 900,
"inspiration": true,
"proficiency_bonus": 2,
"initiative": 3,
"speed": 35,
"hit_points": {
"current": 24,
"max": 24,
"temp": 0,
"formula": "3d10 + 6"
},
"hit_dice": {
"total": 3,
"current": 3,
"dice": "1d10"
},
"death_saves": {
"successes": 0,
"failures": 0
},
"armor_class": 15,
"abilities": {
"strength": 12,
"dexterity": 16,
"constitution": 14,
"intelligence": 10,
"wisdom": 15,
"charisma": 8
},
"saving_throws": ["Strength +3", "Dexterity +5"],
"skills": ["Athletics +3", "Perception +5", "Stealth +5", "Survival +5"],
"passive_perception": 15,
"languages": ["Common", "Elvish", "Sylvan"],
"attacks": [
{
"name": "Longbow",
"atk_bonus": "+7",
"damage": "1d8 + 3",
"damage_type": "Piercing",
"range": "150/600 ft."
}
],
"currency": {
"cp": 15,
"sp": 40,
"ep": 0,
"gp": 25,
"pp": 0
}
}
}
```
---
### 4.2 Base Item Entity (`item.json`)
Used for general adventuring gear, tools, containers, consumables, and magic items.
#### Required Fields in `properties`:
- `name` (`string`)
#### Property Fields:
| Field | Type | Default | Description / Enum |
| :--- | :--- | :--- | :--- |
| `name` | `string` | — | Item name (e.g. `"Rope, Hempen (50 feet)"`). |
| `description` | `string` | `""` | Detailed description or rules text. |
| `cost` | `object` | `{"quantity": 1, "unit": "gp"}` | Value (`quantity`: number, `unit`: `"cp"`, `"sp"`, `"ep"`, `"gp"`, `"pp"`). |
| `weight` | `number` | `0` | Weight in pounds (lbs). |
| `rarity` | `string` | `"common"` | `"common"`, `"uncommon"`, `"rare"`, `"very rare"`, `"legendary"`, `"artifact"`. |
| `attunement` | `boolean` | `false` | Whether the item requires attunement. |
| `equipped` | `boolean` | `false` | Equipped/worn status. |
| `quantity` | `integer` | `1` | Count carried. |
| `grants_modifiers`| `array<object>` | `[]` | Stat bonuses granted when equipped (e.g. `[{"target": "armor_class", "value": 1, "type": "bonus", "source": "Cloak of Protection"}]`). |
#### Example Payload (`item`):
```json
{
"$schema": "../../../schema/entity.json",
"uuid": "8b5123d1-419b-4351-92b0-9b34e56711aa",
"ruleset_id": "open5e",
"entity_type": "item",
"display_name": "Potion of Healing",
"description": "A magical red fluid that restores hit points when consumed.",
"properties": {
"name": "Potion of Healing",
"description": "You regain 2d4 + 2 hit points when you drink this potion.",
"cost": { "quantity": 50, "unit": "gp" },
"weight": 0.5,
"rarity": "common",
"attunement": false,
"equipped": false,
"quantity": 2
}
}
```
---
### 4.3 Weapon Entity (`weapon.json`)
Inherits all fields from `item.json` plus combat damage specifications.
#### Required Fields in `properties`:
- `name` (`string`)
- `damage_dice` (`string`, e.g. `"1d8"`, `"2d6"`)
- `damage_type` (`string`: `"bludgeoning"`, `"piercing"`, or `"slashing"`)
#### Additional Property Fields:
| Field | Type | Default | Description / Enum |
| :--- | :--- | :--- | :--- |
| `weapon_category` | `string` | `"simple"` | `"simple"` or `"martial"`. |
| `weapon_range` | `string` | `"melee"` | `"melee"` or `"ranged"`. |
| `damage_dice` | `string` | `"1d6"` | Damage roll formula (e.g. `"1d8"`, `"2d6"`). |
| `damage_type` | `string` | `"slashing"` | `"bludgeoning"`, `"piercing"`, `"slashing"`. |
| `properties` | `array<string>` | `[]` | 5e weapon properties: `"ammunition"`, `"finesse"`, `"heavy"`, `"light"`, `"loading"`, `"range"`, `"reach"`, `"special"`, `"thrown"`, `"two-handed"`, `"versatile"`. |
| `range_normal` | `integer\|null` | `null` | Normal range in feet (e.g. `20` for dagger, `150` for longbow). |
| `range_long` | `integer\|null` | `null` | Disadvantage range in feet (e.g. `60` for dagger, `600` for longbow). |
| `versatile_dice`| `string\|null` | `null` | Alternate two-handed damage die (e.g. `"1d10"` for longsword/battleaxe). |
#### Example Payload (`weapon`):
```json
{
"$schema": "../../../schema/entity.json",
"uuid": "7f139d42-26cb-4029-a1b7-6ec7e34ef399",
"ruleset_id": "open5e",
"entity_type": "weapon",
"display_name": "Longsword",
"description": "A versatile martial melee blade.",
"properties": {
"name": "Longsword",
"description": "A classic double-edged straight blade with a cruciform hilt.",
"cost": { "quantity": 15, "unit": "gp" },
"weight": 3.0,
"rarity": "common",
"weapon_category": "martial",
"weapon_range": "melee",
"damage_dice": "1d8",
"damage_type": "slashing",
"properties": ["versatile"],
"versatile_dice": "1d10",
"equipped": true,
"quantity": 1
}
}
```
---
### 4.4 Armor Entity (`armor.json`)
Inherits all fields from `item.json` plus protection and armor class modifiers.
#### Required Fields in `properties`:
- `name` (`string`)
- `armor_category` (`string`: `"light"`, `"medium"`, or `"heavy"`)
- `ac_base` (`integer`, minimum `0`)
#### Additional Property Fields:
| Field | Type | Description |
| :--- | :--- | :--- |
| `armor_category` | `string` | `"light"`, `"medium"`, or `"heavy"`. |
| `ac_base` | `integer` | Base AC provided (e.g. `11` for Leather, `14` for Scale Mail, `18` for Plate). |
| `ac_modifier` | `integer` | Bonus over base 10 (e.g. `+1` for Leather, `+4` for Scale Mail, `+8` for Plate). |
| `dex_cap` | `integer\|null` | Max Dex modifier allowed: `null` (uncapped, light armor), `2` (medium armor cap), `0` (heavy armor, no Dex). |
| `strength_requirement` | `integer\|null` | Minimum Strength score required without -10 speed penalty (e.g. `13` or `15`). `null` if none. |
| `stealth_disadvantage` | `boolean` | `true` if wearing this armor imposes disadvantage on Stealth checks. |
#### Example Payload (`armor`):
```json
{
"$schema": "../../../schema/entity.json",
"uuid": "21950d81-817b-40fa-9861-bbd51381aa01",
"ruleset_id": "open5e",
"entity_type": "armor",
"display_name": "Breastplate",
"description": "Fitted metal chest armor with leather backing.",
"properties": {
"name": "Breastplate",
"description": "Protects the wearer's torso while leaving limbs free.",
"cost": { "quantity": 400, "unit": "gp" },
"weight": 20.0,
"rarity": "common",
"armor_category": "medium",
"ac_base": 14,
"dex_cap": 2,
"strength_requirement": null,
"stealth_disadvantage": false,
"equipped": true,
"quantity": 1
}
}
```
---
### 4.5 Shield Entity (`shield.json`)
Inherits all fields from `item.json` plus shield-specific AC bonus and penalties.
#### Required Fields in `properties`:
- `name` (`string`)
- `ac_bonus` (`integer`, standard 5e value is `2`)
#### Additional Property Fields:
| Field | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `ac_bonus` | `integer` | `2` | Armor Class bonus added when wielded. |
| `strength_requirement` | `integer\|null` | `null` | Minimum Strength required to wield without penalty. |
| `stealth_disadvantage` | `boolean` | `false` | Imposes disadvantage on Stealth rolls if `true`. |
#### Example Payload (`shield`):
```json
{
"$schema": "../../../schema/entity.json",
"uuid": "43e2f901-b841-47fa-89fa-948123da6711",
"ruleset_id": "open5e",
"entity_type": "shield",
"display_name": "Shield",
"description": "A wooden or metal shield carried in one hand.",
"properties": {
"name": "Shield",
"description": "Wielding a shield increases your Armor Class by 2.",
"cost": { "quantity": 10, "unit": "gp" },
"weight": 6.0,
"rarity": "common",
"ac_bonus": 2,
"strength_requirement": null,
"stealth_disadvantage": false,
"equipped": true,
"quantity": 1
}
}
```
---
### 4.6 Spell Entity (`spell.json`)
Defines complete 5e spells, cantrips, and rituals.
#### Required Fields in `properties`:
- `level` (`integer`, 0–9; 0 represents cantrips)
- `school` (`string`: abjuration, conjuration, divination, enchantment, evocation, illusion, necromancy, transmutation)
- `casting_time` (`string`, e.g. `"1 action"`, `"1 bonus action"`, `"1 reaction"`)
- `range` (`string`, e.g. `"Self"`, `"Touch"`, `"60 feet"`, `"120 feet"`)
- `duration` (`string`, e.g. `"Instantaneous"`, `"Concentration, up to 1 minute"`)
- `description` (`string`, the full rules text)
#### Additional Property Fields:
| Field | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `components` | `object` | `{"verbal": true, "somatic": true, "material": false}` | Component breakdown: `verbal` (`bool`), `somatic` (`bool`), `material` (`bool`), `material_specified` (`string`). |
| `concentration` | `boolean` | `false` | Requires spellcaster concentration. |
| `ritual` | `boolean` | `false` | Can be cast as a 10-minute ritual without expending a spell slot. |
| `higher_levels` | `string` | `""` | Additional damage or target effects when upcast with higher level slots. |
#### Example Payload (`spell`):
```json
{
"$schema": "../../../schema/entity.json",
"uuid": "e58123f0-49a1-4322-9fa1-01f4218aef82",
"ruleset_id": "open5e",
"entity_type": "spell",
"display_name": "Fireball",
"description": "A bright streak that blossoms with a low roar into an explosion of flame.",
"properties": {
"level": 3,
"school": "evocation",
"casting_time": "1 action",
"range": "150 feet",
"duration": "Instantaneous",
"components": {
"verbal": true,
"somatic": true,
"material": true,
"material_specified": "a tiny ball of bat guano and sulfur"
},
"concentration": false,
"ritual": false,
"description": "Each creature in a 20-foot-radius sphere centered on that point must make a Dexterity saving throw. A target takes 8d6 fire damage on a failed save, or half as much damage on a successful one.",
"higher_levels": "When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d6 for each slot level above 3rd."
}
}
```
---
## 5. Validation & Conformance Rules
When parsing or validating imported entities, external apps should follow these rules:
1. **Top-Level Envelope Validation**:
- Verify `ruleset_id === "open5e"`.
- Ensure `entity_type` matches one of the 6 registered entity types (`character`, `item`, `weapon`, `armor`, `shield`, `spell`).
- Ensure `uuid` is a valid unique string or UUID v4.
2. **Sub-Schema Dispatch**:
- Extract `properties` and validate against the corresponding `entities/{entity_type}.json` schema.
3. **Graceful Defaults**:
- If an optional field is missing (such as `temp` HP or `currency.ep`), assume default 0 or empty structures rather than throwing a validation exception.
4. **Extensibility**:
- Extra custom fields in `properties` are permitted (`additionalProperties: true` in base schemas) to allow apps to preserve their own proprietary metadata (e.g. inventory IDs, campaign notes, asset URLs) without breaking import/export compatibility.
---
## 6. Import & Export Implementation Checklist
When implementing an integration adapter in another application:
- [ ] **Export Checklist**:
- [ ] Generate or preserve a stable `uuid` (UUID v4).
- [ ] Set `"ruleset_id": "open5e"`.
- [ ] Set `"entity_type"` to the exact entity type slug.
- [ ] Populate `"display_name"` with the character/item name.
- [ ] Place all game attributes inside the `"properties"` root object.
- [ ] Export numbers as JSON numbers (not stringified quotes, except for dice formulas like `"1d8 + 3"`).
- [ ] Format ISO 8601 dates for `created_at` and `updated_at`.
- [ ] **Import Checklist**:
- [ ] Check `"ruleset_id" === "open5e"`.
- [ ] Inspect `"entity_type"` to determine character vs. item vs. spell importer.
- [ ] Read `properties.abilities` (handle both raw numeric maps and modifier objects).
- [ ] Safely read `properties.hit_points` (`current`, `max`, `temp`).
- [ ] Safely import or map `properties.attacks` and `properties.currency`.
- [ ] If importing items or weapons into a character inventory, unpack nested items into the character's equipment list.

View File

@@ -0,0 +1,127 @@
{
"$schema": "../../schema/manifest.json",
"id": "open5e",
"uuid": "7a35e4d2-f67b-4890-a292-6a7593c72b21",
"name": "Open5e (D&D 5th Edition SRD)",
"version": "1.0.0",
"description": "5th Edition System Reference Document ruleset providing entity schemas and sheet templates.",
"license": "OGL 1.0a",
"author": {
"name": "Open5e Community",
"url": "https://open5e.com"
},
"entities": [
{
"id": "character",
"name": "Player Character",
"description": "A player character with attributes, proficiencies, classes, equipment, and spells.",
"schema": "entities/character.json",
"default_template": "character_sheet",
"templates": [
"character_sheet",
"character_sheet_alt",
"spellcasting_sheet",
"stat_block",
"character_card",
"character_list_item"
]
},
{
"id": "item",
"name": "Item / Gear",
"description": "Generic items, equipment, adventuring gear, and magical items.",
"schema": "entities/item.json"
},
{
"id": "weapon",
"name": "Weapon",
"description": "Simple and martial melee and ranged weapons.",
"schema": "entities/weapon.json"
},
{
"id": "armor",
"name": "Armor",
"description": "Wearable armor with base AC, dex caps, and strength/stealth rules.",
"schema": "entities/armor.json"
},
{
"id": "shield",
"name": "Shield",
"description": "Equippable shields providing armor class bonuses.",
"schema": "entities/shield.json"
},
{
"id": "spell",
"name": "Spell",
"description": "5e Spells with level, school, casting time, range, and components.",
"schema": "entities/spell.json"
}
],
"templates": [
{
"id": "character_sheet",
"name": "Standard Character Sheet",
"description": "Full interactive 5e character sheet matching the official 3-column print layout.",
"entity_types": ["character"],
"mode": "sheet",
"engine": "html",
"html": "templates/character_sheet.html",
"css": ["templates/character_sheet.css"],
"js": ["templates/character_sheet.js"]
},
{
"id": "character_sheet_alt",
"name": "Alternative Character Sheet",
"description": "5e character sheet with saving throws and skills grouped by ability score.",
"entity_types": ["character"],
"mode": "sheet",
"engine": "html",
"html": "templates/character_sheet_alt.html",
"css": ["templates/character_sheet_alt.css"]
},
{
"id": "spellcasting_sheet",
"name": "Spellcasting Sheet",
"description": "Dedicated 5e spellcasting sheet with cantrips, spell slots 1-9, and spell save DC.",
"entity_types": ["character"],
"mode": "sheet",
"engine": "html",
"html": "templates/spellcasting_sheet.html",
"css": ["templates/spellcasting_sheet.css"]
},
{
"id": "stat_block",
"name": "Creature Stat Block",
"description": "Monster manual style stat block with full actions, traits, and combat statistics.",
"entity_types": ["character"],
"mode": "view",
"engine": "html",
"html": "templates/stat_block.html",
"css": ["templates/stat_block.css"]
},
{
"id": "character_card",
"name": "NPC Character Card",
"description": "Compact NPC card with 8 stat boxes and quick action summaries.",
"entity_types": ["character"],
"mode": "card",
"engine": "html",
"html": "templates/character_card.html",
"css": ["templates/character_card.css"]
},
{
"id": "character_list_item",
"name": "Character List Item",
"description": "Uniform fixed-height quick-reference list item card with non-wrapping horizontal action row.",
"entity_types": ["character"],
"mode": "card",
"engine": "html",
"html": "templates/character_list_item.html",
"css": ["templates/character_list_item.css"]
}
],
"assets": {
"path": "assets",
"images": []
}
}

View File

@@ -0,0 +1,155 @@
.card-page-wrapper {
margin: 0;
padding: 20px;
background-color: #f4f6f8;
font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
display: flex;
justify-content: center;
}
.npc-card {
width: 100%;
max-width: 580px;
background: #ffffff;
border: 1.5px solid #922610;
border-radius: 4px;
padding: 16px 18px 18px;
box-sizing: border-box;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}
.card-top {
display: flex;
justify-content: space-between;
align-items: baseline;
}
.card-name {
margin: 0;
font-size: 22px;
font-weight: 700;
color: #922610;
line-height: 1.15;
}
.card-cr {
font-size: 18px;
font-weight: 500;
color: #555;
white-space: nowrap;
}
.card-subtitle {
font-style: italic;
font-size: 13.5px;
color: #666;
margin: 4px 0 14px 0;
}
.stat-boxes-row {
display: flex;
gap: 6px;
justify-content: space-between;
margin-bottom: 14px;
}
.stat-box {
flex: 1;
position: relative;
border: 1.5px solid #222;
border-radius: 2px;
padding: 6px 2px 4px;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 48px;
background: #ffffff;
box-sizing: border-box;
}
.badge-advantage {
position: absolute;
top: 1.5px;
left: 2.5px;
font-size: 8.5px;
font-weight: 800;
color: #111;
line-height: 1;
}
.badge-proficiency {
position: absolute;
top: 1.5px;
right: 2.5px;
font-size: 8.5px;
font-weight: 800;
color: #111;
line-height: 1;
}
.stat-mod {
font-size: 15px;
font-weight: 700;
color: #111;
line-height: 1.1;
}
.stat-code {
font-size: 9.5px;
font-weight: 600;
color: #333;
margin-top: 3px;
text-transform: uppercase;
}
.action-boxes-grid {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.action-card-box {
flex: 1 1 calc(50% - 8px);
min-width: 140px;
border: 1px solid #333;
border-radius: 2px;
padding: 8px 10px;
background: #ffffff;
box-sizing: border-box;
}
.action-box-title {
font-size: 13.5px;
font-weight: 700;
color: #222;
margin-bottom: 4px;
}
.action-box-desc {
font-size: 11.5px;
line-height: 1.35;
color: #444;
}
/* Single action takes full width */
.action-boxes-grid > .action-card-box:only-child {
flex: 1 1 100%;
}
@media (max-width: 440px) {
.card-page-wrapper {
padding: 8px;
}
.stat-boxes-row {
gap: 3px;
}
.stat-mod {
font-size: 13px;
}
.action-card-box {
flex: 1 1 100%;
}
}

View File

@@ -0,0 +1,118 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{display_name}} - Character Card</title>
<link rel="stylesheet" href="character_card.css">
</head>
<body class="card-page-wrapper">
<div class="npc-card">
<!-- Top Bar: Name & Challenge/Level -->
<div class="card-top">
<h2 class="card-name">{{display_name}}</h2>
<div class="card-cr">
{{#if properties.challenge_rating}}
CR {{properties.challenge_rating}}
{{else if properties.cr}}
CR {{properties.cr}}
{{else if properties.level}}
LVL {{properties.level}}
{{else}}
CR 1
{{/if}}
</div>
</div>
<!-- Subtitle: Size, Type, Subtype, Alignment -->
<div class="card-subtitle">
{{#if properties.size}}{{properties.size}}{{else}}medium{{/if}}
{{#if properties.type}}{{properties.type}}{{else}}Humanoid{{/if}}{{#if properties.subtype}} ({{properties.subtype}}){{else if properties.race}} ({{properties.race}}){{/if}},
{{#if properties.alignment}}{{properties.alignment}}{{else}}unaligned{{/if}}
</div>
<!-- 8 Stat Boxes Row: S, D, C, I, W, Ch, AC, HP -->
<div class="stat-boxes-row">
<!-- STR -->
<div class="stat-box">
<span class="badge-advantage">{{advBadge properties "str"}}</span>
<span class="badge-proficiency">{{profBadge properties.saving_throws "str"}}</span>
<span class="stat-mod">{{modText properties.abilities.strength}}</span>
<span class="stat-code">S</span>
</div>
<!-- DEX -->
<div class="stat-box">
<span class="badge-advantage">{{advBadge properties "dex"}}</span>
<span class="badge-proficiency">{{profBadge properties.saving_throws "dex"}}</span>
<span class="stat-mod">{{modText properties.abilities.dexterity}}</span>
<span class="stat-code">D</span>
</div>
<!-- CON -->
<div class="stat-box">
<span class="badge-advantage">{{advBadge properties "con"}}</span>
<span class="badge-proficiency">{{profBadge properties.saving_throws "con"}}</span>
<span class="stat-mod">{{modText properties.abilities.constitution}}</span>
<span class="stat-code">C</span>
</div>
<!-- INT -->
<div class="stat-box">
<span class="badge-advantage">{{advBadge properties "int"}}</span>
<span class="badge-proficiency">{{profBadge properties.saving_throws "int"}}</span>
<span class="stat-mod">{{modText properties.abilities.intelligence}}</span>
<span class="stat-code">I</span>
</div>
<!-- WIS -->
<div class="stat-box">
<span class="badge-advantage">{{advBadge properties "wis"}}</span>
<span class="badge-proficiency">{{profBadge properties.saving_throws "wis"}}</span>
<span class="stat-mod">{{modText properties.abilities.wisdom}}</span>
<span class="stat-code">W</span>
</div>
<!-- CHA -->
<div class="stat-box">
<span class="badge-advantage">{{advBadge properties "cha"}}</span>
<span class="badge-proficiency">{{profBadge properties.saving_throws "cha"}}</span>
<span class="stat-mod">{{modText properties.abilities.charisma}}</span>
<span class="stat-code">Ch</span>
</div>
<!-- AC -->
<div class="stat-box">
<span class="stat-mod">{{val properties.armor_class}}</span>
<span class="stat-code">AC</span>
</div>
<!-- HP -->
<div class="stat-box">
<span class="stat-mod">
{{#if properties.hit_points.current}}
{{properties.hit_points.current}}
{{else if properties.hit_points.max}}
{{properties.hit_points.max}}
{{else}}
{{val properties.hit_points}}
{{/if}}
</span>
<span class="stat-code">HP</span>
</div>
</div>
<!-- Action Summary Boxes -->
{{#if properties.actions}}
<div class="action-boxes-grid">
{{#each properties.actions}}
<div class="action-card-box">
<div class="action-box-title">{{this.name}}</div>
<div class="action-box-desc">{{formatText this.desc}}</div>
</div>
{{/each}}
</div>
{{/if}}
</div>
</body>
</html>

View File

@@ -0,0 +1,245 @@
/* Character List Item Template - Uniform Fixed Height with Non-Wrapping Horizontal Actions */
:root {
--card-border: #922610;
--card-title: #922610;
--box-border: #222222;
--bg-page: #f4f6f8;
--bg-card: #ffffff;
--bg-box: #ffffff;
--text-main: #111111;
--text-muted: #666666;
--font-sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
body.list-item-page-wrapper {
margin: 0;
padding: 16px;
background-color: var(--bg-page);
font-family: var(--font-sans);
display: flex;
justify-content: center;
}
/* Card has fixed height so all list cards are identical height */
.npc-list-card {
width: 100%;
max-width: 580px;
height: 236px;
background: var(--bg-card);
border: 1.5px solid var(--card-border);
border-radius: 4px;
padding: 12px 14px;
box-sizing: border-box;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
display: flex;
flex-direction: column;
overflow: hidden;
}
/* Header */
.card-top {
display: flex;
justify-content: space-between;
align-items: baseline;
flex-shrink: 0;
}
.card-name {
margin: 0;
font-size: 20px;
font-weight: 700;
color: var(--card-title);
line-height: 1.15;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.card-cr {
font-size: 16px;
font-weight: 500;
color: #555;
white-space: nowrap;
margin-left: 8px;
}
.card-subtitle {
font-style: italic;
font-size: 12px;
color: var(--text-muted);
margin: 2px 0 10px 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex-shrink: 0;
}
/* 8 Stat Boxes */
.stat-boxes-row {
display: flex;
gap: 5px;
justify-content: space-between;
margin-bottom: 10px;
flex-shrink: 0;
}
.stat-box {
flex: 1;
position: relative;
border: 1.2px solid var(--box-border);
border-radius: 2px;
padding: 4px 1px 3px;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 44px;
background: var(--bg-box);
box-sizing: border-box;
}
.badge-advantage {
position: absolute;
top: 1px;
left: 2px;
font-size: 8px;
font-weight: 800;
color: #111;
line-height: 1;
}
.badge-proficiency {
position: absolute;
top: 1px;
right: 2px;
font-size: 8px;
font-weight: 800;
color: #111;
line-height: 1;
}
.stat-mod {
font-size: 14px;
font-weight: 700;
color: var(--text-main);
line-height: 1.1;
}
.stat-code {
font-size: 9px;
font-weight: 600;
color: #333;
margin-top: 2px;
text-transform: uppercase;
}
/* Actions Row: Single Non-Wrapping Row with Horizontal Scrolling */
.action-row-container {
flex: 1;
display: flex;
min-height: 0; /* Allows container to shrink inside flex parent */
overflow: hidden;
}
.action-boxes-row {
display: flex;
flex-wrap: nowrap;
gap: 8px;
width: 100%;
overflow-x: auto;
overflow-y: hidden;
scrollbar-width: thin;
scrollbar-color: #ccc transparent;
-webkit-overflow-scrolling: touch;
padding-bottom: 2px;
}
.action-boxes-row::-webkit-scrollbar {
height: 4px;
}
.action-boxes-row::-webkit-scrollbar-thumb {
background: #ccc;
border-radius: 2px;
}
.action-boxes-row::-webkit-scrollbar-track {
background: transparent;
}
/* Individual Action Card */
.action-card-box {
flex: 0 0 170px;
max-width: 240px;
border: 1px solid #333;
border-radius: 2px;
padding: 6px 8px;
background: #ffffff;
box-sizing: border-box;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* When only 1 action exists (e.g. Acolyte Club), expand full width */
.action-boxes-row > .action-card-box:only-child {
flex: 1 0 100%;
max-width: 100%;
}
.action-box-title {
font-size: 12.5px;
font-weight: 700;
color: #222;
margin-bottom: 2px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex-shrink: 0;
}
.action-box-desc {
font-size: 10.5px;
line-height: 1.25;
color: #444;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
}
/* Empty State (e.g. Unnamed Monster) */
.no-actions-box {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
border: 1px dashed #ccc;
border-radius: 2px;
background: #fafafa;
}
.no-actions-text {
font-size: 11px;
color: #999;
font-style: italic;
}
/* Responsive */
@media (max-width: 440px) {
.list-item-page-wrapper {
padding: 6px;
}
.stat-boxes-row {
gap: 3px;
}
.stat-mod {
font-size: 12px;
}
.action-card-box {
flex: 0 0 145px;
}
}

View File

@@ -0,0 +1,127 @@
<!DOCTYPE html>
<html lang="en">
<head>
<base href="/rulesets/open5e/templates/">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{display_name}} - List Item</title>
<link rel="stylesheet" href="character_list_item.css">
</head>
<body class="list-item-page-wrapper">
<div class="npc-list-card">
<!-- Header: Name & Challenge/Level -->
<div class="card-top">
<h2 class="card-name">{{display_name}}</h2>
<div class="card-cr">
{{#if properties.challenge_rating}}
CR {{properties.challenge_rating}}
{{else if properties.cr}}
CR {{properties.cr}}
{{else if properties.level}}
LVL {{properties.level}}
{{else}}
CR 1
{{/if}}
</div>
</div>
<!-- Subtitle: Size, Type, Subtype, Alignment -->
<div class="card-subtitle">
{{#if properties.size}}{{properties.size}}{{else}}medium{{/if}}
{{#if properties.type}}{{properties.type}}{{else}}Humanoid{{/if}}{{#if properties.subtype}} ({{properties.subtype}}){{else if properties.race}} ({{properties.race}}){{/if}},
{{#if properties.alignment}}{{properties.alignment}}{{else}}unaligned{{/if}}
</div>
<!-- 8 Stat Boxes Row: S, D, C, I, W, Ch, AC, HP -->
<div class="stat-boxes-row">
<!-- STR -->
<div class="stat-box">
<span class="badge-advantage">{{advBadge properties "str"}}</span>
<span class="badge-proficiency">{{profBadge properties.saving_throws "str"}}</span>
<span class="stat-mod">{{modText properties.abilities.strength}}</span>
<span class="stat-code">S</span>
</div>
<!-- DEX -->
<div class="stat-box">
<span class="badge-advantage">{{advBadge properties "dex"}}</span>
<span class="badge-proficiency">{{profBadge properties.saving_throws "dex"}}</span>
<span class="stat-mod">{{modText properties.abilities.dexterity}}</span>
<span class="stat-code">D</span>
</div>
<!-- CON -->
<div class="stat-box">
<span class="badge-advantage">{{advBadge properties "con"}}</span>
<span class="badge-proficiency">{{profBadge properties.saving_throws "con"}}</span>
<span class="stat-mod">{{modText properties.abilities.constitution}}</span>
<span class="stat-code">C</span>
</div>
<!-- INT -->
<div class="stat-box">
<span class="badge-advantage">{{advBadge properties "int"}}</span>
<span class="badge-proficiency">{{profBadge properties.saving_throws "int"}}</span>
<span class="stat-mod">{{modText properties.abilities.intelligence}}</span>
<span class="stat-code">I</span>
</div>
<!-- WIS -->
<div class="stat-box">
<span class="badge-advantage">{{advBadge properties "wis"}}</span>
<span class="badge-proficiency">{{profBadge properties.saving_throws "wis"}}</span>
<span class="stat-mod">{{modText properties.abilities.wisdom}}</span>
<span class="stat-code">W</span>
</div>
<!-- CHA -->
<div class="stat-box">
<span class="badge-advantage">{{advBadge properties "cha"}}</span>
<span class="badge-proficiency">{{profBadge properties.saving_throws "cha"}}</span>
<span class="stat-mod">{{modText properties.abilities.charisma}}</span>
<span class="stat-code">Ch</span>
</div>
<!-- AC -->
<div class="stat-box">
<span class="stat-mod">{{val properties.armor_class}}</span>
<span class="stat-code">AC</span>
</div>
<!-- HP -->
<div class="stat-box">
<span class="stat-mod">
{{#if properties.hit_points.current}}
{{properties.hit_points.current}}
{{else if properties.hit_points.max}}
{{properties.hit_points.max}}
{{else}}
{{val properties.hit_points}}
{{/if}}
</span>
<span class="stat-code">HP</span>
</div>
</div>
<!-- Actions Row: Single Non-Wrapping Row with Horizontal Scroll -->
<div class="action-row-container">
{{#if properties.actions}}
<div class="action-boxes-row">
{{#each properties.actions}}
<div class="action-card-box">
<div class="action-box-title">{{this.name}}</div>
<div class="action-box-desc">{{formatText this.desc}}</div>
</div>
{{/each}}
</div>
{{else}}
<div class="no-actions-box">
<span class="no-actions-text">&mdash; No listed actions &mdash;</span>
</div>
{{/if}}
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,585 @@
/* D&D 5e Standard Character Sheet Styles */
:root {
--border-color: #2b2b2b;
--accent-red: #922610;
--bg-page: #eaedf0;
--bg-sheet: #ffffff;
--bg-box: #f9fbfd;
--text-main: #1e1e1e;
--text-muted: #666666;
--font-sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
--font-serif: "Libre Baskerville", "Georgia", serif;
}
body.sheet-page-wrapper {
margin: 0;
padding: 24px;
background-color: var(--bg-page);
font-family: var(--font-sans);
color: var(--text-main);
display: flex;
justify-content: center;
box-sizing: border-box;
}
.character-sheet-container {
width: 100%;
max-width: 1050px;
background: var(--bg-sheet);
border: 2px solid var(--border-color);
border-radius: 6px;
padding: 20px 24px 24px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
box-sizing: border-box;
}
/* ================= HEADER ================= */
.sheet-header {
display: grid;
grid-template-columns: 320px 1fr;
gap: 16px;
align-items: stretch;
border-bottom: 2px solid var(--border-color);
padding-bottom: 16px;
margin-bottom: 20px;
}
.header-name-box {
border: 1.5px solid var(--border-color);
border-radius: 4px;
padding: 12px 16px;
display: flex;
flex-direction: column;
justify-content: flex-end;
background: var(--bg-box);
}
.character-name {
font-family: var(--font-serif);
font-size: 26px;
color: var(--accent-red);
margin: 0 0 6px 0;
line-height: 1.1;
word-break: break-word;
}
.header-label {
font-size: 9.5px;
font-weight: bold;
color: var(--text-muted);
letter-spacing: 0.5px;
}
.header-details-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px 12px;
border: 1.5px solid var(--border-color);
border-radius: 4px;
padding: 10px 14px;
background: var(--bg-box);
}
.detail-cell {
display: flex;
flex-direction: column;
justify-content: flex-end;
border-bottom: 1px solid #ccc;
padding-bottom: 3px;
}
.detail-val {
font-size: 13.5px;
font-weight: 600;
color: var(--text-main);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-bottom: 2px;
}
/* ================= 3-COLUMN MAIN GRID ================= */
.sheet-main-grid {
display: grid;
grid-template-columns: 320px 340px 1fr;
gap: 16px;
}
.sheet-col {
display: flex;
flex-direction: column;
gap: 12px;
}
/* Generic Section Box */
.section-box {
border: 1.5px solid var(--border-color);
border-radius: 4px;
padding: 10px 12px;
background: #ffffff;
position: relative;
box-sizing: border-box;
}
.box-bottom-label {
text-align: center;
font-size: 9.5px;
font-weight: bold;
color: var(--text-muted);
letter-spacing: 0.5px;
margin-top: 6px;
padding-top: 4px;
border-top: 1px solid #eee;
}
/* ================= LEFT COLUMN ================= */
.abilities-and-skills-row {
display: grid;
grid-template-columns: 88px 1fr;
gap: 12px;
}
/* 6 Abilities */
.abilities-stack {
display: flex;
flex-direction: column;
gap: 10px;
}
.ability-box {
border: 1.5px solid var(--border-color);
border-radius: 6px;
padding: 6px 4px 4px;
display: flex;
flex-direction: column;
align-items: center;
background: var(--bg-box);
text-align: center;
}
.ab-title {
font-size: 8.5px;
font-weight: bold;
color: var(--accent-red);
letter-spacing: 0.5px;
}
.ab-modifier {
font-size: 20px;
font-weight: bold;
color: var(--text-main);
margin: 2px 0;
line-height: 1;
}
.ab-score-pill {
font-size: 11px;
font-weight: 600;
color: #333;
border: 1px solid #999;
border-radius: 10px;
padding: 1px 8px;
background: #ffffff;
}
/* Skills & Saves Stack */
.skills-and-saves-stack {
display: flex;
flex-direction: column;
gap: 10px;
}
.top-stat-pill {
border: 1.5px solid var(--border-color);
border-radius: 16px;
padding: 4px 10px;
display: flex;
align-items: center;
gap: 8px;
background: var(--bg-box);
}
.pill-checkbox {
width: 14px;
height: 14px;
border: 1.5px solid var(--border-color);
border-radius: 50%;
display: inline-block;
}
.pill-checkbox.checked {
background-color: var(--accent-red);
}
.pill-value {
font-size: 13px;
font-weight: bold;
color: var(--text-main);
border-right: 1px solid #ccc;
padding-right: 8px;
}
.pill-label {
font-size: 9px;
font-weight: bold;
color: var(--text-muted);
}
/* Proficiency Lists (Saves & Skills) */
.prof-list {
list-style: none;
margin: 0;
padding: 0;
}
.prof-item {
display: flex;
align-items: center;
font-size: 11.5px;
margin-bottom: 3.5px;
gap: 6px;
line-height: 1.2;
}
.prof-item .dot {
width: 8px;
height: 8px;
border: 1.2px solid var(--border-color);
border-radius: 50%;
display: inline-block;
flex-shrink: 0;
}
.prof-item .dot.filled {
background-color: var(--accent-red);
border-color: var(--accent-red);
}
.prof-bonus {
font-weight: 700;
width: 22px;
text-align: right;
flex-shrink: 0;
}
.prof-name {
color: #333;
}
.skill-attr {
color: #888;
font-size: 10px;
}
/* Passive Perception */
.passive-perception-box {
border: 1.5px solid var(--border-color);
border-radius: 18px;
padding: 6px 12px;
display: flex;
align-items: center;
gap: 10px;
background: var(--bg-box);
}
.passive-score {
font-size: 15px;
font-weight: bold;
color: var(--text-main);
border: 1px solid var(--border-color);
border-radius: 50%;
width: 26px;
height: 26px;
display: flex;
align-items: center;
justify-content: center;
background: #ffffff;
flex-shrink: 0;
}
.passive-label {
font-size: 9.5px;
font-weight: bold;
color: var(--text-muted);
}
.prof-block-content {
font-size: 11.5px;
line-height: 1.45;
}
.prof-line {
margin-bottom: 4px;
}
/* ================= MIDDLE COLUMN ================= */
.combat-top-row {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
}
.combat-badge {
border: 1.5px solid var(--border-color);
border-radius: 6px;
padding: 8px 4px;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: var(--bg-box);
}
.badge-ac {
border-color: var(--accent-red);
}
.badge-value {
font-size: 22px;
font-weight: bold;
color: var(--text-main);
line-height: 1.1;
}
.badge-label {
font-size: 8.5px;
font-weight: bold;
color: var(--text-muted);
margin-top: 3px;
}
/* HP Boxes */
.hp-max-line {
font-size: 10.5px;
color: #666;
border-bottom: 1px solid #eee;
padding-bottom: 4px;
}
.hp-current-val, .temp-hp-val {
font-size: 28px;
font-weight: bold;
text-align: center;
padding: 8px 0;
color: var(--text-main);
}
.hd-and-death-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
}
.half-box {
padding: 6px 8px;
}
.hd-total-line {
font-size: 9.5px;
color: #666;
}
.hd-current-val {
font-size: 18px;
font-weight: bold;
text-align: center;
padding: 4px 0;
}
.death-save-line {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 9px;
font-weight: bold;
margin: 3px 0;
}
.ds-bubbles {
display: flex;
gap: 4px;
}
.ds-bubbles .bubble {
width: 9px;
height: 9px;
border: 1.2px solid var(--border-color);
border-radius: 50%;
display: inline-block;
}
.ds-bubbles .bubble.filled {
background-color: var(--accent-red);
}
/* Attacks Table */
.attacks-table {
width: 100%;
border-collapse: collapse;
font-size: 11px;
margin-bottom: 8px;
}
.attacks-table th {
font-size: 8.5px;
font-weight: bold;
color: var(--text-muted);
border-bottom: 1px solid #ccc;
padding: 2px 4px;
text-align: left;
}
.attacks-table td {
padding: 5px 4px;
border-bottom: 1px solid #eee;
}
.atk-name {
font-weight: 600;
}
.atk-bonus {
font-weight: 700;
color: var(--accent-red);
}
.attack-notes {
font-size: 10.5px;
line-height: 1.35;
color: #444;
margin-top: 6px;
max-height: 120px;
overflow-y: auto;
}
.attack-note-item {
margin: 4px 0;
}
/* Equipment */
.equipment-layout {
display: grid;
grid-template-columns: 56px 1fr;
gap: 8px;
}
.coins-stack {
display: flex;
flex-direction: column;
gap: 4px;
}
.coin-row {
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 2px 4px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 10px;
background: var(--bg-box);
}
.coin-tag {
font-weight: bold;
font-size: 8.5px;
color: var(--accent-red);
}
.coin-val {
font-weight: 600;
}
.items-list-container {
max-height: 180px;
overflow-y: auto;
}
.items-list {
list-style: none;
margin: 0;
padding: 0;
font-size: 11px;
}
.item-row {
display: flex;
justify-content: space-between;
padding: 3px 0;
border-bottom: 1px solid #eee;
}
.equipped-tag {
color: var(--accent-red);
font-weight: bold;
}
.item-meta {
color: #777;
font-size: 10px;
}
/* ================= RIGHT COLUMN ================= */
.roleplay-box {
min-height: 64px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.box-content {
font-size: 11.5px;
line-height: 1.4;
color: #333;
}
.box-content p {
margin: 0;
}
.empty-hint {
color: #999;
font-style: italic;
font-size: 11px;
}
.features-box {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 250px;
}
.features-content {
font-size: 11.5px;
line-height: 1.4;
}
.feature-item {
margin-bottom: 8px;
}
.feature-name {
color: var(--accent-red);
display: block;
margin-bottom: 2px;
}
.feature-desc {
margin: 0;
}
/* Responsive Styles */
@media (max-width: 900px) {
.sheet-header {
grid-template-columns: 1fr;
}
.sheet-main-grid {
grid-template-columns: 1fr;
}
.abilities-and-skills-row {
grid-template-columns: 90px 1fr;
}
}

View File

@@ -0,0 +1,511 @@
<!DOCTYPE html>
<html lang="en">
<head>
<base href="/rulesets/open5e/templates/">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{display_name}} - Character Sheet</title>
<link rel="stylesheet" href="character_sheet.css">
</head>
<body class="sheet-page-wrapper">
<div class="character-sheet-container">
<!-- Top Header Banner -->
<header class="sheet-header">
<div class="header-name-box">
<h1 class="character-name">{{display_name}}</h1>
<label class="header-label">CHARACTER NAME</label>
</div>
<div class="header-details-grid">
<div class="detail-cell">
<div class="detail-val">{{properties.class}}{{#if properties.subclass}} ({{properties.subclass}}){{/if}} {{properties.level}}</div>
<label class="header-label">CLASS &amp; LEVEL</label>
</div>
<div class="detail-cell">
<div class="detail-val">{{#if properties.background}}{{properties.background}}{{else}}&mdash;{{/if}}</div>
<label class="header-label">BACKGROUND</label>
</div>
<div class="detail-cell">
<div class="detail-val">{{#if properties.player_name}}{{properties.player_name}}{{else}}&mdash;{{/if}}</div>
<label class="header-label">PLAYER NAME</label>
</div>
<div class="detail-cell">
<div class="detail-val">{{properties.race}}</div>
<label class="header-label">RACE</label>
</div>
<div class="detail-cell">
<div class="detail-val">{{properties.alignment}}</div>
<label class="header-label">ALIGNMENT</label>
</div>
<div class="detail-cell">
<div class="detail-val">{{#if properties.experience_points}}{{properties.experience_points}}{{else}}0{{/if}} XP</div>
<label class="header-label">EXPERIENCE POINTS</label>
</div>
</div>
</header>
<!-- Main 3-Column Body -->
<main class="sheet-main-grid">
<!-- ================= LEFT COLUMN ================= -->
<section class="sheet-col col-left">
<div class="abilities-and-skills-row">
<!-- 6 Ability Score Boxes -->
<div class="abilities-stack">
<!-- STR -->
<div class="ability-box">
<span class="ab-title">STRENGTH</span>
<span class="ab-modifier">{{modText properties.abilities.strength}}</span>
<div class="ab-score-pill">{{val properties.abilities.strength}}</div>
</div>
<!-- DEX -->
<div class="ability-box">
<span class="ab-title">DEXTERITY</span>
<span class="ab-modifier">{{modText properties.abilities.dexterity}}</span>
<div class="ab-score-pill">{{val properties.abilities.dexterity}}</div>
</div>
<!-- CON -->
<div class="ability-box">
<span class="ab-title">CONSTITUTION</span>
<span class="ab-modifier">{{modText properties.abilities.constitution}}</span>
<div class="ab-score-pill">{{val properties.abilities.constitution}}</div>
</div>
<!-- INT -->
<div class="ability-box">
<span class="ab-title">INTELLIGENCE</span>
<span class="ab-modifier">{{modText properties.abilities.intelligence}}</span>
<div class="ab-score-pill">{{val properties.abilities.intelligence}}</div>
</div>
<!-- WIS -->
<div class="ability-box">
<span class="ab-title">WISDOM</span>
<span class="ab-modifier">{{modText properties.abilities.wisdom}}</span>
<div class="ab-score-pill">{{val properties.abilities.wisdom}}</div>
</div>
<!-- CHA -->
<div class="ability-box">
<span class="ab-title">CHARISMA</span>
<span class="ab-modifier">{{modText properties.abilities.charisma}}</span>
<div class="ab-score-pill">{{val properties.abilities.charisma}}</div>
</div>
</div>
<!-- Proficiency, Inspiration, Saves & Skills -->
<div class="skills-and-saves-stack">
<!-- Inspiration & Proficiency Bonus -->
<div class="top-stat-pill">
<span class="pill-checkbox {{#if properties.inspiration}}checked{{/if}}"></span>
<span class="pill-label">INSPIRATION</span>
</div>
<div class="top-stat-pill">
<span class="pill-value">+{{calcProf properties.level properties.cr}}</span>
<span class="pill-label">PROFICIENCY BONUS</span>
</div>
<!-- Saving Throws Box -->
<div class="section-box saves-box">
<ul class="prof-list">
<li class="prof-item">
<span class="dot {{#if (hasSave properties.saving_throws 'str')}}filled{{/if}}"></span>
<span class="prof-bonus">{{saveBonus properties 'strength'}}</span>
<span class="prof-name">Strength</span>
</li>
<li class="prof-item">
<span class="dot {{#if (hasSave properties.saving_throws 'dex')}}filled{{/if}}"></span>
<span class="prof-bonus">{{saveBonus properties 'dexterity'}}</span>
<span class="prof-name">Dexterity</span>
</li>
<li class="prof-item">
<span class="dot {{#if (hasSave properties.saving_throws 'con')}}filled{{/if}}"></span>
<span class="prof-bonus">{{saveBonus properties 'constitution'}}</span>
<span class="prof-name">Constitution</span>
</li>
<li class="prof-item">
<span class="dot {{#if (hasSave properties.saving_throws 'int')}}filled{{/if}}"></span>
<span class="prof-bonus">{{saveBonus properties 'intelligence'}}</span>
<span class="prof-name">Intelligence</span>
</li>
<li class="prof-item">
<span class="dot {{#if (hasSave properties.saving_throws 'wis')}}filled{{/if}}"></span>
<span class="prof-bonus">{{saveBonus properties 'wisdom'}}</span>
<span class="prof-name">Wisdom</span>
</li>
<li class="prof-item">
<span class="dot {{#if (hasSave properties.saving_throws 'cha')}}filled{{/if}}"></span>
<span class="prof-bonus">{{saveBonus properties 'charisma'}}</span>
<span class="prof-name">Charisma</span>
</li>
</ul>
<div class="box-bottom-label">SAVING THROWS</div>
</div>
<!-- Skills Box (Alphabetical 18 Skills) -->
<div class="section-box skills-box">
<ul class="prof-list">
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'acrobatics')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'acrobatics' 'dexterity'}}</span>
<span class="prof-name">Acrobatics <small class="skill-attr">(Dex)</small></span>
</li>
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'animal_handling')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'animal_handling' 'wisdom'}}</span>
<span class="prof-name">Animal Handling <small class="skill-attr">(Wis)</small></span>
</li>
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'arcana')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'arcana' 'intelligence'}}</span>
<span class="prof-name">Arcana <small class="skill-attr">(Int)</small></span>
</li>
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'athletics')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'athletics' 'strength'}}</span>
<span class="prof-name">Athletics <small class="skill-attr">(Str)</small></span>
</li>
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'deception')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'deception' 'charisma'}}</span>
<span class="prof-name">Deception <small class="skill-attr">(Cha)</small></span>
</li>
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'history')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'history' 'intelligence'}}</span>
<span class="prof-name">History <small class="skill-attr">(Int)</small></span>
</li>
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'insight')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'insight' 'wisdom'}}</span>
<span class="prof-name">Insight <small class="skill-attr">(Wis)</small></span>
</li>
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'intimidation')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'intimidation' 'charisma'}}</span>
<span class="prof-name">Intimidation <small class="skill-attr">(Cha)</small></span>
</li>
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'investigation')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'investigation' 'intelligence'}}</span>
<span class="prof-name">Investigation <small class="skill-attr">(Int)</small></span>
</li>
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'medicine')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'medicine' 'wisdom'}}</span>
<span class="prof-name">Medicine <small class="skill-attr">(Wis)</small></span>
</li>
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'nature')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'nature' 'intelligence'}}</span>
<span class="prof-name">Nature <small class="skill-attr">(Int)</small></span>
</li>
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'perception')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'perception' 'wisdom'}}</span>
<span class="prof-name">Perception <small class="skill-attr">(Wis)</small></span>
</li>
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'performance')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'performance' 'charisma'}}</span>
<span class="prof-name">Performance <small class="skill-attr">(Cha)</small></span>
</li>
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'persuasion')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'persuasion' 'charisma'}}</span>
<span class="prof-name">Persuasion <small class="skill-attr">(Cha)</small></span>
</li>
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'religion')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'religion' 'intelligence'}}</span>
<span class="prof-name">Religion <small class="skill-attr">(Int)</small></span>
</li>
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'sleight_of_hand')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'sleight_of_hand' 'dexterity'}}</span>
<span class="prof-name">Sleight of Hand <small class="skill-attr">(Dex)</small></span>
</li>
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'stealth')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'stealth' 'dexterity'}}</span>
<span class="prof-name">Stealth <small class="skill-attr">(Dex)</small></span>
</li>
<li class="prof-item">
<span class="dot {{#if (isSkillProf properties.skills 'survival')}}filled{{/if}}"></span>
<span class="prof-bonus">{{skillBonus properties 'survival' 'wisdom'}}</span>
<span class="prof-name">Survival <small class="skill-attr">(Wis)</small></span>
</li>
</ul>
<div class="box-bottom-label">SKILLS</div>
</div>
</div>
</div>
<!-- Passive Perception Box -->
<div class="passive-perception-box">
<span class="passive-score">{{passivePerception properties}}</span>
<span class="passive-label">PASSIVE WISDOM (PERCEPTION)</span>
</div>
<!-- Other Proficiencies & Languages Box -->
<div class="section-box proficiencies-box">
<div class="prof-block-content">
{{#if properties.other_proficiencies_and_languages.armor}}
<div class="prof-line"><strong>Armor:</strong> {{join properties.other_proficiencies_and_languages.armor}}</div>
{{/if}}
{{#if properties.other_proficiencies_and_languages.weapons}}
<div class="prof-line"><strong>Weapons:</strong> {{join properties.other_proficiencies_and_languages.weapons}}</div>
{{/if}}
{{#if properties.other_proficiencies_and_languages.tools}}
<div class="prof-line"><strong>Tools:</strong> {{join properties.other_proficiencies_and_languages.tools}}</div>
{{/if}}
{{#if properties.languages}}
<div class="prof-line"><strong>Languages:</strong> {{join properties.languages}}</div>
{{else if properties.other_proficiencies_and_languages.languages}}
<div class="prof-line"><strong>Languages:</strong> {{join properties.other_proficiencies_and_languages.languages}}</div>
{{/if}}
</div>
<div class="box-bottom-label">OTHER PROFICIENCIES &amp; LANGUAGES</div>
</div>
</section>
<!-- ================= MIDDLE COLUMN ================= -->
<section class="sheet-col col-middle">
<!-- Combat Top Row: AC, Initiative, Speed -->
<div class="combat-top-row">
<div class="combat-badge badge-ac">
<span class="badge-value">{{val properties.armor_class}}</span>
<span class="badge-label">ARMOR CLASS</span>
</div>
<div class="combat-badge badge-init">
<span class="badge-value">{{#if properties.initiative}}{{modSign properties.initiative}}{{else}}{{modText properties.abilities.dexterity}}{{/if}}</span>
<span class="badge-label">INITIATIVE</span>
</div>
<div class="combat-badge badge-speed">
<span class="badge-value">{{#if properties.speed}}{{properties.speed}} ft.{{else}}30 ft.{{/if}}</span>
<span class="badge-label">SPEED</span>
</div>
</div>
<!-- Current Hit Points -->
<div class="section-box hp-box">
<div class="hp-max-line">
Hit Point Maximum: <strong>{{properties.hit_points.max}}</strong>
</div>
<div class="hp-current-val">
{{properties.hit_points.current}}
</div>
<div class="box-bottom-label">CURRENT HIT POINTS</div>
</div>
<!-- Temporary Hit Points -->
<div class="section-box temp-hp-box">
<div class="temp-hp-val">
{{#if properties.hit_points.temp}}{{properties.hit_points.temp}}{{else}}--{{/if}}
</div>
<div class="box-bottom-label">TEMPORARY HIT POINTS</div>
</div>
<!-- Hit Dice & Death Saves Row -->
<div class="hd-and-death-row">
<!-- Hit Dice -->
<div class="section-box half-box hd-box">
<div class="hd-total-line">Total: {{#if properties.hit_dice.total}}{{properties.hit_dice.total}}{{else}}{{properties.level}}{{/if}}</div>
<div class="hd-current-val">
{{#if properties.hit_dice.dice}}{{properties.hit_dice.dice}}{{else if properties.hit_points.hit_dice}}{{properties.hit_points.hit_dice}}{{else}}1d10{{/if}}
</div>
<div class="box-bottom-label">HIT DICE</div>
</div>
<!-- Death Saves -->
<div class="section-box half-box death-saves-box">
<div class="death-save-line">
<span class="ds-title">SUCCESSES</span>
<span class="ds-bubbles">
<span class="bubble {{#if (gte properties.death_saves.successes 1)}}filled{{/if}}"></span>
<span class="bubble {{#if (gte properties.death_saves.successes 2)}}filled{{/if}}"></span>
<span class="bubble {{#if (gte properties.death_saves.successes 3)}}filled{{/if}}"></span>
</span>
</div>
<div class="death-save-line">
<span class="ds-title">FAILURES</span>
<span class="ds-bubbles">
<span class="bubble {{#if (gte properties.death_saves.failures 1)}}filled{{/if}}"></span>
<span class="bubble {{#if (gte properties.death_saves.failures 2)}}filled{{/if}}"></span>
<span class="bubble {{#if (gte properties.death_saves.failures 3)}}filled{{/if}}"></span>
</span>
</div>
<div class="box-bottom-label">DEATH SAVES</div>
</div>
</div>
<!-- Attacks & Spellcasting -->
<div class="section-box attacks-box">
<table class="attacks-table">
<thead>
<tr>
<th>NAME</th>
<th>ATK BONUS</th>
<th>DAMAGE/TYPE</th>
</tr>
</thead>
<tbody>
{{#if properties.attacks}}
{{#each properties.attacks}}
<tr>
<td class="atk-name">{{this.name}}</td>
<td class="atk-bonus">{{#if this.atk_bonus}}{{this.atk_bonus}}{{else}}+0{{/if}}</td>
<td class="atk-damage">{{this.damage}} {{this.damage_type}}</td>
</tr>
{{/each}}
{{else if properties.actions}}
{{#each properties.actions}}
<tr>
<td class="atk-name">{{this.name}}</td>
<td class="atk-bonus">+5</td>
<td class="atk-damage">{{this.desc}}</td>
</tr>
{{/each}}
{{else}}
<tr><td colspan="3" class="empty-hint">No attacks equipped</td></tr>
{{/if}}
</tbody>
</table>
{{#if properties.actions}}
<div class="attack-notes">
{{#each properties.actions}}
<p class="attack-note-item"><em><strong>{{this.name}}:</strong></em> {{formatText this.desc}}</p>
{{/each}}
</div>
{{/if}}
<div class="box-bottom-label">ATTACKS &amp; SPELLCASTING</div>
</div>
<!-- Equipment & Coins -->
<div class="section-box equipment-box">
<div class="equipment-layout">
<!-- Coins Column -->
<div class="coins-stack">
<div class="coin-row">
<span class="coin-tag">CP</span>
<span class="coin-val">{{#if properties.currency.cp}}{{properties.currency.cp}}{{else}}0{{/if}}</span>
</div>
<div class="coin-row">
<span class="coin-tag">SP</span>
<span class="coin-val">{{#if properties.currency.sp}}{{properties.currency.sp}}{{else}}0{{/if}}</span>
</div>
<div class="coin-row">
<span class="coin-tag">EP</span>
<span class="coin-val">{{#if properties.currency.ep}}{{properties.currency.ep}}{{else}}0{{/if}}</span>
</div>
<div class="coin-row">
<span class="coin-tag">GP</span>
<span class="coin-val">{{#if properties.currency.gp}}{{properties.currency.gp}}{{else}}0{{/if}}</span>
</div>
<div class="coin-row">
<span class="coin-tag">PP</span>
<span class="coin-val">{{#if properties.currency.pp}}{{properties.currency.pp}}{{else}}0{{/if}}</span>
</div>
</div>
<!-- Equipment List -->
<div class="items-list-container">
<ul class="items-list">
{{#each properties.inventory}}
<li class="item-row">
<span class="item-name">{{this.name}}{{#if this.equipped}} <small class="equipped-tag">(E)</small>{{/if}}</span>
<span class="item-meta">x{{this.quantity}}{{#if this.weight}} &bull; {{this.weight}} lb{{/if}}</span>
</li>
{{/each}}
</ul>
</div>
</div>
<div class="box-bottom-label">EQUIPMENT</div>
</div>
</section>
<!-- ================= RIGHT COLUMN ================= -->
<section class="sheet-col col-right">
<!-- Personality Traits -->
<div class="section-box roleplay-box">
<div class="box-content">
{{#if properties.personality_traits}}
<p>{{formatText properties.personality_traits}}</p>
{{else}}
<span class="empty-hint">None</span>
{{/if}}
</div>
<div class="box-bottom-label">PERSONALITY TRAITS</div>
</div>
<!-- Ideals -->
<div class="section-box roleplay-box">
<div class="box-content">
{{#if properties.ideals}}
<p>{{formatText properties.ideals}}</p>
{{else}}
<span class="empty-hint">None</span>
{{/if}}
</div>
<div class="box-bottom-label">IDEALS</div>
</div>
<!-- Bonds -->
<div class="section-box roleplay-box">
<div class="box-content">
{{#if properties.bonds}}
<p>{{formatText properties.bonds}}</p>
{{else}}
<span class="empty-hint">None</span>
{{/if}}
</div>
<div class="box-bottom-label">BONDS</div>
</div>
<!-- Flaws -->
<div class="section-box roleplay-box">
<div class="box-content">
{{#if properties.flaws}}
<p>{{formatText properties.flaws}}</p>
{{else}}
<span class="empty-hint">None</span>
{{/if}}
</div>
<div class="box-bottom-label">FLAWS</div>
</div>
<!-- Features & Traits (Large Box) -->
<div class="section-box features-box">
<div class="features-content">
{{#if properties.features_and_traits}}
{{#each properties.features_and_traits}}
<div class="feature-item">
<strong class="feature-name">{{this.name}}</strong>
<p class="feature-desc">{{formatText this.desc}}</p>
</div>
{{/each}}
{{else if properties.traits}}
{{#each properties.traits}}
<div class="feature-item">
<strong class="feature-name">{{this.name}}</strong>
<p class="feature-desc">{{formatText this.desc}}</p>
</div>
{{/each}}
{{/if}}
</div>
<div class="box-bottom-label">FEATURES &amp; TRAITS</div>
</div>
</section>
</main>
</div>
</body>
</html>

View File

@@ -0,0 +1,5 @@
// Starter client-side script for open5e character sheet
window.addEventListener('DOMContentLoaded', () => {
console.log('Open5e Character Sheet template initialized.');
});

View File

@@ -0,0 +1,487 @@
/* D&D 5e Alternative (Ability-Grouped) Character Sheet Styles */
:root {
--border-color: #2b2b2b;
--accent-red: #922610;
--bg-page: #eaedf0;
--bg-sheet: #ffffff;
--bg-box: #f9fbfd;
--text-main: #1e1e1e;
--text-muted: #666666;
--font-sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
--font-serif: "Libre Baskerville", "Georgia", serif;
}
body.sheet-page-wrapper {
margin: 0;
padding: 24px;
background-color: var(--bg-page);
font-family: var(--font-sans);
color: var(--text-main);
display: flex;
justify-content: center;
box-sizing: border-box;
}
.character-sheet-container {
width: 100%;
max-width: 1050px;
background: var(--bg-sheet);
border: 2px solid var(--border-color);
border-radius: 6px;
padding: 20px 24px 24px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
box-sizing: border-box;
}
/* Header */
.sheet-header {
display: grid;
grid-template-columns: 320px 1fr;
gap: 16px;
align-items: stretch;
border-bottom: 2px solid var(--border-color);
padding-bottom: 16px;
margin-bottom: 20px;
}
.header-name-box {
border: 1.5px solid var(--border-color);
border-radius: 4px;
padding: 12px 16px;
display: flex;
flex-direction: column;
justify-content: flex-end;
background: var(--bg-box);
}
.character-name {
font-family: var(--font-serif);
font-size: 26px;
color: var(--accent-red);
margin: 0 0 6px 0;
line-height: 1.1;
word-break: break-word;
}
.header-label {
font-size: 9.5px;
font-weight: bold;
color: var(--text-muted);
letter-spacing: 0.5px;
}
.header-details-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px 12px;
border: 1.5px solid var(--border-color);
border-radius: 4px;
padding: 10px 14px;
background: var(--bg-box);
}
.detail-cell {
display: flex;
flex-direction: column;
justify-content: flex-end;
border-bottom: 1px solid #ccc;
padding-bottom: 3px;
}
.detail-val {
font-size: 13.5px;
font-weight: 600;
color: var(--text-main);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-bottom: 2px;
}
/* 3-Column Grid */
.sheet-main-grid {
display: grid;
grid-template-columns: 320px 340px 1fr;
gap: 16px;
margin-bottom: 16px;
}
.sheet-col {
display: flex;
flex-direction: column;
gap: 12px;
}
.section-box {
border: 1.5px solid var(--border-color);
border-radius: 4px;
padding: 10px 12px;
background: #ffffff;
position: relative;
box-sizing: border-box;
}
.box-bottom-label {
text-align: center;
font-size: 9.5px;
font-weight: bold;
color: var(--text-muted);
letter-spacing: 0.5px;
margin-top: 6px;
padding-top: 4px;
border-top: 1px solid #eee;
}
/* Ability-Grouped Box Styles */
.alt-top-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
}
.alt-stat-pill {
border: 1.5px solid var(--border-color);
border-radius: 16px;
padding: 5px 10px;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
background: var(--bg-box);
}
.pill-value {
font-size: 14px;
font-weight: bold;
color: var(--accent-red);
}
.pill-checkbox {
width: 14px;
height: 14px;
border: 1.5px solid var(--border-color);
border-radius: 50%;
display: inline-block;
}
.pill-checkbox.checked {
background-color: var(--accent-red);
}
.pill-label {
font-size: 8.5px;
font-weight: bold;
color: var(--text-muted);
}
.ability-group-box {
border: 1.5px solid var(--border-color);
border-radius: 6px;
padding: 8px 10px;
display: grid;
grid-template-columns: 78px 1fr;
gap: 10px;
align-items: center;
background: #ffffff;
}
.ag-score-badge {
border: 1.2px solid var(--border-color);
border-radius: 4px;
padding: 4px 2px;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
background: var(--bg-box);
}
.ag-title {
font-size: 8px;
font-weight: bold;
color: var(--accent-red);
}
.ag-mod {
font-size: 18px;
font-weight: bold;
color: var(--text-main);
line-height: 1.1;
}
.ag-score {
font-size: 10px;
color: #555;
border: 1px solid #ccc;
border-radius: 8px;
padding: 0 6px;
background: #ffffff;
}
.ag-sublist {
list-style: none;
margin: 0;
padding: 0;
}
.ag-subitem {
display: flex;
align-items: center;
font-size: 11px;
gap: 6px;
margin: 2px 0;
line-height: 1.2;
}
.ag-subitem .dot {
width: 8px;
height: 8px;
border: 1.2px solid var(--border-color);
border-radius: 50%;
display: inline-block;
flex-shrink: 0;
}
.ag-subitem .dot.filled {
background-color: var(--accent-red);
border-color: var(--accent-red);
}
.ag-bonus {
font-weight: 700;
width: 20px;
text-align: right;
flex-shrink: 0;
}
.ag-name {
color: #333;
}
/* Passive Perception */
.passive-perception-box {
border: 1.5px solid var(--border-color);
border-radius: 18px;
padding: 6px 12px;
display: flex;
align-items: center;
gap: 10px;
background: var(--bg-box);
}
.passive-score {
font-size: 15px;
font-weight: bold;
color: var(--text-main);
border: 1px solid var(--border-color);
border-radius: 50%;
width: 26px;
height: 26px;
display: flex;
align-items: center;
justify-content: center;
background: #ffffff;
flex-shrink: 0;
}
.passive-label {
font-size: 9.5px;
font-weight: bold;
color: var(--text-muted);
}
/* Combat Stats */
.combat-top-row {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
}
.combat-badge {
border: 1.5px solid var(--border-color);
border-radius: 6px;
padding: 8px 4px;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: var(--bg-box);
}
.badge-ac { border-color: var(--accent-red); }
.badge-value {
font-size: 22px;
font-weight: bold;
color: var(--text-main);
line-height: 1.1;
}
.badge-label {
font-size: 8.5px;
font-weight: bold;
color: var(--text-muted);
margin-top: 3px;
}
.hp-max-line {
font-size: 10.5px;
color: #666;
border-bottom: 1px solid #eee;
padding-bottom: 4px;
}
.hp-current-val, .temp-hp-val {
font-size: 28px;
font-weight: bold;
text-align: center;
padding: 8px 0;
color: var(--text-main);
}
.hd-and-death-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
}
.half-box { padding: 6px 8px; }
.hd-total-line { font-size: 9.5px; color: #666; }
.hd-current-val {
font-size: 18px;
font-weight: bold;
text-align: center;
padding: 4px 0;
}
.death-save-line {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 9px;
font-weight: bold;
margin: 3px 0;
}
.ds-bubbles { display: flex; gap: 4px; }
.ds-bubbles .bubble {
width: 9px;
height: 9px;
border: 1.2px solid var(--border-color);
border-radius: 50%;
display: inline-block;
}
.ds-bubbles .bubble.filled { background-color: var(--accent-red); }
/* Attacks Table */
.attacks-table {
width: 100%;
border-collapse: collapse;
font-size: 11px;
margin-bottom: 8px;
}
.attacks-table th {
font-size: 8.5px;
font-weight: bold;
color: var(--text-muted);
border-bottom: 1px solid #ccc;
padding: 2px 4px;
text-align: left;
}
.attacks-table td {
padding: 5px 4px;
border-bottom: 1px solid #eee;
}
.atk-name { font-weight: 600; }
.atk-bonus { font-weight: 700; color: var(--accent-red); }
.attack-notes {
font-size: 10.5px;
line-height: 1.35;
color: #444;
margin-top: 6px;
max-height: 120px;
overflow-y: auto;
}
.attack-note-item { margin: 4px 0; }
/* Right Column Roleplay Boxes */
.roleplay-box {
min-height: 64px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.box-content { font-size: 11.5px; line-height: 1.4; color: #333; }
.box-content p { margin: 0; }
.empty-hint { color: #999; font-style: italic; font-size: 11px; }
.features-box {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 250px;
}
.features-content { font-size: 11.5px; line-height: 1.4; }
.feature-item { margin-bottom: 8px; }
.feature-name { color: var(--accent-red); display: block; margin-bottom: 2px; }
.feature-desc { margin: 0; }
/* Bottom Wide Row */
.sheet-bottom-row {
display: grid;
grid-template-columns: 320px 1fr;
gap: 16px;
}
.prof-block-content { font-size: 11.5px; line-height: 1.45; }
.prof-line { margin-bottom: 4px; }
.equipment-layout {
display: grid;
grid-template-columns: 56px 1fr;
gap: 12px;
}
.coins-stack { display: flex; flex-direction: column; gap: 4px; }
.coin-row {
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 2px 4px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 10px;
background: var(--bg-box);
}
.coin-tag { font-weight: bold; font-size: 8.5px; color: var(--accent-red); }
.coin-val { font-weight: 600; }
.items-list-container { max-height: 180px; overflow-y: auto; }
.items-list { list-style: none; margin: 0; padding: 0; font-size: 11px; }
.item-row { display: flex; justify-content: space-between; padding: 3px 0; border-bottom: 1px solid #eee; }
.equipped-tag { color: var(--accent-red); font-weight: bold; }
.item-meta { color: #777; font-size: 10px; }
/* Responsive Styles */
@media (max-width: 900px) {
.sheet-header { grid-template-columns: 1fr; }
.sheet-main-grid { grid-template-columns: 1fr; }
.sheet-bottom-row { grid-template-columns: 1fr; }
}

View File

@@ -0,0 +1,472 @@
<!DOCTYPE html>
<html lang="en">
<head>
<base href="/rulesets/open5e/templates/">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{display_name}} - Alternative Character Sheet</title>
<link rel="stylesheet" href="character_sheet_alt.css">
</head>
<body class="sheet-page-wrapper">
<div class="character-sheet-container">
<!-- Top Header Banner -->
<header class="sheet-header">
<div class="header-name-box">
<h1 class="character-name">{{display_name}}</h1>
<label class="header-label">CHARACTER NAME</label>
</div>
<div class="header-details-grid">
<div class="detail-cell">
<div class="detail-val">{{properties.class}}{{#if properties.subclass}} ({{properties.subclass}}){{/if}} {{properties.level}}</div>
<label class="header-label">CLASS &amp; LEVEL</label>
</div>
<div class="detail-cell">
<div class="detail-val">{{#if properties.background}}{{properties.background}}{{else}}&mdash;{{/if}}</div>
<label class="header-label">BACKGROUND</label>
</div>
<div class="detail-cell">
<div class="detail-val">{{#if properties.player_name}}{{properties.player_name}}{{else}}&mdash;{{/if}}</div>
<label class="header-label">PLAYER NAME</label>
</div>
<div class="detail-cell">
<div class="detail-val">{{properties.race}}</div>
<label class="header-label">RACE</label>
</div>
<div class="detail-cell">
<div class="detail-val">{{properties.alignment}}</div>
<label class="header-label">ALIGNMENT</label>
</div>
<div class="detail-cell">
<div class="detail-val">{{#if properties.experience_points}}{{properties.experience_points}}{{else}}0{{/if}} XP</div>
<label class="header-label">EXPERIENCE POINTS</label>
</div>
</div>
</header>
<!-- Main 3-Column Layout -->
<main class="sheet-main-grid">
<!-- ================= LEFT COLUMN: ABILITY-GROUPED STATS ================= -->
<section class="sheet-col col-left">
<!-- Top Controls: Proficiency Bonus & Inspiration -->
<div class="alt-top-row">
<div class="alt-stat-pill">
<span class="pill-value">+{{calcProf properties.level properties.cr}}</span>
<span class="pill-label">PROFICIENCY BONUS</span>
</div>
<div class="alt-stat-pill">
<span class="pill-checkbox {{#if properties.inspiration}}checked{{/if}}"></span>
<span class="pill-label">INSPIRATION</span>
</div>
</div>
<!-- STRENGTH GROUP -->
<div class="ability-group-box">
<div class="ag-score-badge">
<span class="ag-title">STRENGTH</span>
<span class="ag-mod">{{modText properties.abilities.strength}}</span>
<span class="ag-score">{{val properties.abilities.strength}}</span>
</div>
<ul class="ag-sublist">
<li class="ag-subitem">
<span class="dot {{#if (hasSave properties.saving_throws 'str')}}filled{{/if}}"></span>
<span class="ag-bonus">{{saveBonus properties 'strength'}}</span>
<span class="ag-name">SAVING THROWS</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'athletics')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'athletics' 'strength'}}</span>
<span class="ag-name">Athletics</span>
</li>
</ul>
</div>
<!-- DEXTERITY GROUP -->
<div class="ability-group-box">
<div class="ag-score-badge">
<span class="ag-title">DEXTERITY</span>
<span class="ag-mod">{{modText properties.abilities.dexterity}}</span>
<span class="ag-score">{{val properties.abilities.dexterity}}</span>
</div>
<ul class="ag-sublist">
<li class="ag-subitem">
<span class="dot {{#if (hasSave properties.saving_throws 'dex')}}filled{{/if}}"></span>
<span class="ag-bonus">{{saveBonus properties 'dexterity'}}</span>
<span class="ag-name">SAVING THROWS</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'acrobatics')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'acrobatics' 'dexterity'}}</span>
<span class="ag-name">Acrobatics</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'sleight_of_hand')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'sleight_of_hand' 'dexterity'}}</span>
<span class="ag-name">Sleight of Hand</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'stealth')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'stealth' 'dexterity'}}</span>
<span class="ag-name">Stealth</span>
</li>
</ul>
</div>
<!-- CONSTITUTION GROUP -->
<div class="ability-group-box">
<div class="ag-score-badge">
<span class="ag-title">CONSTITUTION</span>
<span class="ag-mod">{{modText properties.abilities.constitution}}</span>
<span class="ag-score">{{val properties.abilities.constitution}}</span>
</div>
<ul class="ag-sublist">
<li class="ag-subitem">
<span class="dot {{#if (hasSave properties.saving_throws 'con')}}filled{{/if}}"></span>
<span class="ag-bonus">{{saveBonus properties 'constitution'}}</span>
<span class="ag-name">SAVING THROWS</span>
</li>
</ul>
</div>
<!-- INTELLIGENCE GROUP -->
<div class="ability-group-box">
<div class="ag-score-badge">
<span class="ag-title">INTELLIGENCE</span>
<span class="ag-mod">{{modText properties.abilities.intelligence}}</span>
<span class="ag-score">{{val properties.abilities.intelligence}}</span>
</div>
<ul class="ag-sublist">
<li class="ag-subitem">
<span class="dot {{#if (hasSave properties.saving_throws 'int')}}filled{{/if}}"></span>
<span class="ag-bonus">{{saveBonus properties 'intelligence'}}</span>
<span class="ag-name">SAVING THROWS</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'arcana')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'arcana' 'intelligence'}}</span>
<span class="ag-name">Arcana</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'history')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'history' 'intelligence'}}</span>
<span class="ag-name">History</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'investigation')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'investigation' 'intelligence'}}</span>
<span class="ag-name">Investigation</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'nature')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'nature' 'intelligence'}}</span>
<span class="ag-name">Nature</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'religion')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'religion' 'intelligence'}}</span>
<span class="ag-name">Religion</span>
</li>
</ul>
</div>
<!-- WISDOM GROUP -->
<div class="ability-group-box">
<div class="ag-score-badge">
<span class="ag-title">WISDOM</span>
<span class="ag-mod">{{modText properties.abilities.wisdom}}</span>
<span class="ag-score">{{val properties.abilities.wisdom}}</span>
</div>
<ul class="ag-sublist">
<li class="ag-subitem">
<span class="dot {{#if (hasSave properties.saving_throws 'wis')}}filled{{/if}}"></span>
<span class="ag-bonus">{{saveBonus properties 'wisdom'}}</span>
<span class="ag-name">SAVING THROWS</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'animal_handling')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'animal_handling' 'wisdom'}}</span>
<span class="ag-name">Animal Handling</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'insight')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'insight' 'wisdom'}}</span>
<span class="ag-name">Insight</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'medicine')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'medicine' 'wisdom'}}</span>
<span class="ag-name">Medicine</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'perception')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'perception' 'wisdom'}}</span>
<span class="ag-name">Perception</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'survival')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'survival' 'wisdom'}}</span>
<span class="ag-name">Survival</span>
</li>
</ul>
</div>
<!-- CHARISMA GROUP -->
<div class="ability-group-box">
<div class="ag-score-badge">
<span class="ag-title">CHARISMA</span>
<span class="ag-mod">{{modText properties.abilities.charisma}}</span>
<span class="ag-score">{{val properties.abilities.charisma}}</span>
</div>
<ul class="ag-sublist">
<li class="ag-subitem">
<span class="dot {{#if (hasSave properties.saving_throws 'cha')}}filled{{/if}}"></span>
<span class="ag-bonus">{{saveBonus properties 'charisma'}}</span>
<span class="ag-name">SAVING THROWS</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'deception')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'deception' 'charisma'}}</span>
<span class="ag-name">Deception</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'intimidation')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'intimidation' 'charisma'}}</span>
<span class="ag-name">Intimidation</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'performance')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'performance' 'charisma'}}</span>
<span class="ag-name">Performance</span>
</li>
<li class="ag-subitem">
<span class="dot {{#if (isSkillProf properties.skills 'persuasion')}}filled{{/if}}"></span>
<span class="ag-bonus">{{skillBonus properties 'persuasion' 'charisma'}}</span>
<span class="ag-name">Persuasion</span>
</li>
</ul>
</div>
<!-- Passive Perception Box -->
<div class="passive-perception-box">
<span class="passive-score">{{passivePerception properties}}</span>
<span class="passive-label">PASSIVE WISDOM (PERCEPTION)</span>
</div>
</section>
<!-- ================= MIDDLE COLUMN ================= -->
<section class="sheet-col col-middle">
<!-- Combat Top Row -->
<div class="combat-top-row">
<div class="combat-badge badge-ac">
<span class="badge-value">{{val properties.armor_class}}</span>
<span class="badge-label">ARMOR CLASS</span>
</div>
<div class="combat-badge badge-init">
<span class="badge-value">{{#if properties.initiative}}{{modSign properties.initiative}}{{else}}{{modText properties.abilities.dexterity}}{{/if}}</span>
<span class="badge-label">INITIATIVE</span>
</div>
<div class="combat-badge badge-speed">
<span class="badge-value">{{#if properties.speed}}{{properties.speed}} ft.{{else}}30 ft.{{/if}}</span>
<span class="badge-label">SPEED</span>
</div>
</div>
<!-- HP Box -->
<div class="section-box hp-box">
<div class="hp-max-line">
Hit Point Maximum: <strong>{{properties.hit_points.max}}</strong>
</div>
<div class="hp-current-val">{{properties.hit_points.current}}</div>
<div class="box-bottom-label">CURRENT HIT POINTS</div>
</div>
<!-- Temp HP -->
<div class="section-box temp-hp-box">
<div class="temp-hp-val">{{#if properties.hit_points.temp}}{{properties.hit_points.temp}}{{else}}--{{/if}}</div>
<div class="box-bottom-label">TEMPORARY HIT POINTS</div>
</div>
<!-- Hit Dice & Death Saves -->
<div class="hd-and-death-row">
<div class="section-box half-box hd-box">
<div class="hd-total-line">Total: {{#if properties.hit_dice.total}}{{properties.hit_dice.total}}{{else}}{{properties.level}}{{/if}}</div>
<div class="hd-current-val">
{{#if properties.hit_dice.dice}}{{properties.hit_dice.dice}}{{else if properties.hit_points.hit_dice}}{{properties.hit_points.hit_dice}}{{else}}1d10{{/if}}
</div>
<div class="box-bottom-label">HIT DICE</div>
</div>
<div class="section-box half-box death-saves-box">
<div class="death-save-line">
<span class="ds-title">SUCCESSES</span>
<span class="ds-bubbles">
<span class="bubble {{#if (gte properties.death_saves.successes 1)}}filled{{/if}}"></span>
<span class="bubble {{#if (gte properties.death_saves.successes 2)}}filled{{/if}}"></span>
<span class="bubble {{#if (gte properties.death_saves.successes 3)}}filled{{/if}}"></span>
</span>
</div>
<div class="death-save-line">
<span class="ds-title">FAILURES</span>
<span class="ds-bubbles">
<span class="bubble {{#if (gte properties.death_saves.failures 1)}}filled{{/if}}"></span>
<span class="bubble {{#if (gte properties.death_saves.failures 2)}}filled{{/if}}"></span>
<span class="bubble {{#if (gte properties.death_saves.failures 3)}}filled{{/if}}"></span>
</span>
</div>
<div class="box-bottom-label">DEATH SAVES</div>
</div>
</div>
<!-- Attacks & Spellcasting -->
<div class="section-box attacks-box">
<table class="attacks-table">
<thead>
<tr>
<th>NAME</th>
<th>ATK BONUS</th>
<th>DAMAGE/TYPE</th>
</tr>
</thead>
<tbody>
{{#if properties.attacks}}
{{#each properties.attacks}}
<tr>
<td class="atk-name">{{this.name}}</td>
<td class="atk-bonus">{{#if this.atk_bonus}}{{this.atk_bonus}}{{else}}+0{{/if}}</td>
<td class="atk-damage">{{this.damage}} {{this.damage_type}}</td>
</tr>
{{/each}}
{{else if properties.actions}}
{{#each properties.actions}}
<tr>
<td class="atk-name">{{this.name}}</td>
<td class="atk-bonus">+5</td>
<td class="atk-damage">{{this.desc}}</td>
</tr>
{{/each}}
{{else}}
<tr><td colspan="3" class="empty-hint">No attacks equipped</td></tr>
{{/if}}
</tbody>
</table>
{{#if properties.actions}}
<div class="attack-notes">
{{#each properties.actions}}
<p class="attack-note-item"><em><strong>{{this.name}}:</strong></em> {{formatText this.desc}}</p>
{{/each}}
</div>
{{/if}}
<div class="box-bottom-label">ATTACKS &amp; SPELLCASTING</div>
</div>
</section>
<!-- ================= RIGHT COLUMN ================= -->
<section class="sheet-col col-right">
<!-- Personality Traits -->
<div class="section-box roleplay-box">
<div class="box-content">{{#if properties.personality_traits}}<p>{{formatText properties.personality_traits}}</p>{{else}}<span class="empty-hint">None</span>{{/if}}</div>
<div class="box-bottom-label">PERSONALITY TRAITS</div>
</div>
<!-- Ideals -->
<div class="section-box roleplay-box">
<div class="box-content">{{#if properties.ideals}}<p>{{formatText properties.ideals}}</p>{{else}}<span class="empty-hint">None</span>{{/if}}</div>
<div class="box-bottom-label">IDEALS</div>
</div>
<!-- Bonds -->
<div class="section-box roleplay-box">
<div class="box-content">{{#if properties.bonds}}<p>{{formatText properties.bonds}}</p>{{else}}<span class="empty-hint">None</span>{{/if}}</div>
<div class="box-bottom-label">BONDS</div>
</div>
<!-- Flaws -->
<div class="section-box roleplay-box">
<div class="box-content">{{#if properties.flaws}}<p>{{formatText properties.flaws}}</p>{{else}}<span class="empty-hint">None</span>{{/if}}</div>
<div class="box-bottom-label">FLAWS</div>
</div>
<!-- Features & Traits -->
<div class="section-box features-box">
<div class="features-content">
{{#if properties.features_and_traits}}
{{#each properties.features_and_traits}}
<div class="feature-item">
<strong class="feature-name">{{this.name}}</strong>
<p class="feature-desc">{{formatText this.desc}}</p>
</div>
{{/each}}
{{else if properties.traits}}
{{#each properties.traits}}
<div class="feature-item">
<strong class="feature-name">{{this.name}}</strong>
<p class="feature-desc">{{formatText this.desc}}</p>
</div>
{{/each}}
{{/if}}
</div>
<div class="box-bottom-label">FEATURES &amp; TRAITS</div>
</div>
</section>
</main>
<!-- Bottom Wide Row: Proficiencies & Equipment/Notes -->
<div class="sheet-bottom-row">
<!-- Other Proficiencies & Languages -->
<div class="section-box proficiencies-box">
<div class="prof-block-content">
{{#if properties.other_proficiencies_and_languages.armor}}
<div class="prof-line"><strong>Armor:</strong> {{join properties.other_proficiencies_and_languages.armor}}</div>
{{/if}}
{{#if properties.other_proficiencies_and_languages.weapons}}
<div class="prof-line"><strong>Weapons:</strong> {{join properties.other_proficiencies_and_languages.weapons}}</div>
{{/if}}
{{#if properties.other_proficiencies_and_languages.tools}}
<div class="prof-line"><strong>Tools:</strong> {{join properties.other_proficiencies_and_languages.tools}}</div>
{{/if}}
{{#if properties.languages}}
<div class="prof-line"><strong>Languages:</strong> {{join properties.languages}}</div>
{{else if properties.other_proficiencies_and_languages.languages}}
<div class="prof-line"><strong>Languages:</strong> {{join properties.other_proficiencies_and_languages.languages}}</div>
{{/if}}
</div>
<div class="box-bottom-label">OTHER PROFICIENCIES &amp; LANGUAGES</div>
</div>
<!-- Equipment & Notes -->
<div class="section-box equipment-box">
<div class="equipment-layout">
<div class="coins-stack">
<div class="coin-row"><span class="coin-tag">CP</span><span class="coin-val">{{#if properties.currency.cp}}{{properties.currency.cp}}{{else}}0{{/if}}</span></div>
<div class="coin-row"><span class="coin-tag">SP</span><span class="coin-val">{{#if properties.currency.sp}}{{properties.currency.sp}}{{else}}0{{/if}}</span></div>
<div class="coin-row"><span class="coin-tag">EP</span><span class="coin-val">{{#if properties.currency.ep}}{{properties.currency.ep}}{{else}}0{{/if}}</span></div>
<div class="coin-row"><span class="coin-tag">GP</span><span class="coin-val">{{#if properties.currency.gp}}{{properties.currency.gp}}{{else}}0{{/if}}</span></div>
<div class="coin-row"><span class="coin-tag">PP</span><span class="coin-val">{{#if properties.currency.pp}}{{properties.currency.pp}}{{else}}0{{/if}}</span></div>
</div>
<div class="items-list-container">
<ul class="items-list">
{{#each properties.inventory}}
<li class="item-row">
<span class="item-name">{{this.name}}{{#if this.equipped}} <small class="equipped-tag">(E)</small>{{/if}}</span>
<span class="item-meta">x{{this.quantity}}{{#if this.weight}} &bull; {{this.weight}} lb{{/if}}</span>
</li>
{{/each}}
</ul>
</div>
</div>
<div class="box-bottom-label">EQUIPMENT &amp; CHARACTER NOTES</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,221 @@
/* D&D 5e Spellcasting Sheet Styles */
:root {
--border-color: #2b2b2b;
--accent-red: #922610;
--bg-page: #eaedf0;
--bg-sheet: #ffffff;
--bg-box: #f9fbfd;
--text-main: #1e1e1e;
--text-muted: #666666;
--font-sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
--font-serif: "Libre Baskerville", "Georgia", serif;
}
body.sheet-page-wrapper {
margin: 0;
padding: 24px;
background-color: var(--bg-page);
font-family: var(--font-sans);
color: var(--text-main);
display: flex;
justify-content: center;
box-sizing: border-box;
}
.spellcasting-sheet-container {
width: 100%;
max-width: 1050px;
background: var(--bg-sheet);
border: 2px solid var(--border-color);
border-radius: 6px;
padding: 20px 24px 24px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
box-sizing: border-box;
}
/* Header */
.spell-header {
display: grid;
grid-template-columns: 320px 1fr;
gap: 16px;
border-bottom: 2px solid var(--border-color);
padding-bottom: 16px;
margin-bottom: 20px;
}
.spell-header-class-box {
border: 1.5px solid var(--border-color);
border-radius: 4px;
padding: 12px 16px;
display: flex;
flex-direction: column;
justify-content: flex-end;
background: var(--bg-box);
}
.spell-class-name {
font-family: var(--font-serif);
font-size: 26px;
color: var(--accent-red);
margin: 0 0 6px 0;
line-height: 1.1;
}
.spell-header-label {
font-size: 9px;
font-weight: bold;
color: var(--text-muted);
letter-spacing: 0.5px;
}
.spell-header-stats-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
border: 1.5px solid var(--border-color);
border-radius: 4px;
padding: 10px 14px;
background: var(--bg-box);
}
.spell-stat-cell {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-right: 1px solid #ccc;
}
.spell-stat-cell:last-child {
border-right: none;
}
.spell-stat-val {
font-size: 20px;
font-weight: bold;
color: var(--text-main);
margin-bottom: 4px;
}
/* 3-Column Layout */
.spells-main-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
.spells-column {
display: flex;
flex-direction: column;
gap: 14px;
}
.spell-level-box {
border: 1.5px solid var(--border-color);
border-radius: 6px;
background: #ffffff;
overflow: hidden;
}
.spell-level-header {
background: var(--bg-box);
border-bottom: 1.5px solid var(--border-color);
padding: 6px 10px;
display: flex;
align-items: center;
gap: 8px;
}
.level-num {
font-size: 16px;
font-weight: bold;
color: #ffffff;
background: var(--accent-red);
border-radius: 50%;
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.level-title {
font-size: 11px;
font-weight: bold;
color: var(--text-main);
letter-spacing: 0.5px;
}
.spell-level-header.has-slots {
justify-content: space-between;
}
.slot-counters {
display: flex;
gap: 10px;
font-size: 10.5px;
color: #555;
}
.slot-field strong {
color: var(--text-main);
}
.spell-items-list {
list-style: none;
margin: 0;
padding: 6px 10px;
min-height: 80px;
}
.spell-item-row {
display: flex;
align-items: center;
gap: 8px;
padding: 4px 0;
border-bottom: 1px solid #f0f0f0;
font-size: 12px;
}
.spell-item-row:last-child {
border-bottom: none;
}
.spell-prep-circle {
width: 10px;
height: 10px;
border: 1.2px solid var(--border-color);
border-radius: 50%;
display: inline-block;
flex-shrink: 0;
}
.spell-prep-circle.prepared {
background: var(--accent-red);
border-color: var(--accent-red);
}
.spell-prep-circle.invisible {
opacity: 0;
}
.spell-name {
color: var(--text-main);
}
.spell-item-row.empty {
color: #bbb;
justify-content: center;
}
/* Responsive */
@media (max-width: 900px) {
.spell-header {
grid-template-columns: 1fr;
}
.spells-main-grid {
grid-template-columns: 1fr;
}
}

View File

@@ -0,0 +1,277 @@
<!DOCTYPE html>
<html lang="en">
<head>
<base href="/rulesets/open5e/templates/">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{display_name}} - Spellcasting Sheet</title>
<link rel="stylesheet" href="spellcasting_sheet.css">
</head>
<body class="sheet-page-wrapper">
<div class="spellcasting-sheet-container">
<!-- Top Spellcasting Header -->
<header class="spell-header">
<div class="spell-header-class-box">
<h1 class="spell-class-name">
{{#if properties.spellcasting.class}}
{{properties.spellcasting.class}}
{{else if properties.class}}
{{properties.class}}
{{else}}
Spellcaster
{{/if}}
</h1>
<label class="spell-header-label">SPELLCASTING CLASS</label>
</div>
<div class="spell-header-stats-grid">
<div class="spell-stat-cell">
<span class="spell-stat-val">
{{#if properties.spellcasting.ability}}
{{properties.spellcasting.ability}}
{{else}}
WISDOM
{{/if}}
</span>
<label class="spell-header-label">SPELLCASTING ABILITY</label>
</div>
<div class="spell-stat-cell">
<span class="spell-stat-val">
{{#if properties.spellcasting.save_dc}}
{{properties.spellcasting.save_dc}}
{{else}}
13
{{/if}}
</span>
<label class="spell-header-label">SPELL SAVE DC</label>
</div>
<div class="spell-stat-cell">
<span class="spell-stat-val">
{{#if properties.spellcasting.attack_bonus}}
{{modSign properties.spellcasting.attack_bonus}}
{{else}}
+5
{{/if}}
</span>
<label class="spell-header-label">SPELL ATTACK BONUS</label>
</div>
</div>
</header>
<!-- 3-Column Spells Grid -->
<main class="spells-main-grid">
<!-- ================= COLUMN 1: Cantrips, Level 1, Level 2 ================= -->
<section class="spells-column">
<!-- Cantrips (Level 0) -->
<div class="spell-level-box">
<div class="spell-level-header">
<span class="level-num">0</span>
<span class="level-title">CANTRIPS</span>
</div>
<ul class="spell-items-list">
{{#if properties.spellcasting.cantrips}}
{{#each properties.spellcasting.cantrips}}
<li class="spell-item-row">
<span class="spell-prep-circle invisible"></span>
<span class="spell-name">{{#if this.name}}{{this.name}}{{else}}{{this}}{{/if}}</span>
</li>
{{/each}}
{{else}}
<li class="spell-item-row empty"><span class="spell-name">&mdash;</span></li>
{{/if}}
</ul>
</div>
<!-- Level 1 Spells -->
<div class="spell-level-box">
<div class="spell-level-header has-slots">
<span class="level-num">1</span>
<div class="slot-counters">
<span class="slot-field">Total: <strong>{{slotTotal ../properties.spellcasting.slots 1}}</strong></span>
<span class="slot-field">Expended: <strong>{{slotExpended ../properties.spellcasting.slots 1}}</strong></span>
</div>
</div>
<ul class="spell-items-list">
{{#each (filterSpells properties.spellcasting.spells 1)}}
<li class="spell-item-row">
<span class="spell-prep-circle {{#if this.prepared}}prepared{{/if}}"></span>
<span class="spell-name">{{this.name}}</span>
</li>
{{/each}}
</ul>
</div>
<!-- Level 2 Spells -->
<div class="spell-level-box">
<div class="spell-level-header has-slots">
<span class="level-num">2</span>
<div class="slot-counters">
<span class="slot-field">Total: <strong>{{slotTotal ../properties.spellcasting.slots 2}}</strong></span>
<span class="slot-field">Expended: <strong>{{slotExpended ../properties.spellcasting.slots 2}}</strong></span>
</div>
</div>
<ul class="spell-items-list">
{{#each (filterSpells properties.spellcasting.spells 2)}}
<li class="spell-item-row">
<span class="spell-prep-circle {{#if this.prepared}}prepared{{/if}}"></span>
<span class="spell-name">{{this.name}}</span>
</li>
{{/each}}
</ul>
</div>
</section>
<!-- ================= COLUMN 2: Level 3, Level 4, Level 5 ================= -->
<section class="spells-column">
<!-- Level 3 Spells -->
<div class="spell-level-box">
<div class="spell-level-header has-slots">
<span class="level-num">3</span>
<div class="slot-counters">
<span class="slot-field">Total: <strong>{{slotTotal ../properties.spellcasting.slots 3}}</strong></span>
<span class="slot-field">Expended: <strong>{{slotExpended ../properties.spellcasting.slots 3}}</strong></span>
</div>
</div>
<ul class="spell-items-list">
{{#each (filterSpells properties.spellcasting.spells 3)}}
<li class="spell-item-row">
<span class="spell-prep-circle {{#if this.prepared}}prepared{{/if}}"></span>
<span class="spell-name">{{this.name}}</span>
</li>
{{/each}}
</ul>
</div>
<!-- Level 4 Spells -->
<div class="spell-level-box">
<div class="spell-level-header has-slots">
<span class="level-num">4</span>
<div class="slot-counters">
<span class="slot-field">Total: <strong>{{slotTotal ../properties.spellcasting.slots 4}}</strong></span>
<span class="slot-field">Expended: <strong>{{slotExpended ../properties.spellcasting.slots 4}}</strong></span>
</div>
</div>
<ul class="spell-items-list">
{{#each (filterSpells properties.spellcasting.spells 4)}}
<li class="spell-item-row">
<span class="spell-prep-circle {{#if this.prepared}}prepared{{/if}}"></span>
<span class="spell-name">{{this.name}}</span>
</li>
{{/each}}
</ul>
</div>
<!-- Level 5 Spells -->
<div class="spell-level-box">
<div class="spell-level-header has-slots">
<span class="level-num">5</span>
<div class="slot-counters">
<span class="slot-field">Total: <strong>{{slotTotal ../properties.spellcasting.slots 5}}</strong></span>
<span class="slot-field">Expended: <strong>{{slotExpended ../properties.spellcasting.slots 5}}</strong></span>
</div>
</div>
<ul class="spell-items-list">
{{#each (filterSpells properties.spellcasting.spells 5)}}
<li class="spell-item-row">
<span class="spell-prep-circle {{#if this.prepared}}prepared{{/if}}"></span>
<span class="spell-name">{{this.name}}</span>
</li>
{{/each}}
</ul>
</div>
</section>
<!-- ================= COLUMN 3: Level 6, 7, 8, 9 ================= -->
<section class="spells-column">
<!-- Level 6 Spells -->
<div class="spell-level-box">
<div class="spell-level-header has-slots">
<span class="level-num">6</span>
<div class="slot-counters">
<span class="slot-field">Total: <strong>{{slotTotal ../properties.spellcasting.slots 6}}</strong></span>
<span class="slot-field">Expended: <strong>{{slotExpended ../properties.spellcasting.slots 6}}</strong></span>
</div>
</div>
<ul class="spell-items-list">
{{#each (filterSpells properties.spellcasting.spells 6)}}
<li class="spell-item-row">
<span class="spell-prep-circle {{#if this.prepared}}prepared{{/if}}"></span>
<span class="spell-name">{{this.name}}</span>
</li>
{{/each}}
</ul>
</div>
<!-- Level 7 Spells -->
<div class="spell-level-box">
<div class="spell-level-header has-slots">
<span class="level-num">7</span>
<div class="slot-counters">
<span class="slot-field">Total: <strong>{{slotTotal ../properties.spellcasting.slots 7}}</strong></span>
<span class="slot-field">Expended: <strong>{{slotExpended ../properties.spellcasting.slots 7}}</strong></span>
</div>
</div>
<ul class="spell-items-list">
{{#each (filterSpells properties.spellcasting.spells 7)}}
<li class="spell-item-row">
<span class="spell-prep-circle {{#if this.prepared}}prepared{{/if}}"></span>
<span class="spell-name">{{this.name}}</span>
</li>
{{/each}}
</ul>
</div>
<!-- Level 8 Spells -->
<div class="spell-level-box">
<div class="spell-level-header has-slots">
<span class="level-num">8</span>
<div class="slot-counters">
<span class="slot-field">Total: <strong>{{slotTotal ../properties.spellcasting.slots 8}}</strong></span>
<span class="slot-field">Expended: <strong>{{slotExpended ../properties.spellcasting.slots 8}}</strong></span>
</div>
</div>
<ul class="spell-items-list">
{{#each (filterSpells properties.spellcasting.spells 8)}}
<li class="spell-item-row">
<span class="spell-prep-circle {{#if this.prepared}}prepared{{/if}}"></span>
<span class="spell-name">{{this.name}}</span>
</li>
{{/each}}
</ul>
</div>
<!-- Level 9 Spells -->
<div class="spell-level-box">
<div class="spell-level-header has-slots">
<span class="level-num">9</span>
<div class="slot-counters">
<span class="slot-field">Total: <strong>{{slotTotal ../properties.spellcasting.slots 9}}</strong></span>
<span class="slot-field">Expended: <strong>{{slotExpended ../properties.spellcasting.slots 9}}</strong></span>
</div>
</div>
<ul class="spell-items-list">
{{#each (filterSpells properties.spellcasting.spells 9)}}
<li class="spell-item-row">
<span class="spell-prep-circle {{#if this.prepared}}prepared{{/if}}"></span>
<span class="spell-name">{{this.name}}</span>
</li>
{{/each}}
</ul>
</div>
</section>
</main>
</div>
</body>
</html>

View File

@@ -0,0 +1,142 @@
.stat-block-wrapper {
margin: 0;
padding: 16px;
background-color: #f0f2f5;
font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
color: #222;
display: flex;
justify-content: center;
}
.stat-block {
width: 100%;
max-width: 650px;
background: #ffffff;
padding: 24px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
border-radius: 4px;
border-top: 6px solid #922610;
box-sizing: border-box;
}
.sb-header {
margin-bottom: 8px;
}
.sb-name {
font-family: "Libre Baskerville", "Georgia", serif;
font-size: 28px;
font-weight: bold;
color: #922610;
margin: 0 0 4px 0;
line-height: 1.15;
}
.sb-type {
font-style: italic;
font-size: 14px;
color: #555;
margin-bottom: 6px;
}
.red-bar {
height: 3px;
background-color: #922610;
margin: 10px 0;
border-radius: 1px;
}
.sb-vitals, .sb-meta, .sb-traits {
font-size: 14px;
line-height: 1.45;
color: #333;
}
.vital-row, .meta-row {
margin: 4px 0;
}
.sb-abilities {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 4px;
text-align: center;
padding: 6px 0;
}
.sb-ability {
display: flex;
flex-direction: column;
}
.ab-label {
font-weight: bold;
font-size: 12px;
color: #922610;
}
.ab-val {
font-size: 13.5px;
margin-top: 2px;
color: #222;
}
.sb-traits {
margin-top: 10px;
}
.trait-block, .action-block {
font-size: 14px;
line-height: 1.45;
margin: 8px 0;
padding-bottom: 8px;
border-bottom: 1px solid #eee;
text-align: justify;
}
.trait-block:last-child, .action-block:last-child {
border-bottom: none;
padding-bottom: 0;
}
.sb-section {
margin-top: 16px;
}
.section-title {
font-family: "Libre Baskerville", "Georgia", serif;
font-size: 20px;
font-weight: bold;
color: #922610;
margin: 0 0 4px 0;
}
.section-divider {
height: 1.5px;
background-color: #922610;
margin-bottom: 8px;
}
.legendary-preamble {
font-size: 13.5px;
font-style: italic;
line-height: 1.4;
margin: 6px 0 10px 0;
}
/* Responsive adjustments for phones */
@media (max-width: 480px) {
.stat-block-wrapper {
padding: 8px;
}
.stat-block {
padding: 14px;
}
.sb-name {
font-size: 24px;
}
.ab-val {
font-size: 12px;
}
}

View File

@@ -0,0 +1,234 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{display_name}} - Stat Block</title>
<link rel="stylesheet" href="stat_block.css">
</head>
<body class="stat-block-wrapper">
<div class="stat-block">
<!-- Header -->
<header class="sb-header">
<h1 class="sb-name">{{display_name}}</h1>
<div class="sb-type">
{{#if properties.size}}{{properties.size}}{{else}}Medium{{/if}}
{{#if properties.type}}{{properties.type}}{{else}}Humanoid{{/if}}{{#if properties.subtype}} ({{properties.subtype}}){{/if}},
{{#if properties.alignment}}{{properties.alignment}}{{else}}unaligned{{/if}}
</div>
</header>
<div class="red-bar"></div>
<!-- Core Vitals -->
<div class="sb-vitals">
<div class="vital-row">
<strong>Armor Class</strong> {{val properties.armor_class}}{{#if properties.armor_description}} ({{properties.armor_description}}){{/if}}
</div>
<div class="vital-row">
<strong>Hit Points</strong>
{{#if properties.hit_points.current}}
{{properties.hit_points.current}}
{{else if properties.hit_points.max}}
{{properties.hit_points.max}}
{{else}}
{{val properties.hit_points}}
{{/if}}
{{#if properties.hit_points.formula}}
({{properties.hit_points.formula}})
{{else if properties.hit_points.hit_dice}}
({{properties.hit_points.hit_dice}})
{{/if}}
</div>
<div class="vital-row">
<strong>Speed</strong>
{{#if properties.speed_desc}}
{{properties.speed_desc}}
{{else if properties.speed}}
{{properties.speed}} ft.
{{/if}}
</div>
</div>
<div class="red-bar"></div>
<!-- Ability Scores Table -->
<div class="sb-abilities">
<div class="sb-ability">
<span class="ab-label">STR</span>
<span class="ab-val">{{val properties.abilities.strength}} ({{modText properties.abilities.strength}})</span>
</div>
<div class="sb-ability">
<span class="ab-label">DEX</span>
<span class="ab-val">{{val properties.abilities.dexterity}} ({{modText properties.abilities.dexterity}})</span>
</div>
<div class="sb-ability">
<span class="ab-label">CON</span>
<span class="ab-val">{{val properties.abilities.constitution}} ({{modText properties.abilities.constitution}})</span>
</div>
<div class="sb-ability">
<span class="ab-label">INT</span>
<span class="ab-val">{{val properties.abilities.intelligence}} ({{modText properties.abilities.intelligence}})</span>
</div>
<div class="sb-ability">
<span class="ab-label">WIS</span>
<span class="ab-val">{{val properties.abilities.wisdom}} ({{modText properties.abilities.wisdom}})</span>
</div>
<div class="sb-ability">
<span class="ab-label">CHA</span>
<span class="ab-val">{{val properties.abilities.charisma}} ({{modText properties.abilities.charisma}})</span>
</div>
</div>
<div class="red-bar"></div>
<!-- Optional Monster Meta -->
<div class="sb-meta">
{{#if properties.saving_throws}}
<div class="meta-row">
<strong>Saving Throws</strong> {{join properties.saving_throws}}
</div>
{{/if}}
{{#if properties.skills}}
<div class="meta-row">
<strong>Skills</strong> {{join properties.skills}}
</div>
{{/if}}
{{#if properties.damage_vulnerabilities}}
<div class="meta-row">
<strong>Damage Vulnerabilities</strong> {{join properties.damage_vulnerabilities}}
</div>
{{/if}}
{{#if properties.damage_resistances}}
<div class="meta-row">
<strong>Damage Resistances</strong> {{join properties.damage_resistances}}
</div>
{{/if}}
{{#if properties.damage_immunities}}
<div class="meta-row">
<strong>Damage Immunities</strong> {{join properties.damage_immunities}}
</div>
{{/if}}
{{#if properties.condition_immunities}}
<div class="meta-row">
<strong>Condition Immunities</strong> {{join properties.condition_immunities}}
</div>
{{/if}}
{{#if properties.senses}}
<div class="meta-row">
<strong>Senses</strong> {{properties.senses}}
</div>
{{/if}}
{{#if properties.languages}}
<div class="meta-row">
<strong>Languages</strong> {{join properties.languages}}
</div>
{{/if}}
{{#if properties.challenge_rating}}
<div class="meta-row">
<strong>Challenge</strong> {{properties.challenge_rating}}
</div>
{{else if properties.cr}}
<div class="meta-row">
<strong>Challenge</strong> {{properties.cr}}{{#if properties.xp}} ({{properties.xp}} XP){{/if}}
</div>
{{/if}}
{{#if properties.proficiency_bonus}}
<div class="meta-row">
<strong>Proficiency Bonus</strong> +{{properties.proficiency_bonus}}
</div>
{{else if (calcProf properties.level properties.cr)}}
<div class="meta-row">
<strong>Proficiency Bonus</strong> +{{calcProf properties.level properties.cr}}
</div>
{{/if}}
</div>
<!-- Special Traits / Features -->
{{#if properties.traits}}
<div class="sb-traits">
{{#each properties.traits}}
<div class="trait-block">
<em><strong>{{this.name}}:</strong></em> {{formatText this.desc}}
</div>
{{/each}}
</div>
{{/if}}
<!-- Actions Section -->
{{#if properties.actions}}
<section class="sb-section">
<h2 class="section-title">Actions</h2>
<div class="section-divider"></div>
{{#each properties.actions}}
<div class="action-block">
<em><strong>{{this.name}}:</strong></em> {{formatText this.desc}}
</div>
{{/each}}
</section>
{{/if}}
<!-- Bonus Actions Section -->
{{#if properties.bonus_actions}}
<section class="sb-section">
<h2 class="section-title">Bonus Actions</h2>
<div class="section-divider"></div>
{{#each properties.bonus_actions}}
<div class="action-block">
<em><strong>{{this.name}}:</strong></em> {{formatText this.desc}}
</div>
{{/each}}
</section>
{{/if}}
<!-- Reactions Section -->
{{#if properties.reactions}}
<section class="sb-section">
<h2 class="section-title">Reactions</h2>
<div class="section-divider"></div>
{{#each properties.reactions}}
<div class="action-block">
<em><strong>{{this.name}}:</strong></em> {{formatText this.desc}}
</div>
{{/each}}
</section>
{{/if}}
<!-- Legendary Actions Section -->
{{#if properties.legendary_actions}}
<section class="sb-section">
<h2 class="section-title">Legendary Actions</h2>
<div class="section-divider"></div>
{{#if properties.legendary_actions.description}}
<p class="legendary-preamble">{{formatText properties.legendary_actions.description}}</p>
{{else if properties.legendariesDescription}}
<p class="legendary-preamble">{{formatText properties.legendariesDescription}}</p>
{{/if}}
{{#if properties.legendary_actions.actions}}
{{#each properties.legendary_actions.actions}}
<div class="action-block">
<em><strong>{{this.name}}:</strong></em> {{formatText this.desc}}
</div>
{{/each}}
{{else if properties.legendaries}}
{{#each properties.legendaries}}
<div class="action-block">
<em><strong>{{this.name}}:</strong></em> {{formatText this.desc}}
</div>
{{/each}}
{{/if}}
</section>
{{/if}}
</div>
</body>
</html>

View File

@@ -0,0 +1,19 @@
{
"$schema": "../../../schema/entity-definition.json",
"id": "armor",
"name": "Armor",
"description": "SR6 Wearable armor and protective gear providing Defense Rating bonuses.",
"ruleset_id": "sr6",
"version": "1.0.0",
"schema": {
"type": "object",
"required": ["name", "rating"],
"properties": {
"name": { "type": "string" },
"rating": { "type": ["integer", "string"], "description": "Armor rating bonus added to Defense Rating (e.g. 2, 4)." },
"social_modifier": { "type": "integer", "default": 0 },
"capacity": { "type": "integer", "default": 0 },
"notes": { "type": "string" }
}
}
}

View File

@@ -0,0 +1,21 @@
{
"$schema": "../../../schema/entity-definition.json",
"id": "augmentation",
"name": "Augmentation",
"description": "SR6 Cyberware and Bioware implants with essence cost, grade, and enhancements.",
"ruleset_id": "sr6",
"version": "1.0.0",
"schema": {
"type": "object",
"required": ["name", "essence"],
"properties": {
"name": { "type": "string" },
"category": { "type": "string", "enum": ["Cyberware", "Bioware", "Nanoware", "Geneware"], "default": "Cyberware" },
"grade": { "type": "string", "enum": ["Standard", "Alphaware", "Betaware", "Deltaware", "Used"], "default": "Standard" },
"rating": { "type": ["integer", "string"] },
"essence": { "type": "number", "description": "Essence loss." },
"capacity_cost": { "type": "integer" },
"notes": { "type": "string" }
}
}
}

View File

@@ -0,0 +1,326 @@
{
"$schema": "../../../schema/entity-definition.json",
"id": "character",
"name": "Shadowrunner Character",
"description": "A 6th Edition Shadowrunner character with attributes, skills, condition monitors, qualities, augmentations, and combat statistics.",
"ruleset_id": "sr6",
"version": "1.0.0",
"default_template": "character_sheet",
"allowed_templates": [
"character_sheet",
"dossier_sheet"
],
"schema": {
"type": "object",
"required": ["alias", "metatype", "attributes"],
"properties": {
"alias": {
"type": "string",
"description": "Runner handle / street name."
},
"real_name": {
"type": "string",
"description": "Legal name or character identity."
},
"player": {
"type": "string",
"description": "Player name."
},
"notes": {
"type": "string",
"description": "General character notes or mission memo."
},
"metatype": {
"type": "string",
"enum": ["Human", "Elf", "Dwarf", "Ork", "Troll"],
"description": "Character metatype."
},
"ethnicity": {
"type": "string",
"description": "Ethnic or cultural background."
},
"age": {
"type": ["integer", "string"],
"description": "Character age in years."
},
"sex": {
"type": "string",
"description": "Biological sex / gender."
},
"height": {
"type": "string",
"description": "Height (e.g. '2.4 m' or '6 ft 2 in')."
},
"weight": {
"type": "string",
"description": "Weight (e.g. '310 kg')."
},
"reputation": {
"type": ["integer", "string"],
"default": 0,
"description": "Street reputation."
},
"heat": {
"type": ["integer", "string"],
"default": 0,
"description": "Law enforcement attention level."
},
"karma": {
"type": ["integer", "string"],
"default": 0,
"description": "Current unspent Karma."
},
"total_karma": {
"type": ["integer", "string"],
"default": 0,
"description": "Career total Karma earned."
},
"misc": {
"type": "string",
"description": "Miscellaneous character notes."
},
"attributes": {
"type": "object",
"description": "Character core attributes.",
"properties": {
"body": { "type": ["integer", "object"], "description": "Body attribute." },
"agility": { "type": ["integer", "object"], "description": "Agility attribute." },
"reaction": { "type": ["integer", "object"], "description": "Reaction attribute." },
"strength": { "type": ["integer", "object"], "description": "Strength attribute." },
"willpower": { "type": ["integer", "object"], "description": "Willpower attribute." },
"logic": { "type": ["integer", "object"], "description": "Logic attribute." },
"intuition": { "type": ["integer", "object"], "description": "Intuition attribute." },
"charisma": { "type": ["integer", "object"], "description": "Charisma attribute." },
"edge": { "type": ["integer", "object"], "description": "Edge attribute rating." },
"essence": { "type": ["number", "object"], "default": 6.0, "description": "Remaining Essence." },
"magic": { "type": ["integer", "object"], "description": "Magic rating (if awakened)." },
"resonance": { "type": ["integer", "object"], "description": "Resonance rating (if technomancer)." },
"edge_points": { "type": ["integer", "object"], "default": 0, "description": "Current edge points pool." }
}
},
"combat_info": {
"type": "object",
"description": "Derived combat statistics.",
"properties": {
"initiative": { "type": "string", "description": "Physical initiative formula (e.g. '10 + 1D6')." },
"matrix_initiative": { "type": "string", "description": "Matrix initiative formula." },
"astral_initiative": { "type": "string", "description": "Astral initiative formula." },
"defense_rating": { "type": ["integer", "string", "object"], "description": "Defense Rating (Body + Armor)." },
"unarmed_ar": { "type": ["integer", "string", "object"], "description": "Unarmed Attack Rating." },
"composure": { "type": ["integer", "string", "object"], "description": "Composure (Willpower + Charisma)." },
"judge_intentions": { "type": ["integer", "string", "object"], "description": "Judge Intentions (Intuition + Charisma)." },
"memory": { "type": ["integer", "string", "object"], "description": "Memory (Logic + Willpower)." },
"lift_carry": { "type": ["integer", "string", "object"], "description": "Lift/Carry (Body + Willpower)." },
"movement": { "type": "string", "description": "Movement rates (Walking/Running/Sprint)." }
}
},
"condition_monitor": {
"type": "object",
"description": "Physical and Stun damage tracks.",
"properties": {
"physical_damage": { "type": "integer", "default": 0 },
"physical_boxes": { "type": "integer", "description": "Calculated total physical boxes (8 + ceil(body/2))." },
"stun_damage": { "type": "integer", "default": 0 },
"stun_boxes": { "type": "integer", "description": "Calculated total stun boxes (8 + ceil(willpower/2))." },
"overflow": { "type": "integer", "default": 0 }
}
},
"skills": {
"type": "array",
"description": "List of character skills.",
"items": {
"type": "object",
"required": ["name", "rating", "attribute"],
"properties": {
"name": { "type": "string" },
"rating": { "type": "integer", "minimum": 1, "maximum": 12 },
"attribute": { "type": "string" },
"specialization": { "type": "string" },
"expertise": { "type": "string" },
"type": { "type": "string", "enum": ["Action", "Knowledge", "Language"], "default": "Action" },
"dice_pool": { "type": "integer" }
}
}
},
"qualities": {
"type": "array",
"description": "Positive and negative character qualities.",
"items": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string" },
"type": { "type": "string", "enum": ["Positive", "Negative"] },
"notes": { "type": "string" }
}
}
},
"currency_and_ids": {
"type": "object",
"description": "Lifestyles, IDs, licenses, and nuyen.",
"properties": {
"nuyen": { "type": ["integer", "string"], "default": 0 },
"primary_lifestyle": { "type": "string" },
"licenses": { "type": "string" },
"fake_ids": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"rating": { "type": "integer" },
"lifestyle": { "type": "string" },
"funds": { "type": "string" },
"licenses": { "type": "string" }
}
}
}
}
},
"contacts": {
"type": "array",
"description": "Shadow contacts network.",
"items": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string" },
"connection": { "type": "integer", "minimum": 1, "maximum": 6 },
"loyalty": { "type": "integer", "minimum": 1, "maximum": 6 },
"notes": { "type": "string" }
}
}
},
"primary_armor": {
"type": "object",
"properties": {
"name": { "type": "string" },
"rating": { "type": ["integer", "string"] },
"notes": { "type": "string" }
}
},
"primary_ranged_weapon": {
"type": "object",
"properties": {
"name": { "type": "string" },
"dv": { "type": "string" },
"mode": { "type": "string" },
"attack_rating": {
"type": "object",
"properties": {
"close": { "type": ["integer", "string"] },
"near": { "type": ["integer", "string"] },
"far": { "type": ["integer", "string"] },
"extreme": { "type": ["integer", "string"] }
}
},
"ammo": { "type": "string" },
"notes": { "type": "string" }
}
},
"primary_melee_weapon": {
"type": "object",
"properties": {
"name": { "type": "string" },
"dv": { "type": "string" },
"close": { "type": ["integer", "string"] },
"notes": { "type": "string" }
}
},
"ranged_weapons": {
"type": "array",
"items": { "$ref": "#/properties/primary_ranged_weapon" }
},
"melee_weapons": {
"type": "array",
"items": { "$ref": "#/properties/primary_melee_weapon" }
},
"armor": {
"type": "array",
"items": { "$ref": "#/properties/primary_armor" }
},
"matrix_stats": {
"type": "object",
"properties": {
"device_name": { "type": "string" },
"device_rating": { "type": ["integer", "string"] },
"attack": { "type": ["integer", "string"] },
"sleaze": { "type": ["integer", "string"] },
"data_processing": { "type": ["integer", "string"] },
"firewall": { "type": ["integer", "string"] },
"programs": { "type": "array", "items": { "type": "string" } },
"matrix_damage": { "type": "integer", "default": 0 }
}
},
"augmentations": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"rating": { "type": ["integer", "string"] },
"notes": { "type": "string" },
"essence": { "type": "number" }
}
}
},
"vehicles": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"handling": { "type": "string" },
"acceleration": { "type": "string" },
"speed_interval": { "type": "string" },
"top_speed": { "type": "string" },
"body": { "type": ["integer", "string"] },
"armor": { "type": ["integer", "string"] },
"pilot": { "type": ["integer", "string"] },
"sensor": { "type": ["integer", "string"] },
"seats": { "type": ["integer", "string"] },
"notes": { "type": "string" }
}
}
},
"gear": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"rating": { "type": ["integer", "string"] },
"quantity": { "type": "integer", "default": 1 },
"notes": { "type": "string" }
}
}
},
"spells": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"category": { "type": "string", "enum": ["S", "P", "R", "CF"], "description": "Spell, Preparation, Ritual, Complex Form" },
"type_target": { "type": "string" },
"range": { "type": "string" },
"duration": { "type": "string" },
"drain": { "type": "string" },
"notes": { "type": "string" }
}
}
},
"adept_powers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"level": { "type": ["integer", "string"] },
"notes": { "type": "string" }
}
}
}
}
}
}

View File

@@ -0,0 +1,33 @@
{
"$schema": "../../../schema/entity-definition.json",
"id": "corporation",
"name": "Megacorporation",
"description": "SR6 Corporate Court ranked megacorporation profile with extraterritorial status, slogans, and leadership.",
"ruleset_id": "sr6",
"version": "1.0.0",
"schema": {
"type": "object",
"required": ["name", "status"],
"properties": {
"name": { "type": "string" },
"short_name": { "type": "string" },
"status": { "type": "string", "enum": ["AAA", "AA", "A"], "default": "AAA" },
"court_ranking_2080": { "type": "integer", "minimum": 1, "maximum": 10 },
"slogan": { "type": "string" },
"corporate_type": { "type": "string", "enum": ["Public Corporation", "Private Corporation"] },
"world_headquarters": { "type": "string" },
"leadership": {
"type": "object",
"properties": {
"title": { "type": "string" },
"name": { "type": "string" }
}
},
"major_divisions": {
"type": "array",
"items": { "type": "string" }
},
"notes": { "type": "string" }
}
}
}

View File

@@ -0,0 +1,97 @@
{
"$schema": "../../../schema/entity-definition.json",
"id": "dossier",
"name": "Shadowrunner Dossier",
"description": "A comprehensive 4-page runner dossier combining full character statistics with narrative background, roleplaying tips, tactical guidelines, and tailored action pools.",
"ruleset_id": "sr6",
"version": "1.0.0",
"default_template": "dossier_sheet",
"allowed_templates": [
"dossier_sheet",
"character_sheet"
],
"schema": {
"type": "object",
"required": ["alias", "metatype", "archetype", "attributes"],
"properties": {
"archetype": {
"type": "string",
"description": "Character archetype (e.g. 'Troll Street Samurai', 'Combat Mage', 'Elven Decker')."
},
"quote": {
"type": "string",
"description": "Introductory runner quote or catchphrase."
},
"pitch": {
"type": "string",
"description": "Summary pitch for playing this runner."
},
"background": {
"type": "string",
"description": "Full narrative life history and background story."
},
"preferred_tactics": {
"type": "string",
"description": "Combat style, weapon preferences, and tactical guidelines."
},
"roleplaying_tips": {
"type": "string",
"description": "Roleplaying advice, personality traits, and interpersonal dynamics."
},
"vital_contacts": {
"type": "array",
"description": "Key narrative contacts with detailed descriptions.",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"role": { "type": "string" },
"description": { "type": "string" }
}
}
},
"favorite_hangouts": {
"type": "array",
"description": "Locations the runner frequents in the sprawl.",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"location": { "type": "string" },
"description": { "type": "string" }
}
}
},
"favorite_downtime_activities": {
"type": "array",
"description": "Hobbies and off-run pastimes.",
"items": { "type": "string" }
},
"sample_actions": {
"type": "array",
"description": "Tailored sample actions with pre-computed dice pools.",
"items": {
"type": "object",
"properties": {
"action": { "type": "string" },
"action_type": { "type": "string", "enum": ["Minor", "Major", "Free"] },
"dice_pool": { "type": "integer" },
"notes": { "type": "string" }
}
}
},
"edge_boosts": {
"type": "array",
"description": "Recommended edge boosts and tactical options.",
"items": {
"type": "object",
"properties": {
"cost": { "type": "integer" },
"name": { "type": "string" },
"description": { "type": "string" }
}
}
}
}
}
}

View File

@@ -0,0 +1,47 @@
{
"$schema": "../../../schema/entity-definition.json",
"id": "gear",
"name": "Gear / Equipment",
"description": "SR6 Adventuring gear, electronics, tools, commlinks, cyberdecks, and programs.",
"ruleset_id": "sr6",
"version": "1.0.0",
"schema": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string" },
"category": {
"type": "string",
"enum": [
"Gear",
"Commlink",
"Cyberdeck",
"Program",
"Electronics",
"Tool",
"Medical",
"Security",
"Other"
]
},
"rating": { "type": ["integer", "string"] },
"device_rating": { "type": ["integer", "string"] },
"attributes_df": {
"type": "string",
"description": "Data Processing / Firewall ratings (e.g. '2/1')."
},
"active_program_slots": { "type": "integer" },
"attack": { "type": ["integer", "string"] },
"sleaze": { "type": ["integer", "string"] },
"programs": { "type": "array", "items": { "type": "string" } },
"rules": {
"type": "string",
"description": "Game mechanics and rules effect."
},
"quantity": { "type": "integer", "default": 1 },
"availability": { "type": ["integer", "string"] },
"cost": { "type": ["integer", "string"] },
"notes": { "type": "string" }
}
}
}

View File

@@ -0,0 +1,124 @@
{
"$schema": "../../../schema/entity-definition.json",
"id": "npc",
"name": "Non-Player Character / Gang",
"description": "SR6 NPCs, gang members, syndicate leaders, and corporate operatives compatible with character and dossier sheets.",
"ruleset_id": "sr6",
"version": "1.0.0",
"default_template": "character_picker",
"allowed_templates": ["character_picker", "character_sheet"],
"schema": {
"type": "object",
"required": ["alias"],
"properties": {
"alias": {
"type": "string",
"description": "NPC name, handle, or gang designation."
},
"real_name": {
"type": "string",
"description": "Legal name or true identity if known."
},
"archetype": {
"type": "string",
"description": "Role, title, or affiliation (e.g., 'Human Female Government Operative', 'Dwarf Gangers')."
},
"metatype": {
"type": "string",
"description": "Metatype (Human, Elf, Dwarf, Ork, Troll, etc.)."
},
"ethnicity": {
"type": "string",
"description": "Ethnicity or cultural background."
},
"quote": {
"type": "string",
"description": "Characteristic quote or battle cry."
},
"hook": {
"type": "string",
"description": "Gamemaster plot hook or motivation."
},
"notes": {
"type": "string",
"description": "Narrative background and roleplay guidance."
},
"attributes": {
"type": "object",
"description": "Core NPC attributes.",
"properties": {
"body": { "type": ["integer", "object"] },
"agility": { "type": ["integer", "object"] },
"reaction": { "type": ["integer", "object"] },
"strength": { "type": ["integer", "object"] },
"willpower": { "type": ["integer", "object"] },
"logic": { "type": ["integer", "object"] },
"intuition": { "type": ["integer", "object"] },
"charisma": { "type": ["integer", "object"] },
"edge": { "type": ["integer", "string", "object"] },
"essence": { "type": ["number", "object"] },
"magic": { "type": ["integer", "object"] }
}
},
"combat_info": {
"type": "object",
"description": "Quick-reference combat stats.",
"properties": {
"initiative": {
"type": "string",
"description": "Initiative score formula (e.g. '6 + 1D6')."
},
"defense_rating": {
"type": ["integer", "string", "object"],
"description": "Defense rating."
},
"condition_monitor": {
"type": ["integer", "string", "object"],
"description": "Condition monitor boxes."
},
"unarmed_ar": { "type": ["integer", "string", "object"] }
}
},
"skills": {
"type": "array",
"description": "List of active skills and ratings.",
"items": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string" },
"rating": { "type": ["integer", "string"] },
"attribute": { "type": "string" },
"dice_pool": { "type": ["integer", "string"] }
}
}
},
"gear": {
"type": "array",
"description": "Equipment, armor, and commlinks carried.",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"rating": { "type": ["integer", "string"] },
"notes": { "type": "string" }
}
}
},
"weapons": {
"type": "array",
"description": "Weapons equipped.",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"dv": { "type": "string" },
"mode": { "type": "string" },
"attack_rating": { "type": ["integer", "string", "object"] },
"notes": { "type": "string" }
}
}
}
}
}
}

View File

@@ -0,0 +1,21 @@
{
"$schema": "../../../schema/entity-definition.json",
"id": "spell",
"name": "Spell / Complex Form",
"description": "SR6 Hermetic and shamanic spells, preparations, rituals, and technomancer complex forms.",
"ruleset_id": "sr6",
"version": "1.0.0",
"schema": {
"type": "object",
"required": ["name", "category", "drain"],
"properties": {
"name": { "type": "string" },
"category": { "type": "string", "enum": ["Spell", "Preparation", "Ritual", "Complex Form"], "default": "Spell" },
"type_target": { "type": "string", "description": "Physical, Mana, Device, Persona, etc." },
"range": { "type": "string", "description": "Touch, LOS, Area, etc." },
"duration": { "type": "string", "description": "Instant, Sustained, Permanent." },
"drain": { "type": ["integer", "string"], "description": "Drain or Fading value (e.g. '3' or 'DV 4')." },
"notes": { "type": "string" }
}
}
}

View File

@@ -0,0 +1,28 @@
{
"$schema": "../../../schema/entity-definition.json",
"id": "vehicle",
"name": "Vehicle / Drone",
"description": "SR6 Ground vehicles, aircraft, watercraft, and rigger drones.",
"ruleset_id": "sr6",
"version": "1.0.0",
"schema": {
"type": "object",
"required": ["name", "handling", "body", "armor"],
"properties": {
"name": { "type": "string" },
"category": { "type": "string", "enum": ["Drone", "Groundcraft", "Hovercraft", "Watercraft", "Aircraft"] },
"handling": { "type": "string" },
"acceleration": { "type": "string" },
"speed_interval": { "type": "string" },
"top_speed": { "type": "string" },
"body": { "type": ["integer", "string"] },
"armor": { "type": ["integer", "string"] },
"pilot": { "type": ["integer", "string"] },
"sensor": { "type": ["integer", "string"] },
"seats": { "type": ["integer", "string"] },
"mod_slots": { "type": "integer" },
"sensor_array": { "type": "array", "items": { "type": "string" } },
"notes": { "type": "string" }
}
}
}

View File

@@ -0,0 +1,34 @@
{
"$schema": "../../../schema/entity-definition.json",
"id": "weapon",
"name": "Weapon",
"description": "SR6 Ranged and Melee weapons with DV, firing modes, attack ratings across range bands, and ammo.",
"ruleset_id": "sr6",
"version": "1.0.0",
"schema": {
"type": "object",
"required": ["name", "category", "dv"],
"properties": {
"name": { "type": "string" },
"category": {
"type": "string",
"enum": ["Hold-out", "Light Pistol", "Heavy Pistol", "Machine Pistol", "SMG", "Shotgun", "Rifle", "Sniper Rifle", "Assault Cannon", "Blade", "Club", "Unarmed", "Exotic"]
},
"type": { "type": "string", "enum": ["ranged", "melee"], "default": "ranged" },
"dv": { "type": "string", "description": "Damage Value (e.g. '4P', '3S')." },
"mode": { "type": "string", "description": "Firing mode (SS, SA, BF, FA)." },
"attack_rating": {
"type": "object",
"properties": {
"close": { "type": ["integer", "string"] },
"near": { "type": ["integer", "string"] },
"far": { "type": ["integer", "string"] },
"extreme": { "type": ["integer", "string"] }
}
},
"ammo": { "type": "string", "description": "Capacity and reload type (e.g. '15(c)')." },
"accessories": { "type": "array", "items": { "type": "string" } },
"notes": { "type": "string" }
}
}
}

View File

@@ -0,0 +1,13 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "38836c23-969a-4885-b881-029de2531415",
"ruleset_id": "sr6",
"entity_type": "armor",
"display_name": "Armor Jacket",
"description": "Available in many styles, it offers good protection without catching too much attention.",
"properties": {
"name": "Armor Jacket",
"rating": "+4 DR",
"notes": "Available in many styles, it offers good protection without catching too much attention."
}
}

View File

@@ -0,0 +1,13 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "02fd452c-d12f-483b-b0c8-0d7a3c03d6cd",
"ruleset_id": "sr6",
"entity_type": "armor",
"display_name": "Armor Vest",
"description": "A flexible-wrap vest designed to be worn under regular clothing without displaying bulk.",
"properties": {
"name": "Armor Vest",
"rating": "+3 DR",
"notes": "A flexible-wrap vest designed to be worn under regular clothing without displaying bulk."
}
}

View File

@@ -0,0 +1,13 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "e8f060d0-99eb-4592-81b5-6a6583549cc4",
"ruleset_id": "sr6",
"entity_type": "armor",
"display_name": "Lined Coat",
"description": "This duster has been consistently popular on the mean streets of the world’s sprawls for fifty years.",
"properties": {
"name": "Lined Coat",
"rating": "+3 DR",
"notes": "This duster has been consistently popular on the mean streets of the world’s sprawls for fifty years."
}
}

View File

@@ -0,0 +1,377 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "4c8524d7-0f8c-4f76-9d32-bb9a25032b49",
"ruleset_id": "sr6",
"entity_type": "character",
"display_name": "Emu",
"description": "Human Rigger from the official Shadowrun 6th World Beginner Box.",
"template_id": "character_sheet",
"properties": {
"alias": "Emu",
"real_name": "Emu",
"player": "Catalyst Pregen",
"notes": "Human Rigger with a vehicle control rig, drone fleet, and heavy Mafia debt.",
"metatype": "Human",
"ethnicity": "Aboriginal Australian (Wiradjuri)",
"age": 23,
"sex": "Female",
"height": "1.65 m",
"weight": "57 kg",
"reputation": 2,
"heat": 0,
"karma": 0,
"total_karma": 0,
"misc": "Former merc drone pilot; owes 200,000¥ to the Ciarniello Mafia.",
"attributes": {
"body": 2,
"agility": 2,
"reaction": 4,
"strength": 2,
"willpower": 4,
"logic": 4,
"intuition": 6,
"charisma": 3,
"edge": 5,
"essence": 3.6,
"magic": 0,
"edge_points": 5
},
"combat_info": {
"initiative": "10 + 1D6",
"matrix_initiative": "10 + 1D6",
"astral_initiative": "—",
"defense_rating": 6,
"unarmed_ar": 6,
"composure": 7,
"judge_intentions": 10,
"memory": 10,
"lift_carry": 6,
"movement": "5/10/15"
},
"condition_monitor": {
"physical_damage": 0,
"physical_boxes": 9,
"stun_damage": 0,
"stun_boxes": 10,
"overflow": 0
},
"skills": [
{
"name": "Piloting",
"rating": 7,
"attribute": "Reaction",
"specialization": "Groundcraft",
"dice_pool": 13,
"type": "Action"
},
{
"name": "Engineering",
"rating": 6,
"attribute": "Logic",
"specialization": "Gunnery",
"dice_pool": 12,
"type": "Action"
},
{
"name": "Perception",
"rating": 3,
"attribute": "Intuition",
"dice_pool": 9,
"type": "Action"
},
{
"name": "Firearms",
"rating": 3,
"attribute": "Agility",
"dice_pool": 5,
"type": "Action"
},
{
"name": "Electronics",
"rating": 2,
"attribute": "Logic",
"dice_pool": 6,
"type": "Action"
},
{
"name": "Con",
"rating": 2,
"attribute": "Charisma",
"dice_pool": 5,
"type": "Action"
},
{
"name": "Influence",
"rating": 2,
"attribute": "Charisma",
"dice_pool": 5,
"type": "Action"
},
{
"name": "Stealth",
"rating": 2,
"attribute": "Agility",
"dice_pool": 4,
"type": "Action"
},
{
"name": "Biotech",
"rating": 1,
"attribute": "Logic",
"dice_pool": 5,
"type": "Action"
},
{
"name": "Close Combat",
"rating": 1,
"attribute": "Agility",
"dice_pool": 3,
"type": "Action"
},
{
"name": "Seattle Metroplex Geography",
"rating": 2,
"attribute": "Logic",
"dice_pool": 6,
"type": "Knowledge"
},
{
"name": "Smuggling Routes",
"rating": 2,
"attribute": "Logic",
"dice_pool": 6,
"type": "Knowledge"
}
],
"qualities": [
{
"name": "Addiction (Cigarettes)",
"type": "Negative",
"notes": "Level 3 addiction; penalty if in withdrawal."
},
{
"name": "Gearhead",
"type": "Positive",
"notes": "May spend Edge on repair tests and vehicle handling."
},
{
"name": "In Debt",
"type": "Negative",
"notes": "Ciarniello Mafia: 200,000¥ debt, 8,000¥/month interest."
},
{
"name": "Juryrigger",
"type": "Positive",
"notes": "Gains bonus Edge point on Juryrigging tests."
},
{
"name": "SINner",
"type": "Negative",
"notes": "Standard national/system SIN; extra scrutiny and trace exposure."
}
],
"currency_and_ids": {
"nuyen": 265,
"primary_lifestyle": "Low (3 months prepaid)",
"licenses": "Concealed Carry (Assault Rifle), Drone Rigging, Cyberware",
"fake_ids": [
{
"name": "Kylie Mason",
"rating": 3,
"lifestyle": "Low",
"funds": "265¥",
"licenses": "Firearms, Cyberware, RCC"
}
]
},
"contacts": [
{
"name": "Giovanni Valenti",
"loyalty": 2,
"connection": 3,
"notes": "Drone and vehicle fixer, owner of Gio's Garage in Everett."
},
{
"name": "Lenny",
"loyalty": 3,
"connection": 2,
"notes": "Underground safehouse fixer."
},
{
"name": "Steve Draper",
"loyalty": 1,
"connection": 3,
"notes": "Knight Errant dispatcher on the take."
},
{
"name": "Tomaso di Stefano",
"loyalty": 2,
"connection": 2,
"notes": "Ciarniello Mafia loan shark ('Tommy D') and occasional Mr. Johnson."
}
],
"primary_armor": {
"name": "Armor jacket",
"rating": "+4",
"notes": "+4 Defense Rating bonus"
},
"primary_ranged_weapon": {
"name": "FN HAR Assault Rifle",
"dv": "5P",
"mode": "SA/BF/FA",
"attack_rating": { "close": 3, "near": 11, "far": 6, "extreme": 1 },
"ammo": "35(c)",
"notes": "w/ gas-vent system, laser sight"
},
"primary_melee_weapon": {
"name": "Unarmed Strike",
"dv": "2S",
"close": 2,
"notes": "Natural"
},
"ranged_weapons": [
{
"name": "FN HAR Assault Rifle",
"dv": "5P",
"mode": "SA/BF/FA",
"attack_rating": { "close": 3, "near": 11, "far": 6, "extreme": 1 },
"ammo": "35(c)",
"notes": "w/ gas-vent system, laser sight"
}
],
"melee_weapons": [
{
"name": "Unarmed Strike",
"dv": "2S",
"close": 2,
"notes": "Natural"
}
],
"armor": [
{
"name": "Armor jacket",
"rating": "+4",
"notes": "+4 DR bonus"
}
],
"matrix_stats": {
"device_name": "Maersk Spider RCC",
"device_rating": 4,
"attack": 0,
"sleaze": 0,
"data_processing": 4,
"firewall": 5,
"programs": ["Encryption", "Signal Scrubber", "Toolbox"],
"matrix_damage": 0
},
"augmentations": [
{
"name": "Control Rig",
"rating": 2,
"notes": "Grants +2 dice pool bonus and +1 Edge on vehicle skill tests when jumped in.",
"essence": 2.0
},
{
"name": "Cybereyes",
"rating": 3,
"notes": "w/ flare compensation, image link, low-light vision, smartlink, thermographic vision",
"essence": 0.4
},
{
"name": "Reflex Recorder",
"rating": 1,
"notes": "Piloting skill (+1 bonus rating)",
"essence": 0.1
}
],
"vehicles": [
{
"name": "GMC Commodore",
"handling": "4/3",
"accel": "14",
"speed": "120/160",
"armor": 8,
"body": 10,
"pilot": 2,
"sensor": 2,
"notes": "Sports sedan w/ 2 weapon mounts (Mossberg CMDT shotguns, 250 rds)"
},
{
"name": "GMC Bulldog",
"handling": "3/2",
"accel": "10",
"speed": "90/130",
"armor": 12,
"body": 16,
"pilot": 2,
"sensor": 2,
"notes": "Step-van rigger mobile workshop"
},
{
"name": "Lockheed Optic-X2",
"handling": "4",
"accel": "12",
"speed": "80",
"armor": 2,
"body": 3,
"pilot": 4,
"sensor": 4,
"notes": "Stealth recon drone w/ R6 Clearsight, R6 Stealth autosofts"
},
{
"name": "MCT-Nissan Roto-Drone (x3)",
"handling": "4",
"accel": "8",
"speed": "70",
"armor": 6,
"body": 6,
"pilot": 3,
"sensor": 3,
"notes": "Combat drone w/ weapon mount (Ingram Smartgun XI), R6 Maneuver, R6 Targeting autosofts"
},
{
"name": "MCT Hornet (x4)",
"handling": "3",
"accel": "5",
"speed": "30",
"armor": 0,
"body": 1,
"pilot": 2,
"sensor": 2,
"notes": "Micro indoor recon drone w/ R6 Stealth autosoft"
},
{
"name": "Horizon Flying Eye (x3)",
"handling": "3",
"accel": "6",
"speed": "40",
"armor": 1,
"body": 1,
"pilot": 2,
"sensor": 2,
"notes": "Micro surveillance drone w/ smoke grenade upgrade, R6 Maneuver autosoft"
}
],
"gear": [
{ "name": "Armor jacket", "rating": 4, "quantity": 1 },
{ "name": "Automotive mechanic shop", "quantity": 1 },
{
"name": "Maersk Spider RCC",
"rating": 4,
"quantity": 1,
"notes": "DR 4, D/F 4/5"
},
{
"name": "Renraku Sensei commlink",
"rating": 3,
"quantity": 1,
"notes": "DR 3, D/F 2/0"
},
{ "name": "Rating 3 Targeting Autosoft (HK 227)", "quantity": 1 },
{ "name": "Certified credstick", "quantity": 1, "notes": "265¥" },
{ "name": "FN HAR ammo box", "quantity": 175 }
],
"spells": [],
"adept_powers": []
}
}

View File

@@ -0,0 +1,329 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "8f3b2049-3f04-4c17-91de-84bb41e7399a",
"ruleset_id": "sr6",
"entity_type": "character",
"display_name": "Frostburn",
"description": "Ork Combat Mage from the official Shadowrun 6th World Beginner Box.",
"template_id": "character_sheet",
"properties": {
"alias": "Frostburn",
"real_name": "Kendra Maguire",
"player": "Catalyst Pregen",
"notes": "Ork Combat Mage specializing in fire, ice, protective illusions, and healing.",
"metatype": "Ork",
"ethnicity": "White",
"age": 25,
"sex": "Female",
"height": "2 m",
"weight": "115 kg",
"reputation": 2,
"heat": 0,
"karma": 0,
"total_karma": 0,
"misc": "Former NeoNET corporate security magical operative.",
"attributes": {
"body": 4,
"agility": 4,
"reaction": 2,
"strength": 3,
"willpower": 7,
"logic": 5,
"intuition": 1,
"charisma": 3,
"edge": 2,
"essence": 6.0,
"magic": 6,
"edge_points": 2
},
"combat_info": {
"initiative": "3 + 1D6",
"matrix_initiative": "3 + 1D6",
"astral_initiative": "7 + 2D6",
"defense_rating": 7,
"unarmed_ar": 4,
"composure": 10,
"judge_intentions": 4,
"memory": 12,
"lift_carry": 7,
"movement": "5/10/+1"
},
"condition_monitor": {
"physical_damage": 0,
"physical_boxes": 10,
"stun_damage": 0,
"stun_boxes": 12,
"overflow": 0
},
"skills": [
{
"name": "Sorcery",
"rating": 6,
"attribute": "Magic",
"dice_pool": 12,
"type": "Action"
},
{
"name": "Firearms",
"rating": 3,
"attribute": "Agility",
"dice_pool": 7,
"type": "Action"
},
{
"name": "Close Combat",
"rating": 2,
"attribute": "Agility",
"dice_pool": 6,
"type": "Action"
},
{
"name": "Astral",
"rating": 3,
"attribute": "Intuition",
"dice_pool": 4,
"type": "Action"
},
{
"name": "Perception",
"rating": 3,
"attribute": "Intuition",
"dice_pool": 4,
"type": "Action"
},
{
"name": "Athletics",
"rating": 1,
"attribute": "Agility",
"dice_pool": 5,
"type": "Action"
},
{
"name": "Stealth",
"rating": 1,
"attribute": "Agility",
"dice_pool": 5,
"type": "Action"
},
{
"name": "Magical Security",
"rating": 2,
"attribute": "Logic",
"dice_pool": 7,
"type": "Knowledge"
},
{
"name": "Security Procedures",
"rating": 2,
"attribute": "Logic",
"dice_pool": 7,
"type": "Knowledge"
},
{
"name": "Seattle Underground",
"rating": 2,
"attribute": "Logic",
"dice_pool": 7,
"type": "Knowledge"
}
],
"qualities": [
{
"name": "Built Tough",
"type": "Positive",
"notes": "+1 Physical damage track box."
},
{
"name": "Low-light Vision",
"type": "Positive",
"notes": "Natural ork low-light perception."
},
{
"name": "Dependents",
"type": "Negative",
"notes": "Supports her family in Redmond."
},
{
"name": "SINner",
"type": "Negative",
"notes": "Corporate SIN from former employment with NeoNET."
},
{
"name": "Socially Awkward",
"type": "Negative",
"notes": "Direct, blunt, and exasperated demeanor."
}
],
"currency_and_ids": {
"nuyen": 3500,
"primary_lifestyle": "Low (prepaid)",
"licenses": "Concealed Carry, Registered Awakened Practitioner",
"fake_ids": [
{
"name": "Evelyn Graves",
"rating": 3,
"lifestyle": "Low",
"funds": "3,500¥",
"licenses": "Firearms, Mage License"
}
]
},
"contacts": [
{
"name": "Brimstone",
"loyalty": 3,
"connection": 3,
"notes": "Elf combat mage, former NeoNET coworker and fellow runner."
},
{
"name": "Harrison Kellerman",
"loyalty": 2,
"connection": 4,
"notes": "Talismonger and owner of the Io Pan! lore store in Downtown Seattle."
},
{
"name": "Jules Maguire",
"loyalty": 4,
"connection": 2,
"notes": "Ork rigger, Frostburn's older brother and Cascade Ork smuggler."
}
],
"primary_armor": {
"name": "Lined coat",
"rating": "+3",
"notes": "+3 Defense Rating bonus"
},
"primary_ranged_weapon": {
"name": "Walther Palm Pistol",
"dv": "2P",
"mode": "BF",
"attack_rating": { "close": 12, "near": 7, "far": "—", "extreme": "—" },
"ammo": "2(b)",
"notes": "Hold-out pistol"
},
"primary_melee_weapon": {
"name": "Extendible baton",
"dv": "2S",
"close": 5,
"notes": "Club"
},
"ranged_weapons": [
{
"name": "Walther Palm Pistol",
"dv": "2P",
"mode": "BF",
"attack_rating": { "close": 12, "near": 7, "far": "—", "extreme": "—" },
"ammo": "2(b)",
"notes": "Double-barreled hold-out"
}
],
"melee_weapons": [
{
"name": "Extendible baton",
"dv": "2S",
"close": 5,
"notes": "Concealable club"
}
],
"armor": [
{
"name": "Lined coat",
"rating": "+3",
"notes": "+3 DR bonus"
}
],
"matrix_stats": {
"device_name": "Renraku Sensei commlink",
"device_rating": 3,
"attack": 0,
"sleaze": 0,
"data_processing": 2,
"firewall": 0,
"programs": [],
"matrix_damage": 0
},
"augmentations": [],
"vehicles": [],
"gear": [
{ "name": "Lined coat", "rating": 3, "quantity": 1 },
{ "name": "Renraku Sensei commlink", "rating": 3, "quantity": 1 },
{ "name": "Certified credstick", "quantity": 1, "notes": "3,500¥" },
{ "name": "Walther Palm Pistol ammo box", "quantity": 20 }
],
"spells": [
{
"name": "Fireball",
"category": "S",
"type_target": "Physical",
"range": "LOS (Area)",
"duration": "Instant",
"drain": "5",
"notes": "Elemental fire damage area effect"
},
{
"name": "Flamestrike",
"category": "S",
"type_target": "Physical",
"range": "LOS",
"duration": "Instant",
"drain": "4",
"notes": "Single-target direct flame bolt"
},
{
"name": "Ice Spear",
"category": "S",
"type_target": "Physical",
"range": "LOS",
"duration": "Instant",
"drain": "4",
"notes": "Piercing elemental cold damage"
},
{
"name": "Heal",
"category": "S",
"type_target": "Essence",
"range": "Touch",
"duration": "Permanent",
"drain": "3",
"notes": "Repairs physical damage boxes"
},
{
"name": "Combat Sense",
"category": "S",
"type_target": "Mana",
"range": "Touch",
"duration": "Sustained",
"drain": "3",
"notes": "Adds defense dice and awareness"
},
{
"name": "Improved Invisibility",
"category": "S",
"type_target": "Physical",
"range": "Touch",
"duration": "Sustained",
"drain": "4",
"notes": "Cloaks target from visual & technological detection"
},
{
"name": "Levitate",
"category": "S",
"type_target": "Physical",
"range": "LOS",
"duration": "Sustained",
"drain": "4",
"notes": "Telekinetically lifts objects or persons"
},
{
"name": "Mana Barrier",
"category": "S",
"type_target": "Mana",
"range": "LOS (Area)",
"duration": "Sustained",
"drain": "4",
"notes": "Blocks astral forms and hostile spells"
}
],
"adept_powers": []
}
}

View File

@@ -0,0 +1,204 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "e97b91d2-06c5-4d7a-b5a9-467362974eb1",
"ruleset_id": "sr6",
"entity_type": "character",
"display_name": "Rude",
"description": "Troll Street Samurai from the official Shadowrun 6th World Beginner Box.",
"template_id": "character_sheet",
"properties": {
"alias": "Rude",
"real_name": "Unknown (\"Rudiarius\")",
"player": "Catalyst Pregen",
"notes": "Street Samurai meat shield with amnesia and a vicious combat streak.",
"metatype": "Troll",
"ethnicity": "White",
"age": 29,
"sex": "Male",
"height": "2.4 m",
"weight": "310 kg",
"reputation": 3,
"heat": 1,
"karma": 0,
"total_karma": 0,
"misc": "Carries an ancient wooden gladiator practice sword.",
"attributes": {
"body": 7,
"agility": 5,
"reaction": 6,
"strength": 6,
"willpower": 4,
"logic": 4,
"intuition": 4,
"charisma": 2,
"edge": 5,
"essence": 5.5,
"edge_points": 5
},
"combat_info": {
"initiative": "10 + 1D6",
"matrix_initiative": "10 + 1D6",
"astral_initiative": "—",
"defense_rating": 11,
"unarmed_ar": 7,
"composure": 6,
"judge_intentions": 6,
"memory": 8,
"lift_carry": 11,
"movement": "5/10/+1"
},
"condition_monitor": {
"physical_damage": 0,
"physical_boxes": 12,
"stun_damage": 0,
"stun_boxes": 10,
"overflow": 0
},
"skills": [
{ "name": "Firearms", "rating": 6, "attribute": "Agility", "dice_pool": 12, "type": "Action" },
{ "name": "Close Combat", "rating": 3, "attribute": "Agility", "dice_pool": 9, "type": "Action" },
{ "name": "Athletics", "rating": 3, "attribute": "Agility", "dice_pool": 9, "type": "Action" },
{ "name": "Perception", "rating": 3, "attribute": "Intuition", "dice_pool": 7, "type": "Action" },
{ "name": "Engineering", "rating": 2, "attribute": "Logic", "specialization": "Lockpicking", "dice_pool": 6, "type": "Action" },
{ "name": "Influence", "rating": 2, "attribute": "Charisma", "dice_pool": 4, "type": "Action" },
{ "name": "Exotic Weapons", "rating": 3, "attribute": "Agility", "specialization": "Grapple Gun", "dice_pool": 9, "type": "Action" },
{ "name": "Exotic Weapons", "rating": 4, "attribute": "Agility", "specialization": "Grapple Launcher", "dice_pool": 9, "type": "Action" },
{ "name": "Firearms Manufacturers", "rating": 2, "attribute": "Logic", "dice_pool": 6, "type": "Knowledge" },
{ "name": "Security Systems", "rating": 2, "attribute": "Logic", "dice_pool": 6, "type": "Knowledge" },
{ "name": "Urban Brawl Teams", "rating": 2, "attribute": "Logic", "dice_pool": 6, "type": "Knowledge" }
],
"qualities": [
{ "name": "Built Tough", "type": "Positive", "notes": "+1 Physical condition monitor box." },
{ "name": "Dermal Deposits", "type": "Positive", "notes": "+1 natural Armor/Defense Rating." },
{ "name": "High Pain Tolerance", "type": "Positive", "notes": "Reduces wound modifiers by 1." },
{ "name": "Thermographic Vision", "type": "Positive", "notes": "Natural troll heat-signature vision." },
{ "name": "Socially Awkward", "type": "Negative", "notes": "Blunt and lacking empathy due to amnesia." }
],
"currency_and_ids": {
"nuyen": 3500,
"primary_lifestyle": "Low (1 month prepaid)",
"licenses": "Concealed Carry (Heavy Pistol, Sniper Rifle)",
"fake_ids": [
{
"name": "Marcus Vance",
"rating": 3,
"lifestyle": "Low",
"funds": "3,500¥",
"licenses": "Driver's, Concealed Carry"
}
]
},
"contacts": [
{
"name": "Billy Shen",
"loyalty": 2,
"connection": 4,
"notes": "Octagon Triad lieutenant, enforcer, and arms dealer."
},
{
"name": "Four-Finger Wong",
"loyalty": 3,
"connection": 3,
"notes": "Cyber-surgeon and underground street doc."
},
{
"name": "Mia",
"loyalty": 3,
"connection": 2,
"notes": "Part-time fixer and waitress at Peaceable Kingdom."
}
],
"primary_armor": {
"name": "Armor jacket",
"rating": "+2",
"notes": "+2 Defense Rating bonus"
},
"primary_ranged_weapon": {
"name": "Ares Desert Strike",
"dv": "5P",
"mode": "SA",
"attack_rating": {
"close": 3,
"near": 10,
"far": 10,
"extreme": 10
},
"ammo": "14(c)",
"notes": "Sniper rifle w/ imaging scope, shock pad"
},
"primary_melee_weapon": {
"name": "Sword",
"dv": "3P",
"close": 9,
"notes": "Blade"
},
"ranged_weapons": [
{
"name": "Ares Desert Strike (Sniper Rifle)",
"dv": "5P",
"mode": "SA",
"attack_rating": { "close": 3, "near": 10, "far": 10, "extreme": 10 },
"ammo": "14(c)",
"notes": "w/ imaging scope, shock pad"
},
{
"name": "Ares Predator VI (Heavy Pistol)",
"dv": "4P",
"mode": "SA",
"attack_rating": { "close": 9, "near": 9, "far": 7, "extreme": "—" },
"ammo": "15(c)",
"notes": "w/ smartlink"
}
],
"melee_weapons": [
{
"name": "Sword (Blade)",
"dv": "3P",
"close": 9,
"notes": "Monofilament edge"
}
],
"armor": [
{
"name": "Armor jacket",
"rating": "+2",
"notes": "Provides +2 DR"
}
],
"matrix_stats": {
"device_name": "Sony Emperor commlink",
"device_rating": 2,
"attack": 0,
"sleaze": 0,
"data_processing": 1,
"firewall": 1,
"programs": [],
"matrix_damage": 0
},
"augmentations": [
{
"name": "Cybereyes",
"rating": 2,
"notes": "w/ smartlink, low-light vision",
"essence": 0.2
},
{
"name": "Reaction enhancers",
"rating": 1,
"notes": "+1 REA, +1 Initiative",
"essence": 0.3
}
],
"vehicles": [],
"gear": [
{ "name": "Armor jacket", "rating": 2, "quantity": 1 },
{ "name": "Sony Emperor commlink", "rating": 2, "quantity": 1 },
{ "name": "Grapple gun", "quantity": 1, "notes": "w/ 100m stealth rope" },
{ "name": "Certified credstick", "quantity": 1, "notes": "Contains 3,500¥" },
{ "name": "Spare ammo clips (Ares Predator)", "quantity": 3 },
{ "name": "Spare ammo clips (Ares Desert Strike)", "quantity": 2 }
],
"spells": [],
"adept_powers": []
}
}

View File

@@ -0,0 +1,264 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "7a83d9b1-0943-4e89-a2a1-e40d0f287113",
"ruleset_id": "sr6",
"entity_type": "character",
"display_name": "Yu",
"description": "Elf Covert Ops Specialist and Face from the official Shadowrun 6th World Beginner Box.",
"template_id": "character_sheet",
"properties": {
"alias": "Yu",
"real_name": "Yu",
"player": "Catalyst Pregen",
"notes": "Elf Covert Ops Specialist and Face with high agility, charisma, and stealth skills.",
"metatype": "Elf",
"ethnicity": "Cantonese",
"age": 28,
"sex": "Male",
"height": "1.8 m",
"weight": "77 kg",
"reputation": 2,
"heat": 0,
"karma": 0,
"total_karma": 0,
"misc": "Red Dragon / Octagon Triad affiliate; former thief and enforcer in Hong Kong.",
"attributes": {
"body": 3,
"agility": 6,
"reaction": 4,
"strength": 3,
"willpower": 5,
"logic": 5,
"intuition": 5,
"charisma": 8,
"edge": 2,
"essence": 6.0,
"magic": 0,
"edge_points": 2
},
"combat_info": {
"initiative": "9 + 1D6",
"matrix_initiative": "9 + 1D6",
"astral_initiative": "—",
"defense_rating": 6,
"unarmed_ar": 6,
"composure": 13,
"judge_intentions": 13,
"memory": 10,
"lift_carry": 6,
"movement": "5/10/+1"
},
"condition_monitor": {
"physical_damage": 0,
"physical_boxes": 10,
"stun_damage": 0,
"stun_boxes": 11,
"overflow": 0
},
"skills": [
{
"name": "Con",
"rating": 6,
"attribute": "Charisma",
"dice_pool": 14,
"type": "Action"
},
{
"name": "Influence",
"rating": 6,
"attribute": "Charisma",
"dice_pool": 14,
"type": "Action"
},
{
"name": "Stealth",
"rating": 6,
"attribute": "Agility",
"dice_pool": 12,
"type": "Action"
},
{
"name": "Close Combat",
"rating": 4,
"attribute": "Agility",
"dice_pool": 10,
"type": "Action"
},
{
"name": "Firearms",
"rating": 2,
"attribute": "Agility",
"dice_pool": 8,
"type": "Action"
},
{
"name": "Perception",
"rating": 2,
"attribute": "Intuition",
"dice_pool": 7,
"type": "Action"
},
{
"name": "Piloting",
"rating": 2,
"attribute": "Reaction",
"dice_pool": 6,
"type": "Action"
},
{
"name": "Biotech",
"rating": 1,
"attribute": "Logic",
"dice_pool": 6,
"type": "Action"
},
{
"name": "Outdoors",
"rating": 1,
"attribute": "Intuition",
"dice_pool": 6,
"type": "Action"
},
{
"name": "Architecture",
"rating": 2,
"attribute": "Logic",
"dice_pool": 7,
"type": "Knowledge"
},
{
"name": "Close-up Magic",
"rating": 2,
"attribute": "Logic",
"dice_pool": 7,
"type": "Knowledge"
},
{
"name": "Wildlife",
"rating": 2,
"attribute": "Logic",
"dice_pool": 7,
"type": "Knowledge"
}
],
"qualities": [
{
"name": "Catlike",
"type": "Positive",
"notes": "+1 dice pool bonus on stealth and acrobatics tests."
},
{
"name": "Double-Jointed",
"type": "Positive",
"notes": "+1 dice pool bonus on escape and contortion tests."
},
{
"name": "Low-Light Vision",
"type": "Positive",
"notes": "Natural elf low-light perception."
}
],
"currency_and_ids": {
"nuyen": 3500,
"primary_lifestyle": "Low (1 month prepaid)",
"licenses": "Concealed Carry (Light Pistol)",
"fake_ids": [
{
"name": "Raymond Chang",
"rating": 4,
"lifestyle": "Low",
"funds": "3,500¥",
"licenses": "Firearms, Security Tech"
}
]
},
"contacts": [
{
"name": "Billy Shen",
"loyalty": 2,
"connection": 4,
"notes": "Octagon Triad lieutenant, enforcer, and arms dealer."
},
{
"name": "Four-Finger Wong",
"loyalty": 3,
"connection": 3,
"notes": "Cyber-surgeon and underground street doc."
},
{
"name": "Mia",
"loyalty": 3,
"connection": 2,
"notes": "Part-time fixer and waitress at Peaceable Kingdom."
}
],
"primary_armor": {
"name": "Lined coat",
"rating": "+3",
"notes": "+3 Defense Rating bonus"
},
"primary_ranged_weapon": {
"name": "Ares Light Fire 75",
"dv": "2P",
"mode": "SA",
"attack_rating": { "close": 10, "near": 7, "far": 6, "extreme": "—" },
"ammo": "16(c)",
"notes": "w/ silencer, smartgun"
},
"primary_melee_weapon": {
"name": "Extendible baton",
"dv": "3S",
"close": 6,
"notes": "Club"
},
"ranged_weapons": [
{
"name": "Ares Light Fire 75 (Light Pistol)",
"dv": "2P",
"mode": "SA",
"attack_rating": { "close": 10, "near": 7, "far": 6, "extreme": "—" },
"ammo": "16(c)",
"notes": "w/ silencer, smartgun"
}
],
"melee_weapons": [
{
"name": "Extendible baton",
"dv": "3S",
"close": 6,
"notes": "Club"
}
],
"armor": [
{
"name": "Lined coat",
"rating": "+3",
"notes": "+3 DR bonus"
}
],
"matrix_stats": {
"device_name": "Erika Elite commlink",
"device_rating": 4,
"attack": 0,
"sleaze": 0,
"data_processing": 2,
"firewall": 1,
"programs": [],
"matrix_damage": 0
},
"augmentations": [],
"vehicles": [],
"gear": [
{ "name": "Lined coat", "rating": 3, "quantity": 1 },
{ "name": "Erika Elite commlink", "rating": 4, "quantity": 1 },
{ "name": "Disguise kit", "quantity": 1 },
{ "name": "First Aid Kit", "rating": 3, "quantity": 1 },
{ "name": "Passkey", "rating": 4, "quantity": 1 },
{ "name": "Contacts", "quantity": 1, "notes": "w/ smartlink" },
{ "name": "Certified credstick", "quantity": 1, "notes": "3,500¥" },
{ "name": "Spare ammo clips (Ares Light Fire 75)", "quantity": 3 }
],
"spells": [],
"adept_powers": []
}
}

View File

@@ -0,0 +1,257 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "e812d4a5-671c-4b52-9b2f-3d6118bfa934",
"ruleset_id": "sr6",
"entity_type": "character",
"display_name": "Zipfile",
"description": "Dwarf Decker from the official Shadowrun 6th World Beginner Box.",
"template_id": "character_sheet",
"properties": {
"alias": "Zipfile",
"real_name": "Zipfile",
"player": "Catalyst Pregen",
"notes": "Dwarf Decker specializing in illicit host penetration, device control, and Matrix sabotage.",
"metatype": "Dwarf",
"ethnicity": "Bantu",
"age": 23,
"sex": "Female",
"height": "1.1 m",
"weight": "36 kg",
"reputation": 2,
"heat": 0,
"karma": 0,
"total_karma": 0,
"misc": "Azanian neo-anarchist activist and urban brawl fan.",
"attributes": {
"body": 5,
"agility": 3,
"reaction": 4,
"strength": 4,
"willpower": 6,
"logic": 6,
"intuition": 6,
"charisma": 3,
"edge": 4,
"essence": 3.7,
"magic": 0,
"edge_points": 4
},
"combat_info": {
"initiative": "10 + 1D6",
"matrix_initiative": "12 + 1D6",
"astral_initiative": "—",
"defense_rating": 8,
"unarmed_ar": 4,
"composure": 9,
"judge_intentions": 9,
"memory": 12,
"lift_carry": 9,
"movement": "5/10/+1"
},
"condition_monitor": {
"physical_damage": 0,
"physical_boxes": 11,
"stun_damage": 0,
"stun_boxes": 11,
"overflow": 0
},
"skills": [
{
"name": "Cracking",
"rating": 6,
"attribute": "Logic",
"dice_pool": 12,
"type": "Action"
},
{
"name": "Electronics",
"rating": 6,
"attribute": "Logic",
"dice_pool": 12,
"type": "Action"
},
{
"name": "Engineering",
"rating": 2,
"attribute": "Logic",
"dice_pool": 8,
"type": "Action"
},
{
"name": "Perception",
"rating": 3,
"attribute": "Intuition",
"dice_pool": 9,
"type": "Action"
},
{
"name": "Firearms",
"rating": 2,
"attribute": "Agility",
"dice_pool": 5,
"type": "Action"
},
{
"name": "Close Combat",
"rating": 2,
"attribute": "Agility",
"dice_pool": 5,
"type": "Action"
},
{
"name": "Cyberdeck Models",
"rating": 2,
"attribute": "Logic",
"dice_pool": 8,
"type": "Knowledge"
},
{
"name": "German Expressionist Cinema",
"rating": 2,
"attribute": "Logic",
"dice_pool": 8,
"type": "Knowledge"
},
{
"name": "Matrix Security",
"rating": 2,
"attribute": "Logic",
"dice_pool": 8,
"type": "Knowledge"
}
],
"qualities": [
{
"name": "Gearhead",
"type": "Positive",
"notes": "May spend Edge on Repair tests and during downtime repairs."
},
{
"name": "Guts",
"type": "Positive",
"notes": "+2 dice pool bonus on tests resisting fear and intimidation."
},
{
"name": "Thermographic Vision",
"type": "Positive",
"notes": "Natural dwarf heat-signature vision."
}
],
"currency_and_ids": {
"nuyen": 3500,
"primary_lifestyle": "Low (1 month prepaid)",
"licenses": "Concealed Carry (Heavy Pistol), Cyberdeck Operator License",
"fake_ids": [
{
"name": "Nandi Mandela",
"rating": 3,
"lifestyle": "Low",
"funds": "3,500¥",
"licenses": "Heavy Pistol, Hardware Tech"
}
]
},
"contacts": [
{
"name": "Arclight",
"loyalty": 3,
"connection": 4,
"notes": "Combat mage and coordinator for the Black Star neo-anarchist shadowrunner collective."
},
{
"name": "Casey Connors",
"loyalty": 2,
"connection": 3,
"notes": "Owner of the Cathode Glow e-sports bar and tech museum in Tacoma."
},
{
"name": "Jules Maguire",
"loyalty": 2,
"connection": 2,
"notes": "Cascade Ork smuggler."
}
],
"primary_armor": {
"name": "Armor vest",
"rating": "+3",
"notes": "+3 Defense Rating bonus"
},
"primary_ranged_weapon": {
"name": "Ruger Super Warhawk",
"dv": "4P",
"mode": "SS",
"attack_rating": { "close": 8, "near": 11, "far": 8, "extreme": "—" },
"ammo": "6(cy)",
"notes": "Heavy cylinder revolver"
},
"primary_melee_weapon": {
"name": "Unarmed Strike",
"dv": "2S",
"close": 4,
"notes": "Fist / kick"
},
"ranged_weapons": [
{
"name": "Ruger Super Warhawk (Heavy Pistol)",
"dv": "4P",
"mode": "SS",
"attack_rating": { "close": 8, "near": 11, "far": 8, "extreme": "—" },
"ammo": "6(cy)",
"notes": "Heavy revolver"
}
],
"melee_weapons": [
{
"name": "Unarmed Strike",
"dv": "2S",
"close": 4,
"notes": "Natural"
}
],
"armor": [
{
"name": "Armor vest",
"rating": "+3",
"notes": "+3 DR bonus"
}
],
"matrix_stats": {
"device_name": "Renraku Kitsune cyberdeck",
"device_rating": 4,
"attack": 6,
"sleaze": 7,
"data_processing": 4,
"firewall": 4,
"programs": ["Decryption", "Exploit", "Overclock"],
"matrix_damage": 0
},
"augmentations": [
{
"name": "Cyberjack MPI",
"rating": 4,
"notes": "7/6, +2 Matrix initiative",
"essence": 2.3
}
],
"vehicles": [],
"gear": [
{ "name": "Armor vest", "rating": 3, "quantity": 1 },
{
"name": "Renraku Kitsune cyberdeck",
"rating": 4,
"quantity": 1,
"notes": "DR 4, 7/6, 8 slots"
},
{
"name": "Hermes Ikon commlink",
"rating": 5,
"quantity": 1,
"notes": "DR 5, 3/0"
},
{ "name": "Certified credstick", "quantity": 1, "notes": "3,500¥" },
{ "name": "Heavy pistol ammo box (Ruger)", "quantity": 30 }
],
"spells": [],
"adept_powers": []
}
}

View File

@@ -0,0 +1,514 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "7a353684-2e91-4e78-98e3-0d32f508a8c1",
"ruleset_id": "sr6",
"entity_type": "dossier",
"display_name": "Emu (Human Rigger Dossier)",
"description": "Full 4-page narrative dossier for Emu, Human Rigger from the SR6 Beginner Box.",
"template_id": "dossier_sheet",
"properties": {
"alias": "Emu",
"real_name": "Emu",
"player": "Catalyst Pregen",
"archetype": "Human Rigger",
"quote": "\"(when jumped into her Optic-X2 or Roto-Drones) Flightless bird, my arse.\" / \"Stop shooting my bloody drones!\" / \"You know we don't actually say 'toss a shrimp on the barbie,' right? They're prawns, for frag's sake.\"",
"pitch": "Play this character if you like burned rubber and scorched engine oil, commanding a metal-and-plastic army with your brain, or rushing in and charging out of any sticky situation.",
"metatype": "Human",
"ethnicity": "Aboriginal Australian (Wiradjuri)",
"age": 23,
"sex": "Female",
"height": "1.65 m",
"weight": "57 kg",
"reputation": 2,
"heat": 0,
"karma": 0,
"total_karma": 0,
"misc": "Former mercenary drone pilot with an armed sports sedan, drone fleet, and Ciarniello Mafia debt.",
"notes": "Human Rigger commanding aerial recon drones, combat roto-drones, and a modified GMC Commodore sport sedan.",
"background": "Some are born into shadowrunning, some achieve it, and some have shadowrunning thrust upon them. The middle group often choose to become runners because they refuse to be pushed into the role in which their upbringing cast them, whether as a starving barrens rat, a comfortable-but-oppressed wageslave, or a hidebound traditionalist who follows the old ways just because their elders said they should. If Emu's life had begun in one of those roles, she might still be there today. Her parents were both Wiradjuri, descended from the indigenous peoples of New South Wales. Emu's mother came from a family of vocal indigenous-rights activists, while her father was a Japancorp wageslave and a product of modern Australian society, despite his ethnic heritage. As a result, Emu spent her formative years being pulled between two different lives. One week, she'd be on 'holiday' in the Outback with her mother, stepfather, and half-siblings, eating bush tucker and being told how her exposure to 'colonial culture' had prevented her from Awakening into a koradji like her grandfather. The next, she'd be in an air-conditioned corporate housing complex, being the token 'Indigenous friend' for other kids her age the way her father was to his colleagues. Feeling like an outsider no matter where she went, Emu took refuge in tinkering, whether with the complex electronics her father designed or the beat-up old trucks her mother's family drove whenever they went out woop woop. When Emu was a teenager, she fled both of her parents' homes for a technical school in Queensland, where she started training as a mechanic. She took up racing both cars and drones in her spare time, and she earned the attention of a mercenary recruiter, who offered her a contract as a drone pilot. Emu's time as a merc had definite rough patches—she didn't handle military-style discipline well—but the combat experience was the foundation she needed to become a shadowrunner. When her contract was up, she decided it was time for a change of pace, so she left Australia for Seattle. Emu's early days in the shadows were rocky; she kept a roof over her head, barely, but her lack of a control rig made it hard for her to catch and pull off better-paying jobs. In sheer frustration, she borrowed a pile of nuyen from the Ciarniello Mafia to get the headware she needed. Luckily, she ran into Ms. Myth soon after, and so far she's managed to keep her creditors at bay—but if the work dries up, it might be time for another inter-city 'change of pace.'",
"preferred_tactics": "As a rigger, Emu's responsibilities fall into three primary areas: scouting, ferrying her teammates around, and fire support. She favours using her GMC Commodore sport sedan during runs, since it's fast enough to outrun most pursuit and sports a pair of Mossberg shotguns to deal with (almost) anything that can keep up with it, but she keeps a stereotypical 'rigger van' (a GMC Bulldog) for occasions when she needs to field her entire fleet of drones. The drone that gets the most use by far is Emu's Lockheed Optic-X2, a stealth recon platform she uses to scout locations before runs and keep an eye on events on the ground as they unfold. Her MCT Hornets fill the same role when runs take place indoors. If and when a fight breaks out, Emu turns to her trusty Roto-Drones, usually armed with automatic weapons to lay down suppressive fire while Emu and the rest of the team escape.",
"roleplaying_tips": "On the outside, Emu combines the laid-back attitude that many Australians possess with the self-assuredness of a rigger who knows she's damn good at what she does. The flip side is that because she's used to feeling like an outsider, she's wary of commitment, preferring to keep even her teammates at arm's length. She'll have their backs in a scrap, but she's careful not to let herself get too attached.",
"vital_contacts": [
{
"name": "Giovanni Valenti",
"role": "Vehicle & Drone Fixer",
"description": "Owner of Gio's Garage, drone and vehicle salesman."
},
{
"name": "Steve Draper",
"role": "Knight Errant Dispatcher",
"description": "Knight Errant dispatcher on the take."
},
{
"name": "Tomaso di Stefano",
"role": "Mafia Loan Shark",
"description": "Ciarniello Mafia loan shark ('Tommy D') and occasional Mr. Johnson."
}
],
"favorite_hangouts": [
{
"name": "Black's Junk Yard",
"location": "Puyallup",
"description": "A scrap yard and workshop in Puyallup."
},
{
"name": "Gio's Garage",
"location": "Everett",
"description": "An Everett chop shop owned by the Ciarniello Mafia."
},
{
"name": "Grounds for Appeal",
"location": "University District",
"description": "A cafe near the University of Washington."
}
],
"favorite_downtime_activities": [
"Racing cars and drones all over the 'plex",
"Tinkering with her various vehicles",
"Watching action trids, especially Battlerun and Karl Kombatmage Reloaded"
],
"sample_actions": [
{
"action": "Ground Vehicle Operation (Jumped In)",
"action_type": "Major",
"dice_pool": 13,
"notes": "Piloting 7 + Intuition 6 (+2 Control Rig bonus, -Speed penalty)"
},
{
"action": "Flying Drone Operation (Jumped In)",
"action_type": "Major",
"dice_pool": 13,
"notes": "Piloting 7 + Intuition 6 (Controls Optic-X2 or Roto-Drones directly)"
},
{
"action": "Vehicle Gunnery (Jumped In)",
"action_type": "Major",
"dice_pool": 12,
"notes": "Engineering 6 + Gunnery 2 + Logic 4 (Operates Commodore shotguns / drone mounts)"
},
{
"action": "Ground Vehicle Operation (Manual)",
"action_type": "Major",
"dice_pool": 13,
"notes": "Piloting 7 + Reaction 4 + Reflex Recorder 1 + Spec 2 - 1 = 13"
},
{
"action": "Sensor Perception / Spot Ambush",
"action_type": "Minor",
"dice_pool": 9,
"notes": "Perception 3 + Intuition 6 (Via Cybereyes / drone sensors)"
},
{
"action": "Command Drone (Autopilot Orders)",
"action_type": "Minor",
"dice_pool": 10,
"notes": "Drone Pilot 4 + Autosoft 6 (Autonomous recon or evasive maneuvers)"
},
{
"action": "Juryrig Device / Emergency Repair",
"action_type": "Major",
"dice_pool": 10,
"notes": "Engineering 6 + Logic 4 (Grants 1 bonus Edge)"
},
{
"action": "Assault Rifle Shot (FN HAR)",
"action_type": "Major",
"dice_pool": 5,
"notes": "Firearms 3 + Agility 2 (Gas-vent 2, laser sight)"
}
],
"edge_boosts": [
{
"cost": 1,
"name": "Reroll one die",
"description": "Reroll any one die from your roll that failed to score a hit (Post)."
},
{
"cost": 1,
"name": "Add 3 to Initiative",
"description": "Add +3 to your Initiative Score for the combat turn (Any)."
},
{
"cost": 2,
"name": "+1 to single die",
"description": "Add +1 to any single die result, turning a 4 into a 5 (hit) (Post)."
},
{
"cost": 2,
"name": "Give ally 1 Edge",
"description": "Pass 1 Edge point to an allied runner (Any)."
},
{
"cost": 2,
"name": "Negate 1 Edge of foe",
"description": "Negate 1 point of Edge held by an opponent (Pre)."
},
{
"cost": 3,
"name": "Buy automatic hit",
"description": "Add 1 automatic hit to test result (Any)."
},
{
"cost": 3,
"name": "Heal Stun Damage",
"description": "Immediately clear 1 box from your stun damage track."
},
{
"cost": 4,
"name": "Add Edge to Pool",
"description": "Add full Edge attribute (+5) to dice pool and 6s explode (Pre)."
}
],
"attributes": {
"body": 2,
"agility": 2,
"reaction": 4,
"strength": 2,
"willpower": 4,
"logic": 4,
"intuition": 6,
"charisma": 3,
"edge": 5,
"essence": 3.6,
"magic": 0,
"edge_points": 5
},
"combat_info": {
"initiative": "10 + 1D6",
"matrix_initiative": "10 + 1D6",
"astral_initiative": "—",
"defense_rating": 6,
"unarmed_ar": 6,
"composure": 7,
"judge_intentions": 10,
"memory": 10,
"lift_carry": 6,
"movement": "5/10/15"
},
"condition_monitor": {
"physical_damage": 0,
"physical_boxes": 9,
"stun_damage": 0,
"stun_boxes": 10,
"overflow": 0
},
"skills": [
{
"name": "Piloting",
"rating": 7,
"attribute": "Reaction",
"specialization": "Groundcraft",
"dice_pool": 13,
"type": "Action"
},
{
"name": "Engineering",
"rating": 6,
"attribute": "Logic",
"specialization": "Gunnery",
"dice_pool": 12,
"type": "Action"
},
{
"name": "Perception",
"rating": 3,
"attribute": "Intuition",
"dice_pool": 9,
"type": "Action"
},
{
"name": "Firearms",
"rating": 3,
"attribute": "Agility",
"dice_pool": 5,
"type": "Action"
},
{
"name": "Electronics",
"rating": 2,
"attribute": "Logic",
"dice_pool": 6,
"type": "Action"
},
{
"name": "Con",
"rating": 2,
"attribute": "Charisma",
"dice_pool": 5,
"type": "Action"
},
{
"name": "Influence",
"rating": 2,
"attribute": "Charisma",
"dice_pool": 5,
"type": "Action"
},
{
"name": "Stealth",
"rating": 2,
"attribute": "Agility",
"dice_pool": 4,
"type": "Action"
},
{
"name": "Biotech",
"rating": 1,
"attribute": "Logic",
"dice_pool": 5,
"type": "Action"
},
{
"name": "Close Combat",
"rating": 1,
"attribute": "Agility",
"dice_pool": 3,
"type": "Action"
},
{
"name": "Seattle Metroplex Geography",
"rating": 2,
"attribute": "Logic",
"dice_pool": 6,
"type": "Knowledge"
},
{
"name": "Smuggling Routes",
"rating": 2,
"attribute": "Logic",
"dice_pool": 6,
"type": "Knowledge"
}
],
"qualities": [
{
"name": "Addiction (Cigarettes)",
"type": "Negative",
"notes": "Level 3 addiction; penalty if in withdrawal."
},
{
"name": "Gearhead",
"type": "Positive",
"notes": "May spend Edge on repair tests and vehicle handling."
},
{
"name": "In Debt",
"type": "Negative",
"notes": "Ciarniello Mafia: 200,000¥ debt, 8,000¥/month interest."
},
{
"name": "Juryrigger",
"type": "Positive",
"notes": "Gains bonus Edge point on Juryrigging tests."
},
{
"name": "SINner",
"type": "Negative",
"notes": "Standard national/system SIN; extra scrutiny and trace exposure."
}
],
"currency_and_ids": {
"nuyen": 265,
"primary_lifestyle": "Low (3 months prepaid)",
"licenses": "Concealed Carry (Assault Rifle), Drone Rigging, Cyberware",
"fake_ids": [
{
"name": "Kylie Mason",
"rating": 3,
"lifestyle": "Low",
"funds": "265¥",
"licenses": "Firearms, Cyberware, RCC"
}
]
},
"contacts": [
{
"name": "Giovanni Valenti",
"loyalty": 2,
"connection": 3,
"notes": "Drone and vehicle fixer, owner of Gio's Garage in Everett."
},
{
"name": "Lenny",
"loyalty": 3,
"connection": 2,
"notes": "Underground safehouse fixer."
},
{
"name": "Steve Draper",
"loyalty": 1,
"connection": 3,
"notes": "Knight Errant dispatcher on the take."
},
{
"name": "Tomaso di Stefano",
"loyalty": 2,
"connection": 2,
"notes": "Ciarniello Mafia loan shark ('Tommy D') and occasional Mr. Johnson."
}
],
"primary_armor": {
"name": "Armor jacket",
"rating": "+4",
"notes": "+4 Defense Rating bonus"
},
"primary_ranged_weapon": {
"name": "FN HAR Assault Rifle",
"dv": "5P",
"mode": "SA/BF/FA",
"attack_rating": { "close": 3, "near": 11, "far": 6, "extreme": 1 },
"ammo": "35(c)",
"notes": "w/ gas-vent system, laser sight"
},
"primary_melee_weapon": {
"name": "Unarmed Strike",
"dv": "2S",
"close": 2,
"notes": "Natural"
},
"ranged_weapons": [
{
"name": "FN HAR Assault Rifle",
"dv": "5P",
"mode": "SA/BF/FA",
"attack_rating": { "close": 3, "near": 11, "far": 6, "extreme": 1 },
"ammo": "35(c)",
"notes": "w/ gas-vent system, laser sight"
}
],
"melee_weapons": [
{
"name": "Unarmed Strike",
"dv": "2S",
"close": 2,
"notes": "Natural"
}
],
"armor": [
{
"name": "Armor jacket",
"rating": "+4",
"notes": "+4 DR bonus"
}
],
"matrix_stats": {
"device_name": "Maersk Spider RCC",
"device_rating": 4,
"attack": 0,
"sleaze": 0,
"data_processing": 4,
"firewall": 5,
"programs": ["Encryption", "Signal Scrubber", "Toolbox"],
"matrix_damage": 0
},
"augmentations": [
{
"name": "Control Rig",
"rating": 2,
"notes": "Grants +2 dice pool bonus and +1 Edge on vehicle skill tests when jumped in.",
"essence": 2.0
},
{
"name": "Cybereyes",
"rating": 3,
"notes": "w/ flare compensation, image link, low-light vision, smartlink, thermographic vision",
"essence": 0.4
},
{
"name": "Reflex Recorder",
"rating": 1,
"notes": "Piloting skill (+1 bonus rating)",
"essence": 0.1
}
],
"vehicles": [
{
"name": "GMC Commodore",
"handling": "4/3",
"accel": "14",
"speed": "120/160",
"armor": 8,
"body": 10,
"pilot": 2,
"sensor": 2,
"notes": "Sports sedan w/ 2 weapon mounts (Mossberg CMDT shotguns, 250 rds)"
},
{
"name": "GMC Bulldog",
"handling": "3/2",
"accel": "10",
"speed": "90/130",
"armor": 12,
"body": 16,
"pilot": 2,
"sensor": 2,
"notes": "Step-van rigger mobile workshop"
},
{
"name": "Lockheed Optic-X2",
"handling": "4",
"accel": "12",
"speed": "80",
"armor": 2,
"body": 3,
"pilot": 4,
"sensor": 4,
"notes": "Stealth recon drone w/ R6 Clearsight, R6 Stealth autosofts"
},
{
"name": "MCT-Nissan Roto-Drone (x3)",
"handling": "4",
"accel": "8",
"speed": "70",
"armor": 6,
"body": 6,
"pilot": 3,
"sensor": 3,
"notes": "Combat drone w/ weapon mount (Ingram Smartgun XI), R6 Maneuver, R6 Targeting autosofts"
},
{
"name": "MCT Hornet (x4)",
"handling": "3",
"accel": "5",
"speed": "30",
"armor": 0,
"body": 1,
"pilot": 2,
"sensor": 2,
"notes": "Micro indoor recon drone w/ R6 Stealth autosoft"
},
{
"name": "Horizon Flying Eye (x3)",
"handling": "3",
"accel": "6",
"speed": "40",
"armor": 1,
"body": 1,
"pilot": 2,
"sensor": 2,
"notes": "Micro surveillance drone w/ smoke grenade upgrade, R6 Maneuver autosoft"
}
],
"gear": [
{ "name": "Armor jacket", "rating": 4, "quantity": 1 },
{ "name": "Automotive mechanic shop", "quantity": 1 },
{
"name": "Maersk Spider RCC",
"rating": 4,
"quantity": 1,
"notes": "DR 4, D/F 4/5"
},
{
"name": "Renraku Sensei commlink",
"rating": 3,
"quantity": 1,
"notes": "DR 3, D/F 2/0"
},
{ "name": "Rating 3 Targeting Autosoft (HK 227)", "quantity": 1 },
{ "name": "Certified credstick", "quantity": 1, "notes": "265¥" },
{ "name": "FN HAR ammo box", "quantity": 175 }
],
"spells": [],
"adept_powers": []
}
}

View File

@@ -0,0 +1,461 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "4fb9f271-e5d4-4a41-b0be-4a18019b8833",
"ruleset_id": "sr6",
"entity_type": "dossier",
"display_name": "Frostburn (Ork Combat Mage Dossier)",
"description": "Full 4-page narrative dossier for Frostburn, Ork Combat Mage from the SR6 Beginner Box.",
"template_id": "dossier_sheet",
"properties": {
"alias": "Frostburn",
"real_name": "Kendra Maguire",
"player": "Catalyst Pregen",
"archetype": "Ork Combat Mage",
"quote": "\"That's why they say to geek the mage first.\" / \"Boring is always best.\" / \"(long-suffering sigh)\"",
"pitch": "Play this character if you like damaging things with fire and ice, and then fixing the people you like.",
"metatype": "Ork",
"ethnicity": "White",
"age": 25,
"sex": "Female",
"height": "2 m",
"weight": "115 kg",
"reputation": 2,
"heat": 0,
"karma": 0,
"total_karma": 0,
"misc": "Former NeoNET corporate security magical operative.",
"notes": "Ork Combat Mage specializing in fire, ice, protective illusions, and healing.",
"background": "As a child, Frostburn was a made-for-trid underdog success story. She and her family were forced out of the then–Ork Underground by dwarfs intent on 'reclaiming' property they hadn't cared about when it wasn't worth anything. They ended up in Redmond, scraping by on Frostburn's mom's job as a janitor at a NeoNET office building—until Frostburn Awakened. The megacorp fell all over itself to secure the woman's future, even giving her a full scholarship to the University of Washington. The day she showed up at the NeoNET offices, though, old stereotypes had started to creep in. Frostburn's tusks got her assigned to the Seattle division of NeoNET's corporate security force. Even if it wasn't her dream job, Frostburn would eventually decide that NeoSec wasn't such a bad place to work. A few years into the job, she was happy enough that when some 'loss-prevention consultant' gave the ork mage her commcode and said to call if she ever got tired of NeoSec, Frostburn took the pretty troll's contact info, then promptly forgot all about it. When NeoNET collapsed, that commcode became Frostburn's lifeline. The troll woman, known as Ms. Myth, didn't seem the slightest bit surprised when Frostburn called. Myth assured her there were plenty of jobs for a spell-slinger with a background in corporate security—if she was willing to work on the grey side of the law. Not wanting to see her family back in the Redmond Barrens (or worse), Frostburn took her first step into the shadows.",
"preferred_tactics": "Frostburn knows better than anyone else on the team that magic can turn the tide of a battle—and that chucking fireballs at every enemy she sees will have her passed out on the floor from the drain before she has a chance to really make a difference. Ironically, the 'fire and ice' combo of spells that earned the mage her street name are usually a last resort. Instead, she prefers illusory spells to make the team's enemies less effective or defensive spells to protect the others against hostile magic, and she can cast a Heal spell if one of her fellow runners takes a blow. If the team needs to capture a target alive, whether to question them about further resistance or because Mr. Johnson wants them retrieved, she'll use spells focused on stunning the target instead of killing them. In extended battles, Frostburn will summon spirits to fight on her behalf or resort to firearms to minimize drain, though she'll happily take potshots with her trademark elemental spells if she gets the chance. She also frequently uses astral projection to scout targets during the planning stage of a run.",
"roleplaying_tips": "Frostburn doesn't take anything for granted. Her Awakening might've made her special, but she tries not to let it go to her head. She's used to being the provider for her family, and she takes that role seriously, which sometimes means taking jobs that make her squeamish for the sake of paying the bills. She's also the closest thing the group has to a 'team mom,' constantly fussing over the others, which sometimes makes her seem like a bit of a party pooper. The rest of the team knows she has their back, though, even if they wish she'd get off it sometimes. Playing against ork stereotypes, Frostburn is also the most levelheaded member of the team (besides Rude, anyway). She likes runs going according to plan and would rather play it safe for a guaranteed payday than risk going double or nothing. She doesn't lose her cool when a run starts going to drek—hell, her job at NeoNET was to show up when things had already gone to drek—and she has enough leadership experience to rally her comrades when the going gets tough. If she ever blows a run, it won't be because she gave up.",
"vital_contacts": [
{
"name": "Brimstone",
"role": "Elf Combat Mage",
"description": "Former NeoNET coworker and current fellow runner."
},
{
"name": "Harrison Kellerman",
"role": "Talismonger",
"description": "Owner of the Io Pan! lore store in Downtown Seattle."
},
{
"name": "Jules Maguire",
"role": "Ork Rigger",
"description": "Frostburn's older brother and Cascade Ork smuggler."
}
],
"favorite_hangouts": [
{
"name": "Crusher 495",
"location": "Redmond",
"description": "Ork-run nightclub and community hub in Redmond."
},
{
"name": "Downfall",
"location": "Redmond",
"description": "Awakened-friendly bar in Redmond."
},
{
"name": "Magician's Feast",
"location": "Auburn",
"description": "Salish-American restaurant in Auburn offering illusion shows."
}
],
"favorite_downtime_activities": [
"Hiking and camping in the rural parts of the metroplex",
"Listening to goblin rock",
"Spending time with her family"
],
"sample_actions": [
{
"action": "Cast Spell (Sorcery)",
"action_type": "Major",
"dice_pool": 12,
"notes": "Sorcery 6 + Magic 6 (Adjust: Amp up +1 DV / +2 drain; Increase Area +2m / +1 drain)"
},
{
"action": "Counterspell (Boosted Defense)",
"action_type": "Major",
"dice_pool": 12,
"notes": "Sorcery 6 + Magic 6 (Sphere 2m radius, net hits add to defense pool of allies)"
},
{
"action": "Resist Drain",
"action_type": "Free",
"dice_pool": 12,
"notes": "Logic 5 + Willpower 7 (Drain value resisted, excess applied to Stun track)"
},
{
"action": "Ranged Shot (Walther Palm Pistol)",
"action_type": "Major",
"dice_pool": 7,
"notes": "Firearms 3 + Agility 4 (BF mode, DV 2P)"
},
{
"action": "Melee Strike (Extendible Baton)",
"action_type": "Major",
"dice_pool": 6,
"notes": "Close Combat 2 + Agility 4 (Club, DV 2S)"
},
{
"action": "Perception / Spot Trouble",
"action_type": "Minor",
"dice_pool": 4,
"notes": "Perception 3 + Intuition 1 (Low-Light Vision)"
},
{
"action": "Astral Perception / Assensing",
"action_type": "Minor",
"dice_pool": 4,
"notes": "Astral 3 + Intuition 1 (Inspect auras, signatures, and astral forms)"
},
{
"action": "Sneak / Infiltration",
"action_type": "Major",
"dice_pool": 5,
"notes": "Stealth 1 + Agility 4"
}
],
"edge_boosts": [
{
"cost": 1,
"name": "Reroll one die",
"description": "Reroll any one die from your roll that failed to score a hit (Post)."
},
{
"cost": 1,
"name": "Add 3 to Initiative",
"description": "Add +3 to your Initiative Score for the combat turn (Any)."
},
{
"cost": 2,
"name": "+1 to single die",
"description": "Add +1 to any single die result, turning a 4 into a 5 (hit) (Post)."
},
{
"cost": 2,
"name": "Give ally 1 Edge",
"description": "Pass 1 Edge point to an allied runner (Any)."
},
{
"cost": 3,
"name": "Heal Stun Damage",
"description": "Immediately clear 1 box from your stun damage track."
},
{
"cost": 4,
"name": "Add Edge to Pool",
"description": "Add full Edge attribute (+2) to dice pool and 6s explode (Pre)."
},
{
"cost": 5,
"name": "Glitch Foe",
"description": "2s count as glitches for target on their opposed test (Pre)."
}
],
"attributes": {
"body": 4,
"agility": 4,
"reaction": 2,
"strength": 3,
"willpower": 7,
"logic": 5,
"intuition": 1,
"charisma": 3,
"edge": 2,
"essence": 6.0,
"magic": 6,
"edge_points": 2
},
"combat_info": {
"initiative": "3 + 1D6",
"matrix_initiative": "3 + 1D6",
"astral_initiative": "7 + 2D6",
"defense_rating": 7,
"unarmed_ar": 4,
"composure": 10,
"judge_intentions": 4,
"memory": 12,
"lift_carry": 7,
"movement": "5/10/+1"
},
"condition_monitor": {
"physical_damage": 0,
"physical_boxes": 10,
"stun_damage": 0,
"stun_boxes": 12,
"overflow": 0
},
"skills": [
{
"name": "Sorcery",
"rating": 6,
"attribute": "Magic",
"dice_pool": 12,
"type": "Action"
},
{
"name": "Firearms",
"rating": 3,
"attribute": "Agility",
"dice_pool": 7,
"type": "Action"
},
{
"name": "Close Combat",
"rating": 2,
"attribute": "Agility",
"dice_pool": 6,
"type": "Action"
},
{
"name": "Astral",
"rating": 3,
"attribute": "Intuition",
"dice_pool": 4,
"type": "Action"
},
{
"name": "Perception",
"rating": 3,
"attribute": "Intuition",
"dice_pool": 4,
"type": "Action"
},
{
"name": "Athletics",
"rating": 1,
"attribute": "Agility",
"dice_pool": 5,
"type": "Action"
},
{
"name": "Stealth",
"rating": 1,
"attribute": "Agility",
"dice_pool": 5,
"type": "Action"
},
{
"name": "Magical Security",
"rating": 2,
"attribute": "Logic",
"dice_pool": 7,
"type": "Knowledge"
},
{
"name": "Security Procedures",
"rating": 2,
"attribute": "Logic",
"dice_pool": 7,
"type": "Knowledge"
},
{
"name": "Seattle Underground",
"rating": 2,
"attribute": "Logic",
"dice_pool": 7,
"type": "Knowledge"
}
],
"qualities": [
{
"name": "Built Tough",
"type": "Positive",
"notes": "+1 Physical damage track box."
},
{
"name": "Low-light Vision",
"type": "Positive",
"notes": "Natural ork low-light perception."
},
{
"name": "Dependents",
"type": "Negative",
"notes": "Supports her family in Redmond."
},
{
"name": "SINner",
"type": "Negative",
"notes": "Corporate SIN from former employment with NeoNET."
},
{
"name": "Socially Awkward",
"type": "Negative",
"notes": "Direct, blunt, and exasperated demeanor."
}
],
"currency_and_ids": {
"nuyen": 3500,
"primary_lifestyle": "Low (prepaid)",
"licenses": "Concealed Carry, Registered Awakened Practitioner",
"fake_ids": [
{
"name": "Evelyn Graves",
"rating": 3,
"lifestyle": "Low",
"funds": "3,500¥",
"licenses": "Firearms, Mage License"
}
]
},
"contacts": [
{
"name": "Brimstone",
"loyalty": 3,
"connection": 3,
"notes": "Elf combat mage, former NeoNET coworker and current fellow runner."
},
{
"name": "Harrison Kellerman",
"loyalty": 2,
"connection": 4,
"notes": "Talismonger and owner of the Io Pan! lore store in Downtown Seattle."
},
{
"name": "Jules Maguire",
"loyalty": 4,
"connection": 2,
"notes": "Ork rigger, Frostburn's older brother and Cascade Ork smuggler."
}
],
"primary_armor": {
"name": "Lined coat",
"rating": "+3",
"notes": "+3 Defense Rating bonus"
},
"primary_ranged_weapon": {
"name": "Walther Palm Pistol",
"dv": "2P",
"mode": "BF",
"attack_rating": { "close": 12, "near": 7, "far": "—", "extreme": "—" },
"ammo": "2(b)",
"notes": "Hold-out pistol"
},
"primary_melee_weapon": {
"name": "Extendible baton",
"dv": "2S",
"close": 5,
"notes": "Club"
},
"ranged_weapons": [
{
"name": "Walther Palm Pistol",
"dv": "2P",
"mode": "BF",
"attack_rating": { "close": 12, "near": 7, "far": "—", "extreme": "—" },
"ammo": "2(b)",
"notes": "Double-barreled hold-out"
}
],
"melee_weapons": [
{
"name": "Extendible baton",
"dv": "2S",
"close": 5,
"notes": "Concealable club"
}
],
"armor": [
{
"name": "Lined coat",
"rating": "+3",
"notes": "+3 DR bonus"
}
],
"matrix_stats": {
"device_name": "Renraku Sensei commlink",
"device_rating": 3,
"attack": 0,
"sleaze": 0,
"data_processing": 2,
"firewall": 0,
"programs": [],
"matrix_damage": 0
},
"augmentations": [],
"vehicles": [],
"gear": [
{ "name": "Lined coat", "rating": 3, "quantity": 1 },
{ "name": "Renraku Sensei commlink", "rating": 3, "quantity": 1 },
{ "name": "Certified credstick", "quantity": 1, "notes": "3,500¥" },
{ "name": "Walther Palm Pistol ammo box", "quantity": 20 }
],
"spells": [
{
"name": "Fireball",
"category": "S",
"type_target": "Physical",
"range": "LOS (Area)",
"duration": "Instant",
"drain": "5",
"notes": "Elemental fire damage area effect"
},
{
"name": "Flamestrike",
"category": "S",
"type_target": "Physical",
"range": "LOS",
"duration": "Instant",
"drain": "4",
"notes": "Single-target direct flame bolt"
},
{
"name": "Ice Spear",
"category": "S",
"type_target": "Physical",
"range": "LOS",
"duration": "Instant",
"drain": "4",
"notes": "Piercing elemental cold damage"
},
{
"name": "Heal",
"category": "S",
"type_target": "Essence",
"range": "Touch",
"duration": "Permanent",
"drain": "3",
"notes": "Repairs physical damage boxes"
},
{
"name": "Combat Sense",
"category": "S",
"type_target": "Mana",
"range": "Touch",
"duration": "Sustained",
"drain": "3",
"notes": "Adds defense dice and awareness"
},
{
"name": "Improved Invisibility",
"category": "S",
"type_target": "Physical",
"range": "Touch",
"duration": "Sustained",
"drain": "4",
"notes": "Cloaks target from visual & technological detection"
},
{
"name": "Levitate",
"category": "S",
"type_target": "Physical",
"range": "LOS",
"duration": "Sustained",
"drain": "4",
"notes": "Telekinetically lifts objects or persons"
},
{
"name": "Mana Barrier",
"category": "S",
"type_target": "Mana",
"range": "LOS (Area)",
"duration": "Sustained",
"drain": "4",
"notes": "Blocks astral forms and hostile spells"
}
],
"adept_powers": []
}
}

View File

@@ -0,0 +1,403 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "4c9e88d1-21e3-49fb-a720-6d38e24fa218",
"ruleset_id": "sr6",
"entity_type": "dossier",
"display_name": "Rude (Troll Street Samurai Dossier)",
"description": "Full 4-page narrative dossier for Rude, Troll Street Samurai from the SR6 Beginner Box.",
"template_id": "dossier_sheet",
"properties": {
"alias": "Rude",
"real_name": "Unknown (\"Rudiarius\")",
"player": "Catalyst Pregen",
"archetype": "Troll Street Samurai",
"quote": "\"You said non-lethal. He ain't dead. You gonna yap 'til he bleeds out?\" / \"I do the job, I get paid.\"",
"pitch": "Play this character if you like breaking things, shooting things, and forgetting to care what people think of you.",
"metatype": "Troll",
"ethnicity": "White",
"age": 29,
"sex": "Male",
"height": "2.4 m",
"weight": "310 kg",
"reputation": 3,
"heat": 1,
"karma": 0,
"total_karma": 0,
"misc": "Carries an ancient wooden practice sword from his gladiator past.",
"notes": "Street Samurai meat shield with amnesia and direct brutal tactics.",
"background": "Ask Rude where he's from, and he'll shrug and say he doesn't know—because he doesn't. There are a lot of things Rude doesn't know, like his real name or what his life was like growing up or how he first descended into the shadows. In fact, he doesn't remember much of anything before he woke up in a street clinic in Chicago about four years ago. He guesses he's from the CAS because he's got a drawl, and he calls himself Rude because one of the only things he does remember is a man calling him 'Rudiarius' and handing him a wooden sword. He found out later that a rudiarius was what people in ancient Rome called a gladiator who chose to keep fighting in the arena after they'd won their freedom. That wooden sword is the only thing Rude has from whatever his life used to be, just because he likes having it around. Of course, with no memory of how or why he'd been in Chicago, Rude didn't feel particularly compelled to stay there. Instead, he signed on with a smuggler crew as security and traveled the world. If there was one place Rude kept coming back to, though, it was Seattle; he probably had more layovers there than every other major city on the Pacific Rim combined. He ran into Ms. Myth at a bar in the Seattle Underground during one of those layovers, and when she offered him a spot on her new team, he decided to stick around for a while.",
"preferred_tactics": "Having a bomb go off inside his brain might've fragged Rude's memories, but it didn't dull his skills. In keeping with the whole 'gladiator' thing, his fighting style is direct and brutal. He's most comfortable with hacking his enemies to pieces with a sword, and since being a troll makes him the team's de facto meat shield, he might as well do it in a way the other side won't be able to ignore. When the situation calls for ranged combat, though, Rude's no slouch with a gun. His favorite sidearm is a beaten-up Ruger Super Warhawk sized to fit a troll, but he's equally comfortable with everything from submachine guns to assault cannons, and he burns through APDS and explosive ammo like it's going out of style. Rude isn't entirely 'pink mohawk'—he understands the value of stealth, even if his idea of stealth is 'shoot 'em before they see you' instead of 'sneak past so they don't.'",
"roleplaying_tips": "Rude lives up to his name, but not because he goes out of his way to be a jerk—he just doesn't really think about other people's feelings. A life on the streets has hardened Rude's will and stolen a lot of his empathy, and his amnesia means he can't remember what having empathy was like back when he cared. Because of that, he doesn't usually consider whether his words might offend someone before he speaks. The other side of Rude's lack of empathy is that his decisions are motivated solely by his own interests. He knows full well that in the long term, he'll benefit more from working with a competent, trustworthy team and keeping his rep clean than by betraying people over a few extra nuyen.",
"vital_contacts": [
{
"name": "Hez",
"role": "Neighborhood Watch Lieutenant",
"description": "Skraacha gang / neighborhood watch lieutenant in the Seattle Underground."
},
{
"name": "Jimmy Vitello",
"role": "Industrial Manager / Former Muscle",
"description": "Manager at Max's Ironworks and former Mafia muscle."
},
{
"name": "Momma Dot",
"role": "Arms Dealer",
"description": "Owner of BBC Weapon Works in Renton."
}
],
"favorite_hangouts": [
{
"name": "BBC Weapon Works",
"location": "Renton",
"description": "A troll-owned gun shop in Renton."
},
{
"name": "The Biz",
"location": "Seattle Underground",
"description": "The black-market hub of the Seattle Underground."
},
{
"name": "The Coliseum",
"location": "Snohomish",
"description": "A paracritter-fighting arena in Snohomish."
}
],
"favorite_downtime_activities": [
"Browsing gun-aficionado sites for new purchase ideas",
"Rocking out at orxploitation shows",
"Watching paracritter fights at the Coliseum"
],
"sample_actions": [
{
"action": "Sniper Shot (Ares Desert Strike)",
"action_type": "Major",
"dice_pool": 12,
"notes": "Firearms 6 + Agility 5 + smartlink 1 (SA mode, DV 5P)"
},
{
"action": "Heavy Pistol Double Tap (Predator VI)",
"action_type": "Major",
"dice_pool": 12,
"notes": "Firearms 6 + Agility 5 + smartlink 1 (SA mode, DV 4P)"
},
{
"action": "Melee Cleave (Sword)",
"action_type": "Major",
"dice_pool": 9,
"notes": "Close Combat 3 + Agility 5 + troll reach (DV 3P)"
},
{
"action": "Dodge Physical Attack",
"action_type": "Minor",
"dice_pool": 10,
"notes": "Reaction 6 + Intuition 4"
},
{
"action": "Damage Soak",
"action_type": "Free",
"dice_pool": 7,
"notes": "Body 7 (+2 Armor Jacket adds to Defense Rating)"
},
{
"action": "Pick Mechanical/Electronic Lock",
"action_type": "Major",
"dice_pool": 8,
"notes": "Engineering 2 + Logic 4 + Lockpicking spec 2"
},
{
"action": "Perception / Spot Ambush",
"action_type": "Minor",
"dice_pool": 7,
"notes": "Perception 3 + Intuition 4 (Thermographic Vision)"
}
],
"edge_boosts": [
{
"cost": 1,
"name": "Reroll one die",
"description": "Reroll any one die from your roll that failed to score a hit."
},
{
"cost": 2,
"name": "+1 to single die",
"description": "Add +1 to any single die result, turning a 4 into a 5 (hit)."
},
{
"cost": 3,
"name": "Heal Stun Damage",
"description": "Immediately clear 1 box from your stun damage track."
},
{
"cost": 4,
"name": "Add Edge to Pool",
"description": "Add full Edge attribute (+5) to dice pool and 6s explode."
}
],
"attributes": {
"body": 7,
"agility": 5,
"reaction": 6,
"strength": 6,
"willpower": 4,
"logic": 4,
"intuition": 4,
"charisma": 2,
"edge": 5,
"essence": 5.5,
"edge_points": 5
},
"combat_info": {
"initiative": "10 + 1D6",
"matrix_initiative": "10 + 1D6",
"astral_initiative": "—",
"defense_rating": 11,
"unarmed_ar": 7,
"composure": 6,
"judge_intentions": 6,
"memory": 8,
"lift_carry": 11,
"movement": "5/10/+1"
},
"condition_monitor": {
"physical_damage": 0,
"physical_boxes": 12,
"stun_damage": 0,
"stun_boxes": 10,
"overflow": 0
},
"skills": [
{
"name": "Firearms",
"rating": 6,
"attribute": "Agility",
"dice_pool": 12,
"type": "Action"
},
{
"name": "Close Combat",
"rating": 3,
"attribute": "Agility",
"dice_pool": 9,
"type": "Action"
},
{
"name": "Athletics",
"rating": 3,
"attribute": "Agility",
"dice_pool": 9,
"type": "Action"
},
{
"name": "Perception",
"rating": 3,
"attribute": "Intuition",
"dice_pool": 7,
"type": "Action"
},
{
"name": "Engineering",
"rating": 2,
"attribute": "Logic",
"specialization": "Lockpicking",
"dice_pool": 6,
"type": "Action"
},
{
"name": "Influence",
"rating": 2,
"attribute": "Charisma",
"dice_pool": 4,
"type": "Action"
},
{
"name": "Exotic Weapons",
"rating": 3,
"attribute": "Agility",
"specialization": "Grapple Gun",
"dice_pool": 9,
"type": "Action"
},
{
"name": "Exotic Weapons",
"rating": 4,
"attribute": "Agility",
"specialization": "Grapple Launcher",
"dice_pool": 9,
"type": "Action"
},
{
"name": "Firearms Manufacturers",
"rating": 2,
"attribute": "Logic",
"dice_pool": 6,
"type": "Knowledge"
},
{
"name": "Security Systems",
"rating": 2,
"attribute": "Logic",
"dice_pool": 6,
"type": "Knowledge"
},
{
"name": "Urban Brawl Teams",
"rating": 2,
"attribute": "Logic",
"dice_pool": 6,
"type": "Knowledge"
}
],
"qualities": [
{
"name": "Built Tough",
"type": "Positive",
"notes": "+1 Physical condition monitor box."
},
{
"name": "Dermal Deposits",
"type": "Positive",
"notes": "+1 natural Armor/Defense Rating."
},
{
"name": "High Pain Tolerance",
"type": "Positive",
"notes": "Reduces wound modifiers by 1."
},
{
"name": "Thermographic Vision",
"type": "Positive",
"notes": "Natural troll heat-signature vision."
},
{
"name": "Socially Awkward",
"type": "Negative",
"notes": "Blunt and lacking empathy due to amnesia."
}
],
"currency_and_ids": {
"nuyen": 3500,
"primary_lifestyle": "Low (1 month prepaid)",
"licenses": "Concealed Carry (Heavy Pistol, Sniper Rifle)",
"fake_ids": [
{
"name": "Marcus Vance",
"rating": 3,
"lifestyle": "Low",
"funds": "3,500¥",
"licenses": "Driver's, Concealed Carry"
}
]
},
"contacts": [
{
"name": "Billy Shen",
"loyalty": 2,
"connection": 4,
"notes": "Octagon Triad lieutenant, enforcer, and arms dealer."
},
{
"name": "Four-Finger Wong",
"loyalty": 3,
"connection": 3,
"notes": "Cyber-surgeon and underground street doc."
},
{
"name": "Mia",
"loyalty": 3,
"connection": 2,
"notes": "Part-time fixer and waitress at Peaceable Kingdom."
}
],
"primary_armor": {
"name": "Armor jacket",
"rating": "+2",
"notes": "+2 Defense Rating bonus"
},
"primary_ranged_weapon": {
"name": "Ares Desert Strike",
"dv": "5P",
"mode": "SA",
"attack_rating": { "close": 3, "near": 10, "far": 10, "extreme": 10 },
"ammo": "14(c)",
"notes": "Sniper rifle w/ imaging scope, shock pad"
},
"primary_melee_weapon": {
"name": "Sword",
"dv": "3P",
"close": 9,
"notes": "Blade"
},
"ranged_weapons": [
{
"name": "Ares Desert Strike (Sniper Rifle)",
"dv": "5P",
"mode": "SA",
"attack_rating": { "close": 3, "near": 10, "far": 10, "extreme": 10 },
"ammo": "14(c)",
"notes": "w/ imaging scope, shock pad"
},
{
"name": "Ares Predator VI (Heavy Pistol)",
"dv": "4P",
"mode": "SA",
"attack_rating": { "close": 9, "near": 9, "far": 7, "extreme": "—" },
"ammo": "15(c)",
"notes": "w/ smartlink"
}
],
"melee_weapons": [
{
"name": "Sword (Blade)",
"dv": "3P",
"close": 9,
"notes": "Monofilament edge"
}
],
"armor": [
{
"name": "Armor jacket",
"rating": "+2",
"notes": "Provides +2 DR"
}
],
"matrix_stats": {
"device_name": "Sony Emperor commlink",
"device_rating": 2,
"attack": 0,
"sleaze": 0,
"data_processing": 1,
"firewall": 1,
"programs": [],
"matrix_damage": 0
},
"augmentations": [
{
"name": "Cybereyes",
"rating": 2,
"notes": "w/ smartlink, low-light vision",
"essence": 0.2
},
{
"name": "Reaction enhancers",
"rating": 1,
"notes": "+1 REA, +1 Initiative",
"essence": 0.3
}
],
"vehicles": [],
"gear": [
{ "name": "Armor jacket", "rating": 2, "quantity": 1 },
{ "name": "Sony Emperor commlink", "rating": 2, "quantity": 1 },
{ "name": "Grapple gun", "quantity": 1, "notes": "w/ 100m stealth rope" },
{
"name": "Certified credstick",
"quantity": 1,
"notes": "Contains 3,500¥"
},
{ "name": "Spare ammo clips (Ares Predator)", "quantity": 3 },
{ "name": "Spare ammo clips (Ares Desert Strike)", "quantity": 2 }
],
"spells": [],
"adept_powers": []
}
}

View File

@@ -0,0 +1,401 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "43e2f491-b3b1-4c6e-827d-99572d4cfbe1",
"ruleset_id": "sr6",
"entity_type": "dossier",
"display_name": "Yu (Elf Covert Ops Specialist / Face Dossier)",
"description": "Full 4-page narrative dossier for Yu, Elf Covert Ops Specialist and Face from the SR6 Beginner Box.",
"template_id": "dossier_sheet",
"properties": {
"alias": "Yu",
"real_name": "Yu",
"player": "Catalyst Pregen",
"archetype": "Elf Covert Ops / Face",
"quote": "\"They can't hit what they can't see.\" / \"My team can handle the tough jobs, Mr. Johnson. The question is, are you willing to pay a premium price for premium work?\" / \"(roguish grin)\"",
"pitch": "Play this character if deception, sneakiness, charm, and guile are your weapons of choice!",
"metatype": "Elf",
"ethnicity": "Cantonese",
"age": 28,
"sex": "Male",
"height": "1.8 m",
"weight": "77 kg",
"reputation": 2,
"heat": 0,
"karma": 0,
"total_karma": 0,
"misc": "Red Dragon Triad affiliate; expert pickpocket, lockpick, and con artist.",
"notes": "Elf Covert Ops Specialist and Face adept at infiltration, disguise, charm, and fast-talking.",
"background": "Once upon a time, Yu was a corp kid from the Canton Confederation, living a life of relative abundance. He always assumed he'd end up a wageslave like his parents, until the Second Matrix Crash erased his family's identities and sent the corp they worked for into bankruptcy. Mere months later, Yu's parents were killed by Black Chrysanthemum Triad members demanding protection fees they couldn't pay, and ten-year-old Yu fled from Foshan to Hong Kong. He ended up as a member of a pickpocket gang, then joined the Red Dragon Triad as a thief and enforcer. Yu probably would've spent the rest of his life with the Red Dragons, but one of his Triad brothers got wrapped up in better-than-life chips and went on a frenzy, and Yu was forced to kill him in self-defense. The Triad bosses knew it wasn't Yu's fault, but they couldn't let the killing go unanswered, so they shipped him off to an allied syndicate in Seattle. There, Yu met Billy Shen, and Billy passed his name along to Ms. Myth when the troll fixer was putting her new crew together.",
"preferred_tactics": "Making trouble without being seen is Yu's bread and butter. The skills he acquired as a thief—moving silently, picking locks, placing and palming items without being seen—have served him well in the shadows. He prefers to be completely invisible when possible, but he's gotten pretty good at using disguises if the situation calls for it. Since meeting Ms. Myth, Yu has seen the value in being able to get what he wants through charm as well as deception. He's turning his natural elven charisma toward being the team's face and often takes the lead in negotiating with prospective employers who approach them for jobs. Ms. Myth sometimes ropes him into helping with her corporate infiltrations, now that she is looking after a new crew along with her old crew of Sledge, Coydog, Hardpoint, and Gentry. Yu's not afraid to use violence when he needs to, but he does try to keep the body count to a minimum—partly because he knows wageslaves are people too, and partly because he'd rather have those wageslaves' bosses go after them for letting their guard down than come after him to avenge their fallen comrade. He prefers not to 'fight' so much as 'ambush,' and if he finds himself in open combat, he'll do his best to stay behind cover and plink away with whatever firearm he has handy.",
"roleplaying_tips": "Yu has two distinct personalities: on the job, and off. Off the job, he's an overgrown teenager who hangs out with his friends, plays sports, sleeps around, experiments with drugs, and uses his charm to get out of trouble. He sees his fellow Red Dragon Triad members and their affiliates, like the Octagon Triad, as family and is loyal to them to a fault. He won't take a run that goes against the Red Dragons' interests, but he's upfront about it and tries to make sure his refusal won't screw the team over somehow. On the other hand, when he doesn't have to worry about the Red Dragons, Yu extends the same loyalty to his shadowrunner comrades as he does to his Triad family. He won't willingly turn on them for anything, and if one team member has a problem, he's always willing to help—for as long as they're willing to endure his barrages of terrible puns, anyway. On the job, Yu's a chameleon. He can be as charming or as cold as he needs to be, and he'll work with just about anyone—and do so with a smile—regardless of their background. The only people he refuses to deal with are BTL dealers and organleggers, because of how those two trades have wreaked havoc on his life. He takes a certain joy in tearing them down.",
"vital_contacts": [
{
"name": "Billy Shen",
"role": "Octagon Triad Lieutenant",
"description": "Octagon Triad lieutenant, enforcer, and arms dealer."
},
{
"name": "Four-Finger Wong",
"role": "Cyber-Surgeon",
"description": "Underground street doc and cyber-surgeon."
},
{
"name": "Mia",
"role": "Part-Time Fixer",
"description": "Waitress at Peaceable Kingdom and part-time fixer."
}
],
"favorite_hangouts": [
{
"name": "Peaceable Kingdom",
"location": "Tacoma",
"description": "A Chinese restaurant in Tacoma."
},
{
"name": "The Sports Bar",
"location": "Downtown Seattle",
"description": "A bustling sports bar in Downtown Seattle."
},
{
"name": "Vigilant Iron Schooling House",
"location": "Redmond",
"description": "A martial arts studio in Redmond."
}
],
"favorite_downtime_activities": [
"Hanging out with his fellow Triad members",
"Playing and watching basketball",
"Studying martial arts"
],
"sample_actions": [
{
"action": "Fast-Talk / Con Mark",
"action_type": "Major",
"dice_pool": 14,
"notes": "Con 6 + Charisma 8 (Opposed vs. target Willpower + Intuition)"
},
{
"action": "Negotiation / Influence Mr. Johnson",
"action_type": "Major",
"dice_pool": 14,
"notes": "Influence 6 + Charisma 8"
},
{
"action": "Sneak Past Guards / Infiltrate",
"action_type": "Major",
"dice_pool": 12,
"notes": "Stealth 6 + Agility 6 (Opposed vs. Perception + Intuition)"
},
{
"action": "Palming / Sleight of Hand",
"action_type": "Major",
"dice_pool": 12,
"notes": "Stealth 6 + Agility 6"
},
{
"action": "Ambush Baton Strike",
"action_type": "Major",
"dice_pool": 10,
"notes": "Close Combat 4 + Agility 6 (DV 3S, net hits add to damage)"
},
{
"action": "Silenced Pistol Shot (Ares Light Fire)",
"action_type": "Major",
"dice_pool": 8,
"notes": "Firearms 2 + Agility 6 (SA mode, DV 2P, smartlink contacts)"
},
{
"action": "Disguise Identity",
"action_type": "Major",
"dice_pool": 11,
"notes": "Stealth 6 + Intuition 5 (Threshold for observers to see through)"
},
{
"action": "Maglock Bypass (Passkey)",
"action_type": "Major",
"dice_pool": 4,
"notes": "Passkey Rating 4 vs. Maglock Rating"
}
],
"edge_boosts": [
{
"cost": 1,
"name": "Reroll one die",
"description": "Reroll any one die from your roll that failed to score a hit (Post)."
},
{
"cost": 1,
"name": "Add 3 to Initiative",
"description": "Add +3 to your Initiative Score for the combat turn (Any)."
},
{
"cost": 2,
"name": "+1 to single die",
"description": "Add +1 to any single die result, turning a 4 into a 5 (hit) (Post)."
},
{
"cost": 2,
"name": "Give ally 1 Edge",
"description": "Pass 1 Edge point to an allied runner (Any)."
},
{
"cost": 2,
"name": "Negate 1 Edge of foe",
"description": "Negate 1 point of Edge held by an opponent (Pre)."
},
{
"cost": 3,
"name": "Buy automatic hit",
"description": "Add 1 automatic hit to test result (Any)."
},
{
"cost": 3,
"name": "Heal Stun Damage",
"description": "Immediately clear 1 box from your stun damage track."
},
{
"cost": 4,
"name": "Add Edge to Pool",
"description": "Add full Edge attribute (+2) to dice pool and 6s explode (Pre)."
}
],
"attributes": {
"body": 3,
"agility": 6,
"reaction": 4,
"strength": 3,
"willpower": 5,
"logic": 5,
"intuition": 5,
"charisma": 8,
"edge": 2,
"essence": 6.0,
"magic": 0,
"edge_points": 2
},
"combat_info": {
"initiative": "9 + 1D6",
"matrix_initiative": "9 + 1D6",
"astral_initiative": "—",
"defense_rating": 6,
"unarmed_ar": 6,
"composure": 13,
"judge_intentions": 13,
"memory": 10,
"lift_carry": 6,
"movement": "5/10/+1"
},
"condition_monitor": {
"physical_damage": 0,
"physical_boxes": 10,
"stun_damage": 0,
"stun_boxes": 11,
"overflow": 0
},
"skills": [
{
"name": "Con",
"rating": 6,
"attribute": "Charisma",
"dice_pool": 14,
"type": "Action"
},
{
"name": "Influence",
"rating": 6,
"attribute": "Charisma",
"dice_pool": 14,
"type": "Action"
},
{
"name": "Stealth",
"rating": 6,
"attribute": "Agility",
"dice_pool": 12,
"type": "Action"
},
{
"name": "Close Combat",
"rating": 4,
"attribute": "Agility",
"dice_pool": 10,
"type": "Action"
},
{
"name": "Firearms",
"rating": 2,
"attribute": "Agility",
"dice_pool": 8,
"type": "Action"
},
{
"name": "Perception",
"rating": 2,
"attribute": "Intuition",
"dice_pool": 7,
"type": "Action"
},
{
"name": "Piloting",
"rating": 2,
"attribute": "Reaction",
"dice_pool": 6,
"type": "Action"
},
{
"name": "Biotech",
"rating": 1,
"attribute": "Logic",
"dice_pool": 6,
"type": "Action"
},
{
"name": "Outdoors",
"rating": 1,
"attribute": "Intuition",
"dice_pool": 6,
"type": "Action"
},
{
"name": "Architecture",
"rating": 2,
"attribute": "Logic",
"dice_pool": 7,
"type": "Knowledge"
},
{
"name": "Close-up Magic",
"rating": 2,
"attribute": "Logic",
"dice_pool": 7,
"type": "Knowledge"
},
{
"name": "Wildlife",
"rating": 2,
"attribute": "Logic",
"dice_pool": 7,
"type": "Knowledge"
}
],
"qualities": [
{
"name": "Catlike",
"type": "Positive",
"notes": "+1 dice pool bonus on stealth and acrobatics tests."
},
{
"name": "Double-Jointed",
"type": "Positive",
"notes": "+1 dice pool bonus on escape and contortion tests."
},
{
"name": "Low-Light Vision",
"type": "Positive",
"notes": "Natural elf low-light perception."
}
],
"currency_and_ids": {
"nuyen": 3500,
"primary_lifestyle": "Low (1 month prepaid)",
"licenses": "Concealed Carry (Light Pistol)",
"fake_ids": [
{
"name": "Raymond Chang",
"rating": 4,
"lifestyle": "Low",
"funds": "3,500¥",
"licenses": "Firearms, Security Tech"
}
]
},
"contacts": [
{
"name": "Billy Shen",
"loyalty": 2,
"connection": 4,
"notes": "Octagon Triad lieutenant, enforcer, and arms dealer."
},
{
"name": "Four-Finger Wong",
"loyalty": 3,
"connection": 3,
"notes": "Cyber-surgeon and underground street doc."
},
{
"name": "Mia",
"loyalty": 3,
"connection": 2,
"notes": "Part-time fixer and waitress at Peaceable Kingdom."
}
],
"primary_armor": {
"name": "Lined coat",
"rating": "+3",
"notes": "+3 Defense Rating bonus"
},
"primary_ranged_weapon": {
"name": "Ares Light Fire 75",
"dv": "2P",
"mode": "SA",
"attack_rating": { "close": 10, "near": 7, "far": 6, "extreme": "—" },
"ammo": "16(c)",
"notes": "w/ silencer, smartgun"
},
"primary_melee_weapon": {
"name": "Extendible baton",
"dv": "3S",
"close": 6,
"notes": "Club"
},
"ranged_weapons": [
{
"name": "Ares Light Fire 75 (Light Pistol)",
"dv": "2P",
"mode": "SA",
"attack_rating": { "close": 10, "near": 7, "far": 6, "extreme": "—" },
"ammo": "16(c)",
"notes": "w/ silencer, smartgun"
}
],
"melee_weapons": [
{
"name": "Extendible baton",
"dv": "3S",
"close": 6,
"notes": "Club"
}
],
"armor": [
{
"name": "Lined coat",
"rating": "+3",
"notes": "+3 DR bonus"
}
],
"matrix_stats": {
"device_name": "Erika Elite commlink",
"device_rating": 4,
"attack": 0,
"sleaze": 0,
"data_processing": 2,
"firewall": 1,
"programs": [],
"matrix_damage": 0
},
"augmentations": [],
"vehicles": [],
"gear": [
{ "name": "Lined coat", "rating": 3, "quantity": 1 },
{ "name": "Erika Elite commlink", "rating": 4, "quantity": 1 },
{ "name": "Disguise kit", "quantity": 1 },
{ "name": "First Aid Kit", "rating": 3, "quantity": 1 },
{ "name": "Passkey", "rating": 4, "quantity": 1 },
{ "name": "Contacts", "quantity": 1, "notes": "w/ smartlink" },
{ "name": "Certified credstick", "quantity": 1, "notes": "3,500¥" },
{ "name": "Spare ammo clips (Ares Light Fire 75)", "quantity": 3 }
],
"spells": [],
"adept_powers": []
}
}

View File

@@ -0,0 +1,394 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "98dc54b1-8b02-44df-91ea-72e8fa440a33",
"ruleset_id": "sr6",
"entity_type": "dossier",
"display_name": "Zipfile (Dwarf Decker Dossier)",
"description": "Full 4-page narrative dossier for Zipfile, Dwarf Decker from the SR6 Beginner Box.",
"template_id": "dossier_sheet",
"properties": {
"alias": "Zipfile",
"real_name": "Zipfile",
"player": "Catalyst Pregen",
"archetype": "Dwarf Decker",
"quote": "\"How can you support a system that pays us to destroy itself?\" / \"Eish! That IC is wiz!\" / \"(triumphant vuvuzela noise)\"",
"pitch": "Play this character if you like illicit hacking and weaponizing people's devices against them.",
"metatype": "Dwarf",
"ethnicity": "Bantu",
"age": 23,
"sex": "Female",
"height": "1.1 m",
"weight": "36 kg",
"reputation": 2,
"heat": 0,
"karma": 0,
"total_karma": 0,
"misc": "Azanian neo-anarchist activist and urban brawl fan with a custom Renraku Kitsune deck.",
"notes": "Dwarf Decker and virtual saboteur specializing in host penetration, device spoofing, and matrix surveillance.",
"background": "Zipfile grew up in the urban brawl hotspot of Emfuleni, part of Azania's Pretoria-Witwatersrand-Vaal Metroplex. As a young girl, she loved the excitement, the chaos, the adrenaline-junkie rush that came with watching the local brawlers every weekend. It almost made her forget how she used to live in one of the buildings inside that urban arena, until Ares had evicted her family from their home and turned Emfuleni into an international spectacle. As a teenager, Zipfile lost both of her parents when DeBeers-Omnitech literally worked them to death in one of their mines. The shock and bitterness over their deaths led Zipfile and her younger brother to join a neo-anarchist cell in PWV. The neo-anarchists saw potential in her and sent her off to one of their training camps, where she learned how to use her cyberdeck to disrupt the system. Zipfile ultimately left Azania, though, when a conflict between neo-anarchist groups turned violent and most of her former runner team got killed. She met Ms. Myth through a fellow decker who was an urban brawl fan, and she uses her nuyen from those jobs to support both the neo-anarchist cause and the brother she left in Azania.",
"preferred_tactics": "Zipfile has never been one for the subtle approach. She delights in acting as a virtual saboteur, throwing wrenches in the corps' Matrix machinery until it collapses under its own weight. As far as she's concerned, disrupting systems is a metaphor for disrupting the system, and she considers tagging corporate hosts with virtual graffiti a vital component of her neo-anarchist outreach. She doesn't just want to beat the 'tools of the establishment' at their own game: she wants to make sure they know who beat them. Zipfile isn't completely lacking in discretion though. She knows her team will only succeed if they support each other, so she will (grudgingly) pass on chances to make the corps look bad if doing so would jeopardize the run or her teammates. Due to her love for urban brawl, Zipfile has gone out of her way to make sure she's a passable runner-and-gunner in addition to her Matrix expertise. She's pestered Rude into helping her improve her marksmanship, and she regularly takes her Ruger Super Warhawk on runs, although she has yet to fire it in anger (outside of a Miracle Shooter game, anyway).",
"roleplaying_tips": "What Zipfile lacks in physical stature, she makes up for in personality and presence. She's outgoing, bombastic, and more cheerful than anyone not perpetually stoned has any right to be. She's also a walking encyclopedia of random facts, which is how she got her runner handle; a fellow decker christened her Zipfile because she's 'a lot of data in a compressed package.' Zipfile is also the most principled member of the team. She doesn't hesitate to preach about the virtues of neo-anarchism and doesn't always take kindly to people questioning her beliefs. She's equally apt to argue with her fellow neo-anarchists though, since she's willing to take nuyen from the system to fund her efforts to bring it down. Zipfile's zeal for her cause is rooted in one of the rarest qualities in the shadows: caring. She cares about her teammates, her fellow neo-anarchists, her brother in Azania, and the people of the world in general. She's been on the receiving end of the worst that corps and governments can inflict on people, and she truly believes that her ideals are the best way to solve that problem. Finally, although she's not big on nations—governments are part of the system, too—Zipfile takes pride in her heritage. When people ask her about her accent or verbal tics like the omnipresent eish, she'll gladly tell them that she's Xhosa, and she can often be spotted wearing merch from the PWV Imikhonto urban brawl team (and feeling guilty for giving in to her consumer urges).",
"vital_contacts": [
{
"name": "Arclight",
"role": "Combat Mage / Coordinator",
"description": "Combat mage and coordinator for the Black Star neo-anarchist shadowrunner collective."
},
{
"name": "Casey Connors",
"role": "Tech Bar Owner",
"description": "Owner of the Cathode Glow e-sports bar and tech museum in Tacoma."
},
{
"name": "Jules Maguire",
"role": "Cascade Ork Smuggler",
"description": "Cascade Ork smuggler and fixer connection."
}
],
"favorite_hangouts": [
{
"name": "Dawn of Atlantis",
"location": "Matrix Node",
"description": "A Matrix-based fantasy RPG set in 'historical' Atlantis."
},
{
"name": "The Cathode Glow",
"location": "Tacoma",
"description": "An e-sports bar and tech museum in Tacoma."
},
{
"name": "The Sports Bar",
"location": "Downtown Seattle",
"description": "A lively sports bar in Downtown Seattle."
}
],
"favorite_downtime_activities": [
"Attending neo-anarchist events",
"Playing Matrix games, especially Dawn of Atlantis and Miracle Shooter",
"Watching urban brawl"
],
"sample_actions": [
{
"action": "Hack Host / Gain Access",
"action_type": "Major",
"dice_pool": 12,
"notes": "Cracking 6 + Logic 6 (Illegal, opposed vs. Firewall + Willpower)"
},
{
"action": "Crack File Protection",
"action_type": "Major",
"dice_pool": 14,
"notes": "Cracking 6 + Logic 6 + Decryption 2 (Removes encryption/protection)"
},
{
"action": "Matrix Perception / Scan Node",
"action_type": "Minor",
"dice_pool": 12,
"notes": "Electronics 6 + Intuition 6 (Inspect icons, hosts, and hidden personas)"
},
{
"action": "Spoof Command (Elevators / Systems)",
"action_type": "Major",
"dice_pool": 12,
"notes": "Cracking 6 + Logic 6 (Send false instructions to connected devices)"
},
{
"action": "Snoop Communications Feed",
"action_type": "Major",
"dice_pool": 12,
"notes": "Cracking 6 + Logic 6 (Overclock program adds +1 Edge)"
},
{
"action": "Data Spike Attack",
"action_type": "Major",
"dice_pool": 12,
"notes": "Cracking 6 + Logic 6 (Attack rating 6, inflicts Matrix damage)"
},
{
"action": "Heavy Pistol Shot (Ruger Warhawk)",
"action_type": "Major",
"dice_pool": 5,
"notes": "Firearms 2 + Agility 3 (SS mode, DV 4P)"
},
{
"action": "Spot Ambush / Physical Perception",
"action_type": "Minor",
"dice_pool": 9,
"notes": "Perception 3 + Intuition 6 (Thermographic Vision)"
}
],
"edge_boosts": [
{
"cost": 1,
"name": "Reroll one die",
"description": "Reroll any one die from your roll that failed to score a hit (Post)."
},
{
"cost": 1,
"name": "Add 3 to Initiative",
"description": "Add +3 to your Initiative Score for the combat turn (Any)."
},
{
"cost": 2,
"name": "+1 to single die",
"description": "Add +1 to any single die result, turning a 4 into a 5 (hit) (Post)."
},
{
"cost": 2,
"name": "Give ally 1 Edge",
"description": "Pass 1 Edge point to an allied runner (Any)."
},
{
"cost": 2,
"name": "Negate 1 Edge of foe",
"description": "Negate 1 point of Edge held by an opponent (Pre)."
},
{
"cost": 3,
"name": "Buy automatic hit",
"description": "Add 1 automatic hit to test result (Any)."
},
{
"cost": 3,
"name": "Heal Stun Damage",
"description": "Immediately clear 1 box from your stun damage track."
},
{
"cost": 4,
"name": "Add Edge to Pool",
"description": "Add full Edge attribute (+4) to dice pool and 6s explode (Pre)."
}
],
"attributes": {
"body": 5,
"agility": 3,
"reaction": 4,
"strength": 4,
"willpower": 6,
"logic": 6,
"intuition": 6,
"charisma": 3,
"edge": 4,
"essence": 3.7,
"magic": 0,
"edge_points": 4
},
"combat_info": {
"initiative": "10 + 1D6",
"matrix_initiative": "12 + 1D6",
"astral_initiative": "—",
"defense_rating": 8,
"unarmed_ar": 4,
"composure": 9,
"judge_intentions": 9,
"memory": 12,
"lift_carry": 9,
"movement": "5/10/+1"
},
"condition_monitor": {
"physical_damage": 0,
"physical_boxes": 11,
"stun_damage": 0,
"stun_boxes": 11,
"overflow": 0
},
"skills": [
{
"name": "Cracking",
"rating": 6,
"attribute": "Logic",
"dice_pool": 12,
"type": "Action"
},
{
"name": "Electronics",
"rating": 6,
"attribute": "Logic",
"dice_pool": 12,
"type": "Action"
},
{
"name": "Engineering",
"rating": 2,
"attribute": "Logic",
"dice_pool": 8,
"type": "Action"
},
{
"name": "Perception",
"rating": 3,
"attribute": "Intuition",
"dice_pool": 9,
"type": "Action"
},
{
"name": "Firearms",
"rating": 2,
"attribute": "Agility",
"dice_pool": 5,
"type": "Action"
},
{
"name": "Close Combat",
"rating": 2,
"attribute": "Agility",
"dice_pool": 5,
"type": "Action"
},
{
"name": "Cyberdeck Models",
"rating": 2,
"attribute": "Logic",
"dice_pool": 8,
"type": "Knowledge"
},
{
"name": "German Expressionist Cinema",
"rating": 2,
"attribute": "Logic",
"dice_pool": 8,
"type": "Knowledge"
},
{
"name": "Matrix Security",
"rating": 2,
"attribute": "Logic",
"dice_pool": 8,
"type": "Knowledge"
}
],
"qualities": [
{
"name": "Gearhead",
"type": "Positive",
"notes": "May spend Edge on Repair tests and during downtime repairs."
},
{
"name": "Guts",
"type": "Positive",
"notes": "+2 dice pool bonus on tests resisting fear and intimidation."
},
{
"name": "Thermographic Vision",
"type": "Positive",
"notes": "Natural dwarf heat-signature vision."
}
],
"currency_and_ids": {
"nuyen": 3500,
"primary_lifestyle": "Low (1 month prepaid)",
"licenses": "Concealed Carry (Heavy Pistol), Cyberdeck Operator License",
"fake_ids": [
{
"name": "Nandi Mandela",
"rating": 3,
"lifestyle": "Low",
"funds": "3,500¥",
"licenses": "Heavy Pistol, Hardware Tech"
}
]
},
"contacts": [
{
"name": "Arclight",
"loyalty": 3,
"connection": 4,
"notes": "Combat mage and coordinator for the Black Star neo-anarchist shadowrunner collective."
},
{
"name": "Casey Connors",
"loyalty": 2,
"connection": 3,
"notes": "Owner of the Cathode Glow e-sports bar and tech museum in Tacoma."
},
{
"name": "Jules Maguire",
"loyalty": 2,
"connection": 2,
"notes": "Cascade Ork smuggler."
}
],
"primary_armor": {
"name": "Armor vest",
"rating": "+3",
"notes": "+3 Defense Rating bonus"
},
"primary_ranged_weapon": {
"name": "Ruger Super Warhawk",
"dv": "4P",
"mode": "SS",
"attack_rating": { "close": 8, "near": 11, "far": 8, "extreme": "—" },
"ammo": "6(cy)",
"notes": "Heavy cylinder revolver"
},
"primary_melee_weapon": {
"name": "Unarmed Strike",
"dv": "2S",
"close": 4,
"notes": "Natural"
},
"ranged_weapons": [
{
"name": "Ruger Super Warhawk (Heavy Pistol)",
"dv": "4P",
"mode": "SS",
"attack_rating": { "close": 8, "near": 11, "far": 8, "extreme": "—" },
"ammo": "6(cy)",
"notes": "Heavy revolver"
}
],
"melee_weapons": [
{
"name": "Unarmed Strike",
"dv": "2S",
"close": 4,
"notes": "Natural"
}
],
"armor": [
{
"name": "Armor vest",
"rating": "+3",
"notes": "+3 DR bonus"
}
],
"matrix_stats": {
"device_name": "Renraku Kitsune cyberdeck",
"device_rating": 4,
"attack": 6,
"sleaze": 7,
"data_processing": 4,
"firewall": 4,
"programs": ["Decryption", "Exploit", "Overclock"],
"matrix_damage": 0
},
"augmentations": [
{
"name": "Cyberjack MPI",
"rating": 4,
"notes": "7/6, +2 Matrix initiative",
"essence": 2.3
}
],
"vehicles": [],
"gear": [
{ "name": "Armor vest", "rating": 3, "quantity": 1 },
{
"name": "Renraku Kitsune cyberdeck",
"rating": 4,
"quantity": 1,
"notes": "DR 4, 7/6, 8 slots"
},
{
"name": "Hermes Ikon commlink",
"rating": 5,
"quantity": 1,
"notes": "DR 5, 3/0"
},
{ "name": "Certified credstick", "quantity": 1, "notes": "3,500¥" },
{ "name": "Heavy pistol ammo box (Ruger)", "quantity": 30 }
],
"spells": [],
"adept_powers": []
}
}

View File

@@ -0,0 +1,15 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "e8027c8e-c25c-49a4-b8f8-f680b49ac492",
"ruleset_id": "sr6",
"entity_type": "gear",
"display_name": "Decryption",
"description": "Files all over the Matrix are encrypted; this program helps break that protection.",
"properties": {
"filename": "decryption",
"name": "Decryption",
"category": "Program",
"rules": "+2 dice on Crack File Action.",
"notes": "Files all over the Matrix are encrypted; this program helps break that protection."
}
}

View File

@@ -0,0 +1,17 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "a631687e-cabd-46b7-bb4e-0567ce368310",
"ruleset_id": "sr6",
"entity_type": "gear",
"display_name": "Erika Elite",
"description": "The elegant design and smooth functionality make this commlink live up to its name.",
"properties": {
"filename": "erika_elite",
"name": "Erika Elite",
"category": "Commlink",
"device_rating": 4,
"attributes_df": "2/1",
"active_program_slots": 2,
"notes": "The elegant design and smooth functionality make this commlink live up to its name."
}
}

View File

@@ -0,0 +1,15 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "4ef5c6a6-3d5a-419a-a8f3-12e7b1452fa6",
"ruleset_id": "sr6",
"entity_type": "gear",
"display_name": "Exploit",
"description": "Crowbar to help deckers get past entryways that might otherwise stay locked.",
"properties": {
"filename": "exploit",
"name": "Exploit",
"category": "Program",
"rules": "Reduce Defense Rating of hacking target by 2.",
"notes": "Crowbar to help deckers get past entryways that might otherwise stay locked."
}
}

View File

@@ -0,0 +1,17 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "46eb16b3-8048-418b-8260-fab94623cf78",
"ruleset_id": "sr6",
"entity_type": "gear",
"display_name": "Hermes Ikon",
"description": "A commlink for people who have money to spend on keeping their personal data safe.",
"properties": {
"filename": "hermes_ikon",
"name": "Hermes Ikon",
"category": "Commlink",
"device_rating": 5,
"attributes_df": "3/0",
"active_program_slots": 2,
"notes": "A commlink for people who have money to spend on keeping their personal data safe."
}
}

View File

@@ -0,0 +1,15 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "fd0a9d2b-8440-4c2e-b1f4-7c0bf563f877",
"ruleset_id": "sr6",
"entity_type": "gear",
"display_name": "Overclock",
"description": "Amp up a machine past manufacturer limits to get a dangerous job done.",
"properties": {
"filename": "overclock",
"name": "Overclock",
"category": "Program",
"rules": "Add two dice to a Matrix action. Adds to Overwatch Score as do defense hits.",
"notes": "Amp up a machine past manufacturer limits to get a dangerous job done."
}
}

View File

@@ -0,0 +1,18 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "6174631f-599b-4678-8779-4da6fe1bb454",
"ruleset_id": "sr6",
"entity_type": "gear",
"display_name": "Renraku Kitsune",
"description": "Get where you’re not supposed to be...and do it with style!",
"properties": {
"filename": "renraku_kitsune",
"name": "Renraku Kitsune",
"category": "Cyberdeck",
"device_rating": 4,
"attack": 7,
"sleaze": 6,
"program_slots": 8,
"notes": "Get where you’re not supposed to be...and do it with style!"
}
}

View File

@@ -0,0 +1,17 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "8e6c3af8-1816-407f-a39e-62af989576cc",
"ruleset_id": "sr6",
"entity_type": "gear",
"display_name": "Renraku Sensei",
"description": "Middle managers and teenagers with money like the Sensei for giving a sense of status.",
"properties": {
"filename": "renraku_sensei",
"name": "Renraku Sensei",
"category": "Commlink",
"device_rating": 3,
"attributes_df": "2/0",
"active_program_slots": 1,
"notes": "Middle managers and teenagers with money like the Sensei for giving a sense of status."
}
}

View File

@@ -0,0 +1,17 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "edc2ae00-5a28-4fb7-a312-bb08e19c2ace",
"ruleset_id": "sr6",
"entity_type": "gear",
"display_name": "Sony Emperor",
"description": "Popular because it’s cheap and not the worst, this commlink works with few frills.",
"properties": {
"filename": "sony_emperor",
"name": "Sony Emperor",
"category": "Commlink",
"device_rating": 2,
"attributes_df": "1/1",
"active_program_slots": 1,
"notes": "Popular because it’s cheap and not the worst, this commlink works with few frills."
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "4cf564fe-5b8b-4c26-a063-ce692d263b02",
"ruleset_id": "sr6",
"entity_type": "gear",
"display_name": "White Noise Generator",
"description": "Creates a field of random noise that inhibits audio surveillance.",
"properties": {
"filename": "white_noise_generator",
"name": "White Noise Generator",
"category": "Security",
"device_rating": 3,
"rules": "All Perception tests to overhear a conversation within 3m receive a -DR modifier.",
"notes": "Creates a field of random noise that inhibits audio surveillance."
}
}

View File

@@ -0,0 +1,104 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "0c3cd5a4-294c-4fda-867f-d5c3b01db5e9",
"ruleset_id": "sr6",
"entity_type": "npc",
"display_name": "Ancients",
"description": "Go-Gang / Elf Gangers from the SR6 Beginner Box.",
"template_id": "character_picker",
"properties": {
"alias": "Ancients",
"archetype": "Go-Gang / Elf Gangers",
"metatype": "Elf",
"notes": "Vicious elves who use the speed of their racing bikes to strike with viper-like speed and lethality. They all rock the neon green encircled A on their jackets.",
"quote": "“Our blood gives us pride. Yours will bring you shame.”",
"hook": "Fiercely territorial, the Ancients cause trouble for any intruders and trespassers.",
"attributes": {
"body": 2,
"agility": 4,
"reaction": 3,
"strength": 2,
"willpower": 2,
"logic": 2,
"intuition": 2,
"charisma": 3,
"edge": 0,
"essence": 6
},
"combat_info": {
"initiative": "5 + 1D6",
"defense_rating": 3,
"condition_monitor": 9
},
"skills": [
{
"name": "Piloting",
"rating": 7,
"attribute": "Reaction",
"dice_pool": 10
},
{
"name": "Close Combat",
"rating": 5,
"attribute": "Agility",
"dice_pool": 9
},
{
"name": "Firearms",
"rating": 5,
"attribute": "Agility",
"dice_pool": 9
},
{
"name": "Influence",
"rating": 5,
"attribute": "Charisma",
"dice_pool": 8
},
{
"name": "Perception",
"rating": 4,
"attribute": "Intuition",
"dice_pool": 6
}
],
"gear": [
{
"name": "Gang leather",
"rating": "+1 DR"
},
{
"name": "Sony Emperor commlink",
"rating": 2
},
{
"name": "Yamaha Rapier motorcycle"
},
{
"name": "Katana"
},
{
"name": "Uzi V submachine gun"
}
],
"primary_ranged_weapon": {
"name": "Uzi V",
"dv": "3P",
"mode": "SA/BF",
"attack_rating": {
"close": 8,
"near": 8,
"far": 7
}
},
"primary_melee_weapon": {
"name": "Katana",
"dv": "4P",
"close": 10
},
"primary_armor": {
"name": "Gang leather",
"rating": "+1"
}
}
}

View File

@@ -0,0 +1,96 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "72a0806c-4ba5-4ea3-87d9-04e6dd5f3648",
"ruleset_id": "sr6",
"entity_type": "npc",
"display_name": "Big Ben",
"description": "Ragers Leader / Male Ork Ganger from the SR6 Beginner Box.",
"template_id": "character_picker",
"properties": {
"alias": "Big Ben",
"real_name": "Ben Jones",
"archetype": "Ragers Leader / Male Ork Ganger",
"metatype": "Ork",
"notes": "Ben Jones grew up tough. He was Big Ben by the time he was ten. He came to join the Ragers because half his family was already in, and he made his way up the ranks fast.",
"quote": "“If you’re not pissed off at the world, then you’re not RRAARRGGHH!”",
"hook": "Big Ben balances chaos with prudence, never taking a fight he’ll definitely lose.",
"attributes": {
"body": 7,
"agility": 4,
"reaction": 4,
"strength": 6,
"willpower": 3,
"logic": 3,
"intuition": 3,
"charisma": 4,
"edge": 2,
"essence": 6
},
"combat_info": {
"initiative": "7 + 1D6",
"defense_rating": 7,
"condition_monitor": 13
},
"skills": [
{
"name": "Close Combat",
"rating": 10,
"attribute": "Agility",
"dice_pool": 14
},
{
"name": "Firearms",
"rating": 8,
"attribute": "Agility",
"dice_pool": 12
},
{
"name": "Influence",
"rating": 8,
"attribute": "Charisma",
"dice_pool": 12
},
{
"name": "Perception",
"rating": 7,
"attribute": "Intuition",
"dice_pool": 10
}
],
"gear": [
{
"name": "Gang Leather",
"rating": "+1 DR"
},
{
"name": "Erika Elite commlink",
"rating": 4
},
{
"name": "Bike Chain"
},
{
"name": "Defiance T-250 shotgun"
}
],
"primary_ranged_weapon": {
"name": "Defiance T-250",
"dv": "4P",
"mode": "SA",
"attack_rating": {
"close": 7,
"near": 10,
"far": 6
}
},
"primary_melee_weapon": {
"name": "Bike Chain",
"dv": "2S",
"close": 4
},
"primary_armor": {
"name": "Gang Leather",
"rating": "+1"
}
}
}

View File

@@ -0,0 +1,88 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "9cb52fc9-c235-4d16-bafa-581bfc8c5ce5",
"ruleset_id": "sr6",
"entity_type": "npc",
"display_name": "Erika Hoffman",
"description": "Human Female Government Operative from the SR6 Beginner Box.",
"template_id": "character_picker",
"properties": {
"alias": "Erika Hoffman",
"real_name": "Erika Hoffman",
"archetype": "Human Female Government Operative",
"metatype": "Human",
"ethnicity": "UCAS White",
"notes": "Erika Hoffman has been working for the UCAS government since before she could walk; her politician parents groomed her for political success from birth.",
"quote": "“It’s an insane world, so keep it on the other side of your limo.”",
"hook": "Hoffman has access to resources and needs help. What more do you need?",
"attributes": {
"body": 2,
"agility": 3,
"reaction": 3,
"strength": 2,
"willpower": 4,
"logic": 3,
"intuition": 3,
"charisma": 6,
"edge": 4,
"essence": 6
},
"combat_info": {
"initiative": "6 + 1D6",
"defense_rating": 4,
"condition_monitor": 10
},
"skills": [
{
"name": "Influence",
"rating": 10,
"attribute": "Charisma",
"dice_pool": 16
},
{
"name": "Close Combat",
"rating": 5,
"attribute": "Agility",
"dice_pool": 8
},
{
"name": "Firearms",
"rating": 5,
"attribute": "Agility",
"dice_pool": 8
},
{
"name": "Perception",
"rating": 5,
"attribute": "Intuition",
"dice_pool": 8
}
],
"gear": [
{
"name": "Armor clothing",
"rating": 2
},
{
"name": "Sony Emperor commlink",
"rating": 2
},
{
"name": "Yamaha Pulsar I taser"
}
],
"primary_ranged_weapon": {
"name": "Yamaha Pulsar I",
"dv": "4S (e)",
"mode": "SS",
"attack_rating": {
"close": 9,
"near": 9
}
},
"primary_armor": {
"name": "Armor clothing",
"rating": "+2"
}
}
}

View File

@@ -0,0 +1,104 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "c2fc5de3-1ab2-4fd9-a7df-3e0abaee5711",
"ruleset_id": "sr6",
"entity_type": "npc",
"display_name": "Green Phoenix",
"description": "Ancients Leader / Male Elf Gang Leader from the SR6 Beginner Box.",
"template_id": "character_picker",
"properties": {
"alias": "Green Phoenix",
"archetype": "Ancients Leader / Male Elf Gang Leader",
"metatype": "Elf",
"notes": "Focused and powerful, Green Phoenix teaches his people how to look beyond short-term conflicts to get big scores. But he still likes busting heads.",
"quote": "“The sharpness of elven steel is unrivaled. As you’ll see.”",
"hook": "Proud and ambitious, Green Phoenix is always building toward his gang’s future.",
"attributes": {
"body": 4,
"agility": 7,
"reaction": 6,
"strength": 3,
"willpower": 3,
"logic": 2,
"intuition": 4,
"charisma": 7,
"edge": 3,
"essence": 6
},
"combat_info": {
"initiative": "10 + 1D6",
"defense_rating": 5,
"condition_monitor": 10
},
"skills": [
{
"name": "Piloting",
"rating": 14,
"attribute": "Reaction",
"dice_pool": 20
},
{
"name": "Influence",
"rating": 14,
"attribute": "Charisma",
"dice_pool": 21
},
{
"name": "Close Combat",
"rating": 13,
"attribute": "Agility",
"dice_pool": 20
},
{
"name": "Firearms",
"rating": 11,
"attribute": "Agility",
"dice_pool": 18
},
{
"name": "Perception",
"rating": 9,
"attribute": "Intuition",
"dice_pool": 13
}
],
"gear": [
{
"name": "Gang Leather",
"rating": "+1 DR"
},
{
"name": "Hermes Ikon commlink",
"rating": 5
},
{
"name": "Yamaha Rapier motorcycle"
},
{
"name": "Katana"
},
{
"name": "Uzi V submachine gun"
}
],
"primary_ranged_weapon": {
"name": "Uzi V",
"dv": "3P",
"mode": "SA/BF",
"attack_rating": {
"close": 8,
"near": 8,
"far": 7
}
},
"primary_melee_weapon": {
"name": "Katana",
"dv": "4P",
"close": 10
},
"primary_armor": {
"name": "Gang Leather",
"rating": "+1"
}
}
}

View File

@@ -0,0 +1,89 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "f13179e7-3180-41da-b079-eb92bd4eae4c",
"ruleset_id": "sr6",
"entity_type": "npc",
"display_name": "Ragers",
"description": "Dwarf Gangers from the SR6 Beginner Box.",
"template_id": "character_picker",
"properties": {
"alias": "Ragers",
"archetype": "Dwarf Gangers",
"metatype": "Dwarf",
"notes": "Gang members are fiercely loyal to each other and fight in groups, pulling fallen comrades out of trouble if need be. They also respect strength when used correctly.",
"quote": "“RRRAAAAAARRRRRGGGGGHHHHHHH!”",
"hook": "Forces of chaos who roam the streets and are ready for a fight at all times.",
"attributes": {
"body": 4,
"agility": 2,
"reaction": 2,
"strength": 5,
"willpower": 3,
"logic": 2,
"intuition": 2,
"charisma": 2,
"edge": 1,
"essence": 6
},
"combat_info": {
"initiative": "4 + 1D6",
"defense_rating": 4,
"condition_monitor": 10
},
"skills": [
{
"name": "Close Combat",
"rating": 5,
"attribute": "Agility",
"dice_pool": 7
},
{
"name": "Firearms",
"rating": 5,
"attribute": "Agility",
"dice_pool": 7
},
{
"name": "Perception",
"rating": 4,
"attribute": "Intuition",
"dice_pool": 6
}
],
"gear": [
{
"name": "Gang Leather",
"rating": "+1 DR"
},
{
"name": "Sony Emperor commlink",
"rating": 2
},
{
"name": "Club"
},
{
"name": "Defiance T-250 shotgun"
}
],
"primary_ranged_weapon": {
"name": "Defiance T-250",
"dv": "4P",
"mode": "SA",
"attack_rating": {
"close": 7,
"near": 10,
"far": 6
}
},
"primary_melee_weapon": {
"name": "Club",
"dv": "3S",
"close": 6
},
"primary_armor": {
"name": "Gang Leather",
"rating": "+1"
}
}
}

View File

@@ -0,0 +1,95 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "0adfaf3c-bf19-4f21-a73f-e7918af1fd4a",
"ruleset_id": "sr6",
"entity_type": "npc",
"display_name": "Rusted Stilettos",
"description": "Ork Gangers from Glow City (SR6 Beginner Box).",
"template_id": "character_picker",
"properties": {
"alias": "Rusted Stilettos",
"archetype": "Ork Gangers",
"metatype": "Ork",
"notes": "The twisted Rusted Stilettos have spent too much time near Glow City, site of a nuclear reactor meltdown. The ones who’ve survived are terrifyingly deformed, and deadly.",
"quote": "“Beauty isn’t real. We are.”",
"hook": "Twisted and mutated, this gang serves a dragon, making them inscrutable to mere mortals.",
"attributes": {
"body": 5,
"agility": 2,
"reaction": 2,
"strength": 5,
"willpower": 2,
"logic": 2,
"intuition": 2,
"charisma": 2,
"edge": 1,
"essence": 6
},
"combat_info": {
"initiative": "4 + 1D6",
"defense_rating": 7,
"condition_monitor": 11
},
"skills": [
{
"name": "Close Combat",
"rating": 5,
"attribute": "Agility",
"dice_pool": 7
},
{
"name": "Firearms",
"rating": 5,
"attribute": "Agility",
"dice_pool": 7
},
{
"name": "Influence",
"rating": 5,
"attribute": "Charisma",
"dice_pool": 7
},
{
"name": "Perception",
"rating": 4,
"attribute": "Intuition",
"dice_pool": 6
}
],
"gear": [
{
"name": "Gang Leather",
"rating": "+1 DR"
},
{
"name": "Sony Emperor commlink",
"rating": 2
},
{
"name": "Knife"
},
{
"name": "Browning Ultra Power heavy pistol"
}
],
"primary_ranged_weapon": {
"name": "Browning Ultra Power",
"dv": "3P",
"mode": "SA",
"attack_rating": {
"close": 10,
"near": 9,
"far": 6
}
},
"primary_melee_weapon": {
"name": "Knife",
"dv": "2P",
"close": 6
},
"primary_armor": {
"name": "Gang Leather",
"rating": "+1"
}
}
}

View File

@@ -0,0 +1,105 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "2948bb04-3d46-48c3-b17b-2b23c2bb6c3e",
"ruleset_id": "sr6",
"entity_type": "npc",
"display_name": "Spikes",
"description": "Go-Gang / Troll Gangers from the SR6 Beginner Box.",
"template_id": "character_picker",
"properties": {
"alias": "Spikes",
"archetype": "Go-Gang / Troll Gangers",
"metatype": "Troll",
"notes": "Big-muscled brutes on big loud hogs, the Spikes are all trolls and all heavily muscled with plenty of tattoos. They are like an all-troll version of the Hell’s Angels.",
"quote": "“Go ahead, draw a weapon. My jacket needs more metal.”",
"hook": "Large and angry, Spikes are always looking for new victims, especially elves.",
"attributes": {
"body": 6,
"agility": 2,
"reaction": 2,
"strength": 7,
"willpower": 1,
"logic": 1,
"intuition": 2,
"charisma": 2,
"edge": 1,
"essence": 6
},
"combat_info": {
"initiative": "4 + 1D6",
"defense_rating": 7,
"condition_monitor": 13
},
"skills": [
{
"name": "Close Combat",
"rating": 5,
"attribute": "Agility",
"dice_pool": 7
},
{
"name": "Firearms",
"rating": 5,
"attribute": "Agility",
"dice_pool": 7
},
{
"name": "Piloting",
"rating": 5,
"attribute": "Reaction",
"dice_pool": 7
},
{
"name": "Influence",
"rating": 5,
"attribute": "Charisma",
"dice_pool": 7
},
{
"name": "Perception",
"rating": 4,
"attribute": "Intuition",
"dice_pool": 6
}
],
"gear": [
{
"name": "Leather",
"rating": "+1 DR"
},
{
"name": "Sony Emperor commlink",
"rating": 2
},
{
"name": "HD Scorpion bike",
"rating": 3
},
{
"name": "Bike Chain"
},
{
"name": "Defiance T-250 Shotgun"
}
],
"primary_ranged_weapon": {
"name": "Defiance T-250",
"dv": "4P",
"mode": "SA",
"attack_rating": {
"close": 7,
"near": 10,
"far": 6
}
},
"primary_melee_weapon": {
"name": "Bike Chain",
"dv": "2S",
"close": 4
},
"primary_armor": {
"name": "Leather",
"rating": "+1"
}
}
}

View File

@@ -0,0 +1,83 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "f7c985b7-d3ed-41e8-af58-8ba870d215da",
"ruleset_id": "sr6",
"entity_type": "npc",
"display_name": "The Claw",
"description": "Rusted Stilettos Leader / Male Troll Ganger from the SR6 Beginner Box.",
"template_id": "character_picker",
"properties": {
"alias": "The Claw",
"archetype": "Rusted Stilettos Leader / Male Troll Ganger",
"metatype": "Troll",
"notes": "A twisted troll who gained a name from the mutation of his right hand into something resembling a crab’s claw. He uses it as a weapon, but the visual is what’s terrifying.",
"quote": "“Your face could be fixed. My claw is ready. Let’s operate.”",
"hook": "The Claw is a dragon-worshipping fanatic, making him dangerous and unpredictable.",
"attributes": {
"body": 7,
"agility": 3,
"reaction": 3,
"strength": 6,
"willpower": 2,
"logic": 2,
"intuition": 2,
"charisma": 2,
"edge": 4,
"essence": 2,
"magic": 6
},
"combat_info": {
"initiative": "5 + 1D6",
"defense_rating": 8,
"condition_monitor": 14
},
"skills": [
{
"name": "Close Combat",
"rating": 9,
"attribute": "Agility",
"dice_pool": 12
},
{
"name": "Firearms",
"rating": 6,
"attribute": "Agility",
"dice_pool": 9
},
{
"name": "Influence",
"rating": 8,
"attribute": "Charisma",
"dice_pool": 10
},
{
"name": "Perception",
"rating": 5,
"attribute": "Intuition",
"dice_pool": 7
}
],
"gear": [
{
"name": "Gang Leather",
"rating": "+1 DR"
},
{
"name": "Sony Emperor commlink",
"rating": 2
},
{
"name": "Claw Weapon (DV 4P, AR 8)"
}
],
"primary_melee_weapon": {
"name": "Crab Claw Mutation",
"dv": "4P",
"close": 8
},
"primary_armor": {
"name": "Gang Leather",
"rating": "+1"
}
}
}

View File

@@ -0,0 +1,104 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "11df7705-3c2f-4744-a4c7-f6278a1f8ada",
"ruleset_id": "sr6",
"entity_type": "npc",
"display_name": "Torque",
"description": "Spikes Leader / Male Troll Gang Leader from the SR6 Beginner Box.",
"template_id": "character_picker",
"properties": {
"alias": "Torque",
"archetype": "Spikes Leader / Male Troll Gang Leader",
"metatype": "Troll",
"notes": "As a gang leader, he hates elves and really hates the Ancients, which means he has a special loathing for Green Phoenix. He became a leader because he knows how to make deals to get what he wants.",
"quote": "“Look, just shut up and help me find an elf to punch.”",
"hook": "He became a leader because he knows how to make deals to get what he wants.",
"attributes": {
"body": 5,
"agility": 6,
"reaction": 5,
"strength": 8,
"willpower": 4,
"logic": 2,
"intuition": 4,
"charisma": 3,
"edge": 2,
"essence": 1.7
},
"combat_info": {
"initiative": "9 + 1D6",
"defense_rating": 7,
"condition_monitor": 13
},
"skills": [
{
"name": "Close Combat",
"rating": 5,
"attribute": "Agility",
"dice_pool": 11
},
{
"name": "Firearms",
"rating": 5,
"attribute": "Agility",
"dice_pool": 11
},
{
"name": "Piloting",
"rating": 5,
"attribute": "Reaction",
"dice_pool": 10
},
{
"name": "Influence",
"rating": 5,
"attribute": "Charisma",
"dice_pool": 8
},
{
"name": "Perception",
"rating": 4,
"attribute": "Intuition",
"dice_pool": 8
}
],
"gear": [
{
"name": "Gang Leather",
"rating": "+1 DR"
},
{
"name": "Sony Emperor commlink",
"rating": 2
},
{
"name": "Harley-Davidson Scorpion motorcycle"
},
{
"name": "Bike Chain"
},
{
"name": "Defiance T-250 Shotgun"
}
],
"primary_ranged_weapon": {
"name": "Defiance T-250",
"dv": "4P",
"mode": "SA",
"attack_rating": {
"close": 7,
"near": 10,
"far": 6
}
},
"primary_melee_weapon": {
"name": "Bike Chain",
"dv": "2S",
"close": 4
},
"primary_armor": {
"name": "Gang Leather",
"rating": "+1"
}
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "5eea3b01-8139-44b7-9f75-48b83e37cb78",
"ruleset_id": "sr6",
"entity_type": "spell",
"display_name": "Armor",
"description": "Hardens the body of the target to absorb damage.",
"properties": {
"name": "Armor",
"category": "Spell",
"spell_type": "Manipulation",
"type_target": "P",
"range": "T",
"duration": "S",
"drain": "3",
"damage": "—",
"rules": "Add net hits to target’s Defense Rating and Body for Damage Resistance tests.",
"notes": "Hardens the body of the target to absorb damage."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "d3665eea-eb14-4f47-ad01-5f1745145cf0",
"ruleset_id": "sr6",
"entity_type": "spell",
"display_name": "Combat Sense",
"description": "Heightened awareness of possible dangers and ability to react faster.",
"properties": {
"name": "Combat Sense",
"category": "Spell",
"spell_type": "Detection",
"type_target": "M",
"range": "T",
"duration": "S",
"drain": "3",
"damage": "—",
"rules": "Net hits on Spellcasting test added to target’s dice pool for Surprise tests.",
"notes": "Heightened awareness of possible dangers and ability to react faster."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "82974286-ee99-4c81-8de9-b9aa55b49e92",
"ruleset_id": "sr6",
"entity_type": "spell",
"display_name": "Confusion",
"description": "Hits target with a swirl of images and emotions leaving them disoriented.",
"properties": {
"name": "Confusion",
"category": "Spell",
"spell_type": "Illusion",
"type_target": "M",
"range": "LOS",
"duration": "S",
"drain": "4",
"damage": "—",
"rules": "Target suffers dice pool penalty equal to net hits on all non-resistance tests.",
"notes": "Hits target with a swirl of images and emotions leaving them disoriented."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "943e28cb-9469-45c0-b526-7f8f6c309f33",
"ruleset_id": "sr6",
"entity_type": "spell",
"display_name": "Detect Life",
"description": "Points sentient beings out hiding in rubble, forests, or buildings.",
"properties": {
"name": "Detect Life",
"category": "Spell",
"spell_type": "Detection",
"type_target": "M",
"range": "T",
"duration": "S",
"drain": "3",
"damage": "—",
"rules": "",
"notes": "Points sentient beings out hiding in rubble, forests, or buildings."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "56a68e73-c248-40e6-974c-ad4a7e1d203a",
"ruleset_id": "sr6",
"entity_type": "spell",
"display_name": "Fireball",
"description": "Every runner fears that tiny speck of fire hurtling their way.",
"properties": {
"name": "Fireball",
"category": "Spell",
"spell_type": "Combat (Indirect)",
"type_target": "P",
"range": "LOS (A)",
"duration": "I",
"drain": "6",
"damage": "P, Special (Fire)",
"rules": "Area-effect fire storm engulfing all targets in radius.",
"notes": "Every runner fears that tiny speck of fire hurtling their way."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "f07b3b06-516b-46af-a1a9-26fece3ecb3c",
"ruleset_id": "sr6",
"entity_type": "spell",
"display_name": "Flamestrike",
"description": "A classic fire explosion in their faces.",
"properties": {
"name": "Flamestrike",
"category": "Spell",
"spell_type": "Combat (Direct)",
"type_target": "P",
"range": "LOS",
"duration": "I",
"drain": "5",
"damage": "P, Special (Fire)",
"rules": "Roll Sorcery + Magic vs. Defense/Resistance.",
"notes": "A classic fire explosion in their faces."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "b7678c78-b961-412d-a422-be1054fe9a5a",
"ruleset_id": "sr6",
"entity_type": "spell",
"display_name": "Heal",
"description": "Quickest and most effective way to repair bullet wounds.",
"properties": {
"name": "Heal",
"category": "Spell",
"spell_type": "Health",
"type_target": "P",
"range": "T",
"duration": "P",
"drain": "3",
"damage": "—",
"rules": "Roll Sorcery + Magic with threshold (5 - Essence). Heals 1 box Stun or Physical per net hit.",
"notes": "Quickest and most effective way to repair bullet wounds."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "5642493b-c5d6-4fb7-815d-19452ad00e8f",
"ruleset_id": "sr6",
"entity_type": "spell",
"display_name": "Ice Spear",
"description": "Piercing sub-zero temperature extreme.",
"properties": {
"name": "Ice Spear",
"category": "Spell",
"spell_type": "Combat (Direct)",
"type_target": "P",
"range": "LOS",
"duration": "I",
"drain": "5",
"damage": "P, Special (Cold)",
"rules": "",
"notes": "Piercing sub-zero temperature extreme."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "ab5dce99-4a91-49cd-a839-f15ffdf48a7f",
"ruleset_id": "sr6",
"entity_type": "spell",
"display_name": "Improved Invisibility",
"description": "Fades from view, becoming transparent.",
"properties": {
"name": "Improved Invisibility",
"category": "Spell",
"spell_type": "Illusion",
"type_target": "P",
"range": "T",
"duration": "S",
"drain": "4",
"damage": "—",
"rules": "Net hits become threshold on tests to see character. Works against tech and living eyes.",
"notes": "Fades from view, becoming transparent."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "73270407-036d-4975-8832-be7d6a4104fa",
"ruleset_id": "sr6",
"entity_type": "spell",
"display_name": "Increase Attribute",
"description": "Strengthens, speeds, or enlightens the target.",
"properties": {
"name": "Increase Attribute",
"category": "Spell",
"spell_type": "Health",
"type_target": "P",
"range": "T",
"duration": "S",
"drain": "3",
"damage": "—",
"rules": "Roll Sorcery + Magic (5 - Essence). Increase selected attribute by 1 per net hit.",
"notes": "Strengthens, speeds, or enlightens the target."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "b2b57542-0a55-4cd9-b0fd-d16a5eb44477",
"ruleset_id": "sr6",
"entity_type": "spell",
"display_name": "Levitate",
"description": "Defying gravity and moving people or cargo with your mind.",
"properties": {
"name": "Levitate",
"category": "Spell",
"spell_type": "Manipulation",
"type_target": "P",
"range": "LOS",
"duration": "S",
"drain": "6",
"damage": "—",
"rules": "50 kg per hit. Move target at caster’s Magic rating in meters/turn (Minor Action).",
"notes": "Defying gravity and moving people or cargo with your mind."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "aa17822b-96be-47d4-ad43-aec50fc947f4",
"ruleset_id": "sr6",
"entity_type": "spell",
"display_name": "Mana Barrier",
"description": "Want a spirit-free room? A mana barrier is the way to go.",
"properties": {
"name": "Mana Barrier",
"category": "Spell",
"spell_type": "Manipulation",
"type_target": "M",
"range": "LOS (A)",
"duration": "S",
"drain": "5",
"damage": "—",
"rules": "Blocks spirits, spells, and astrally projecting mages. Hits equal Barrier Rating.",
"notes": "Want a spirit-free room? A mana barrier is the way to go."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "b1560955-0e61-4b75-a5fd-4e66da356f42",
"ruleset_id": "sr6",
"entity_type": "spell",
"display_name": "Stunball",
"description": "Knocks out a whole room full of potential speed bumps.",
"properties": {
"name": "Stunball",
"category": "Spell",
"spell_type": "Combat (Indirect)",
"type_target": "M",
"range": "LOS (A)",
"duration": "I",
"drain": "4",
"damage": "S",
"rules": "",
"notes": "Knocks out a whole room full of potential speed bumps."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "bd72b9ba-8888-4a20-a8c5-b68cb79dadcf",
"ruleset_id": "sr6",
"entity_type": "spell",
"display_name": "Stunbolt",
"description": "Channels mana in a way that hurts, but only to stun.",
"properties": {
"name": "Stunbolt",
"category": "Spell",
"spell_type": "Combat (Direct)",
"type_target": "M",
"range": "LOS",
"duration": "I",
"drain": "3",
"damage": "S",
"rules": "",
"notes": "Channels mana in a way that hurts, but only to stun."
}
}

View File

@@ -0,0 +1,23 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "58e68112-353b-41a5-87bc-fef36c069fd7",
"ruleset_id": "sr6",
"entity_type": "vehicle",
"display_name": "Ford Americar",
"description": "Nothing special to look at, but will get you from here to there with no one giving a second glance.",
"properties": {
"filename": "ford_americar",
"name": "Ford Americar",
"category": "Groundcraft",
"handling": "4/5",
"acceleration": "9",
"speed_interval": "20",
"top_speed": "160",
"body": 11,
"armor": 4,
"pilot": 1,
"sensor": 2,
"seats": 4,
"notes": "Nothing special to look at, but will get you from here to there with no one giving a second glance."
}
}

View File

@@ -0,0 +1,23 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "b83f97be-f970-409b-85f3-7d0612d047e3",
"ruleset_id": "sr6",
"entity_type": "vehicle",
"display_name": "Harley-Davidson Scorpion",
"description": "The typical heavy-bodied, chromed road hog, with some armor and a whole lot of attitude.",
"properties": {
"filename": "harley_davidson_scorpion",
"name": "Harley-Davidson Scorpion",
"category": "Groundcraft",
"handling": "3/5",
"acceleration": "16",
"speed_interval": "30",
"top_speed": "200",
"body": 7,
"armor": 6,
"pilot": 1,
"sensor": 1,
"seats": 2,
"notes": "The typical heavy-bodied, chromed road hog, with some armor and a whole lot of attitude."
}
}

View File

@@ -0,0 +1,22 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "82936168-8bdb-47d8-af83-f3bfdc74ac1a",
"ruleset_id": "sr6",
"entity_type": "vehicle",
"display_name": "MCT-Nissan Roto-Drone",
"description": "MCT-Nissan got this right so long ago, they have never changed it much.",
"properties": {
"filename": "mct_nissan_roto_drone",
"name": "MCT-Nissan Roto-Drone",
"category": "Drone",
"handling": "3",
"acceleration": "20",
"speed_interval": "30",
"top_speed": "160",
"body": 5,
"armor": 6,
"pilot": 3,
"sensor": 2,
"notes": "MCT-Nissan got this right so long ago, they have never changed it much."
}
}

View File

@@ -0,0 +1,22 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "b894742f-ccbe-4636-9fbb-bb6ee6af0556",
"ruleset_id": "sr6",
"entity_type": "vehicle",
"display_name": "Steel Lynx",
"description": "This is what people mean when they refer to a “killing machine.”",
"properties": {
"filename": "steel_lynx",
"name": "Steel Lynx",
"category": "Drone",
"handling": "3/5",
"acceleration": "15",
"speed_interval": "15",
"top_speed": "80",
"body": 10,
"armor": 16,
"pilot": 4,
"sensor": 4,
"notes": "This is what people mean when they refer to a “killing machine.”"
}
}

View File

@@ -0,0 +1,23 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "d139efa9-ad6d-47a7-82dd-aa2340478131",
"ruleset_id": "sr6",
"entity_type": "vehicle",
"display_name": "Yamaha Rapier",
"description": "A classic racing bike seen beneath the hoops of go-gangers and corp brats alike.",
"properties": {
"filename": "yamaha_rapier",
"name": "Yamaha Rapier",
"category": "Groundcraft",
"handling": "3/6",
"acceleration": "27",
"speed_interval": "25",
"top_speed": "250",
"body": 5,
"armor": 2,
"pilot": 1,
"sensor": 1,
"seats": 2,
"notes": "A classic racing bike seen beneath the hoops of go-gangers and corp brats alike."
}
}

View File

@@ -0,0 +1,21 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "efaeb2c4-a522-4e53-9511-2add148fa7de",
"ruleset_id": "sr6",
"entity_type": "weapon",
"display_name": "Ares Desert Strike",
"description": "The Desert Strike for the Desert Wars is the tagline today.",
"properties": {
"name": "Ares Desert Strike",
"dv": "5P",
"mode": "SA",
"attack_rating": {
"close": 3,
"near": 10,
"far": 10,
"extreme": 10
},
"extras": "detachable imaging scope, shock pad",
"notes": "The Desert Strike for the Desert Wars is the tagline today."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "16bcf531-339b-4ae5-9efb-cd7a82e71bfd",
"ruleset_id": "sr6",
"entity_type": "weapon",
"display_name": "Ares Light Fire 75",
"description": "The Light Fire Series is designed for special operators.",
"properties": {
"name": "Ares Light Fire 75",
"dv": "2P",
"mode": "SA",
"attack_rating": {
"close": 10,
"near": 7,
"far": 6
},
"extras": "barrel-mounted silencer, laser sight, smartgun",
"notes": "The Light Fire Series is designed for special operators."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "f108cf3f-8245-4453-a5dd-f9fb0584081d",
"ruleset_id": "sr6",
"entity_type": "weapon",
"display_name": "Ares Predator VI",
"description": "The Predator VI is genuine innovation built into some classic styling.",
"properties": {
"name": "Ares Predator VI",
"dv": "4P",
"mode": "SA",
"attack_rating": {
"close": 9,
"near": 9,
"far": 7
},
"extras": "smartgun",
"notes": "The Predator VI is genuine innovation built into some classic styling."
}
}

View File

@@ -0,0 +1,18 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "803382f0-8ede-4945-a0a1-6851a6a45648",
"ruleset_id": "sr6",
"entity_type": "weapon",
"display_name": "Bike Chain",
"description": "Go gangs love to pull the old equipment off their scrap bikes and smack people with it.",
"properties": {
"name": "Bike Chain",
"dv": "2S",
"mode": "NA",
"attack_rating": {
"close": 4
},
"extras": "None",
"notes": "Go gangs love to pull the old equipment off their scrap bikes and smack people with it."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "4acd41df-6fd2-471d-a099-3322da21c056",
"ruleset_id": "sr6",
"entity_type": "weapon",
"display_name": "Browning Ultra Power",
"description": "Cheaper than the Predator and offers a built-in top-mounted laser sight.",
"properties": {
"name": "Browning Ultra Power",
"dv": "3P",
"mode": "SA",
"attack_rating": {
"close": 10,
"near": 9,
"far": 6
},
"extras": "laser sight",
"notes": "Cheaper than the Predator and offers a built-in top-mounted laser sight."
}
}

View File

@@ -0,0 +1,18 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "596ee4fd-b8c4-45e6-9058-7a91cd3be89e",
"ruleset_id": "sr6",
"entity_type": "weapon",
"display_name": "Club",
"description": "An axe handle, baseball bat, crowbar, tire iron, wrench, or two-by-four.",
"properties": {
"name": "Club",
"dv": "3S",
"mode": "NA",
"attack_rating": {
"close": 6
},
"extras": "None",
"notes": "An axe handle, baseball bat, crowbar, tire iron, wrench, or two-by-four."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "6d0383c0-e204-4980-818e-fd6e71e9cac8",
"ruleset_id": "sr6",
"entity_type": "weapon",
"display_name": "Defiance T-250",
"description": "A street howitzer, this semi-auto shotgun is available in normal or short-barreled versions.",
"properties": {
"name": "Defiance T-250",
"dv": "4P",
"mode": "SA",
"attack_rating": {
"close": 7,
"near": 10,
"far": 6
},
"extras": "None",
"notes": "A street howitzer, this semi-auto shotgun is available in normal or short-barreled versions."
}
}

View File

@@ -0,0 +1,18 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "8db99eff-97ee-48ed-b742-08f307409bd7",
"ruleset_id": "sr6",
"entity_type": "weapon",
"display_name": "Extendable Baton",
"description": "Can be extended with a wrist flick or a wireless signal.",
"properties": {
"name": "Extendable Baton",
"dv": "2S",
"mode": "NA",
"attack_rating": {
"close": 5
},
"extras": "None",
"notes": "Can be extended with a wrist flick or a wireless signal."
}
}

View File

@@ -0,0 +1,18 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "2ed0ed2c-4acb-4e1a-b168-e2f636511438",
"ruleset_id": "sr6",
"entity_type": "weapon",
"display_name": "Katana",
"description": "The iconic two-handed sword of the samurai is standard issue for trid shadowrunners.",
"properties": {
"name": "Katana",
"dv": "4P",
"mode": "NA",
"attack_rating": {
"close": 10
},
"extras": "None",
"notes": "The iconic two-handed sword of the samurai is standard issue for trid shadowrunners."
}
}

View File

@@ -0,0 +1,19 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "405ac1d8-d948-4f61-80c6-5736c4d53054",
"ruleset_id": "sr6",
"entity_type": "weapon",
"display_name": "Knife",
"description": "A catch-all term for a variety of different deadly fighting blades.",
"properties": {
"name": "Knife",
"dv": "2P",
"mode": "NA",
"attack_rating": {
"close": 6,
"near": 1
},
"extras": "max range, 20 meters",
"notes": "A catch-all term for a variety of different deadly fighting blades."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "deee47e3-7521-4bce-afac-79246287c964",
"ruleset_id": "sr6",
"entity_type": "weapon",
"display_name": "Ruger Super Warhawk",
"description": "Shiny and chromed and makes holes the size of a troll’s fist straight out of the box.",
"properties": {
"name": "Ruger Super Warhawk",
"dv": "4P",
"mode": "SA",
"attack_rating": {
"close": 8,
"near": 11,
"far": 8
},
"extras": "None",
"notes": "Shiny and chromed and makes holes the size of a troll’s fist straight out of the box."
}
}

View File

@@ -0,0 +1,18 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "b8c27f0b-b5f4-4f4c-a26c-2e146a2c8ea2",
"ruleset_id": "sr6",
"entity_type": "weapon",
"display_name": "Sword",
"description": "A heavy blade on a one-handed grip that comes in a variety of styles.",
"properties": {
"name": "Sword",
"dv": "3P",
"mode": "NA",
"attack_rating": {
"close": 9
},
"extras": "None",
"notes": "A heavy blade on a one-handed grip that comes in a variety of styles."
}
}

View File

@@ -0,0 +1,20 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "e23a7a67-8a63-4c58-bc25-2bf852727539",
"ruleset_id": "sr6",
"entity_type": "weapon",
"display_name": "Uzi V",
"description": "The latest model Uzi is a big market entry for Spinrad Global.",
"properties": {
"name": "Uzi V",
"dv": "3P",
"mode": "SA/BF",
"attack_rating": {
"close": 8,
"near": 8,
"far": 7
},
"extras": "None",
"notes": "The latest model Uzi is a big market entry for Spinrad Global."
}
}

View File

@@ -0,0 +1,19 @@
{
"$schema": "../../../schema/entity.json",
"uuid": "c6f3d100-246f-474c-aa97-f6c9e4d633ef",
"ruleset_id": "sr6",
"entity_type": "weapon",
"display_name": "Yamaha Pulsar I",
"description": "Uses wireless capacitors, meaning increased range compared to wired tasers.",
"properties": {
"name": "Yamaha Pulsar I",
"dv": "4S (e)",
"mode": "SS",
"attack_rating": {
"close": 9,
"near": 9
},
"extras": "max range, 50 meters",
"notes": "Uses wireless capacitors, meaning increased range compared to wired tasers."
}
}

107
rulesets/sr6/helpers.js Normal file
View File

@@ -0,0 +1,107 @@
/**
* SR6 Ruleset Handlebars Helpers
* Auto-loaded by preview server for ruleset 'sr6'.
*/
module.exports = function (handlebars) {
// Compute maximum physical damage boxes: 8 + ceil(body / 2)
handlebars.registerHelper('calcPhysicalBoxes', function (body) {
const b = typeof body === 'object' && body !== null ? (body.value || body.base || 0) : Number(body || 0);
return 8 + Math.ceil(b / 2);
});
// Compute maximum stun damage boxes: 8 + ceil(willpower / 2)
handlebars.registerHelper('calcStunBoxes', function (willpower) {
const w = typeof willpower === 'object' && willpower !== null ? (willpower.value || willpower.base || 0) : Number(willpower || 0);
return 8 + Math.ceil(w / 2);
});
// Format currency with nuyen symbol
handlebars.registerHelper('formatNuyen', function (amount) {
if (amount === undefined || amount === null) return '0¥';
const num = typeof amount === 'number' ? amount : parseInt(String(amount).replace(/[^0-9]/g, ''), 10) || 0;
return `${num.toLocaleString('en-US')}¥`;
});
// Format dice pool helper: (skill rating + linked attribute value)
handlebars.registerHelper('calcDicePool', function (skill, attributes) {
if (!skill) return 0;
const rating = typeof skill.rating === 'number' ? skill.rating : (parseInt(skill.rating, 10) || 0);
const attrName = (skill.attribute || '').toLowerCase();
let attrVal = 0;
if (attributes && attrName && attributes[attrName] !== undefined) {
const a = attributes[attrName];
attrVal = typeof a === 'object' && a !== null ? (a.value || a.base || 0) : (Number(a) || 0);
}
const bonus = skill.expertise ? 3 : (skill.specialization ? 2 : 0);
return rating + attrVal + bonus;
});
// Safe attribute value extractor
handlebars.registerHelper('attr', function (attributes, name) {
if (!attributes || !name) return '—';
const val = attributes[name.toLowerCase()];
if (val === undefined || val === null) return '—';
return typeof val === 'object' ? (val.value ?? val.base ?? '—') : val;
});
// Helper to build 3-box rows for condition monitor
handlebars.registerHelper('conditionMonitorRows', function (totalBoxes, currentDamage, maxGridBoxes, options) {
const total = Number(totalBoxes) || 8;
const damage = Number(currentDamage) || 0;
const maxBoxes = Number(maxGridBoxes) || 18;
const rowsCount = Math.ceil(maxBoxes / 3);
let output = '';
for (let r = 0; r < rowsCount; r++) {
const boxes = [];
for (let c = 1; c <= 3; c++) {
const boxIdx = r * 3 + c;
if (boxIdx <= maxBoxes) {
boxes.push({
index: boxIdx,
active: boxIdx <= total,
filled: boxIdx <= damage,
blackedOut: boxIdx > total,
isThreshold: c === 3,
penalty: -(r + 1)
});
}
}
output += options.fn({
rowNumber: r + 1,
penalty: -(r + 1),
boxes: boxes
});
}
return output;
});
// Matrix condition monitor boxes generator (1 to 12)
handlebars.registerHelper('matrixMonitorBoxes', function (maxBoxes, currentDamage, options) {
const total = Number(maxBoxes) || 12;
const damage = Number(currentDamage) || 0;
let output = '';
for (let i = 1; i <= total; i++) {
output += options.fn({
index: i,
filled: i <= damage
});
}
return output;
});
// Edge points tracker generator (1 to maxEdge)
handlebars.registerHelper('edgePointsBoxes', function (maxEdge, currentEdge, options) {
const max = Number(maxEdge) || 7;
const curr = Number(currentEdge) || 0;
let output = '';
for (let i = 1; i <= Math.max(7, max); i++) {
output += options.fn({
index: i,
filled: i <= curr,
disabled: i > max
});
}
return output;
});
};

Some files were not shown because too many files have changed in this diff Show More