Fichas de conjuntos de reglas

Usa esta página para diseñar la ficha de personaje de un conjunto de reglas: atributos, habilidades, campos y listas, estados vivos, contadores de heridas, penalizaciones, descansos y el texto del Game Master, además de la ficha del grupo y los relojes de progreso. Es para quienes escriben conjuntos de reglas. Antes de empezar, lee Escribir conjuntos de reglas de Game Mode.

La ficha

Todo lector de números los nombra con una referencia de valor: un objeto con exactamente una clave entre const, field, derived, abilityScore, abilityMod, abilityModFromField, skillMod, saveMod, listSum, livePool, liveTrack e itemStat. Por ejemplo, una reserva con máximo derivado: "max": { "derived": "grit_max" }.

Qué hace una prueba sin entrenamiento. Una habilidad o salvación en la que el personaje no tiene entrenamiento (su nivel es el primero) se tira como siempre, salvo que el conjunto diga otra cosa con untrained en la habilidad o salvación o en la sección donde está (la regla propia de la habilidad o salvación tiene prioridad):

"sections": [{ "id": "labour", "label": "Labour", "untrained": { "by": -1 } }],
"skills": [
  { "id": "dig", "label": "Dig", "ability": "sinew", "section": "labour", "untrained": "refuse" },
  { "id": "listen", "label": "Listen", "ability": "nerve", "untrained": "harder" }
]

Las secciones en atributos, habilidades y salvaciones, y untrained en cualquier lugar, requieren Capability API 1.41 en un conjunto empaquetado.

Una habilidad o salvación puede llevar un cap, una referencia de valor que es lo máximo a lo que puede llegar su prueba: una puntuación que no puede superar o un contador que la frena. Gravewatch limita Soothe a la Resolve que le queda a un guardián, "cap": { "livePool": "resolve" }. El número limitado es el que muestra la ficha y el que tira cada prueba, y un cambio con with= se calcula sobre el número anterior al límite y después se vuelve a limitar. Un límite no puede leer un modificador de habilidad o salvación, ni tampoco el valor derivado que lee ni ningún valor derivado declarado antes que ese, para que la ficha se siga calculando una sola vez, de arriba abajo. Capability API 1.39.

hideWhen oculta un campo, un valor derivado, una lista, una reserva o un contador simple según el valor de otro campo, exactamente de una de tres formas: equals un valor, notEquals un valor (oculto siempre que el campo tenga cualquier otro, que es como se dice "solo para este tipo de personaje") o in una lista de valores. Cada valor nombrado debe ser uno que el campo pueda contener, o la regla nunca coincidiría, y se comprueba de uno en uno; para notEquals e in eso incluye el rango de un campo numérico y la longitud de un campo de texto. La regla lee el valor que muestra el editor de fichas: un campo sin valor es el valor con el que empieza una ficha en blanco, y un valor enum que el conjunto ya no ofrece es el predeterminado del campo. El archivo 5e usa equals para ocultar espacios de conjuro a quien no lanza conjuros; Gravewatch quita el aceite de linterna de la ficha de todo guardián que no esté en la guardia nocturna con "hideWhen": { "field": "watch", "notEquals": "night" }. Una capa no puede retirar un valor con el que compare cualquiera de ellas. Un contador de heridas no puede ocultarse, porque las tiradas y los combates lo leen muestre lo que muestre la ficha. notEquals e in requieren Capability API 1.39.

El max de un contador simple puede ser una referencia de valor en vez de un número, para que una puntuación del personaje determine hasta dónde llega: "max": { "field": "willpower_rating" }. Su min y su default siguen siendo números. Un contador de heridas con niveles con nombre tiene un max igual a su número de niveles; un contador de casillas numeradas tiene la longitud que indica su propio max (consulta Casillas numeradas más abajo). alwaysShow: true muestra un contador en el bloque de ficha del GM incluso en su valor predeterminado, para una puntuación que importa en cada turno; sin él, un contador en su valor predeterminado se omite, porque tres salvaciones contra la muerte a cero no dicen nada. Estos tres requieren Capability API 1.37 en un conjunto empaquetado.

Estados vivos: una forma, una postura, una luz

Un campo enum se elige al crear el personaje y no cambia, y un estado solo está activado o desactivado. Un estado vivo es un valor de un conjunto cerrado que cambia durante el juego: la forma de un cambiaformas, una postura de combate, cuánto alumbra una linterna.

