ゲームエフェクトデザイナーのブログ | A Real-Time VFX Artist's Blog

About Making Materials on UE, Making Tools with C#, etc

Making of TaskQuest

TaskQuest」をどんな感じで作っていったか軽くまとめておきたいと思います。

 2019.1.11 実装編も書きました!
 Making of TaskQuest<実装編> - ゲームエフェクトデザイナーのブログ (新)

 

制作の動機


これまでちょっとしたタスク管理を個人的に行う際に、メモ帳などのテキストエディタで行ったり、エクセルで行ったり、アナログな付箋紙で行ったりしていましたが、どれも不便に感じていました。

テキストエディタだと、進行中のタスクや完了したタスクのグループ分けを手作業でやるというのは非効率すぎます。。

エクセルのソートやフィルタでそのあたりは吸収できますが、以下のような不満があります。

・起動にちょっと時間がかかる
・タスク管理面では必要以上にメニュー等が多くて余分な面積を取る
 なのでウインドウサイズを小さくして画面の隅っこに置いて使うには不向き
・「完了」などタスクのステータスに応じたフィルタリングの操作がやや煩雑
  ⇒ こちらはVBAでボタン作ったりすればフォローできますね


そこで「Backlog」のようなすっきりしたルックでWindows用のスタンドアローンなツールがあればなあと思っていました(Webベースだと個人でラフに使う分には、リストのコピペなどレスポンス良くできずあまり好みでは無いので)。

C#Windowsフォームアプリを作るようになってからは、タスク管理アプリも「いつか作りたいな」といった感じで制作候補の1つになっていました。

ちなみに、ドット絵のキャラが成長する要素は最初から入れたいと思っていました。

例えば「Yahoo!知恵袋」でもスコアを稼いでグレードを上げていくようなシステムが入っていますが、こういったゲーミフィケーション的な要素は世の中の色んなものに入っていて欲しいと昔から思っていたので、タスク管理を楽しくするためにも欲しい機能だなあと。

制作開始したきっかけ


とは言え、Windowsフォームで使えるコントロール(ボタンやリストなどのGUIパーツ)を使ってどうしたら再現できるのか悩んでいました。

当時は「ListFusen」のように2カラムなスタイルにして、左側にはタスクをリスト上に並べて、クリックすると右側に詳細が表示されるような形かな~となんとなく思っていましたが、こちらでも紹介している書籍「作って覚えるVisual C# 2017 デスクトップアプリ入門」の家計簿アプリをあらためてなぞってみた際に「家計簿アプリのアレンジでいける!」と思って、具体的にアプリの中身を考え始めました。

草案みたいなもの


スマホのメモアプリに最初にざーっと必要な要件を書き出したのがこちらです(長い!)。

タスク管理アプリ「Task Quest」

◆トップ画面

今やっているタスクをトップに表示する?
→ 悪くないが頻繁にアプリにアクセス必要になる 面倒がられそう

そしてタスクリストは普段消しておき、ボタン押下ですぐリストの開閉ができるようにする?
→ 同上

また、今やってるタスク表示の横に完了ボタンを置くとなお快適に?
→ 完了ボタンをトップに置くのはありかも 但し実工数を付け忘れそう

タスクが終わったら完了にする流れはこの方が習慣付けやすいかも。
また、画面もスッキリする。

敵と戦ってるようなキャラアニメも乗せたい

アイコンは
・新規タスク追加
・選択タスクの削除
・完了にする

情報は
・タスク総数 0 / 0 (個)
・総工数 0 / 0 (日)
・Lv
・経験値 見せない方が良いかも

◆リストの挙動

タスクをダブクリで設定画面が開く
タスクの難易度に応じた敵アイコン
概要欄は文字数を制限して省略する

◆リストの表示モード

フィルタは完了以外、完了、すべて
大カテゴリでのフィルタも?

検索ありにする?
大カテゴリ、内容、ID、備考で可能?

◆設定画面

ボタンはOK、トップに表示、完了

完了時には実際の工数を入力させる?
オプションで選べると良さそう
最初に設定した工数と差分を出して見積もり精度を表示する?

◆リスト

大カテゴリ プルダウン?
内容
ID
難度 プルダウン 固定
工数
進捗 プルダウン 固定
備考

