🗂

ソシャゲのスタミナ計算処理の実装 common js

2023/02/15に公開

ソシャゲでも最近は放置系が大流行りで、スタミナ制はめっきり下火らしい。
なので、小生がとある案件で10年前ぐらいに使った、スタミナ計算処理を紹介する。
ちなみにその案件は、とっくの昔にサービス終了してる。
加えて強調しておくが、全ての案件がこの処理をやってる。という意味ではまったくない。

仕様

  • 時間で自然回復する。
  • 自然回復率はプレイヤーレベル等で上下しうる
  • 自然回復には上限値がある。
  • 自然回復上限値は、プレイヤーレベルで上下しうる
  • アイテムで回復する場合には、自然回復の上限を超えることができる。

実装

時間による自然回復では、単なる一次関数として表せる。

現在値 = 初期値 + 経過時間 * 自然回復率

https://github.com/kamawanu/zenn.dev-kamawanu-codes/blob/main/apsample/ap.js#L1-L12

timeoffset=0で自然回復停止を意味する。これの意味は後述する。
recoverylimitは、自然回復の限界値である。 ユーザのレベル帯で制御することが多いと思われるので関数にしておいたほうが後々都合が良い。

https://github.com/kamawanu/zenn.dev-kamawanu-codes/blob/main/apsample/ap.js#L14-L24

recoverypersecondsは自然回復率。本来の意図を示すため逆数にしてるが、もちろん通常はそんな面倒なことはしない。
getepochは現在時刻取得。ミリ秒までの解像度は必要ないので大抵は1000で割ってしまうと思われるが、関数化の意図はそれだけではない。後述。
overflowは、AP上限。自然回復の限界値と分けてるのは意味がある。 AP回復アイテムを使っても、回復上限値までしか増えなかったらプレイヤーは損したと思うだろう。

https://github.com/kamawanu/zenn.dev-kamawanu-codes/blob/main/apsample/ap.js#L26-L43

この処理の目玉はこれ。ある時刻時点のAP値を計算する。
自然回復の上限を超えてたら、キャップして、timeoffset=0にする。
非可逆の処理をやってしまったので、timeoffsetを外部入力してる意味がなくなったが、他の処理の都合もあるのでこのまま行く。

https://github.com/kamawanu/zenn.dev-kamawanu-codes/blob/main/apsample/ap.js#L44-L56

APの消費は、valueoffsetを新しい値で上書きして、timeoffsetをリセットする。
自然回復の限界値を超えてる可能性があるのでその判定もする。

この処理は、入力をマイナスにするとそのままAP直接回復に使えてしまう。
overflowの判定は、そのためのものである。
ちなみにcommon jsでは、整数とundefindの比較は常に"成立しない"ようだ。
サンプルの状態では無制限となる。

実行してみる

ただこのまま馬鹿正直に実行すると、自然回復周りのテストには実時間を待つしかない。
不便なので小細工をしてつかうことにする。

https://github.com/kamawanu/zenn.dev-kamawanu-codes/blob/main/apsample/t.js#L5-L16

getepochをオーバーライドして、timeshiftで計算時刻をずらせるようにした。関数化はこのためである。

https://github.com/kamawanu/zenn.dev-kamawanu-codes/blob/main/apsample/t.js#L17-L23

以降それなりにうまく動いてそうに見える。小生はnodejsで動作確認をしている。

https://github.com/kamawanu/zenn.dev-kamawanu-codes/tree/main/apsample

Discussion