"live": {
  "states": [
    {
      "id": "stance",
      "label": "Stance",
      "values": ["guarded", "steady", "reckless"],
      "valueLabels": { "guarded": "Guarded", "steady": "Steady", "reckless": "Reckless" },
      "default": "steady"
    }
  ]
}

Números que lo siguen. Un valor derivado con "op": "enumTable" da un número para cada valor de un campo enum o de un estado vivo:

{
  "id": "stance_brawn",
  "label": "Stance on Brawn",
  "op": "enumTable",
  "from": { "liveState": "stance" },
  "table": { "guarded": -1, "reckless": 2 },
  "default": 0
}

Los estados vivos, enumTable y un paso de descanso que nombra un state requieren Capability API 1.42 en un conjunto empaquetado.

Contadores de heridas: salud en una escala de marcas

Muchos sistemas no cuentan puntos de golpe. Tienen una columna de casillas, cada una peor que la anterior, y marcas una al recibir daño. Añade kinds y, o bien levels con nombre, o bien boxes numeradas (abajo), a una entrada live.tracks para convertir un número en una de estas escalas:

¿Qué forma necesita tu sistema? Una reserva guarda CUÁNTO daño llegó; un contador guarda cuánto Y de qué tipo era cada parte. Si tu sistema dice que una herida es contundente, letal o agravada, y cuál fue sigue importando después del golpe (porque lo agravado cura más despacio, no puede absorberse o es lo que acaba matando), ese tipo tiene que conservarse en algún sitio tras la tirada, y solo una marca lo conserva. Una reserva de puntos no puede: una vez restado el daño, solo es un número menor, y nada en la ficha recuerda qué puntos eran de cada tipo. Por eso combat.damageKinds se rechaza en un conjunto de reglas cuya salud es una reserva, en vez de ignorarse sin avisar. Una reserva sí puede tener damageTypes, y un oponente puede resistirlos o ser inmune a ellos, porque esa es una cuestión de cuánto del golpe llega, no de qué herida queda después.

{
  "id": "harm",
  "label": "Harm",
  "min": 0,
  "max": 4,
  "levels": [
    { "label": "Scuffed", "penalty": 0 },
    { "label": "Winded", "penalty": -1 },
    { "label": "Bleeding", "penalty": -3 },
    { "label": "Down", "penalty": -99 }
  ],
  "kinds": [
    { "id": "knock", "label": "K", "severity": 0 },
    { "id": "tear", "label": "T", "severity": 1 }
  ]
}

Las reglas exactas, porque una interpretación vaga produce un contador incorrecto:

Marcar durante el juego. El GM escribe [sheet: op="damage" track="harm" kind="knock" amount="1"] y cura con amount negativo. En un contador que se llena por casilla, añade box="3" para la casilla donde cae el golpe. La forma de reserva de damage, que nombra pool=, no cambia. El comando track ordinario se rechaza para heridas: un número no identifica los tipos de marcas nuevas. El jugador también puede marcar y limpiar casillas a mano, como esperan estos sistemas.

Un combate también puede marcarlo. Apunta combat.health al contador en vez de a una reserva: un golpe acertado marca las casillas que indica combat.damageKinds.marks, del tipo al que ese bloque asigna su daño. Un personaje con el contador lleno está caído, el estado que consulta la regla de muerte. En un contador que se llena por casilla, el daño per-point nombra la casilla donde cae y per-blow apunta a la primera, y un golpe que ninguna casilla puede recibir derriba al personaje, que es lo que significa quedar fuera de combate en los sistemas que usan un contador así. Curar elimina una marca, la más leve, de cualquier tipo. Los puntos temporales se rechazan porque el contador no tiene un espacio para ellos. El motor lo lee como niveles RESTANTES; el resto del combate, caer, revivir, el registro y el resumen no cambia.

Un descanso puede curar heridas. Un paso de restauración que use "to" lo reduce a esa cantidad de marcas, incluido el desbordamiento; con un "by" NEGATIVO elimina esa cantidad, empezando por el desbordamiento, así que "by": { "const": -2 } elimina dos. Un paso que además nombra un kind solo elimina marcas de ese tipo: "Catch your breath" de Gravewatch es { "track": "harm", "kind": "knock", "to": "min" }, que cura los golpes y deja los desgarros. Un paso que AÑADIRÍA marcas no hace nada, porque un descanso no causa daño, y eso incluye un "by" positivo: se omite sin aviso, así que escribe el signo menos.