カテゴリのプルダウンはどうする?
ありの方が快適になるが、後から変更すると一気に全て変わってしまうが‥
あると登録時には快適になる
しかしカテゴリ登録の手間は増える
カテゴリ登録の画面と設定保存が必要
とりあえず無し?

設定ファイル書き換えも可能にする?

◆レベル

累計の経験値でレベルが決まる
タスク完了時にレベルアップ判定
専用のメッセージと演出を入れたい

経験値
タスク登録
・基礎10 * 難度 * 工数h
・難度倍率は 1, 2, 3
例:難易度中の8時間作業
10 * 2 * 8 = 160
・難度は含めない方が良いかも
工数は時間単位
工数は含めない方が良いかも
固定値でいくなら基礎ポイントは高め
50くらい?
タスク最初に20個登録して1000
1タスク平均3hとして1日3タスク消化
150取得、1週間750、1ヶ月3000
1年36000 タスク登録だけで

タスク変更
・ひとまず考慮しない?
・ちゃんと差分を増減させる?
・タスク完了を差し戻した場合は考慮しないといけない
何もしなくても経験値を増やせちゃう

タスク削除、未完
・ひとまず考慮しない?
・登録と同じ経験値をマイナスする?

タスク完了
・基礎30 * 難度 * 実工数
・難度倍率は 1, 2, 3
例:30 * 2 * 8 = 480
難度小1日240、中480、大720
難度中で1週間2400、1ヶ月9600
1年115200
タスク登録を足すと151200

細かくタスクを登録した方がメリット持たせるには、タスク登録は固定の経験値が良いかも
実装も計算もシンプルになる
レベルダウンも無くせる wiz..

予定より早く終わらせた場合は?
ボーナス?
見積もり精度の方が重要かも

見積もり精度も考慮させたい
見積もり精度ボーナス?
見積もり精度の計算
工数を1として実工数の割合を出す
1はボーナス * 1.2
0.8〜1.2はボーナス *1.1

全タスク完了ボーナス?
タスク沢山登録するメリット無くなる

どれくらいLvUpさせる?
1年使ってくれたら万々歳すぎる
Lv50くらい?
1年の経験値が150000としたら
単純に均等割りで1Lvに3000
対数的にする?
最初だけはサクサク上げたい
使い始めの初日、200でLv2とか
500でLv3、900でLv4、1400でLv5
タスク20個登録の難度中8hでLv5

◆レベルアップ時の演出

ファンファーレを入れたい
メッセージを入れたい
・レベル、タスク総数、総工数
・キャラステータス持たせる?
ランダム要素に上がりやすさを加える
難度(優先度)高い 力
難度(優先度)低い 素早さ
工数大きい 体力 3h〜くらい?
工数小さい 素早さ 1〜2hくらい?
コメント書いてたら 運の良さ
見積もり精度高いと 賢さ
二律背反は無いが、力と体力どちらも高い時は素早さが低い

レベルアップ時
優先度 80% 力or素早さ+1 20% 無し
工数 80% 体力or素早さ+1 20% 無し
コメント 80% 運+1 20% 無し
総合見積もり精度を出す
70%以上で賢さ+1 満たないと無し

ステータスの偏りでグラ変える?
一定条件で忍者/ロード/侍とか wiz

○下級クラス
Lv10以上
見積もり精度関係なし
最も高いステータスの割合で決まる
力 = ウォーリア
体力 = クレリック
素早さ = ローグ

○中級クラス
Lv20以上
見積もり精度関係なし
力 + 体力 = ナイト
力 + 素早さ = アーチャー
体力 + 素早さ = ビーストテイマー

○上級クラス
Lv30以上
見積もり精度が高い役職
特定の値を超えてかつ割合で決まる
見積もり精度が満たない場合は中級
賢さ + 力 = パラディン
賢さ + 体力 = ドラグーン
賢さ + 素早さ = ウォーロック
賢さ + 力 + 体力 = ○○○○
賢さ + 力 + 素早さ = ○○○○
賢さ + 体力 + 素早さ = ○○○○

○その他
Lv10以上 運が一番高い = ○○○○
Lv30以上 運が一番高い + 賢さ = ○○○○
確率的にはレアにしたい
バランス良いタスクで几帳面だとなる
可能性がある感じ

◆難度の定義

カンタン、ふつう、ムズい

カンタンは単純作業
リスト記入、報告、会議出席
バウンディングボックス設定

ふつうは普段の制作作業
テクスチャ、モデル、エフェクト

