init: 剧情事件协作 Web 编辑器独立仓(从 SGame/tools/event_authoring 拆出)

This commit is contained in:
bia
2026-06-08 16:50:27 +08:00
commit f5669dc01d
32 changed files with 3497 additions and 0 deletions

93
ir_compile.py Normal file
View File

@ -0,0 +1,93 @@
# -*- coding: utf-8 -*-
"""Story IR -> 可注入的 GameEventData 配置编译器 + 校验器CLI 壳)。
用法:
python ir_compile.py samples/yuye_koumen.ir.json
python ir_compile.py samples/yuye_koumen.ir.json -o out.events.json
python ir_compile.py samples/yuye_koumen.ir.json --deploy [--qiyu] [--strict-points]
校验/编译/词典内核在 ir_core 包(与 M5 Web 后端共用)。本文件只做参数解析、
文件读写、报告打印、部署拷贝。校验不过则报错退出、不产出任何配置。
points/movePoint/camp2Fighters 里的 slot(P1/NP1) 是点位名,坐标存同名
{group}.points.jsonM1 点位集),运行时直接读;编译器只校验点位名存在。
"""
import argparse
import json
import os
import shutil
import sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import ir_core
def main():
ap = argparse.ArgumentParser()
ap.add_argument("ir")
ap.add_argument("-o", "--out")
ap.add_argument("--deploy", action="store_true",
help="编译后部署到 Assets/StreamingAssets/Story/Config/{group}.events.json")
ap.add_argument("--qiyu", action="store_true", help="配合 --deploy部署到 Qiyu/ 子目录")
ap.add_argument("--strict-points", action="store_true",
help="点位集文件缺失也视为错(部署前严格门)")
args = ap.parse_args()
with open(args.ir, encoding="utf-8") as f:
ir = json.load(f)
dic = ir_core.load_dictionary()
errs, warns = ir_core.validate(ir, dic, strict_points=args.strict_points)
for w in warns:
print("[警告] " + w)
if errs:
print("[校验失败] 共 %d 项,未产出配置:" % len(errs))
for e in errs:
print(" - " + e)
sys.exit(1)
try:
rows = ir_core.compile_ir(ir, dic)
except ir_core.CompileError as e:
print("[编译错误] %s" % e)
sys.exit(1)
base = args.ir
for ext in (".json", ".ir"):
if base.endswith(ext):
base = base[: -len(ext)]
out = args.out or base + ".events.json"
with open(out, "w", encoding="utf-8") as f:
json.dump(rows, f, ensure_ascii=False, indent=2)
print("[校验通过]")
print("[编译完成] %s -> %s" % (args.ir, out))
print(" group=%s%d" % (ir["id"], len(rows)))
stage = ir.get("stage", {})
print(" 舞台: %s 点位集: %s" % (stage.get("type", "?"),
stage.get("point_set") or ir["id"]))
print(" 角色->点位(原型,真实坐标见点位集):")
for r in ir.get("roles", []):
print(" %-4s = %s %s" % (r["slot"], r["name"], r.get("archetype", "")))
texts = ir_core.extract_texts(ir)
i18n_out = base + ".i18n.tsv"
with open(i18n_out, "w", encoding="utf-8") as f:
f.write("# 简体中文(key,勿改)\t韩文(待译繁体无需填SGameText 自动转换)\n")
for t in texts:
f.write(t + "\t\n")
print("[i18n] 抽取 %d 条可见文本 -> %s" % (len(texts), i18n_out))
print(" 简繁自动覆盖;韩文翻译填好后合并进 Assets/StreamingAssets/i18n/ko.tsv")
if args.deploy:
proj = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sub = "Qiyu" if args.qiyu else ""
dst_dir = os.path.join(proj, "Assets", "StreamingAssets", "Story", "Config", sub)
os.makedirs(dst_dir, exist_ok=True)
dst = os.path.join(dst_dir, ir["id"] + ".events.json")
shutil.copy(out, dst)
print("[部署] -> %s" % dst)
if __name__ == "__main__":
main()