beautiful_soup

conda activate game-env pip install -r requirements.txt python app_pygame.py

Wasm (Web Assembly) 版のビルド方法

"combat",
"assets/data",
"system",
"utils", フォルダ内のファイルは scripts/build_wasm_bundle.py によりZIP圧縮するため、変更があればターミナルに以下のコマンドを入力 (base) PS D:\Python\beautiful_soup> cd scripts (base) PS D:\Python\beautiful_soup\scripts> python build_wasm_bundle.py Wrote Wasm bundle: D:\Python\beautiful_soup\web_wasm\python_bundle.zip (base) PS D:\Python\beautiful_soup\scripts> cd ..     (base) PS D:\Python\beautiful_soup> python wasm_app.py Wasm static server: http://127.0.0.1:8000/web_wasm/

継続して情報を保持するための方針(wasm_app.py 起点の画面横断)

単一の状態オブジェクトを source of truth にする ff3_wasm_menu_state_v1 に全画面共通で使うデータを保持し、各画面は「自分の担当フィールドだけ更新」し、未知フィールドは必ず温存(merge)してください。今回の修正はこの原則に合わせています。.

部分更新時に overwrite しない localStorage.setItem 前に既存 state を展開し、差分だけ上書きする({ …existing, changedField: … })運用に統一すると、今回のような画面間データ消失を防げます。.

保存エンベロープにも menu_state を同梱 セーブファイルに menu_state を含めることで、ロード復元時に UI 側の詳細状態(魔法セット候補など)も戻せます。.

Render deployment

If you created the Render Web Service manually (not Blueprint), set the same commands in Render dashboard:

/opt/render/project/src is Render’s repository root path, so these commands still work when Render’s working directory differs from the repo root.

main へ確実に反映する Git 手順(PowerShell)

work ブランチが存在しない環境でも使えるように、main へ直接反映する最短手順です。

  1. 最新の main を取得
    • git checkout main
    • git pull origin main
  2. requirements.txtmain にあるか確認(rg 不要)
    • git ls-tree -r --name-only HEAD | findstr /R "^requirements\.txt$"
  3. 変更をコミット
    • git add requirements.txt render.yaml README.md
    • git commit -m "Add Render deployment files and docs"
  4. main へ push
    • git push origin main
  5. push されたコミットに requirements.txt が含まれるか再確認
    • git fetch origin
    • git ls-tree -r --name-only origin/main | findstr /R "^requirements\.txt$"
  6. Render 側で確認
    • Deploy ログの Checking out commit <hash> in branch main<hash> が、 手順 4 で push したコミットと一致することを確認

work ブランチを使う場合は、先に git branch --list work で存在確認し、 存在しない場合は git switch -c work で作成してから作業してください。

Browser-only battle execution (Pyodide / Wasm)

Flask の /battle/round で行っている「JSON を受け取り、1 ラウンドを計算し、ログと結果を返す」処理は、 combat.wasm_api.WasmBattleEngine に切り出したことで、Pyodide 上でも同じ DTO 契約のまま再利用できます。

どのファイルを設け、どこを起点に実行するか

Flask 版の flask_app.py に相当する Wasm 版の起点は、次の 4 ファイル構成です。

ローカル開発時は、次の順で起動すると Flask 版に近い流れを確認しやすいです。

  1. python scripts/build_wasm_bundle.py
  2. python wasm_app.py
  3. ブラウザで http://127.0.0.1:8000/web_wasm/ を開く

この構成では、wasm_app.py はあくまで静的ファイル配信用であり、戦闘計算そのものはブラウザ内の Pyodide 上で完結します。

Save data / Slot design

JSON Schema / Validation

Python side

from combat.wasm_api import WasmBattleEngine

engine = WasmBattleEngine.create_default(seed=7)

initial_payload = engine.build_initial_payload()
result_json = engine.execute_round_json(
    '{"planned_actions": [], "lifecycle_state": "ready_for_actions"}'
)

Browser side (example)

import { loadPyodide } from "https://cdn.jsdelivr.net/pyodide/v0.28.3/full/pyodide.mjs";

const pyodide = await loadPyodide();
await pyodide.loadPackage("typing-extensions");
await pyodide.loadPackage("jsonschema");
await pyodide.runPythonAsync(`
from combat.wasm_api import WasmBattleEngine
engine = WasmBattleEngine.create_default(seed=7)

def run_battle_round_wasm(js_input_json):
    return engine.execute_round_json(js_input_json)
`);

const runRound = pyodide.globals.get("run_battle_round_wasm");
const resultJson = runRound(JSON.stringify({
  planned_actions: [],
  lifecycle_state: "ready_for_actions",
}));
const result = JSON.parse(resultJson);
console.log(result.logs);
console.log(result.session_status);

Design notes