ムズいは新表現の模索、検証など
成功するか不安なもの
できた時に仲間から尊敬される作業

◆優先度


ほかの作業より先に提出する必要あり
作業の遅れが開発全体の遅れに直結


普通の作業


後回しにしてOK
または最悪やらなくて良い 努力目標

◆名前と性別の入力

必要に思う!
性別はナイーブなので扱わない?
でもあった方が良い
しかしグラフィックは倍大変

変数を用意
Strings name;
Bool male;
初めてアプリ起動時に聞く

オプション設定から変更できる

◆経験値取得とレベルアップの実装

○経験値取得処理
int exp;
只々足していき、消費やマイナス無し

・タスク追加時 50固定
exp += 50;
経験値バー更新

・タスク削除時 何も無し

・タスク完了時
モンスターを倒すグラフィック再生
優先度と工数に応じて変わる
exp += 30 * *
次にレベルアップ判定に行く

○レベルアップ処理
int lv;
こちらも只々足していく
int lvupNext = lv+ 1;
int lvupNow = lv;
int lvupNextExp =
int lvupNowExp =
必要経験値 lvupNext - lvupNow
現在経験値 exp - lvupNowExp
現在 ÷ 必要 * 100 = %

・タスク完了時
While 条件を満たさなくなるまで
次のLvUp条件を満たした
経験値バーを一旦100%にする
グラフィック表示 + SE
メッセージ
○○は Lv 00 になった!
○○が ○ あがった
LvUpしたフラグON
Break;
ジョブチェンジ判定
今は何のジョブになるか?
今と同じジョブなら終了
別のジョブなら
グラフィック表示 + SE
メッセージ
○○ は ○○ にジョブチェンジ
ジョブチェンジしたフラグON
終了判定
経験値バー更新
フラグに合わせてヒントを表示
"工数を入力すると良いことが!"
"見積もりに近いと良いことが!"
"ステータスでジョブが変わる!"
"タスクは細かく分けよう!"
フラグを全てOFF
OKボタンを表示(消しておく)

◆グラフィックデータ

下記 * 性別分

デフォルトの絵 赤ちゃん Lv1専用
冒険者見習い Lv2〜9まで
ジョブ14種類
計16種

敵の種類
優先度3 * 工数3 * バリエ3 = 27種
バリエはレベルに合わせる?

倒す演出エフェクト GIFアニメ重ねる
殴り、一閃、フラッシュ

消滅エフェクトきらきら GIFアニメ

ボタンアイコン 6種
追加、編集、検索、複製、削除、歯車

◆保存

CSVの形で保存
なのでエクスポート機能は無し

◆おまけ要素

○アプリ情報

メールアドレス
ブログ
ツイッターとアイコン
作成日とバージョン
バージョンアップボタンで対応

○デジタル証明書

プロジェクトのアセンブリ情報のプロパティで設定できる模様?

○未処理で完了

モンスターが逃げる演出とSE

○カラーチェンジ

オプションで色変え
帯の色を自由に変えられる
アイコンは中間色にする必要がある
Lv10で解放とか?

○ジョブ図鑑

オプションでレベルと経験値をリセットできるようにする

ジョブ図鑑でなったジョブが表示

基本ジョブが全て埋まると
勲章アイコンが画面に付く
全ジョブが埋まると
マスターアイコンが画面に付く

◆リリース方法

Booth
500円でどうか

GUMROAD
お値段を決めて買ってもらうサービス
簡単な1ページ説明書
おまけでメイキングPDF付ける?


ざっと見ても分かる通り、タスク管理としての機能よりもキャラ成長要素の仕様をどうするかのメモの方が多いです。楽しいですね。。

ちなみに、大体のRPGではレベルが上がるほどに必要な経験値が増えますが、タスクから得られる経験値が一定なのと、使用して月日が経つほどにレベルアップの頻度が落ちていくのは寂しいと思い、レベルが上がっていってもある程度一定のペースで上がり続けていくバランスに落とし込みました。Wizardryのようにレベル1000とか上がってもいいじゃない。

また、ジョブはネタバレになるので一部伏せていますが、元ネタとしては「Wizardry」「Tastics Ogre」「FF」あたりが混ざっています。忍者とかロードとか入れたいですよね!