Casillas numeradas en vez de niveles con nombre

Si un contador mide tanto como la resistencia del personaje, dale boxes en vez de levels. Tiene tantas casillas como su propio max, que puede ser un valor que calcula la ficha (nunca uno que lea el estado vivo), hasta 64:

{
  "id": "strain",
  "label": "Strain",
  "min": 0,
  "max": { "derived": "strain_boxes" },
  "boxes": {
    "penalty": {
      "by": "remaining",
      "table": [
        [0, -1],
        [1, 0]
      ]
    }
  },
  "kinds": [{ "id": "strain", "label": "S", "severity": 0 }],
  "fill": "indexed",
  "onFull": "refuse"
}

Llenar por casilla y contadores que rechazan

Niveles que añade una lista

"extra": { "list": "scars", "countColumn": "levels", "penaltyColumn": "penalty" } en un contador con niveles con nombre permite que una lista de la ficha lo alargue para cada personaje. Cada fila, en orden, añade su cantidad de niveles (16 como máximo) con su penalización, después del último nivel cuya penalización sea al menos igual de buena, con el nombre de ese nivel si las penalizaciones coinciden y, si no, con el de la penalización. Las cicatrices de Gravewatch funcionan así. Una lista que la ficha oculta no añade nada, y si se borra una fila mientras sus niveles están marcados, las marcas que ya no caben se conservan como desbordamiento: editar la ficha no deshace el daño.

boxes, fill, onFull, extra y el kind de un paso de descanso requieren Capability API 1.40 en un conjunto empaquetado.

La penalización de las tiradas

resolution.penaltyFrom nombra el contador de heridas que penaliza todas las pruebas del conjunto. Se declara, no se presupone: sin él, las tiradas funcionan igual que antes de que existieran los contadores.

Lo que HACE la penalización depende del tipo de resolución, igual que el número de la ficha:

Debe nombrar un contador de heridas. Uno ordinario no tiene penalización y se rechaza al importar. El resultado indica la aplicada, para que el jugador entienda por qué tiró menos dados; el bloque de ficha del GM también muestra el peldaño y su coste.

Modificadores fuera de la ficha

Algunos números de una ficha acompañan a cada tirada a la que afectan: una mochila pesada en cada escalada, una penalización de armadura en cada intento de sigilo, una bendición en todo. resolution.adjust lo indica, en cualquiera de los dos tipos:

"adjust": [{ "value": { "derived": "burdened" }, "abilities": ["brawn"] }]

El resultado indica lo que añadió la ficha (adjust="-2" en el registro y una línea en la tarjeta de dados), para que el jugador vea por qué una tirada salió así. Requiere Capability API 1.38 en un conjunto empaquetado.

Descansos

Un descanso es una lista de restauraciones y elementos que borrar. Cada paso nombra un objetivo (pool, poolGroup, listPools, track o state) y lo fija ("to": "max", "to": "min" o un número) o modifica ("by": { "const": 1 } o "by": { "fractionOfMax": 0.5 }). Si nombra un contador de heridas, solo puede curarlo, así que su by es negativo; consulta arriba. Un paso que nombra un estado vivo solo lo fija, en "default" o en uno de sus valores. Un paso poolGroup con fractionOfMax cambia cada reserva del grupo según su propia fracción; añade "shared": true (Capability API 1.77) para calcular la fracción sobre el máximo de todo el grupo y repartirla entre las reservas del grupo en el orden en que las lista la ficha, cada una hasta lo que le falta. El descanso largo de 5e, "la mitad del número total de" dados de golpe del personaje, guardados en una reserva por dado, es { "poolGroup": "hit_dice", "by": { "fractionOfMax": 0.5, "round": "down", "min": 1 }, "shared": true }.

Texto del Game Master

Referencia completa de reglas para el GM

El gmReference opcional de nivel superior contiene la referencia completa de reglas del conjunto para el Game Master, de hasta 16.000 caracteres. Pon aquí las reglas de arbitraje ampliadas y deja las instrucciones breves sobre pruebas y recursos en gm.checkGuidance y gm.sheetGuidance. Esos campos, y gm.worldGuidance, mantienen sus límites de 1.500 caracteres; el texto de las capas también conserva sus límites actuales.

