差分

ナビゲーションに移動 検索に移動
 本ツールはTRPGシステム「ソード・ワールド2.5」を遊ぶためのWebアプリです。ユーザーは自身のキャラクターを登録し、特定の活動を行うユニットに所属させる事ができます。アプリ側はユニットに設定されている属性(活動内容や所在地、メンバーの平均レベルなど)を元にキャラクターが実行可能なイベントを提示し、その成否を記録していくことができます。
==プロジェクト全体仕様まとめ(2025/05/18時点)==
開発環境:http://localhost/index.php
===基本設計===
*TRPG(SW2.5)向けのユニット・キャラクター・イベント管理ツール
*フラットファイル(JSON)ベースでストレージ管理(DBレス)
*ユーザーアカウントごとに個別ファイルを管理(characters, units, logs, イベントなど)
*管理者アカウントは「config.php」ファイル内で設定
open_sw25/
├── public/ # 公開ディレクトリ(Webサーバーのドキュメントルート)
│ ├── index.php # フロントコントローラー
│ └── assets/ # 静的ファイル(CSS, JS, 画像など)
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── main.js
│ └── images/
├── src/ # PHPのソースコード
│ ├── Auth.php
│ ├── Character.php
│ ├── Unit.php
│ ├── Member.php
│ ├── Event.php
│ └── Log.php
├── data/ # ユーザーデータ(JSONファイル)
│ ├── users/ # 各ユーザーごとのディレクトリ
│ │ ├── users.json # ユーザ情報の管理用ファイル
│ │ ├── user_{uid}/ # ユーザごとの個別データ
│ │ │ ├── characters.json
│ │ │ ├── units.json
│ │ │ ├── user_events.json # 一般アカウント用イベントデータ
│ │ │ ├── character_log.json
│ │ │ ├── invites.json
│ │ │ └── unit_log.json
│ │ └── ...
│ ├── lists
│ │ ├── works_list.json
│ │ ├── local_list.json
│ │ └── ...
│ └── events/ # 全体公開イベントデータ
│ ├── 冒険者.json
│ └── ...
├── config/ # 設定ファイル
│ ├── function.php # その他補助用の関数格納
│ └── config.php
└── README.md # プロジェクトの説明
 
