Skip to content

About

ワールドボーダーを Chunky が実際に焼き終わった範囲に追随させる Forge MOD(1.20.1・サーバ専用)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Border Keeper

ワールドボーダーを、Chunky が実際に焼き終わった範囲に追随させる Forge MOD(Minecraft 1.20.1・サーバ専用)。

何のためか

プレイヤーが未生成の土地へ出ると、その場でチャンク生成が走る。地形MODを重ねた構成では 1チャンクの生成が重く、参加直後に数十秒サーバが止まる。

Chunky で事前生成しておいても、焼けた範囲の外へ出られては同じことが起きる。 ボーダーを「焼けた範囲」の内側に置き続ければ、遊んでいる最中に生成が起こらない。

この MOD は Chunky の進捗を受け取り、ボーダーをそこへ追随させる。

動き

Chunky の進捗イベント(world / chunks / complete)
  ↓
半径 = 8 × √(焼けたチャンク数)          ※ concentric(中心から輪を広げる順)が前提
  ↑ ⚠ **この前提は機械が確かめる**(下記)
  ↓
ボーダー = 半径 − 余白(view-distance + 2 チャンク)
  ↓
ネザー = オーバーワールド ÷ 8

ワールドの容量が予算(既定 45GB)を超えたら、事前生成を一時停止する。

前提

  • Chunky(必須。進捗を受け取る相手)
  • pattern=concentric で走らせること。⚠ region 順だと「ここまで焼けた」と言える瞬間が 完走時しか無く、進捗から半径を出せない
  • 次元ごとに独立したボーダーを持つには World Border Fixer 等が要る (バニラのボーダーは全次元で1つ)

設計で気をつけたところ

実運用で踏んだ失敗の対策が入っている。数字にはすべて理由がある(詳細はコードの注記)。

なぜ
完走したタスクには 5% の割引を掛けない 掛けたままだと焼き終わってもボーダーが手前で止まる
64ブロック以内の差では動かさない 目標が毎回わずかにズレるので、動かし続けてしまう
根拠ゼロで縮めない 「測れなかった」と「焼けていない」は別物。遊べていた範囲が突然閉じる
下限128 はスポーン周辺の内側 大きくすると「生成済みの場所にしか行けない」が破れる
ネザーは常に ÷8 ちょうど ポータルの行き先が丸められるのを、どちら向きにも防ぐ
余白は view-distance から出す ボーダーに立つと view-distance ぶんが配られる=生成される
止めるのは cancel ではなく pause cancel だと進捗が消えて再開できない

判断は BorderPlan に切り出してある。 Minecraft も Chunky も出てこないので、 サーバを起動せずに机上で確かめられる。

なぜ MOD なのか

元々はサーバの外で動く運用スクリプトだった。RCON で繋ぎ、サーバのログを正規表現で読んで 進捗を得ていた。Chunky が ChunkyAPI で進捗を公開していると気づいて中へ移した。

外に居たせいで抱えていた厄介事は、中に入れば全部消える。

  • ログを正規表現で読む → イベントを受け取るだけ
  • ログは再起動で切り替わるので region ファイルのヘッダを自前で読んでいた → 進捗は届く
  • 前のワールドの残骸タスクを弾く仕掛け → そもそも読まない
  • RCON → level.getWorldBorder().setSize()
  • 実行環境に Python があるかを気にしていた → 依存が消える

常駐の寿命も正しくなる。 外部の常駐は「落ちても黙って止まる」という不具合を抱えるが、 ボーダーを更新する必要があるのはサーバが動いている間だけなので、 MOD の中の定期処理なら寿命がぴったり一致する。

確認済みの動き(実機)

作りたてのワールドを閉じる 直径 59,999,968 → 256
焼けるにつれて広がる 1,779チャンク→321 / 2,158→386 / 2,573→451 / 3,025→516
ネザーが常に 1/8 OW 581 / ネザー 72
再起動をまたぐ 581 → 646 → 720(縮まない)
完走で割引が外れる 4,225チャンク・完走 → 720

