# メイドハッカソン大概念
## 大概念
- 無駄に捻くれた恋愛ゲーム
- 真夏の夜の〇〇でデート 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)
- セリフ
- ユーザーとのコネクション
- フロントエンド
- スタート画面
- チャット画面
- メイドとテキストフォームとメイドのメッセージが流れる
- 選択画面
- 背景描画
- 現在のユーザーの接続数