それからオミットとなったアイデアも色々とあります。TaskQuestというからにはタスクも敵キャラとしてドット絵を用意して戦闘画面風の演出を入れたかったりはしましたが、「完成がかなり遠のきそうだ」と思って諦めました。。

こちらが、上記メモを書いていた時のツイートです。

 

制作開始!


まずはコントロールを配置しながら大枠のデザインを決めて、エクセルの表のような「DataGridView」というコントロールに、タスクを登録できるところまで実装しました。

会社から帰宅したら作るという感じで1週間ほどすると根幹となる機能は入りましたが、まだまだ実装を予定している機能が大量にあり、また色んな不具合や不便な要素に困っている状態でした。

 

成長要素の導入とクラス分け


1つのCSファイルにズラズラっと全ての変数や関数を書いていると可読性が下がり大変になってきたので、クラス分けの先駆けとして「ツール設定を管理するクラス」「キャラのステータスを管理するクラス」を用意して移し換えました。

実はここで初めて「プロパティ」を試しました。

プロパティという単語自体はアーティストでも色んなツールを使う上で普段から慣れ親しんでいるものですが、プログラム初心者の身からすると変数と何が違うのかよく分からない訳です。でもとりあえず使ってみようと(結局、クラス内で変数のようにしか扱っていないので変数で良かったかなという感じではありますが)。

この頃、C#を触り始めて1年半ほどでツール制作にも徐々に慣れてきてはいましたが、仕事ではコーディングしないのであくまで趣味の範疇です。まだまだ文法は知らないことばかりで初めて試すものも多く、また「構造体」「インターフェース」「デリゲート」など全く分からない状態でした。

その時の気持ちはこちら。

また設定を管理するようなクラスはアクセス修飾子をstaticにしてメモリに常駐させ、newしなくてもいつでもプロパティの中身を読み書きできるようにすると便利ということに気付いて、後から全てstaticに書き替えたりしました。

それまでクラスのアクセス周りはよく分からずに困ることが多かったのですが、例えば子となる別のフォームから親となるメインフォームを制御したい場合に、メインフォーム自身をコンストラクタの引数として渡してあげたら可能だというのも今回の制作でようやく理解した感じです。それも「多分スマートではない方法なんだろうな」と思いつつ、他に方法を知らないのでとりあえずメインフォームやそれに属するコントロールを別のフォーム生成時にコンストラクタで渡すというのを非常に多用しています。

さて、下記のような成長要素を暫定で入れましたが、このようにメッセージボックスを表示するだけなら非常に楽です。しかし、後にちゃんとデザインした独自のフォームに表示させようとした際に中身が複雑になってかなり苦労しました。

 

色々な機能を実装


必須機能として「完了以外」「完了」などのステータスに応じたフィルタリングを入れましたがここでかなり躓き、データベース・DataSet・DataTableと、それらの値を表示するDataGridViewとのやり取りの基礎的なあたりを色々調べたりしました。

また、複数セルへの一括入力や一括ペーストにも対応しました。こちらは必須だろうと。

しかしDataGridViewのイベントを取得するタイミングが色々とあるものの、それぞれのタイミングで色んな問題が噴出し、不具合に悩まされることとなります。

f:id:moko_03_25:20190110163500g:plain

キャラステータス画面やオプション画面も入りました。

こういった縦横に自由に敷き詰めるレイアウトで画面を作ると、設定項目が1つ増減するだけでレイアウトに大きく影響するのであまりよく無いですね。。

f:id:moko_03_25:20190110163604g:plain

色を選択するためのフォームを作ったり‥

f:id:moko_03_25:20190110163717g:plain

初起動時の設定画面を作ったり‥

f:id:moko_03_25:20190110164156j:plain

ジョブ図鑑を作りました。ジョブを新たに取得するごとにシルエットがオープンになる感じです。

こういったオマケ的な要素は、デザインするのは楽しいですが実装すること自体は単純なので面倒ですね。。気分転換したい時にはドット絵を修正したりしていました。

f:id:moko_03_25:20190110164237g:plain

タスク完了>レベルアップ>ジョブチェンジの演出のためのフォームを作って差し替えましたが、RPGメッセージ風にテキストを表示するために同期&非同期処理について調べたり、GIFアニメ画像を載せたりするためにコントロールのレイヤー周りについて調べたりして結構大変でした。。

結局のところ「Windowsフォームは制約が多すぎて、コントロールに重なるようにビジュアル的な演出を入れるのには向かない」という結論に達し、ここは色々と割り切りました。残念です。。