"gmReference": "When a journey crosses hostile country, judge supplies, shelter and exposure before the next leg. A failed navigation check costs time rather than silently moving the party to its destination."

La referencia aparece bajo Game Master rules reference en el prompt de sistema estable, una vez por solicitud. Nunca se copia en el recordatorio de cada turno. Como el resto del texto apto para prompts, debe ocupar una sola línea, sin caracteres de control, corchetes ni llaves de macro ({{ y }}). Si la solicitud sigue superando el límite de contexto tras los ajustes habituales del historial y del presupuesto de respuesta, la referencia se acorta con un corte marcado antes de recortar las instrucciones principales. Déjala sin definir para mantener los prompts actuales. Un paquete que la use debe declarar en el manifiesto schemaVersion: 2 y capabilityApi: { "major": 1, "minor": 145 } o posterior.

Relojes de progreso del grupo y de la escena (clocks)

Capability API 1.143 añade un objeto clocks opcional de nivel superior. Omítelo para mantener desactivados los comandos de reloj. El objeto es estricto: solo acepta estas tres claves.

"clocks": {
  "sizes": [4, 6, 8],
  "max": 8,
  "text": "Create clocks for looming threats and long projects. Tick them when the fiction advances."
}

sizes admite de uno a seis números enteros distintos de segmentos, cada uno de 2 a 12; de forma predeterminada es [4, 6, 8]. max es el número máximo de relojes que se conservan a la vez, de 1 a 12, y de forma predeterminada vale 8. El text opcional es una línea apta para prompts de hasta 400 caracteres que explica cuándo debe crear y avanzar relojes el GM. Un objeto vacío activa los valores predeterminados.

Los relojes pertenecen al grupo o a la escena, no a un personaje. El recordatorio del GM enumera sus nombres y su llenado en cada turno y enseña estos comandos:

Los nombres son líneas únicas de 1 a 100 caracteres sin comillas dobles, corchetes, caracteres de control ni llaves de macro. Cada etiqueta pide exactamente una acción. Los comandos se aplican en el orden de la respuesta, así que un reloj se puede crear y avanzar en la misma respuesta. El motor reescribe cada etiqueta con result="ok" now="4/6" (o now="cleared"), o con result="refused" reason="...". Se descartan los atributos de resultado que aporte el modelo. Se rechazan los relojes desconocidos y las solicitudes mal formadas; se aplican como máximo 40 comandos por respuesta.

Game Mode muestra un círculo segmentado, el nombre y el llenado junto al estado del grupo. Las etiquetas se quedan en la respuesta guardada como comprobantes y se ocultan de la narración. Los relojes se guardan en cada instantánea del estado de la partida como rulesetClocks; si faltan datos, no hay relojes. Regenerar parte de la instantánea anterior, continuar parte de la actual, y seleccionar o eliminar swipes o mensajes restaura los relojes junto con el resto de esa instantánea.

Ficha de grupo: una banda, una nave o Story Points compartidos

Capability API 1.144 añade un party opcional de nivel superior, junto a sheet. Contiene una ficha compartida por partida, como la banda de Blades, la nave de Lasers & Feelings o los Story Points de Genesys:

"party": {
  "label": "Crew",
  "fields": [
    { "id": "heat", "label": "Heat", "type": "number", "min": 0, "max": 9, "default": 0 },
    { "id": "vault", "label": "Vault capacity", "type": "number", "min": 0, "max": 16, "default": 8 },
    { "id": "upgrades", "label": "Upgrades", "type": "text", "maxLength": 400 }
  ],
  "pools": [{ "id": "coin", "label": "Coin", "max": { "field": "vault" }, "start": "empty" }],
  "advancement": { "fields": ["heat", "vault", "upgrades"], "text": "Record heat after a score." },
  "text": "Coin belongs to the crew."
}

fields usa el mismo esquema de campos que sheet.fields; pools usa el de sheet.live.pools, incluidos start, group, hideWhen y allowTemp. Se necesita al menos un campo o una reserva, y sus IDs deben ser únicos dentro de la ficha de grupo. Los IDs de personaje y de grupo pueden coincidir. En esta versión menor, las fichas de grupo no tienen secciones, listas, atributos, valores derivados ni migraciones de ficha de personaje. El max de una reserva lee una constante o un campo numérico del grupo. Las fórmulas de personaje no pueden leer valores del grupo, y las fórmulas del grupo no pueden leer valores de personaje. hideWhen también nombra solo campos del grupo.

