生きることは忘れること

[Simutrans] cityrules.tabで都市の発展を制御する

Simutransには様々な機能がありますが、本記事では取り上げられることが意外と少ないcityrules.tabを見ていきたいと思います。

cityrules.tabはSimutransにいくつかある設定ファイルのひとつで、都市の発展に関する設定を担当しています。通り一遍の解説は設定ファイル/cityrules.tab - Simutrans日本語化・解説に譲り、本記事では市道・建物の生成ルールを詳しく取り上げます。

cityrules.tabを編集することで、都市が発展する際に市道・建物がどのように建設されるかを制御することができます。先行研究として、シムトランス観光局 - Simutrans Tourism - 碁盤の目状の町並み作りに挑戦があります。

以下、SimutransはすべてStandardです。

cityrules.tabを試してみる

手始めに、いくつかのcityrules.tabで発展の様子を観察してみることにします。準備として、適当にマップを生成します。

生成されたマップの中から、この小さい村をクローズアップします。

そしてチートツール「都市の人口を増やす」を連打します。まずはpak64デフォルトのcityrules.tabでやってみましょう。

人口が増えました。街は、もとあった都市間道路に沿って広がりを持って発展しました。

今度は前記シムトランス観光局から発展ルールをお借りして、同じことをやってみます。

今度は市道が碁盤目状に形成される、前とは異なる発展の仕方になりました。

このように、発展ルールを調整することにより、都市の発展を制御することができます。

pak.nipponは独自のcityrules.tabを持っているので、これも試してみます。

デフォルトの場合に少し似ているようですが、斜めの道路の周りに建物ができないなど、やはりまた異なる仕方で発展しました。

cityrules.tabでできること

それではcityrules.tabを編集するとどんなことができるのでしょうか。実験的にいくつか発展ルールを作ってみました。

建物を作らない

cityrules.tabに発展ルールをひとつも記述しないと、人口を増やしても建物が生えなくなります。

特殊建築物以外の建物が増えていないのがわかります。都市ダイアログで確認すると、人口2,0002に対して無職者が1,7252・浮浪者が1,6752と通常より極めて大きくなっています。

まあ、無職者と浮浪者が増えるのですが…。このあたりの挙動は、市域内の道路を全撤去した場合の挙動と似ています。「モニュメントは市道で周囲を囲んで建設される」という仕様があるので、ちょっとだけ市道が増えているのがわかります。

碁盤目都市

建物は生やすけれど新たな市道を作らない、というのも当然可能です。この場合そのままでは既存の幹線道路に沿って市域が拡大してしまうので、あらかじめ道路網を整備しておくようなプレイスタイルに有効でしょう。特に、デフォルトのままでは、いわゆる碁盤目都市は2×2格子以外にするのが難しかったところをうまいことやれるようになります。

4×4格子でやってみます。まずはデフォルトのcityrules.tabから。

4×4格子の碁盤目上でデフォルトのcityrules.tabを使って発展させたときの様子です。

格子の中に市道ができたり、市道ができなかった格子は内部が埋められずに残ってしまったりして、うまいこといきません。

次に4×4格子に適するような発展ルールを作ってやってみます。

新たな市道はほとんど建設されず、格子の内部にも市内建築物ができました。

市内建築物を綺麗に生やすことができました。モニュメントが生えたせいで市道が建設されているところがありますが、これはcityrules.tabではどうしようもないので仕方ありません。

同じ4×4格子でも、格子を邪魔しない程度に市道を生やすルールも可能です。少し小さめの碁盤を用意して試してみます。

そして人口を増やします。

このように碁盤の中は余計な道路が生えすぎず、しかし碁盤の外へ枠を越えて発展していきます。碁盤の中でちょっと道路ができているのはモニュメントが生えると周りに影響してしまうのが理由です。さすがに碁盤の外に無から4×4格子を生成するのは無理ですが、許容できる程度の生え方にはなったかなと思います。最初の碁盤を「田」ではなく「井」の字型にするとまた違うかもしれません。

格子を維持しつつ道路を生やす発展ルールは、マップ内に碁盤の計画都市とそれ以外の都市を共存させることを目論んで書きました。そこで、碁盤を引かなくてもちゃんと道路が生えて都市が広がってくれることを試してみます。

うまくいっています。

ただ、このルールは4×4碁盤の内外の調和が取れるように直線を多めにしつつ、4×4格子の中に市道ができないように分岐を少なくしたので、道路が平行なまま接続せず何マスも続いてしまうというケースがちらほら見られます。今の例では右上あたりにその傾向が出ているのがわかります。

初期生成都市

新しいマップを作ったときに生成される都市も、内部的には人口を増やすツールと似たような処理をしているっぽく、ということはcityrules.tabで制御できます。

たとえば先のルールで新しいマップを生成してみます。

生成されたマップの中で人口の多い都市を見ると、先のケースと似たような特徴が顕れているのが分かります。

新しいマップを作るときにこのルールにするのはあまり適当とは思えない感もありますが、ルールが適用されているのは確認できると思います。マップ生成時とそれ以降の開発とでcityrules.tabを使い分けることは可能なので、マップ生成に最適化したcityrules.tabを作るとよい感じになるかもしれません。

cityrules.tabの書き方