===🔐 アカウント===
各ユーザーアカウントは以下のデータを個別に保持:
===👤 キャラクター登録・管理(アカウント単位)===
項目名 内容*id(キャラクターID):一意のランダム英数字(自動生成)キャラクターID 自動生成の一意な英数字*name(キャラクター名):キャラ名(フリーテキスト)キャラクターURL キャラクターシートのURL*sheetUrl(キャラクターURL):キャラシートURL(json取得に使用)キャラクター名 フリーテキスト*description(キャラクター概要):キャラ概要(改行可)キャラクター概要 改行可能なフリーテキストタグ ソート用のフリーテキスト*tags(タグ):タグ(一覧上での並び替え等に使う)
===🛡️ ユニット登録・管理(アカウント単位)===
項目名 内容*id(ユニットID):一意のランダム英数字(自動生成)ユニットID 自動生成の一意な英数字*name(ユニット名):ユニット名ユニット名 フリーテキスト*description(ユニット概要):概要(改行可)ユニット概要 改行可能なフリーテキスト*works(ワークス):活動内容(works_list.jsonから選択)*location(所在地):**place_name(所在地:地名):地名(フリーテキスト)ワークス works_list**region(所在地:地方):地方(local_list.json から選択(ドロップダウン)jsonから選択)**scale(所在地:規模):規模(「キャンプ」「基地」「村」「町」「都市」「国」から選択)*base(拠点):**base_name(拠点名):拠点名**base_description(拠点概要):拠点概要(改行可)所在地(地名) フリーテキスト**base_cost(維持費):維持費(G単位)所在地(地方) local_list.json から選択(ドロップダウン)*skill_type(技能):"冒険者" or "一般技能"(自由入力)所在地(規模) 「キャンプ」「基地」「村」「町」「都市」「国」から選択*members(メンバー):拠点名 フリーテキスト**character_id(キャラクターID)※拠点概要 改行可能なフリーテキスト**owner_gid:キャラクター保有アカウントのgid維持費 0G以上の数値**position(役職):役職(フリーテキスト)メンバー アカウント保有キャラから選択。技能と役職も併記**level(レベル):スキルlevel(数字入力)技能 「冒険者」または「一般技能(フリーテキスト)」**status:承認状況役職 フリーテキスト*AL(平均レベル):技能の平均レベル(数字入力)AL(平均Lv) キャラクターURL + ?mode=json から技能Lvを取得して算出(切り上げ)*leader_id(リーダー):リーダーキャラID(メンバーから選択)リーダー メンバーから1人選択*creator(ユニット作成者):ユニット作成者のアカウントIDユニット作成者 アカウントID*created_at / updated_at(作成日時/更新日時):タイムスタンプユニット操作権限 アカウントID指定で追加可能作成日時 タイムスタンプ ※メンバーに選択可能なキャラクター更新日時 タイムスタンプ 自身が所有するキャラクターのみ選択可能ですが、他アカウントのキャラクターであっても「招待中」という形でメンバー候補に加えられる。招待中のキャラクターを保有しているユーザーは、該当のユニットページで「ユニットに参加する」と操作することで正式にユニットへ参加できます(その後、ユニットからは任意のタイミングで脱退できます)。
🔄 キャラクターの兼業===
キャラが複数のユニットに所属可能。選択中キャラが属する各ユニットで可能なイベントが選択可能になる。UI的には、画面上部にキャラ一覧→選択→ユニットとイベント表示、みたいな流れ。
===🎯 イベント(events/ワークス名.json)===項目名 内容====イベントデータ構造====イベントID 一意な英数字*id(イベントID)イベント名 フリーテキスト*title(イベント名)*description(イベント詳細):難易度含めたすべてのテキスト(自由記述)*min_al(min_al):必要AL*requires(前提イベント:省略可):前提イベントID(文字列 or 配列)*以下、ユニット条件でフィルタ可能なオプションキー(全部文字列 or 配列)**unit_id(自身のアカウント保有ユニットから選択)**base_name**place_name**region**scale ====フィルタロジック====*指定されたユニットの情報に対して、すべての条件を満たすイベントのみ提示*条件が存在しないものは無条件(つまり、広く使える)※ 条件に合うイベントのみ表示可能。前提イベントを駆使すればストーリー仕立てが可能になる設計。 例: { "id": "event_001", "title": "港の怪しい取引", "description": "夜の港で奇妙な荷物が…\\n依頼主は名もなき老漁師だった。", "min_al 最小AL(条件)": 3 } ===🗃️ ログの種類===*キャラクターログ(character_log.json)**所属ユニットの履歴**実行したイベントと結果**ユニット脱退・解散などの経緯 { "char_abc123": ["event_001", "event_007"] } {ユニット条件 "action": "join unit", "unit_id": "unit_abc", "timestamp": "2025-05-15T15:00:00+09:00" } { "event_id": "ev_battle_001", "unit_id": "unit_abc", "result": "success", "timestamp": "2025-05-18T15:00:00+09:00" } *ユニットログ(unit_log.json)**メンバー加入・脱退**イベント実行履歴**ユニットの更新・解散履歴 ===🖥️ UI構成と機能整理=======① メイン画面(ゲームプレイ/イベント選択)====*表示内容:**選択中キャラクター(アイコン・名前・URL)**所属ユニットの一覧(選択可)**条件に一致するイベントの一覧(前提イベントチェック、AL/拠点などの一致で絞り込み)**イベントの詳細(description)**「このイベントを実行」ボタン(ログ保存)*ユーザーができる操作:**キャラ切り替え**ユニット選択**イベント実行 → 成功/失敗などの選択肢 → ログに記録====② キャラクター管理画面====*表示内容:**自アカウント保有キャラ一覧**各キャラのステータス、所属ユニット、ログボタン**ユーザーができる操作:**キャラクター登録(URL・名前・概要・タグ)**キャラクター編集**キャラクター削除(脱退処理込み)**キャラクターログ閲覧(所属履歴、イベント履歴)====③ ユニット管理画面====*表示内容:**自アカウントが作成・管理するユニット一覧**ユニット詳細、所属キャラ、作成者、権限保持者など*ユーザーができる操作:**ユニット作成**ユニット編集(名前、ワークス、拠点、構成メンバーなど)**メンバー追加・削除**操作権限の付与(他アカウント)**ユニット削除(解散ログ記録)====④ イベント管理画面====※サイト管理者と一般ユーザーで仕様が異なる!🔒 サイト管理者(管理者フラグあり)*できること:**ユーザー全体へのイベント提供が可能 👤 一般ユーザー*できること:**自分が作成したユニット専用イベントの作成・編集**条件:そのユニット名/拠点名/所在地に限定**そのユニットに所属しているキャラのみが選択可能**自作イベントの削除・修正**自作イベントでも、他人に使わせたくないものはロック可(?) "public_scope": "global" | "unit_only"  イベント作成・編集フォーム内にチェックボックスを設置: ・表示ラベル例:「全体に公開する(管理者のみ)」 ・管理者ログイン時のみこのチェックボックスを操作可能 ・一般ユーザーにはこの項目は表示されるが「読み取り専用(disabled)」で操作不可 ====⑤ アカウント管理画面====*表示内容:**表示名**ユーザーID**パスワード変更**アカウント削除ボタン*ユーザーができる操作:**表示名・パス変更**アカウント削除(ユニットとキャラにログが残る) ===🔥 削除時の挙動定義===*アカウント削除時**保有ユニット:解散 → キャラログに「ユニット解散(アカウント削除)」記録**保有キャラ:削除 → 所属ユニットには「キャラ脱退(アカウント削除)」を記録*ユニット削除時**所属キャラのログに「ユニット解散(ユニット削除)」を記録*キャラクター削除時**所属ユニットから脱退 → ユニットログに「キャラ脱退(キャラ削除)」を記録 ===🔧 その他設定ファイル===*works_list.json:ワークス名一覧*local_list.json:地方名一覧 =テストしたAPI===①―A アカウントA登録 & cookie保存== curl -X POST http://localhost/api/user/register \ -H "Content-Type: application/json" \ -d '{"display":"ユーザA","id":"userA","pass":"passA"}' \ -c cookieA.txt ==①―B アカウントB登録== curl -X POST http://localhost/api/user/register \ -H "Content-Type: application/json" \ -d '{"display":"ユーザB","id":"userB","pass":"passB"}' \ -c cookieB.txt ==② アカウントAでログイン== curl -X POST http://localhost/api/user/login \ -H "Content-Type: application/json" \ -d '{"id":"userA","pass":"passA"}' \ -b cookieA.name、basetxt -c cookieA.name、place_name、region、scale による指定txt ==③ キャラA作成 & ユニット作成==前提イベント 成功している必要があるイベントIDリスト(任意)===キャラA=== curl -X POST http://localhost/api/char/create \ -H "Content-Type: application/json" \ -b cookieA.txt -c cookieA.txt \ -d '{"name":"キャラA","sheetUrl":"https://sheet/a","description すべての説明・難易度・演出を含むフリーテキスト":"Aのキャラ","tags":"test"}'  # 返り値の "id" を控える → 例: CHAR_A_ID
※ 条件に合うイベントのみ表示可能。ストーリー仕立てが可能になる設計。===ユニットA=== curl -X POST http://localhost/api/unit/create \ -H "Content-Type: application/json" \ -b cookieA.txt -c cookieA.txt \ -d '{"name":"ユニットA","description":"テストユニット"}'
🗃️ ログの種類キャラクターログ(character_log.json)所属ユニットの履歴 # 返り値の "id" を控える → 例: UNIT_ID
実行したイベントと結果==④ アカウントBでログイン & キャラB作成== curl -X POST http://localhost/api/user/login \ -H "Content-Type: application/json" \ -d '{"id":"userB","pass":"passB"}' \ -b cookieB.txt -c cookieB.txt
ユニット脱退・解散などの経緯 curl -X POST http://localhost/api/char/create \ -H "Content-Type: application/json" \ -b cookieB.txt -c cookieB.txt \ -d '{"name":"キャラB","sheetUrl":"https://sheet/b","description":"Bのキャラ","tags":"test"}'
ユニットログ(unit_log.json)メンバー加入・脱退 # 返り値 "id" → CHAR_B_ID
イベント実行履歴==⑤ アカウントAでユニットに自キャラA即時追加==(招待を経由しないパターン確認) curl -X POST http://localhost/api/member/invite \ -H "Content-Type: application/json" \ -b cookieA.txt -c cookieA.txt \ -d '{"unitOwnerGid":"9139e4d21e497f51", "unitId":"1890fa5d", "charOwnerGid":"9139e4d21e497f51", "charId":"b944034b"}'
ユニットの更新・解散履歴==⑥ アカウントA → アカウントB キャラBを招待== curl -X POST http://localhost/api/member/invite \ -H "Content-Type: application/json" \ -b cookieA.txt -c cookieA.txt \ -d '{"unitOwnerGid":"9139e4d21e497f51", "unitId":"1890fa5d", "charOwnerGid":"2f11472dba7fc9a7", "charId":"f2de295c"}'
🔥 削除時の挙動定義==⑦ アカウントBで招待承認==アカウント削除時 curl -X GET http://localhost/api/member/invites \保有ユニット:解散 → キャラログに「ユニット解散(アカウント削除)」記録 -b cookieB.txt
保有キャラ:削除 → 所属ユニットには「キャラ脱退(アカウント削除)」を記録 curl -X POST http://localhost/api/member/accept \ -H "Content-Type: application/json" \ -b cookieB.txt -c cookieB.txt \ -d '{"unitOwnerGid":"9139e4d21e497f51", "unitId":"1890fa5d", "charOwnerGid":"2f11472dba7fc9a7", "charId":"f2de295c"}'
ユニット削除時==⑧ 最終確認:ユニット詳細 & キャラ所属確認==所属キャラのログに「ユニット解散(ユニット削除)」を記録===ユニットAには2キャラ入ってAL計算されている?=== curl -X GET "http://localhost/api/unit/detail?gid=9139e4d21e497f51&unitId=1890fa5d" -b cookieB.txt -c cookieB.txt
キャラクター削除時===キャラBに unit_memberships が反映されている?===所属ユニットから脱退 → ユニットログに「キャラ脱退(キャラ削除)」を記録 curl -X GET "http://localhost/api/character/detail?gid=2f11472dba7fc9a7&charId=f2de295c" -b cookieB.txt -c cookieB.txt
🔧 その他設定ファイル==今後ためす==works_list curl -X POST http://localhost/api/unit/delete \ -H "Content-Type: application/json" \ -b cookie.json:ワークス名一覧txt \ -d '{ "id": "ユニットID" }'
local_list curl -X POST http://localhost/api/user/delete -b cookie.json:地方名一覧txt -c cookie.txt

案内メニュー