f:id:moko_03_25:20190110170949g:plain

下図は After Effects で作ったイメージ画像ですが、たったこれだけのこと(コントロールにまたがるようにGIF画像を上に載せて表示する)ができないんですよね。。

f:id:moko_03_25:20190110171616g:plain

という訳で、着手を始めて1ヶ月ほどであらかたの機能が入りました。

この後にも実行ファイルにアイコンを適用したり保存データを暗号化したり不具合を取り除いたりと、1ヶ月ほど追加でちょこちょこと作業はありましたが、大体の機能はこのあたりで入った感じです。

 

テストしてくれる方とslackでやり取り


今回は当初より「販売する」というのが1つの試みでもあったので、不具合満載の商品をリリースする訳にもいきません。そこで会社の同僚やTwitterのフォロワーさんに何人かにテストをお願いして触ってもらい、不具合報告や要望などをいただきながら開発を進めていました。

ありがたいことにTwitterですぐにお声掛けをいただき、slackで専用のプロジェクトを用意してそこでやり取りさせていただきました。

f:id:moko_03_25:20190110173033j:plain

最新の実行ファイルもどんどんアップしていけますし、とても便利でした。

分からない時にどうしたのか


大体はココナラで有料で質問して解決しています。
有料だと気兼ねなく聞けるのが良いですね!

いつもお世話になっているのはこちらの「Kazuki Takayama」さんになります。

他にも、ある不具合の原因が分からずに困っていた時 sw(@Callisto_n)さんに泣き付いて、勉強会の帰りにカフェで不具合を見つけていただいたのですが、その際にソースコードをざっと見渡して改善ポイントまで教えていただいたりしました(swさんその節はありがとうございました‥!)。

諦めたこと


一番大きいところでは、複数人でのタスク管理です。

「TaskQuest」はあくまで個人のちょっとしたタスク管理を想定しているため、お仕事で使うには正直厳しいと思っています。特に複数人で1つのプロジェクトを同時編集したいと思った場合には、恐らく以下のようなあたりの実装が必要なのかなと‥。

こちらは今の自分には厳しいと思って諦めました。

・データベースの知識
 サーバ上でリストを管理して、クライアントのアプリからアクセスする形

・アカウントを登録&管理するような仕組み
 パーミッションとかも含めた色々な設定

複数アカウントの同時編集の仕組み


こちらに関しては「Googleスプレッドシートなど元からクラウド上で複数人の編集が可能になっているサービスを利用すれば楽にできるのでは?」というアドバイスをいただいたことがあり、それならもしかしたら手軽にいけたりするんでしょうか。また機会があれば試してみたいです。

次に、スマホアプリとしてのリリースです。

こちらは「Xamarin」とか使う感じでしょうか。軽く調べた感じでは面白そうではあるのですが、今の自分にはまだまだ敷居が高そうな印象がありました。でもそのうち試してみたくはあります。

それから、アンドゥとリドゥの実装。

C#でUndo/Redoを実装した - Qiita

こちらで概念から解説されていて「これは今の自分には無理だ」と即諦めました。。

複数行の一括削除。

リストと複数セルの選択ができるのだから、複数行を一括削除もしたいものと思います。でもこれはアンドゥとリドゥが実装されている前提になると思いました。うっかりミスで複数行を削除してしまった場合に悲劇となります。。なのでこちらも同時に諦めました。

全タスクの文字列の検索・フィルタリング・置換

データベースとDataGridViewの理解が怪しいため不具合の温床になりそうで諦めました。。

 

販売してみる


今回は自分が作ったプログラムを初めて販売してみました。

世の中に非常に優秀なフリーソフトが大量にあることは勿論知っていますし、例え50円や100円のお値段設定だとしてもクレジットカード決済やコンビニ振り込み等のハードルから触ってもらえる機会が大幅に失われるだろうと思いましたし、「素人が作った不出来なものを売って良いのか?」という自問もありましたが、「どれくらいの人に買ってもらえるのだろう?」という純粋な興味が大きくありました。

目標としては40人の方にご購入いただいて2万円を売り上げることです。
そうすれば、C#関連書籍の購入とココナラの取り引きの費用などを回収できる感じです。

現在リリース10日ほどで18本売れたので、このまま40本達成できたら嬉しいなという感じです。