1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【初投稿テスト】非同期ネットゲーム作ってみた

Last updated at Posted at 2019-03-07

非同期ネットゲーム仕様書

はじめに

本書は、RPGアツマールで開催される非同期ネットゲームコンテスト(2019年3月3日(日)23:59〆切)に向けて作成するゲームの仕様を書いた物である。

  • マークダウン記法で記述するテキストデータである。
  • UML部分はPlantUMLを使用する。

マークダウン記法

本書で使用するマークダウン記法について、使い方と書き方を以下に記述する。

使い方

書き方

マークダウン記法では、文章内の改行は無視される。
画面の右端で自動改行される。
明示的に改行させたい時は行末に空白2つを付ける。
このようになります。
ですよ。

  • ハイフン+スペース「- 」を行頭に付けると、箇条書きになる。
  • 行頭に「●」が付く。
    • 行頭にスペース2個を付けると、インデントも可能。
  • 本書では要件や仕様に関する記述は、基本的に箇条書きで記述している。
  1. 連番による箇条書きは、番号+スペースを行頭に付ける。
    1. 番号は「1. 」だけでも自動採番される
    2. だから、「1. 」の方が変更に強い
  2. 改行が必要な時は、このように
    行末にスペース2個を付ける。
  3. 番号の場合はスペース4個でインデントする。
  4. 本書では処理の順序を表したい場合に使用する。

【注意】
箇条書きや引用などの文章の塊がある場合、その塊の種類が変わる所で空白行を入れる。

「> 」は引用です。
引用する時に開始行の先頭に使います。
このように表示されます。

表は以下のように記述する。

|A|ヘッダ|てすと|項目名|
|---|:---:|---|---|
|AAA|B|テスト|表の内容|
|Aの内容2|センタリング|C|表の内容2|
|Aの内容03|表はこのように書く|Test|D|

この記述により、以下のように表示される。