「ぼくのかんがえたさいきょうの発展を達成するためにはどんなcityrules.tabを書けばよいか」解説マニュアルが存在しないので試みに書いてみます。対象読者としてはsimuconf.tabなどのSimutransの何らかの設定ファイルを多少弄ったことある以上の人を想定しています。また、前記日本語wikiの該当ページもあわせて参照するとよいです。

準備1:設定項目を理解する

cityrules.tabの発展ルールのセクションは次のようになっています。

house_1 = ... Hn. sss
house_1.chance = -2

house_2 = ... .nH sss
house_2.chance = -2

road_1 = .H. SnS .sS
road_1.chance = 8

road_2 = .H. .n. SsS
road_2.chance = 4

house_1house_1.chanceの2行で1組の設定で、これを何個も並べていくことになります。houseの他にroadもあり、書き方は同じです。houseが建物の生え方、roadが市道の生え方に関する設定です。

house_1の方は、記号・アルファベットをたくさん並べます。この並んでいる文字は、1文字が1タイルに対応していて、全体で正方形の領域を表現しています。正方形のサイズは3×3・5×5・7×7のどれかでなければいけません。

house_1 = ... Hn. sss
# これは、正方形の領域
# ...
# Hn.
# sss
# に対応する

Simutransの設定ファイルは1行1項目が基本なので、正方形をスライスして1行に並べて書きます。

各文字の意味はデフォルトのcityrules.tabのコメントや日本語wikiに書いてあります。書き抜いてくると次のようになります。

S 道路ではない
s 道路
n 裸地(何もない素の地面)
H 建物(house)ではない
h 建物
T 停留所(stop)ではない
t 停留所
U allowed slope for roads
u forbidden slope for roads
. なんでもよい

house_1.chanceの方は整数で、その組の「重み」を指定します。日本語wikiには「この規則が適用される確率を表します」と書いてあります。同じことです。数値が大きい方が「軽い」「確率が低い」「選ばれにくい」です。

準備2:動きを理解する

さて、都市が発展するときには、次のような動作をします(これは日本語wikiの「アルゴリズム」を噛み砕いたものです)。

  1. 建物・道路を生やす候補となるタイルを選ぶ。
  2. 今選んだ候補タイルを中心とする正方形の領域を考える。その正方形と、cityrules.tabの発展ルールの正方形とを比べてみて、一致するルールだけを残す。
  3. 残ったルールをhouseroadに分ける。
  4. houseroadのそれぞれについて、残ったルールの“chance”に対応する「重み」をぜんぶ足す。「重み」の和が充分大きければ、そのタイルに建物あるいは道路ができる(TRPGが分かる方は、「重み」の和がステータス値で、そこにSimutransがダイスを振っていくと考えれば近いです(ほんまかいな))。

(とても大雑把な表現をしたので、正確なアルゴリズムについては日本語wikiやソースコードをあたってください。)

目標ルールをcityrules.tabに落とし込む

やることは「準備2」を逆算することなのですが、慣れていないとなかなか難しい。しかしながら、自分のやっていることを他人にできるようにマニュアルとして書くのも難しい。。。一言でまとめると「ひたすら試行錯誤する」になってしまう。

  1. 「あり得そうなシナリオ」をいくつか用意する。具体的には、初期生成された都市にあり得そうな配置を何パターンか選ぶことになる。計画都市を対象にするなら碁盤目も。紙やパソコンに書きつけておくとよい。
  2. 各シナリオについて、「こういうふうに道路が生えたら嬉しい」「ここには道路は生えて欲しくない」というような事例を作る。
  3. 「こういうふうに道路が生えたら嬉しい」を実現できるようなルールを書く。その上で、そのルールで「ここには道路は生えて欲しくない」が発生しうるかどうかよーく考えてみる。
  4. 「ここには道路が生えて欲しくない」が発生しなさそうなルールを採用して、cityrules.tabに書く。
  5. そのルール群で「都市の人口を増やす」を試してみる。
  6. 生えて欲しくない道路や建物ができてしまったら、その原因となったルールがどれか考えてみる。それらしきルールがあれば、それをどうにか改良する。
  7. よさげになるまで繰り返す。

ね、簡単でしょ?

ちなみに、建物と道路では、道路の方が小さな違いがクリティカルになることが多くて難しいように感じました。

もっといい方法があるよという方はぜひご紹介ください(というか、私自身数時間試したに過ぎないのですよね…)。Advent Calendarがなくてもブログは書いていいのよ(チラッ

cityrules.tabの限界

cityrules.tabを弄らないのと弄るのとでは見える景色が結構違うのではないかな、と思うのですが、しかしcityrules.tabを弄ってもできないこともあります。

最も大きいのは、「マップ全体通して同じcityrules.tabが適用される」ということで、都市ごとに異なるルールを適用したりできないので、現実のゲームプレイでは柔軟性に欠けると言わざるを得ないかもしれません。また、ルールの記述法が「物足りない」というか、目標とするルールを素直に表現することができず、妥協した書き方をした上で変な所が出なくなるまで試行錯誤する、みたいなことを私の場合はしていて、これは大きな課題だと思います。

cityrules.tabを書いての所感

これからのこと

こんなこといいな、できたらいいな、ふしぎなパッチがかなえてくれる(

配布

途中のスクリーンショットを撮るのに使ったcityrules.tabは近日中に配布する予定です(準備が間に合いませんでしたごめんなさい)。