games-development-ai/contracts/play-loop/game-event.schema.json
lili cbfd4d871b
Some checks failed
contract-gates / contract-gates (push) Has been cancelled
docs-gate / docs-gate (push) Has been cancelled
feat(acceptance): 闭合 playtest v3 与 A+ 可信消费链
固化 Match-3 生产者、视觉、音频与双 Judge 证据闭包。

将《山海行纪》r1.1 绑定新的不可变 release,并以生产预检现场核验 bundle、Registry/2 和 25 项 Writer 快照。

同步地图1平衡锁值、跨游戏回归修复、验收契约与 SoT 证据。
2026-07-28 20:16:13 -07:00

146 lines
5.2 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://wanxiang.ai/contracts/play-loop/game-event.schema.json",
"title": "GameEvent",
"description": "playtest/2 与 playtest/3 共用的版本化业务事件。ctx.log 诊断不属于本契约;只有 ctx.event 产生的 native 事件和 historical_replay 明确适配的 legacy 事件可以进入业务证据流。playtest/3 可追加 eventRole 区分当前 profile proof 与跨 profile observation。",
"type": "object",
"required": [
"eventVersion", "evidenceMode", "scope", "namespace", "type", "message", "payload",
"payloadCanonical", "payloadHash", "producer", "seq", "actionId", "virtualTimeMs", "sourceEventVersion",
"adapterVersion", "sourceMessageHash"
],
"properties": {
"eventVersion": { "const": "game-event/1" },
"evidenceMode": { "enum": ["native", "legacy-adapted"] },
"scope": { "const": "game" },
"namespace": { "type": "string", "pattern": "^game/[a-z][a-z0-9-]*\\.[a-z][a-z0-9-]*$" },
"type": { "$ref": "#/$defs/eventType" },
"eventRole": {
"enum": ["profile-proof", "cross-profile-observation"],
"description": "playtest/3 运行时分类。当前 proof profile 事件可参与义务候选;其它已注册 profile 事件只供 Judge 观察,不能满足义务。"
},
"message": { "type": "string" },
"payload": { "type": "object" },
"payloadCanonical": {
"type": "string",
"minLength": 2,
"maxLength": 65536,
"description": "Node runner 的 stableStringify(payload) 原文payloadHash 只对这段 UTF-8 文本取 SHA-256跨语言消费者不得重序列化浮点复算。"
},
"payloadHash": { "$ref": "#/$defs/sha256" },
"producer": { "type": "string", "minLength": 1 },
"seq": { "type": "integer", "minimum": 1 },
"actionId": { "type": "string", "pattern": "^action-[1-9][0-9]*$" },
"virtualTimeMs": { "type": "integer", "minimum": 0 },
"sourceEventVersion": { "type": ["string", "null"] },
"adapterVersion": { "type": ["string", "null"] },
"sourceMessageHash": {
"anyOf": [
{ "$ref": "#/$defs/sha256" },
{ "type": "null" }
]
}
},
"patternProperties": { "^_": {} },
"additionalProperties": false,
"allOf": [
{
"if": {
"properties": { "evidenceMode": { "const": "native" } },
"required": ["evidenceMode"]
},
"then": {
"properties": {
"sourceEventVersion": { "type": "null" },
"adapterVersion": { "type": "null" },
"sourceMessageHash": { "type": "null" }
}
},
"else": {
"properties": {
"sourceEventVersion": { "const": "legacy-game-log/1" },
"adapterVersion": { "type": "string", "minLength": 1 },
"sourceMessageHash": { "$ref": "#/$defs/sha256" }
}
}
},
{
"if": {
"properties": { "type": { "const": "puzzle.swap-committed" } },
"required": ["type"]
},
"then": { "properties": { "payload": { "$ref": "#/$defs/swapCommittedPayload" } } }
},
{
"if": {
"properties": { "type": { "const": "puzzle.match-formed" } },
"required": ["type"]
},
"then": { "properties": { "payload": { "$ref": "#/$defs/matchFormedPayload" } } }
}
],
"$defs": {
"eventType": {
"type": "string",
"pattern": "^[a-z][a-z0-9-]*\\.[a-z][a-z0-9-]*$"
},
"sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"cell": {
"type": "object",
"required": ["row", "column"],
"properties": {
"row": { "type": "integer", "minimum": 1, "maximum": 12 },
"column": { "type": "integer", "minimum": 1, "maximum": 12 }
},
"additionalProperties": false
},
"pair": {
"type": "array", "minItems": 2, "maxItems": 2,
"items": { "$ref": "#/$defs/cell" }
},
"swapCommittedPayload": {
"type": "object",
"required": ["moveId", "pair", "boardRevisionBefore", "boardRevisionAfter"],
"properties": {
"moveId": { "type": "string", "minLength": 1 },
"pair": { "$ref": "#/$defs/pair" },
"boardRevisionBefore": { "type": "integer", "minimum": 0 },
"boardRevisionAfter": { "type": "integer", "minimum": 1 }
},
"additionalProperties": false
},
"matchRun": {
"type": "object",
"required": ["axis", "cells"],
"properties": {
"axis": { "enum": ["horizontal", "vertical"] },
"cells": {
"type": "array", "minItems": 3, "maxItems": 12,
"items": { "$ref": "#/$defs/cell" }
}
},
"additionalProperties": false
},
"matchFormedPayload": {
"type": "object",
"required": ["moveId", "runs", "matchedCells", "matchedCount"],
"properties": {
"moveId": { "type": "string", "minLength": 1 },
"runs": {
"type": "array", "minItems": 1, "maxItems": 8,
"items": { "$ref": "#/$defs/matchRun" }
},
"matchedCells": {
"type": "array", "minItems": 3, "maxItems": 144,
"items": { "$ref": "#/$defs/cell" }
},
"matchedCount": { "type": "integer", "minimum": 3, "maximum": 144 }
},
"additionalProperties": false
}
}
}