Add prototype gameplay loop with character/battlefield assets and server game APIs.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
"""Generate battlefield concept boards with the project image generation flow.
|
||||
|
||||
This script delegates image creation to ``Tools/gpt_image_generate.py`` with
|
||||
the project-standard ``gpt-image-2.5`` model. It deliberately does not draw
|
||||
placeholder diagrams with PIL. Use ``--dry-run`` to inspect requests without
|
||||
calling the remote service.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
OUT = ROOT / "Doc/Design/Scene/Battlefield"
|
||||
PROMPT_FILE = OUT / "battlefield_design_prompts.json"
|
||||
IMAGE_TOOL = ROOT / "Tools/gpt_image_generate.py"
|
||||
|
||||
|
||||
def load_prompts() -> dict:
|
||||
return json.loads(PROMPT_FILE.read_text(encoding="utf-8-sig"))
|
||||
|
||||
|
||||
def mark_generated(design_id: str, output: Path, status_file: Path) -> None:
|
||||
manifest_path = OUT / "battlefield_scene_manifest.json"
|
||||
if not manifest_path.is_file():
|
||||
return
|
||||
manifest = json.loads(manifest_path.read_text(encoding="utf-8-sig"))
|
||||
for option in manifest.get("designOptions", []):
|
||||
if option.get("id") == design_id:
|
||||
option.setdefault("generation", {}).update(
|
||||
{
|
||||
"tool": "Tools/gpt_image_generate.py",
|
||||
"model": "gpt-image-2.5",
|
||||
"status": "generated",
|
||||
"output": str(output.relative_to(ROOT)).replace("\\", "/"),
|
||||
"statusFile": str(status_file.relative_to(ROOT)).replace("\\", "/"),
|
||||
"generatedAtUtc": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
|
||||
}
|
||||
)
|
||||
if manifest.get("requestedDesign") == design_id:
|
||||
manifest["selectedDesign"] = design_id
|
||||
manifest.setdefault("designGeneration", {}).update(
|
||||
{
|
||||
"tool": "Tools/generate_battlefield_designs.py",
|
||||
"imageTool": "Tools/gpt_image_generate.py",
|
||||
"model": "gpt-image-2.5",
|
||||
"status": "generated",
|
||||
"generatedAtUtc": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
|
||||
"note": "已生成并覆盖总览图。",
|
||||
}
|
||||
)
|
||||
manifest_path.write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Use gpt-image-2.5 to generate the three battlefield design boards."
|
||||
)
|
||||
parser.add_argument("--design", choices=["A", "B", "C", "all"], default="all")
|
||||
parser.add_argument("--dry-run", action="store_true", help="print requests without calling the image API")
|
||||
parser.add_argument("--quality", default="auto", choices=["auto", "low", "medium", "high"])
|
||||
args = parser.parse_args()
|
||||
|
||||
data = load_prompts()
|
||||
selected = data["designs"] if args.design == "all" else [next(x for x in data["designs"] if x["id"] == args.design)]
|
||||
OUT.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for item in selected:
|
||||
output = OUT / item["file"]
|
||||
callback = OUT / f"{output.stem}_gpt_image_status.json"
|
||||
command = [
|
||||
sys.executable,
|
||||
str(IMAGE_TOOL),
|
||||
"--prompt",
|
||||
item["prompt"],
|
||||
"--model",
|
||||
"gpt-image-2.5",
|
||||
"--aspect-ratio",
|
||||
"1024x1024",
|
||||
"--quality",
|
||||
args.quality,
|
||||
"--output",
|
||||
str(output),
|
||||
"--callback-file",
|
||||
str(callback),
|
||||
"--result-only",
|
||||
]
|
||||
print(f"[{item['id']}] {item['name']}")
|
||||
print(" ".join(json.dumps(part, ensure_ascii=False) for part in command))
|
||||
if args.dry_run:
|
||||
continue
|
||||
try:
|
||||
subprocess.run(command, cwd=ROOT, check=True)
|
||||
except subprocess.CalledProcessError as exc:
|
||||
print(
|
||||
"image generation failed; configure GRSAI_API_KEY or "
|
||||
"GPT_IMAGE_API_KEY and rerun this command",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return exc.returncode or 1
|
||||
mark_generated(item["id"], output, callback)
|
||||
print(f"saved: {output}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user