A ヘッダ てすと 項目名
AAA B テスト 表の内容
Aの内容2 センタリング C 表の内容2
Aの内容03 表はこのように書く Test D
バッククォート3個「```」を開始行、終了行に書いて囲った
  この範囲は
自由に空白や改行できる。

開始側のバッククォート3個「```」の後に、テキストデータの形式を記述する。
この例では「```text」としているが、
「```javascript」「```plantuml」と書くと、その言語として表示される。

そのため
  ソースコードを
    書くのに最適。

本書で使いそうなマークダウン記法の書き方は以上。
なお、下の横線は「***」と記述する。


ゲーム情報 (概要)

ゲームの目的

  • 花を育てる。
    • 当初予定では、「いちご狩り」をするゲームであったが、いちごの素材がないため断念した。
  • 花をプレゼントして好感度を上げる。
  • キャラクターの人気投票をする。

ゲームタイトル

  • 『花摘み【パケキャラ総選挙】』を仮タイトルとする。
    • 「花摘み」は品がないがインパクトはあると思われるので、仮タイトルとする。
  • 最終的に、タイトルは『PKG16 総選挙』とした。

ゲームの流れ (基本設計)

概要

  • 放置系ゲームの要領で花を育て、花をパケキャラにプレゼントし、プレゼントの量でパケキャラの人気を競う。
  • 「パケキャラ」とは、RPGツクールMVの「パッケージキャラクター」の事である。本ゲームではNPCである。
  • 他人が育てた花を取る事が出来る。
  • パケキャラごとに好感度ランキングを用意する。

花を育てる

放置系ゲーム要素は以下の流れとする。

  1. 種を植える(プレイヤー操作)。
  2. 種が草に育つ(放置)。
  3. 草が花に育つ(放置)。
  4. 花が実になる(放置)。
  5. 実が種になる(放置)。
  6. 種が草に育つ(放置)。繰り返し。
  • 花壇は全プレイヤー共通の領域とする。
  • 花壇の数はプレイヤーの数に応じて増やす。
    • 自動でマップの拡張できる?
      しかし、1プレイヤーに1マップなどにするとマップ数が増えると困るので、自動で増やすのはやめた方が良さそう。
    • 花壇の数は何らかのタイミングで作者が手動で増やす。(増やせるように作る事)
  • 花の成長状況を花の上に表示させたい。「あと何秒で次の状態になるか」を表示する。

花を摘む

  • プレイヤーは、「花」または「実」を採取する事が出来る。
  • 「花」と「実」以外は採取できない。
  • 花壇は共通領域なので、他のプレイヤーが育てた「花」や「実」を採取する事が出来る。
  • 花を摘んだ花壇は「空き」になる。プレイヤーが種を植えるまで「空き」になる。

花をプレゼントする。

  • プレイヤーはパケキャラに「花」または「実」をプレゼントする事が出来る。
  • プレイヤーがプレゼントする事で、「好感度」と「種」と「所持金」を得る事が出来る
    (このゲームに公職選挙法のようなものは無い)。
  • プレイヤーがプレゼントする事で、パケキャラの人気ポイントが上昇する。

種の入手

  • プレイヤーはゲーム開始時に「種」をいくつか持っている。
  • プレイヤーがパケキャラにプレゼントした時に、「種」と「所持金」をもらえる。
    • 「実」をプレゼントした時に、その「種」をもらえると面白いかも。
      出所がはっきりしているので。
  • プレイヤーは所持金を使用して「種」を買う事が出来る。

プレイヤーのデータ

  • アイテム(植える前の「種」、採取した「花」または「実」)
    • 「種」と「花」&「実」でアイテム種別を分ける。
  • プレイヤーの実績を表す何か。
    • 実績アイテム(大事なもの)
  • 経験値(レベル)
  • 所持金
  • 好感度(パケキャラそれぞれなので、16人分)
    • ステータス画面を使うのと、アイテムの個数で表現するの、どっちが楽?
    • 変数を16個用意して、ステータス画面でその変数を表示する?

アツマールAPIを使う場面

  • 花壇はプレイヤー共有なので、何らかのAPIを使用する。
    • 使うAPIは、グローバルシグナルになりそう。
    • 花の成長はプレイヤーごとに行い、採取した時にシグナルを送る。
    • 採取シグナルを受け取ると、その花壇は「空き」になる。
    • タイミングによっては、同じ花壇で複数プレイヤーが同時に採取できるが、許容する。
    • APIの通信は『5秒に1回よりも緩やかにすること』との事なので、採取シグナル送受信のタイミングで、何らかの演出を行い、時間を稼ぐ。
  • ランキング機能を使う。
    • パケキャラごとの好感度をランキングにする。
    • パケキャラ総選挙の順位はランキング機能を使わない。プレイヤーのランキングではないので。
  • 総選挙の順位に、グローバルサーバー変数を使用する。
    • 1キャラにつき1変数を使用すると、16個のグローバルサーバー変数が必要になる。
    • グローバルサーバー変数では、トリガーを使用して値の変更を行う。

パケキャラ

  • RPGツクールMVのパッケージキャラ16体を使う。
  • マップに表示する。
  • プレゼントを渡す事が出来る。プレゼントは総選挙の票(人気ポイント)を兼ねている。
    • プレゼントは「花」または「実」である。
    • アイテム選択の処理でプレゼントを渡す。
  • 好きな「花」「実」があり、それによってプレゼント時の好感度に差がある。
  • 好きな「花」「実」の説明と、プレゼントを渡す場所は分けておく。
    • 好きな「花」「実」の説明はすぐに見れる場所に置く。
    • プレゼントを渡す場所は、パケキャラごとにマップを用意する。
    • プレゼントを渡してお礼を受け取ると、ランキングAPIの通信を行う。そのため、(プレゼントは1アイテムずつ選択するが)プレゼントに対してのお礼はまとめて受け取るのが良さそう。そのマップを出る時でもイイかも。

メモ

  • メッセージWindowに歩行キャラを表示させたい。名前だけでパケキャラを識別するのが難しいと思われるため。
    • アイコン化(32×32)するか、プラグインを用意するか。
    • IconSet.pngを下に拡張できるので、アイコン化するのが良さそう。

詳細設計

  • 詳細設計の代わりに、JavaScriptのソースコードを記述する。

Promise全般

// promise() を使いたい場合
// thenはPromise受信時に実行される
// catchはエラー発生時に実行される
// ドット「.」区切りで連続して記述する
// 1行で書くとこのようになっている
promise().then(function(a){ 非同期処理 }).catch(function(b){ エラー処理 });

グローバルシグナル送信

window.RPGAtsumaru.experimental.signal.sendSignalToGlobal(data)
// catchはエラー発生時に実行される
// 引数errを受け取る
.catch(function(err){
    switch(err.code) {
    case "UNAUTHORIZED":
        // プレイヤーがログインしていない
        console.log('send error : UNAUTHORIZED');
        break;
    case "BAD_REQUEST":
        // ゲーム側で何か間違えているとき=指定したボードIDが大きすぎるかマイナスの場合などに発生
        console.log('send error : BAD_REQUEST');
        break;
    case "INTERNAL_SERVER_ERROR":
        // サーバー側で何らかの問題=通信不良やメンテ等で発生
        console.log('send error : INTERNAL_SERVER_ERROR');
        break;
    case "API_CALL_LIMIT_EXCEEDED":
        // 短時間にゲームAPIを利用しすぎて、一時的に利用を制限されている
        console.log('send error : API_CALL_LIMIT_EXCEEDED');
        break;
    }
});

グローバルシグナル受信

window.RPGAtsumaru.experimental.signal.getGlobalSignals()
// thenはPromise受信時に実行される
// Promiseの内容を引数vとして受け取る
// 非同期処理なので、いつ受信するかは分からない事に注意!
.then(function(v){
    KRD_checkSignal(v); // 別関数で処理する
})
// catchはエラー発生時に実行される
// 引数errを受け取る
.catch(function(err){
    switch(err.code) {
    case "INTERNAL_SERVER_ERROR":
        // サーバー側で何らかの問題=通信不良やメンテ等で発生
        console.log('get error : INTERNAL_SERVER_ERROR');
        break;
    case "API_CALL_LIMIT_EXCEEDED":
        // 短時間にゲームAPIを利用しすぎて、一時的に利用を制限されている
        console.log('get error : API_CALL_LIMIT_EXCEEDED');
        break;
    }
});

データフロー

plantuml_2019-03-07T22-01-19.png

plantuml_2019-03-07T22-43-33.png

plantuml_2019-03-07T22-43-54.png

plantuml_2019-03-07T22-44-13.png

plantuml_2019-03-07T22-44-26.png

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?