advancement.fields nombra los campos number, text o longtext que el GM puede cambiar de forma permanente. advancement.text y text aceptan cada uno una línea apta para prompts de como máximo 400 caracteres. El summary opcional reutiliza gm.sheetSummary: sus fields seleccionan campos del grupo; derived y lists deben estar vacíos. Sin resumen, se muestran todos los campos visibles del grupo. Las reservas aparecen siempre.

[sheet: sheet="party" op="restore" pool="coin" amount="3"]
[sheet: sheet="party" op="spend" pool="coin" amount="2"]
[sheet: sheet="party" op="advance" field="heat" by="2"]
[sheet: sheet="party" op="advance" field="upgrades" to="Hidden vault"]

sheet="party" selecciona la ficha compartida; omite who. El who="party" existente sigue aplicándose a cada personaje y nunca cambia la ficha compartida. Esta versión menor permite spend, restore y el advance de campos en la ficha de grupo. Las fichas desconocidas, las operaciones no admitidas, las reservas insuficientes, los avances no declarados y los valores no válidos se rechazan y se reescriben con el resultado del motor. Las reservas del grupo siguen la misma aritmética de actual y máximo, y los mismos valores predeterminados, que las reservas de personaje.

El GM recibe en cada turno la etiqueta, los campos y las reservas del grupo junto a los bloques de ficha de los personajes. Game Mode ofrece una ficha de grupo plegable y de solo lectura junto a los retratos de los personajes, con la misma presentación de ficha. Los valores permanentes se guardan una sola vez en los metadatos del chat (gamePartySheet), junto a gameCharacterCards, y comparten los comprobantes de avance. Las reservas vivas usan la entrada reservada $party de rulesetLive; los nombres normalizados de personaje no pueden coincidir con ella. Regenerar parte de antes de la respuesta, y seleccionar o eliminar swipes restaura los valores permanentes y vivos mediante el historial existente. Los conjuntos sin party mantienen su comportamiento actual.

Creación compartida del grupo (Capability API 1.163). Una ficha de grupo puede incluir lists (hasta 12, escritas como las listas de la ficha de personaje), un builder guiado propio y fromMembers: hasta 8 campos numéricos del grupo que se leen de los personajes del grupo, cada uno { "field", "count": true } (cuántos personajes hay) o { "field", "sum": "<character number field>" } (lo que suman los suyos, como los puntos de Totem). Los campos de miembros se calculan a partir de los personajes tal como están cada vez que se lee la ficha compartida, así que, si un personaje se une o se va, cambian al instante. Con listas, el summary.lists del grupo puede nombrarlas.

El creador se escribe exactamente igual que el de un personaje (reservas, pasos, filas con precio, ofertas de gasto, perfiles) y sigue las mismas reglas respecto a los campos y las listas propios del grupo. Sus pasos de catálogo y de copia de filas pueden leer los catálogos del conjunto que alimentan las listas del grupo. En Game Mode, cualquier jugador abre Edit en la ficha compartida, que ofrece la configuración guiada, y la guarda para todo el grupo. Cada guardado nombra la revisión sobre la que se abrió (gamePartySheetRevision en los metadatos del chat, que sube con cada guardado y con los cambios de la propia historia): un guardado abierto antes de que llegara el de otra persona se rechaza, se muestra la ficha más reciente y el borrador del jugador sigue abierto, así que volver a guardar es su decisión de sustituirla.

"party": {
  "label": "The Crew",
  "fields": [
    { "id": "tier", "label": "Tier", "type": "number", "min": 0, "max": 4, "default": 0 },
    { "id": "size", "label": "Crew size", "type": "number", "min": 0, "max": 12, "default": 0 }
  ],
  "lists": [{ "id": "upgrades", "label": "Upgrades", "columns": [{ "id": "name", "label": "Name", "type": "text" }] }],
  "builder": { "steps": [{ "id": "upgrades", "label": "Upgrades", "kind": "rows", "list": "upgrades" }] },
  "fromMembers": [{ "field": "size", "count": true }]
}