# メイドハッカソン大概念 ## 大概念 - 無駄に捻くれた恋愛ゲーム - 真夏の夜の〇〇でデート with メイド - 海辺 - 花火 - 2つを選ぶ(シナリオ) - 夜景の綺麗な福岡の街並(同時接続数が20になったらサジェストされる隠し要素) - 上にポップアップで表示される - やること - メイドとデート(シナリオに沿う) - メイドとのコミュニケーション(シナリオ関係無しにメイドにメッセージを常時爆撃出来る) - ユーザーの心を揺さぶる演出 - メイドの好感度が上がるとテクスチャの解像度が落ちる - セリフは優しくなる - メイドとの好感度が下がると解像度が上がる - セリフは辛辣になる ## maid hackathon APIの仕様 ### ホストURL https://stego-chan.yukinissie.com ### 1. シナリオリストの取得 #### URI ``` /api/scenario-info ``` #### クエリ key|value|example ---|---|--- scenarioId|string|scenario_1 #### example ``` /api/scenario-info?scenarioId=scenario_1 ``` #### Response ```json= // GET /api/scenario-info?scenarioId=scenario_1 { "data": [ { "id": "scene_1_1", "name": "hoge", "next_scene": "selection", "first": true }, { "id": "scene_1_2", "name": "hoge", "next_scene": "準備中", "first": false }, . . . { "id": "scene_1_11", "name": "hoge", "next_scene": "準備中", "first": false } ], "message": "ok" } ``` ### 2. シーンオブジェクトの取得 #### URI ``` /api/scene ``` #### クエリ key|value|example ---|---|--- sceneId|string|scene_1_1 value|number|-2121212 #### example ``` /api/scene?sceneId=scene_3_11&value=-211132 ``` #### Response ##### example1 ```json= // GET /api/scene?sceneId=scene_1_1&value=832028 { "data": { "id": "dialogue_1_1", "serifs": [ { "type": "normal", "id": "1_1_1", "serif": [ "example", "example" ] }, { "type": "normal", "id": "1_1_2", "serif": [ "example2", "example2" ] }, { "type": "select", "id": "1_1_3", "serif": [ "どちらにする?" // selectの場合でも配列で管理 ], "selects": [ { "message": "example3", "id": "scene_1_2", "value": 10 }, { "message": "example3", "id": "scene_1_3", "value": -114514 } ] } ] }, "message": "ok" } ``` ##### example2 ```json= // GET /api/scene?sceneId=scene_3_11&value=-2112 { "data": { "id": "dialogue_3_11", "serifs": [ { "type": "normal", "id": "3_11_1", "serif": [ "example", "example" ] }, { "type": "normal", "id": "3_11_2", "serif": [ "example2", "example2" ] } ] }, "message": "ok" } ``` ## 仕様 - シーンオブジェクト - シナリオオブジェクト ### 基本の流れ シナリオ(花火、海辺などを選択) -> 対応するシナリオオブジェクトを一括取得 -> 各シナリオオブジェクトにあるIDからセリフDBにアクセスしてシーンに対応したセリフデータを取得する。好感度はサーバー内部で計算を行うのでフロントは関係ない。好感度=constantでとりあえず実装して、その後動的に変える! 注意:この下は全てREST APIで提供します。 ```json //シナリオオブジェクト //花火、海辺、福岡の夜の街並みを選ぶ時に必要な概念 { "id":"一意のシナリオID", "name":"シナリオの名前。最初シナリオを選択するときに表示すると良き", } //シーンオブジェクト //博多駅のシーン(scenario_id=hoge,scene_num=0)・・・今日どこ行こう?そうだ、天神に行こう //天神に到着(scenario_id=hoge,scene_num=1)・・・天神に到着! { "id":"シーンに割り当てる一意のID。シナリオに関するデータは大体こいつをロードすれば良い", "scenario_id":"親のシナリオID", "scene_num":"自身のシーンの順番(0から始まる)。要らない気もする。" } ``` セリフオブジェクトはJSON配列で返ってくる。DBにシナリオIDを条件に検索する。これはシーケンシャルなデータで配列の順に表示されれば良い。遅延取得などには対応しない予定。なお、分岐が発生する場合は以後は別シーンになるので注意。 セリフオブジェクトにはいくつかのtypeがある。これらのタイプをJSON形式で示し解説する。 scene_idからセリフデータを取ってくるとき ```json { "id":"hogehoge", "scene_id":"piyopiyo", //入ってる順番に先頭から呼んでいけばおk! "serifs":[ { "type":"基本のセリフか選択肢オブジェクトかを示すtypeが書かれている。" "id":"一意に割り当てるID", "scene_id":"シーンID", "serif":[ "今日は何処に行こう?", "そうだ、天神駅に行こう(唐突)", .... ], }, { "type":"基本のセリフか選択肢オブジェクトかを示すtypeが書かれている。" "id":"一意に割り当てるID", "scene_id":"シーンID", "serif":[ "今日は何処に行こう?", "そうだ、天神駅に行こう(唐突)", .... ], }, { "type": "select", "serif":"今日どこ行く?", "selects":[ { "message":"海", "id":"ジャンプ先のシーンID" }, { "message":"山", "id":"ジャンプ先のシーンID" }, ], },.... ] } ``` ```json //各タイプ共通要素 //normal,selectが文字列で格納されています { "id":"一意に割り当てるID", "scene_id":"シーンID", } //基本のセリフオブジェクト { "type":"基本のセリフか選択肢オブジェクトかを示すtypeが書かれている。" "id":"一意に割り当てるID", "scene_id":"シーンID", "serif":[ "今日は何処に行こう?", "そうだ、天神駅に行こう(唐突)", .... ], } //画像付きセリフ //画像付きメッセージの表示は画像を中央に表示すれば良い。相手が隠れても問題ない。画像の表示期限は次のセリフに移るまでである。 { "image_serif":[ { "serif":"hogehoge:こちらは配列ではなくただのstringであることが保証されている", "url":"画像の保存リンク" },.. ] } //選択肢オブジェクト //選択肢はボタンなどを利用することを想定している。 //ボタンにメッセージを表示して押すと新しいシーンが決定するのでそのシーンのオブジェクトを取得していく。 { "type": "select", "serif":"今日どこ行く?", "selects":[ { "message":"海", "id":"ジャンプ先のシーンID" }, { "message":"山", "id":"ジャンプ先のシーンID" }, ], } ``` ### WebSocket通信で双方向通信で行われるやりとり **随時アクションオブジェクトの仕様を示します。** - こちらからのメッセージ送信(常時) - メイドに常時メッセージを送るとセリフ枠とは別に吹き出しか何かで簡単なレスを行う(インタラクティブなアプリになる) ```json //メッセージを投げる時 { "action":"SEND_MESSAGE", "message":"message", "user_id":"user_id", //nullでも良い(バックエンドだけで対応出来る) } //メイドからメッセージがやってくる時 { "action":"MAID_MESSAGE", "message":"message", //ダイアログとかポップアップでよしなに表示 } ``` - メイドのグラフィックレベル(グラフィックレベルを元に画像をスケールダウン) ```json { "action":"NOTIFY_MAID_LEVEL", "level":1 //0~10で、数字が大きいほどグラフィックの品質が向上する } ``` - 現在のユーザーの接続数 ```json { "action":"CONNECTION_COUNT", "num":100, } ``` ## フロントエンド - フロントエンド - スタート画面 - シナリオ選択画面 - シーン画面 - 選択パターン - セリフが出てくるパターン - メイドとテキストフォームとメイドのメッセージが流れる ## バックエンド班向けもう少し細かい仕様 **ゴールは上のフロントと合わせた仕様のデータを作成すること。そのデータを生成するロジックを複雑にしていくことでゲーム感を出していく。** ### 内部で持つパラメーター - 好感度(Userと1対1で紐付いたもの)、以後ユーザー好感度とする - 好感度累積値(重み付けされたやつ、好感度が低い方が重みが高くなる)、以後は単に好感度と表現する。 シーンについて補足: シナリオ:花火、シーン:1,2,3が存在すると仮定。 シーン1について、内部的にはnつのシナリオデータを用意する。これはユーザー好感度に影響される。 ユーザーからシーンの取得が来たときには - 外部シーンID(上の仕様で書いたシーンID)と好感度からnつのラベルにマッピングしたキーを合わせて検索を行う - 該当オブジェクトを返却する。 つまり、外から見えるシーン1について内部的にはnつのシーンデータが存在することになる。これをどれだけ作るかはシナリオライターのキャパシティーにかかっている。 ## バックエンドの実装 - WebSocket通信機構の実装 - 各種ステータス観測・送信 - リアルタイムチャット - REST API(シナリオデータの取得周り) - テストデータを返す - DB繋ぎ込み - 好感度に応じたシナリオ選択ロジック ## バックエンドの開発スケジュール 来週の水曜日程度を目標に上にあるシナリオを返すなどのAPIを一通り作成してテストオブジェクトを仕込む部分まで実装する。 その後、内部ロジックとリアルタイムコミュニケーション機構の準備を行う。 --- **ここより下は前回の覚書。気にしない** - 干渉される要素 - 好感度 - 0~100の値にする - セリフの質が変わる(10刻みでクオリティが変わっていく) - メイドの画像が粗くなる - メイドをコンポーネント化して上塗り - セリフ - API化します - ツリー構造的に定義 - 各要素毎にキーを決めて - 自然言語処理でよしなに出来ないか? - 難しい - 出来るか分からない - けど、出来れば楽 - セリフはデータ仕様を決める - 目的:フロントとセリフ職人の依存関係を無くす - 大概念 - 基本はJSON配列 - 各オブジェクトにはtypeとテキストとその他必要に応じてオブジェクトが設定されている - text:テキストデータだけ - select:テキスト+selectオブジェクト配列がある - selectオブジェクトは{選択肢、テキスト、ID(API叩く時に渡すやつ)} - 画像付きテキスト - 好感度の計算 - 一端保留にしましょう - フロント・バックエンド版・設計・セリフ職人 - バックエンド(WebSocket) - セリフ - ユーザーとのコネクション ### 仕様 - 干渉される要素 - 好感度 - 0~100の値にする - セリフの質が変わる(10刻みでクオリティが変わっていく) - - メイドの画像が粗くなる - メイドをコンポーネント化して上塗り - セリフ - 5つのストーリー毎にシナリオを作成 - フローチャート的にインタラクティブ要素を取り入れながらやる - ツリー構造的に定義 - 各要素毎にキーを決めて - 自然言語処理でよしなに出来ないか? - 難しい - 出来るか分からない - けど、出来れば楽 - セリフはデータ仕様を決める - 目的:フロントとセリフ職人の依存関係を無くす - 大概念 - 基本はJSON配列 - 各オブジェクトにはtypeとテキストとその他必要に応じてオブジェクトが設定されている - text:テキストデータだけ - select:テキスト+selectオブジェクト配列がある - selectオブジェクトは{選択肢、テキスト、ID(API叩く時に渡すやつ)} - 画像付きテキスト - 好感度の計算 - 一端保留にしましょう - フロント・バックエンド版・設計・セリフ職人 - バックエンド(WebSocket) - セリフ - ユーザーとのコネクション - フロントエンド - スタート画面 - チャット画面 - メイドとテキストフォームとメイドのメッセージが流れる - 選択画面 - 背景描画 - 現在のユーザーの接続数