⚠ 未確認: 予算に達したときの停止(試験で再現できていない)/ プレイヤーが居る間の挙動(Chunky Autopause が止めたとき)。

ライセンス

MIT

⚠ 前提(concentric)が守られているかを確かめる

書いてあるだけでは守られない。 2026-08-18 に実際に破った——ワールドを作り直したあと chunky start を焼き順の指定なしで叩き、region(領域ファイル単位)で走った。 ⚠ 遠くから先に焼かれるので 8 × √チャンク数 が嘘の半径になり、 ボーダーが未生成の土地まで開いていた(中心から 1,488 ブロック先を焼いている状態)。

py worlds/world-3/dev/verify/check_chunky_order.py             # 判定する
py worlds/world-3/dev/verify/check_chunky_order.py --self-test # ツール自身を対照で試す

⚠ 設定ファイルの pattern= を見てはいけない——走行中は古い値のままで、 実際に concentric で走っていたのに region と書いてあった。 このツールは実際に焼いている座標から判定する(concentric なら max(|x|, |z|) ≒ √(焼けたチャンク数) / 2)。

server/play_ctl.py status が自動で回すので、ステージングサーバの様子を見るたびに鳴る。

⚠⚠ 1.2.0 — Chunky の申告を、実際に生成されている土地で抑える(2026-08-21)

何が起きたか

ステージングサーバのワールドを別のもの(焼いた候補の複製)へ差し替えたあと、 このMODがボーダーを 3072 → 2866 に広げた。根拠は 「オーバーワールド 45,727 チャンク」——⚠ その数は前の世界(seedG)の焼きのものだった。

⚠ Chunky の進捗はワールドの外(config/chunky/tasks/)に在るので、 ワールドを差し替えても残る。 差し替え先に実在したのは 27,026 チャンクで、 原点まわりで全部そろっていたのは ±1,184。つまり ボーダーの内側に未生成の土地が 498 ブロック分入った。

踏み込むとチャンク生成が走り、Dynamic Waters の山岳河川づくりで サーバスレッドが 217 秒止まった(spark の最大tick)。 ⚠ 症状は「入れるのに地形が来ない・遠景だけ見える」で、ログには何も出ない。 原因に辿り着くのに jstack が要った。

直したこと

追加したもの 何をするか
GeneratedExtent region ファイルの見出しから「原点まわりで全部そろっている半径」を測る(⚠ Minecraft を知らないので机上で確かめられる。⚠ 輪ごとに見るので半径の2乗の手間で済む)
BorderPlan.clampToGenerated 申告から出した半径を、実測 − 余白で上から抑える。⚠ 測れなければ抑えない(「測れなかった」と「焼けていない」は別物)
記録の1行 実測の全部そろう半径 を足した。⚠ 申告と実測のどちらが効いたのかが後から読めないと、調べ直しになる

⚠ チャンク数では代わりにならない。 同じ数でも、輪の形に焼けているのか穴だらけなのかで 「安全に歩ける半径」は変わる。形を見るしかない。

確かめたこと

机上(Minecraft 抜き・javac で直接コンパイル)

見たもの 結果
実際のワールドを測る 1,184 ブロック(play_ctl.py border の Python 実装と独立に一致)
無いフォルダ 0(=抑えない)
申告 > 実測 実測 − 余白(9999 → 992)
申告 < 実測 申告のまま(500 → 500)
測れない(0) 抑えない(9999 → 9999)
事故の再現(申告 45,727 チャンク) 半径 1,433 → 992(直径 1,984)

実機(ステージングサーバ・前の世界の進捗をわざと戻して起動)

Border Keeper: ボーダー 1500 → 1984(オーバーワールド 45817 チャンク・余白 192・実測の全部そろう半径 1184)

⚠ 申告だけなら 2,870 まで開くところを 1,984 で止めた。 外から py server/play_ctl.py border でも「置いてよい上限 1984 / OK」を確認した。

About

ワールドボーダーを Chunky が実際に焼き終わった範囲に追随させる Forge MOD(1.20.1・サーバ専用)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages