DebtCraft は「国の借金を返す」がテーマのサーバーだけど、開国して数日たつと「ダイヤを掘って納める」以外にやることが少ない、という声が出てきた。そこで、経済まわりの機能を8つまとめて足した。
足したもの
| 機能 | 中身 |
|---|---|
| 相場の変動 | 同じ品がたくさん納められると値下がりし、数日かけて戻る |
| 景気イベント | 週末は好景気(返済も売却も1.2倍)。平日は抽選で好景気か不況 |
| 実績と称号 | 「7日連続ログイン」「1回でダイヤ64個分返済」などで称号がもらえる |
| 全員目標 | 国民の返済の累計が100兆円に届くたびに、返した全員に報酬 |
| 国債 | お金を預けると7日で5%増えて戻る |
| 公共事業 | 建築の材料を全員で納め、完成したら報酬 |
| 取引所 | プレイヤー同士で売買。手数料5%は国庫に入って借金が減る |
| 税務調査 | 毎晩だれか1人の家に「調査官」が来る演出 |
作り方:仕様書を書いて1つずつ
プラグインは Java(Paper)で、書いている。今回は量が多いので、先に仕様書(FEATURES.md)と DB の変更(SQL)を書き、「9-1 から順に、1つ作るごとにテスト鯖で確かめてから次へ」と決めた。
仕様で気をつけたのは、お金が増える抜け道を作らないこと。
- 景気の倍率を「売却」だけに掛けると、「売ってから所持金で返済」が普通に納めるより得になる。なので、返済と売却の両方に掛けた
- 相場の「取引量」は、納品と売却の両方で増やす。売却を数えないと、売る方が得な場面ができる
- 国債を買えば差し押さえを逃れられてしまうので、差し押さえの順番を「所持金 → 国債 → アイテム」にした
- 取引所の売上や国債の利息は「収入」として税金をかける
テスト鯖を作った
今までは本番に直接入れて試していたけど、人が入っているときに何度も再起動するのは良くない。そこで、検証用の VLAN に本番と同じ構成の VM(mctest01)を作り、DB も本番のコピーを入れた。
PC で deploy-test.ps1 を実行すると、jar を作ってテスト鯖に送り、再起動してログを出すところまで自動で進む。テストで返済や税金をいくら入れても、本番の借金時計は汚れない。
ハマったこと1:設定の書き足しで止まる
プラグインには「config.yml に無いキーは、例のファイルから書き足す」仕組みがある。実績を足した版を入れたら、起動時にこう出て止まった。
設定エラー: achievements.big-repay.title の称号 futoppara が shop.titles にありません
実績(achievements)は書き足されたのに、実績が使う称号(shop.titles)が書き足されていなかった。称号のセクションは「利用者が中身を決めるもの」として、すでにあれば一切さわらない作りになっていたのが原因。足りない称号だけ id ごと書き足し、それでも無ければ止めずに警告にするよう直してもらった。
本番に入れていたら、サーバーごとプラグインが止まっていたところだった。テスト鯖を作った意味があった。
ハマったこと2:初回起動で過去の分が一気に配られる
全員目標は「累計返済が100兆円の倍数に届いたら報酬」。素直に作ると、初めて起動したときに、それまでの累計がもう何回分も超えていた場合、超えた分がまとめて配られてしまう。
そこで、初回起動のときは「今までの節目は報酬なしで記録するだけ」にした。さらに、まだ1つも節目に届いていない場合に備えて、「初回起動の記録」として n=0 の行を必ず入れる。この行がないと、次の起動も「初回」と判定されてしまう。
ハマったこと3:新しい jar が入らない
0.9.6 を入れたはずなのに、テスト鯖のログには 0.9.5 と出続けた。テスト鯖の古い jar を消しても、すぐ戻る。
デプロイスクリプトの、この1行が原因だった。
$jar = (Get-ChildItem build\libs\DebtCraft-*.jar | Select-Object -First 1).FullName
build\libs に 0.9.5 と 0.9.6 の両方が残っていて、名前順で最初の 0.9.5 を毎回送っていた。「更新日時が新しい順」に並べてから選ぶように直した。
Get-ChildItem build\libs\DebtCraft-*.jar | Sort-Object LastWriteTime -Descending | Select-Object -First 1
本番用のスクリプトも同じ書き方をしていたので、本番に古い版を入れる前に気づけてよかった。
学んだこと
- 経済の機能は、1つずつは単純でも、組み合わせると抜け道ができる。仕様を書く段階で「どうすれば得をするか」を考えておく
- 「初回」と「2回目以降」で動きが変わる処理は、初回の判定そのものを記録しておく
- テスト鯖は、作るのは手間でも、本番を止めずに何度も試せるのが大きい