himeshi’s blog

Simutrans本体改造まわりのお話をつらつらと

各パッチのこれまでと今後

この記事はSimutrans Advent Calendar 16日目のエントリとして書かれたものです。 

adventar.org前回はOTRPについてお話したので今回はそれ以外のパッチについてお話します。

市道化防止パッチ

本家フォーラム: https://forum.simutrans.com/index.php?topic=17333.0

2017年8月に開催した実践パッチ開発ゼミで題材として開発してもらい、実際に本家フォーラムに持っていってもらったパッチです。

現行シムトラでも穴を掘って高架を敷設すれば市街地における市道化を回避することはできるのですが、いかんせん面倒くさいので本体としてラクな手段を用意しようというものでした。パッチゼミ中では「一定速度以上の道路を全て市道化しない」方式と「特殊なwayobjが引いてある道路は市道化しない」方式とで実装してもらいました。個人的には後者の方が好きです。

特にアルゴリズム的に困難な場所もなく、必要性も明快であったのですんなり通るかなと思っていましたが実際は本家フォーラムで猛反対に合ってしまいました。欧州では市街地のど真ん中で車が高速に行き交いすることがない(このあたりは歩行者保護の観点から言って日本の道路が遅れているところですが。)ため、このパッチはただの「チート機能」でしかなかったようです。結局「ただ市道化を防止するだけならチートなので認めない。何かしらの犠牲が必要だ」ということで議論は決裂しましたが、「市道化防止を施した道路に市内建築物が接道することは認めない。市内建築物が接道している道路に市道化防止を施すことは認めない」ようにすればいい感じになるのではと思っているので時間があれば実装してみたいところです。というよりそんなに難しくないのでどなたか実装してみてください。

 

roadsignのfront/back

本家フォーラム: https://forum.simutrans.com/index.php?topic=17438.0

 

Ebiさんの積年の悩みを解決するパッチとして実装を試みました。

wayやwayobjにはfront/backが実装されているのにroadsignには無いせいでいろいろと表現が限られているとのことで、roadsignでもfront/backを実装しようというパッチです。「試みました」と書きましたが、実際はこのパッチは既にひとつの完成形になっていますし、ちゃんと動きます。

ところが本家フォーラムに持っていくと、次のような理由で統合を拒否されました。

  • どうせならdiagonalやslope、積雪対応もやって。全部できるまでは統合しないよ
  • drive_on_leftで左シフトを行うとfront/back関係が矛盾する。

1つめに関しては、実装も複雑になる上にアドオンを作るときの労力もかなり増大するので正直実装するコストに対してあんまり良い結果にはならないと考えています。まあ実際は途中まで実装はしてあるのですが。

2つめに関しては、これは画像シフトを行う以上本質的に起こる問題で、それはそうとしか言いようがありません。というより、front/backを必要とするroadsignは路面上に載ってるものやアーチ状の構造を持つ標識なのであって、このような画像で画像シフトが起こったら困ります。左側通行右側通行で画像位置を変化させる必要があるものは本質的にfront/backを必要としないはずです。そのような場合は従来の書き方をしていただければ現行シムトラと全く同じようにfront/backが自動調整されて画像シフトされるので、front/backを必要とするならdrive_on_leftによるoffset_leftを0にすれば解決する話です。

と、いう話を本家フォーラムでも繰り返し説明してきましたが、本家フォーラムの皆さんは「front/backが必要でかつ左側通行の時に画像シフトが必要な場合」の対処が必要だという主張をされています。まあたしかに鉄道信号で線路上に地上子がある場合、地上子はdrive_on_leftで画像シフトしては困りますが信号機自体は画像シフトされた上で前後関係も適切に設定されなければなりませんね。そこまで要求するなら左側通行用と右側通行用を別個のアドオンで作ってくださいという感じではありますが。

 

道路信号の方角設定

 shingoushori氏によるパッチです。現行の道路信号は南北・東西を定めた時間で切り替えるだけですが、このパッチでは各時間ごとに交差点への進入許可方向を自由に設定できるようになります。

 進入方向を自由に設定できるので定間隔化装置が非常にコンパクトになります。鉄道だと運転系統を増やそうとするとしばしば定間隔化装置の用地が問題になりますが、コレなら狭い都市のど真ん中にも遠慮なく作れますね!

 OTRPで4車線×2車線道路の交差点を作ろうと思うとどうしてもコレが必要です。TKU氏による直線上信号設置法だと2車線道路側で交差点横断中に信号が変わって交差点中に取り残されるリスクを取りきれません。

現在は交差点にマーカーを設定し、そこに16進数で進入方向を書く方式です。さすがにそれだと一般向けには不親切なので、もう少しわかりやすいUIで本家に持っていくと楽しいかなと思います。あくまでもshingoushori氏のパッチなので今のところ私が持っていく予定はありませんが、OTRPに非常に効果的なパッチなので取り上げさせてもらいました。

 

64bit化

 OS基盤64bitに移行してから随分とたちました。が、simutransは未だに32bitバイナリが公式で配布されてます。

まず理解していただきたいのが、64bit化をすると使えるメモリ空間が広くなるというだけで自動的に高速化するわけではありません。2GBを超えるような超巨大マップをやらない限りは32bitで十分です。(それでも最近は超巨大マップをやる人が増えているようですが。)64bit版バイナリの作り方はKTOK氏がまとめてくださっています。(リプを辿ってください)

 手順を見ればわかるとおり、途中でコードを書き換えます。例えば↓

https://github.com/aburch/simutrans/blob/master/obj/baum.cc#L322

乱数を得るのに「オブジェクト自身のポインタを値として使う」というなんともビックリな実装です。こんな感じでコードの奥深くに32bitであることを前提としたようなコードが散りばめられているので、「安全な」64bitバイナリを作ろうと思うとそれ相応の作業が必要です。とはいえ超巨大マップをやらない限りは64bit化をしてもあまり恩恵がないので誰もやらないというのが実情です。

シムトラはもともとHajo氏によって開発が始められました。たしか90年代です。C++の世界ではC++11でスマートポインタが導入されメモリリークに苦しむ時代は終わりましたが、シムトラのコードは古(いにしえ)のコードなので未だに生ポインタを扱い、メモリリークとSegmentation Faultで落ちます。どうにかならんかなぁ・・・

 

 

次回は「自動車プレイはどうして難しいのか」について書こうかなと思います。また、12月23日のシムトラ学会で登壇します。お楽しみに。