ラベル Cities: Skylines の投稿を表示しています。 すべての投稿を表示
ラベル Cities: Skylines の投稿を表示しています。 すべての投稿を表示

2017年5月20日土曜日

Visual Studio 2017でPushCommand.ExecutePushCommand

週末なのでMicrosoft Visual Studio 2015を2017に更新することにしました。
保守案件がありそうな2008やそれ以前のを残して2012以降をばっさりと切り捨ててすっきりです。

同時にUnityも5.6にしたらAdMobが動かない。。。
開発環境を更新したのですから当然何かあるとは思っていましたが、まずUnity側で事案発生。まあ、所詮誰も遊んでくれないゲームアプリで利用しているだけなので更新することもないでしょうから当分こちらは放置です。

2017はこの段階では別段何事もなさそうだったので、早速Cities: SkylinesのMODを今度発売されたMass Transit DLC用に機能追加をしてテストして無事リリース。
早速早期対応ありがとう(意訳)なコメントをいただいて、照れくさくござる。

ここまでは順調だったのですが、テストを完了してローカルでコミットされていたソース群をオレオレサーバにpushしようとして開発環境移行時多発事案の発生であります。
リモート リポジトリへのブランチのプッシュ中にエラーが発生しました: Git failed with a fatal error.
fatal: unable to access 'https://xxx/yyy.git/': SSL certificate problem: self signed certificate in certificate chain
数年前から趣味で作ったソフト群はサーバ上に設置したgitbucketという大変スバラシイソフトウェア経由で管理しており、それへのアクセスはhttpsを経由して行っていたのですが、先日までの2015では特に叱られもしませんでした。
2017からちゃんと対応するようにしたのでしょうか、オレオレ証明書なんか知らねーよとおむずかりです。

これはまあ、言われた通りにすればいいので、オレオレ認証局の証明書をconfigに追加するか、そもそも証明書のチェックをさせないかのどちらかで対応可能です。
  1. オレオレ認証局の証明書をconfigに追加する場合
    証明書はderじゃだめでpemじゃないとダメな様子です。
    https://oreoreというサーバを証明するca_oreore.derという証明書があったとして、opensslでder形式からpem形式に変換するには以下の構文になります。
    openssl x509 -in ca_oreore.der -inform DER -out ca_oreore.pem -outform PEM
    ここでできたca_oreore.pemを .git/config に、以下を追記してあげます。

    [http "https://oreore/"]
    sslCAInfo = X:/path/to/ca_oreore.pem


    お気づきかと思いますが、ドライブレターがついています。
    ついていないと、標準インストールの場合、
    C:\Program Files (x86)\Microsoft Visual Studio\2017\[エディション名\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Git\mingw32
    という気が遠くなるような深いパスがrootとなってしまいます。
    素敵な仕様ですネ。
    また、バックスラッシュ(\)ではなくスラッシュで記述したほうがよろしいかと思います。また、"https://oreore/"を省いてもいいのですが、それだとサーバ毎に証明書を設定することはできません。
  2. 証明書をガン無視させたい場合
    .git/configに下記の行を追記します。
    [http]
    sslVerify = false
まあ、ここまでは良かったんですが、いざpushしようとするとさらにおむずかりのようで、コンソールに書きのメッセージがお出ましになられました。
リモート リポジトリへのブランチのプッシュ中にエラーが発生しました: Git failed with a fatal error.
    PushCommand.ExecutePushCommand
こっちは先ほどと違って、何を言ってるのかわかりません。
今現在、記事にしている最中ですが現時点でもさっぱり訳が分かっていません。

PushCommand.ExecutePushCommandで検索すると、2017添付のgitを最新版に更新したら直っただとかopenssl系のdllが混在していただとかいろいろ記事はあるのですが、それらすべてを試しても何の解決にもなりません。

加えてサーバ側のgitリポジトリのアクセス許可や実行ユーザを再度確認したりVisual Studioを再インストールしたり、修復したり、などと試していて、これだけで土曜がつぶれてしまいました。

さらに直接gitコマンドでpushを試みたところ、さらにわけのわからないエラーが。
リモート側に存在しないpackファイルをunpackしようとして存在しない(ないんだからないわな)からって大激怒してるんです、keepだけ残して。
もう本気で意味不明でごわります。

リモートリポジトリからcloneしなおして、再度commit, pushを行っても同様の結果ですし、サーバ側のgitのバージョンは1.8、PC側が2.13ということで、バージョンの違いではないかと考えてサーバ側からpcをmountしてpushしても同様に怒られるし、ほとほと困じ果てました。
ふとコミットを一度取り消し、コミットメッセージを変更してコミットしてpushしたら。。。通りました。

いったいなんなんだ!!
それがしも大激怒です。

テスト用リポジトリを作成し、通らなかったときとまったく同じコミットメッセージをつけてコミットすると、今度は何事もなく通るじゃありませんか。
ますます意味不明です。

git fsckしても問題ないし、cloneはできるし、何がどうなってるのかさっぱりわかりません。

とても恥ずかしいことをしている気がするので、ここにご報告する次第です。

2017年3月10日金曜日

Google AdMob, AdSenseの導入

このような場末のマニアックなブログにまで来てくださる方たちですからadblockの導入率が高いと思いますが、実は先日、AdSenseを導入いたしました。
私自身も自宅内サーバのdnsmasqでふつーに広告URLをdropしていますのでPCでもタブレットでもスマホでも広告は見えません。(まあ、自分自身でうっかりクリックすると契約違反になるそうですのでむしろ自衛となるわけだからいいよね)

なぜ今頃こんなことを言い出したかというと、AdSenseを導入できなくて阿鼻叫喚している人が多いということを知って驚いたからです。

事前に申し上げておきますが、広告掲載開始の知らせを受けて一か月程度ですが、
¥100円
にもなってないサイトの記事ですので、そこのところはご承知おきください。

以下、すごく長い余談です。
まず、いきなり話が飛ぶようですが導入の動機はUnityです。

そもそも、Cities: SkylinesというゲームのMODを作っていて、そのCities: SkylinesはUnityがベースになっているのですが、私はまったくUnityというものを知らないながら(そしてC#にも不慣れながら)調子に乗っていくつかMODをリリースしてみたものの、そもそもUnityってなんなのよ、どういうものなのさ、と気になっていました。

で、あるパズルゲームのアイディアが浮かんだので、Unityってゲームエンジンなんだから作れないかな?と、これをUnityで実装してみようと思い立ったのがきっかけでした。
調べてみると、なんとWindows, Linux, Android, iOS, なんでもかんでも一つのコードで動かせるというじゃあありませんか。びっくりしました。
さらに個人利用は無料だっちゅうので、こりゃあいい、一つ勉強してやるべえ、と実際に作り始めてみますと、最初は独特の概念などがあって面食らったものの、Cities: SkylinesのMOD作りで見よう見まねで苦労してきた甲斐があってかほんの数日で作りたいとおもっていた以上のものができてしまいました(もともと大したものではないのですが)。
もちろん、こんなことが可能だったのはUnityだけでなく、ゲーム用の楽曲や画像などの素材を提供してくれる各サイトの皆さんのおかげということはこの場を借りて感謝を申し上げたいと思います。

で、実際にAndroidの実機がいくつかあり、実際にテストプレイをしてみると、本当にコードを書き換える必要もなく古い機種でも割合快適にプレイできるapkをUnityが吐いてくれているのに気をよくしてしまい、(かなり)過去にAndroid用アプリを公開しているためデベロッパーID取得費用の$25も支払い済みですので、個人的には結構満足な出来だったので最適化をしたうえでAndroid用のゲームとして公開してみようと思い立ちました。

そこで、さらに一工夫してみたいと思いました。広告です。
今時のアプリは何でもかんでも広告がついてます。

これまでの経験からAndroid用アプリは余程経費をかけないとダウンロード数が伸びないことはわかっているので、今回もほぼ誰も遊んでくれるどころかGoogle Playで誰にも見つけてもらえないところに落ち着くことは目に見えていますし、そもそもこれまで個人的な活動で作ってきたプログラムは数多くフリーウェアとして公開してきましたが(MS-DOS用常駐プログラムすらVectorさんでいまだにおいていただいていてたりします)、AndroidやiOSの世界は独特です。過当競争どころの騒ぎではありません。
まーどうせ誰にも見てもらえないなら技術的に面白そうだというだけでやってみてもいいだろうということで広告を入れるには何がいいかな、と調べると、GoogleがやってるAdMobというのがあることを知りました。

そこで、どうせAndroidだからGoogleさんのサービスがいいやねと思い、AdMobを導入するにはどうすればいいか、と調べてみると申し込みが必要で、それは当たり前ですが、これとAdSenseがなんか連携しているということでした。で、このAdSense、どっかで見たなー、と思ったら、このブログで何年か前だったか、割と読んでいただいた記事があって、その時にAdSenseに申し込んでくれたらうれしいなー、みたいなことをログイン時に言われてたのを思い出しました。
まあ、そんなことはほんの一瞬だけでしたので、たぶん勧誘する対象を誤判定したんでしょう。

話が回りくどくて恐縮ですが、これでAdSenseに申し込んだ理由にやっと戻ってこれました。AdMobに申し込むとAdSenseとAdWordsのアカウントを同時に取得させられるとのことでしたので、折角の機会ですしAdSenseのほうも申し込んでしまえ、という次第です。
AdWordsのほうは、これはむしろGoogleさんに広告をお願いするアカウントのようなので、そんなこたあまずないだろうと思います。

で、間借りしているこのBloggerさんだと、ボタン一発で申し込みができるようになっていましたので、さっそくそのボタンを押して見ました。すると、AdMobと違ってAdSenseのほうは広告出稿に当たりサイトの審査があるんだそうで、時間がかかるから待てと。

あらあら、思わぬ手間がかかるのね、と思いましたが、じゃあ折角もらった時間だし、ゲームのブラッシュアップでもしてみようかとおもっていると、翌日だか翌々日だかには偉そうに「おめでとうございます!広告が掲載されました!」とかメールをよこす始末です。
広告媒体が広がるんだから広告主のほうがおめでてーんじゃないの普通?と思いつつ、まあ、これで中断していたAdMobのほうも手続きを進めて、ゲームをリリースしましました。

ちょっとAdMobのほうに飛びますが、AdMobのほうは審査も一切なし、Unity用ライブラリもしっかり整っていてあっさりテスト用広告表示もできて、拍子抜けするほどでした。なるほど、ここまで簡単なら猫も杓子もアプリに搭載しますわね。
こちらは$25も払ってフリーウェアを配布しているのにわけのわからないいちゃもんつけてくるやつ、もとい、ユーザ様(なんで急に卑屈になってんだ!)とかいますが、自分自身が世界の中心においでの方が山ほどいるのですからまあ、中心がどれだけあるのかわからないのがこの世の中ですのでせめて広告代でも・・・と思ったら甘いんですよねえ。
なんせ誰にも使ってもらえないのですから広告代だって入らない。来るのはいちゃもんばかり。なーんだいつもの通りじゃん、てな具合。
無料なんだから使うほうも自己責任で使えや、作ってる方は誠心誠意作ってんだからよー、といっても通じませんわねこのご時世。

ま、やっと本題に戻りますが、AdSenseの話を書く気になったのは、冒頭でも触れましたが、審査に通らないとか通すためには云々という話が多いという話を聞いたからでした。

私自身は上述の通り、ボタンを押したっきり、何もしていません。ですので余計びっくりしました。
申請期間中の記事の更新もなし、記事数も少なく、一日のページビューなど口に出すだに烏滸がましいこのブログです。100そこそこです。

審査が通らないと話を聞かされてから試しに検索してみると、確かにそういう記事がどっさり出てきます。
中には涙ぐましく申請前にダミーサイトを作るだのサイト利用約款を作るだの(これはプライバシーポリシーという形で私も最近ページを作りました。確かにGoogleに追跡されてるよ!という警告を表示するのは賛成でしたので)なんだか偉そうに「審査合格」を指南しているサイトも多々見受けられ、ほとほと考え込まされました。

一応申し添えますが、審査合格指南者の言っていることはすべてこのブログには当てはまりません。だから、審査に通りたいなら彼らの言うことを聞いても無駄でしょう。なぜなら、ここに実例があるから。

確かに、出稿主がなんでこんなブログに出稿したいかと考えたかはわかりません。そして、出稿主の期待もむなしくページビューもなく実際に支払われる額も\100円未満。そんなサイトでも何もしなくても彼らの言うところの審査に通りました。

ま、出稿先としてまるで魅力がないことは明白なのであっさり広告出稿停止なんてことになりそうですが、審査に通らないということでお悩みな方には何かこのブログにヒントがあるのかもしれませんよ。

そうそう、AdMobのほうですが、こちらはなんと
¥0円
です。だって自分で検索してもGoogle Playで見つかんないんだもんなあ。当たり前ですよねえ。それに私が作ったゲームにも魅力がないってことです。残念ですが、まーそんなもんかなあ、くらいの気持ちで次に行きましょう。自分でもやってないし(アイディアを形にするのが好きなので形になってしまった後は・・・まぁお察しください)
そもそも、自分が作ってるものなのに自身のブログで宣伝もせず、むしろこのブログで公開しているプログラムがらみというと、主に自分が利益を得ない洋ゲー日本語化用スクリプトとかが主ですからねぇ。
見る人が見ればバカに見えることこの上ありますまいなあ。

本当にお恥ずかしい話ですが、当ブログは恥を記録してまいるのが主眼ですので、AdSenseやAdMobネタを提供してくださったGoogleさんに、今回もいいネタをいただいた気がしております。

ご清聴ありがとうございました。

2016年2月21日日曜日

Cities: Skylines 1.3.0の日本語化シートを用意してくださった方を称賛させてください

1.3.0用のCities: Skylinesの日本語化シートを用意してくださった方に強い感銘を受けたので、チラシの裏として駄文をつづります。人様を駄文で称えることに関しましては重々お詫びいたします。

前置きとして、Cities: Skylinesの自作MODの更新が発端になったので、そこから書きます。

先日発表されたSnowfallですが、事前にMODを利用してくださっているユーザーさんから「Snowfallで登場するTramとかHeatingとかに対応するつもりあんのかな、α版から贔屓にしてやってんだぞ(だから当然対応しろよな)(意訳)」的なお声を頂戴してしまっていたので、そりゃもう震えあがって発表直後の日本時間深夜からコードの解析に入りました。

その結果、幸いAfter Darkの時と同様なつくり、つまりvanilla部分にほとんどのコードが置かれていることが判明したので、追加量が多くて作業時間そのものはかかったものの、滞りなくmodの更新を済ませることができました。

この段階ではまだ日本語化作業は開始もされていない様子だったので、自作MODも英語版だけでテストしてリリースしました。

わざわざ「英語版でテスト」などと特筆するというのは、自作のMODは表示する文字列は一応多国語に対応していて、文字列IDが振られている文字列を組み合わせて自分が望む文字列を作り出すということをやっているので、テストしないとどんな文字列が出てくるか知れたものではないからです。もちろん英語が最優先ですが、私の母語は日本語なので、日本語でも違和感なく表示された方がいいわけです。

まあ、まだ日本語化作業が開始もされてない状況なので、当分ほっとくか、と思っていた矢先、翌日だか翌々日だったか、「あんたのMODなんかおかしいぞ(意訳)」という報告をいただいたため早速調査をすることにしたのですが、ふと「そろそろ開始くらいはされたかな?」と作業所をのぞいてみると、依然開始されていませんでした。

ユーザさんがおかしいというのだから何が問題があるはずなのでMODの更新が必要になるわけですが、さらにその後日本語化がされたとして、文言が合わなかったら日本語に対応するだけの更新をするのもなんだか気が引けるので、せめて自身で「翻訳されたとしてもこうなるはずだからこのIDは使えるな」という文字列を探そうと思って、ふと気づきました。

バイナリのロケールファイルの展開方法が分からない。

ありゃあ、そこから調べないとだめかぁ、と思ってMODのどこが変なのか調査しながら、片手間にちょこちょこen.localeファイルの開き方を少しづつ調べたりしているうちに、作業所のスプレッドシートに1.3.0用の文字列のデータの更新を始めてくれた(BOLDにした理由は後程触れます)方が現れたため、これは渡りに船と見に行ってみると、結構な量の翻訳対象テキストが追加されていたものの、ほとんど空欄のままの状況で、せいぜいTRAMがトラムと訳されている程度。

さすがに最近シートに追加され始めたばかりですから、翻訳作業に携わる人もあまり集まっていない様子です。

こりゃあイカン、こんなんじゃリリースされるのいつになるかわからんと思うと、日頃利用させていただいている感謝もあり、ここは一気に翻訳しちゃおう、と思い立ち、バグ探しそっちのけで翻訳に取り組むことにしました。

この手の作業は、とにかく空欄を埋めることが肝要だと思っています。

そうすれば口だけ野郎とかがいくら喧々囂々の用語論争をしようが大抵の場合は「とにかく完成したんだから一度リリースしよう」ということになるからです。
もちろん、侃々諤々なら大いに価値があるんですけど、たいていは喧々囂々のほうで終始してこの駄文以上にとりとめがないのですよね。

ですので、まずは着手し、どういう形であれ、形を作る。これが重要だと思います。
特に不特定多数が集まるリーダー不在のプロジェクトの場合は事前に相談しようものなら収拾がつかなくなること請け合いです。
「こうしてみたんだけどどうかな?」なら前に進めますが、「こうしたいんだけどどうだろう?」は絶対ダメです。裁定者がいないからです。

何にせよ埋めておけば、それを叩き台にしてより良い翻訳を考案することができます。
手直しのほうがずっと難易度も敷居も低いですから、それだけ多くの人に添削してもらえるわけです。

そのため、もう既にMODのSnowfall対応を通じて追加部分の内容はわかっているので(とはいえ運河関係の原文を見た時には咄嗟にコードを見直してしまいましたが、あれは将来のアップデート用なのかな?)、仮に原文で面倒な言い回しをしていても意訳でさらっと流し、用語のブレがあっても頓着せず、とにかく埋めることに専念しました。
尤も、Coverを覆雪としたのは評判悪いみたいですが、ともかくも訳文があれば批判もできるわけですので、今後より適切な訳語に置き換えられてゆくでしょう。

また、どうも変な訳語だとおもうものには自分の語句であれ誰かが翻訳した語句であれ、提案として私が訳語で使っている言葉とその理由をシートに記述しておき、特に変更せず第三者に判断をゆだねて時間を節約しました。

Capitalism Labと違って翻訳そのものは大変難易度が低く、SVOCの語順の強制もないので機械翻訳の出番もあまりなく、順調に翻訳を進め(といっても結局私自身の能力では何時間もかかったのですが)、ついに皆さんと協力して全部訳し切りました。

やった!翻訳率100%達成だ!よし訳文を見直すか!!

・・・見直しているうちに、ふと気づくと、翻訳率がまた100%を割っています。

えっ?

戸惑っても仕方がないので、空欄を探して再度翻訳作業を開始しました。
そして、再度100%を達成。見直し。100%を割って・・・

えっ?

なんだ?どうなってるんだ?追加されているのは確かに新しい語句で、誰かが消去しているわけではないことは明白です。

しばらく見ていると、原文欄に編集中の印が出て、ペラっと、原文が追記されるのが目に入りました。さらに見ていると、ちょっと間をおいて、同様の作業が繰り返されています。

なんとシートに翻訳対象を用意してくれている方は、手作業でシートに新規和訳が必要な分を追加していたのです。
私はこれを見て思わず声をあげて感嘆してしまいました。

これだけ膨大なテキストを手作業で1セル1セル全て行うなど大変な忍耐力がなければ、とてもできることではないと思います。特に、生半可な気持ちじゃ絶対できません。

しかし、それを実際にやっている人がここにいるんだ、と思った瞬間、とても驚くと同時に、本当に頭の下がる思いでした。

ここでもうお気づきかと思いますが、先ほど「後程触れます」というBOLDで記述した一文を私は見逃していて、勝手に翻訳対象文がシートに追加「された」ものと思い込んでいたわけです。

実際には、追加を「開始」したということだったのでした。

結局私は睡魔に負けて23時でギブアップしてしまったのですが、その後、夜の一時までずっと作業を続けておられたようです。

金曜の朝9時半から実におよそ40時間

まさかぶっ続けってことはないと思いますが、その間コツコツと作業を続けておいでになったわけです。

本当に感嘆を禁じえません

あまりに感銘を受けたため、思わずこのような駄文を書き散らしております。

しかも、その後、朝の8時半にはja.localeをリリースしてくれるという働きぶりにはもう頭が上がりません。

ちょうど私のmodも「なんかおかしい」部分を特定し、修正して更新する直前だったので、無事日本語版での表示でも違和感がないことが確認してリリースすることができました。

本当にどうもありがとうございました。

また、僭越かつ厚顔ではありますが、今回は控えめに言っても追加分のうち半分以上は翻訳でき(もちろん手直しをいただいた訳文はいっぱいありますし、自分は特別だなんぞまるで思っていませんので念のため申し添えます)、ある程度ご恩返しができたかな、と多少の自負を致しております。

それに、Capitalism Labの作業シートでやりたかったことがすべてできました。

時間がたつにつれて参加される人も増え、ある時期からは空欄を埋める人、文が以前のバージョンと整合が取れているかチェックして修正する人、もっといい訳文に改善する人(自分の訳文が目の前で改善されてゆくのは本当に楽しかった!)、提案に対してご自分の考えを述べてくれる人(例えば雪寄場の提案を行ったところ、北海道では雪投げ場という表現もあると知り、私は「なるほど」と思いましたし、お尻がどうのこうのという文章はなんだろうな、とおもっていたら元ネタの小説があると教えられたり、こういう例をはじめとして大変勉強になりました)、本当に様々な人が同時に作業を行い、どんどん結果が積み重なってゆく様は圧巻で、その他大勢の一人としてこのような経験を得たことを大変光栄に思います。

それに、作業が実に楽しい。こればっかりは実際にやった方だけが分かる楽しみですよね。

十数時間というほんの短い間でしたが、プログラムの世界でのコミュニティへの参加とはちょっと違う、貴重な体験でした。

まあ、人の言うことをちゃんと聞かないで勝手に勘違いしたり、バグを作りこんでいたり、結局はこのblogの目的である恥の記録も達成できてしまいましたが、とにかく今回、繰り返しになりますが、シートを用意してくださった方の忍耐力とモチベーションの高さに強く感銘を受け、感謝の念とともに、このように駄文を書き散らした次第です。

ご清聴、ありがとうございました。
ちなみに、私、まだ買ってません。

2015年12月17日木曜日

UnityではSystem.IO.Compression.GZipStreamが使えない

UnityではSystem.IO.Compression.GZipStreamが使えない!!
シリアル化したセーブデータを圧縮・伸長したいのに!!

と思ったらきちんと代替手段が用意されていたで御座候。
それどころかbzip2まで用意されてござる(遅いから今回は使わないけど)。

しかも、(おそらく)セーブデータなどでの圧縮・伸長用に考慮されているとみえ、streamとして扱える丁寧なつくりです。

私事ながら現在手掛けているC:SL用MODはシリアル化するとかなり大きくなるデータを扱うMODなのでSystem.IO.Compression名前空間のお友達に会えないとわかった時にはどうしようかと思いましたが、このおかげでセーブデータ長制限に引っかかる率も格段に下がってありがたい限りです。

使い方は超簡単。例えばリストア先クラスfooがあったとして、速度重視でgzipで伸長してシリアルデータからオブジェクトに戻す場合は、
BinaryFormatter bf = new BinaryFormatter();
using ( MemoryStream ms = new MemoryStream( savedata ) ){
  using ( GZipInputStream gs = new GZipInputStream( ms ) ){
    foo = bf.Deserialize( gs ) );
  }
}
MemoryStreamをコンストラクタへの引数にするだけ。
間に一枚かぶせるだけで済みます。圧縮(GZipOutputStream)の場合もまた然り。

・・・確かに標準のライブラリより多機能かもしれないけど・・・メンドクセ

2015年12月11日金曜日

Cities: SkylinesのmonoランタイムにはSystem.Type.op_Equalityメソッドがない

ようやくロード・セーブの方式も確立して、多言語化もほぼサポートして、基本的な雛形が完成したので、さあこれからだ!というところでいきなり躓きました。

データ保持用のクラスに項目を追加しただけで急に動かなくなりました。

Cities: Skylinesでのデバッグは仮に例外が発生していても本体側で握りつぶしてしまうのでどこで起きているかわかりません。
そのうえ、Unityの仕様だと思いますが、プロセスにアタッチしてもソースレベルではデバッグが不可能。
デバッグコンソールか自力でエラーログをファイルに吐くしかなくて、さらにスタックトレースを出そうとしても、トレース情報がランタイムによって消去されてしまって表示不可能ときた。

提供されているクラスライブラリのドキュメントがどこにもない(どう探しても見つからない!!)ので試行錯誤や諸先輩方の公開されているソースだけに頼っている上に、いまどきprintfデバッグが必要というとんでもない代物なのでなかなか進みませんが、ただメンバを追加しただけなのに急に動かなるとかいったいどういうことが起きているのかさっぱりわかりませんでした。

とりあえず怪しそうなところをprintfデバッグで絞り込んでcatchしてみると
MissingMethodException: Method not found: 'System.Type.op_Equality'
なる例外が。

このエラーは追加したクラスのメソッドを呼び出す際に発生していることが分かりました。
呼び出されるメソッドはただコンストラクタから呼び出されて変数の初期化をするだけの変哲もないもので、そもそもこんなメソッドを呼んだこともないし見たこともないので面喰いました。

調べてみると、これは.Net Framework v4で追加されたものだそうですが、monoはv4に対応しているものの、Cities: Skylinesの採用するミドルウェア(Unity)が古いmonoを採用しているため、v3.5相当の機能しか使えないことがやっとわかりました。

VisualStudio2015でビルドまでしてしまっていたので、v4.6がターゲットになっていたため、このトラブルに見舞われました。

最初からきちんと調べるか、ビルドはCities: Skylines側が提供するバイナリで行えばこのようなトラブルは起きえないのですが、自分の粗忽さから招いた自業自得でした。

また一つ、恥をかいてしまいました。

2015年12月9日水曜日

Cities: Skylinesのmodを作ってみよう

ということで、昨日から作り始めました。

assetじゃないよ。
modとassetをごっちゃになさっている方はそのままブラウザの戻るボタンを押下してくださいませ。

C:SLのmodはC#で書くんだぜ、ということらしいので久しぶりにC#触ったけど、なんだか以前触った時よりものすごく進化していますねえ。びっくりしました。

まあ、別にC#に精通するつもりはないのであんまり深く追っかけないことにして、とりあえずひな形としてIUserModを継承したクラスを作って、NameとDescriptionを返せばとりあえずは体裁が整います。

でもこれだけじゃ意味がないので、UI画面を作るにはUIPanelから継承したクラスを作って、それをLoadingExtensionBaseを継承したクラスメンバのOnLevelLoaded()で、

UIView.GetAView().AddUIComponent( typeof( "UIPanelから継承したクラス" ) )

とするとUI画面ができました。

画面が出てしまえばもうこっちのものなので、今度はその画面に表示するデータをセーブファイルに紛れ込ませる方法は、ISerializableDataExtensionを継承したクラスを作るだけ。

C#のすごいところは、リストを含んでいようがインナークラスを含んでいようが、いとも簡単にシリアライズできてしまったところ。
これは実に驚きました。

うーん、なんて楽なんだ・・・

ポインタがある言語ではクラスや関数が多種類あるけど呼び出し形式もとれるデータ形式も同じだよ、というような場合の処理は関数やメンバ変数へのポインタが大変便利ですが、メモリ管理が自分でできない言語だと多少厄介です。
その点、javaと同様にC#もリフレクションが充実しているようです。
おかげで、メンバ名で直接メンバの値を操作できるような仕組みが実装できました(でもやっぱりポインタのほうが分かりやすいなぁ・・・)。

たとえば、

public class foo{
  public bar piyo ;
  public foo(){
    piyo = new bar();
  }
  public class bar{
    public int hoge;
  }
}

なクラスに"piyo.hoge"というメンバに"文字列で"アクセスしたいなぁ、といったときに

float getValueFromMemberName( object topobj, string member )
{
string[] arrays = member.Split( '.' );
object obj = topobj;
for ( int i = 0 ; i < arrays.Length ; i++ )
{
Type t = obj.GetType();
obj = t.InvokeMember( arrays[i], System.Reflection.BindingFlags.GetField, null, obj, null );
}
return (float)Convert.ChangeType( obj, typeof( float ) );
}
という関数をでっち上げて、topobjに new foo() したオブジェクトを指定して、memberに文字列で"piyo.hoge"と指定してやると、hogeの値が(intなのに)floatで頂戴できるという寸法。
まあ、ポインタが使えない苦肉の策なんですけども、javaとかC#のような言語ならではですねえ。

いまだにCSLのライブラリ群のドキュメントを見つけられていないんですが、VisualStudioのオブジェクトブラウザでメソッドやクラスを眺めているだけでだいたい見当がついちゃったのはこの手の言語ならではでしょうね。

基本的な表示とセーブデータへの私のmod固有のデータのセーブ・ロード方法が分かったので、あとはきちんとUIを作るだけになりました。
ドキュメントが全然ないフレームワークに乗っかっても1日でここまで来るとは思いにもよりませんでした。

あとは、同じようなmodが先に公開されませんように祈りつつコーディング作業を急がなくては。。。

2015年11月16日月曜日

Cities: Skylinesをやってみた その3

ふと気づくと膨大な時間を費やしていて「自分はいったい何をしていたのだろう」と自問自答することがわかっているのにも拘わらず、やっぱり起動してしまうのは典型的な中毒症状なんでしょうね。

わざわざdespawnさせないmodを入れて数十キロに及ぶ渋滞を見事に解消できた瞬間の醍醐味はたまりません。

主に渋滞の原因となるのは道路も線路も貨物輸送です。
特に貨物駅前の渋滞は深刻になりがちですが、実は割合簡単に貨物駅前の渋滞は解消できます。渋滞してしまうのは主に

  1. 貨物駅から出た車両がスムーズに目的の商業施設に到達できずに途中で信号待ちや交通量の多い車線と合流させていて渋滞してしまう
  2. 輸入(市内移送を含む)に加えて輸出車両が多すぎて貨物駅への帰還と搬入速度が追い付かない
の2点が主な原因となりますが、項番1は単純に目的地近くまで遅滞なく到達できる道路を引けばそれでしまいです。というよりも、これを行うことがまず大前提です。なのでおいておくとして、深刻なのは項番2です。
こうなると貨物駅の増設が最も効果的ですが、小手先で何とかしたい場合は貨物駅へのアクセス口を若干工夫すると搬入速度が上がります。

例えば、以下のような直線道路に沿って貨物駅が敷設されている場合、計測してみると41両/毎分程度、貨物駅に入場できます(画面では速度3になっていますが、計測時は速度1でカウントしました)。
一方、以下のように搬入するトラックをなるべく減速させないように入口を工夫して計測してみると、47両/毎分まで搬入可能になります。
両者とも数回づつカウントしましたが、概ね誤差は0~1両でした。
20%弱の搬入量の向上が見込めますので、「あと少し搬入速度が速まればなんとかなる!」という場合には有効かもしれません。
ですが、やはり王道は輸出入量に合わせた貨物駅の増設ということになると思います。

まあ、道路は引き方次第で結構どうにでもなるのですが、貨物列車の渋滞はかなり厳しいです。
勿論貨客分離は当然のこと、さらに外部につながる貨物駅は限定する、渋滞した貨車が経路を分岐点を塞がないように線路を引くことを前提としていても、

たとえば、こーんなのや、

 こーゆーのや、
 こーんな具合に
画面が続く限りに貨物列車がイモムシの行列のように延々と画面に収まらない長さで連なってしまうと途方に暮れてしまいます。
まさに圧倒的な物量作戦で都市を破綻させる恐るべき事態に見えます。

しかし、原因は簡単で、貨物駅の荷捌き時間がかなり遅いにもかかわらず、一駅に集中させすぎているから列車を捌ききれずにこんなことが発生するわけです。

そんな時は、経路ツールmodで貨物駅から出場する貨物トラックが最も多く向かう先を調査して、その近くに貨物駅を設置すると、一気にイモムシの行列が激減します。

しかし、これらをすべて一つ一つ、地道に解決していった先に待ち受けるものがあります。
オブジェクト制限です。

たとえば、
左が本来の車両数、右が上限に達してしまった後spawnした車両です。
運転台がない電車が120km/hで疾走していきます。

貨物列車も同様です。貨車なんか1両も引いてないただの機関車が爆走してきます。
編成の長さゆえにあれほど苦しんだ配線なんぞお構いなしです。

結局こんなむなしい事態に陥ることが分かっているのに、やっぱりやってしまいます。
つくづく典型的な中毒症状を呈しているなあ、と我ながら思います。

2015年10月20日火曜日

Cities: Skylinesをやってみた その2

人口15万人程度の都市を2つほど作ってみました。

重い、重い、とあちらこちらで言われていましたのでどうなるかと思いましたが、ふたを開けてみればこの程度の人口では、ブラウザゲーで農場経営を片手間にやりながら新区画の成長待ちをしていても動作は軽快なので安心しました。なお、アセットはファミリーマートしか入れていません。

試しにsteamから人口30万人ほどのセーブデータをダウンロードしてみると、さすがにややカクつきは見られたものの、個人的にはどうってことはないレベルでした。
但し、f/sが気になって仕方ない人には悶絶ものかもしれませんが。

1つ目の都市はヨーロッパスタイルだったので、区画の形に従って隙間なく建物が並ぶロジックには大いに感銘を受けたものの、高密度区画が住居も商店もオフィスも、どいつもこいつも同じにしか見えなくなって飽きて放棄。

2つ目の都市は亜寒帯で作り始めましたが、現代的な建物にようやく巡り合えてホっとしています。
こちらの都市は15万人でやめたわけではなく、低密度を多めにしているため、開発面積のわりにあまり人口が伸びていません。低密度中心だとメガロポリス解禁までえらい時間がかかる上に財政上も割とシビア(それでも甘々ですが)になりますね。

ところで、地区を指定した上で、その地区に対してスタイルを指定(以下の画像の赤枠矢印のところで指定しています)すると、そのスタイルの建物だけが生えてくるという面白い機能があったので試してみると、以下のようになりました。



画面に映っている建物はほぼすべて高密度な住居なのですが、手前側はヨーロッパ風建築だけが立ち並んで風致地区のような感じになり、奥は近代的な高層建築となってメリハリが出てきた感じがします。
しかし、改めて画像をみると、陰になっていたりヨーロッパ建築地区にハイテク住宅条例を適用したせいか太陽光だか太陽熱パネルが汚らしいですね。
山など正月の澄み切った空気の時にかろうじて高い建物から富士山か筑波山が見えるようなところで生まれ育ったもので、つい山の稜線にヤられてしまったのかもしれません。。。

steamのworkshopでもdistrict styleで検索してみると、なかなかよさそうなものがありますので、メモリが許してくれる範囲内で試してみたいなと思っています。

ところで、現在悩んでいることが一つ。
やたらとこのゲーム、フィルタが白っぽくありませんか?
フィルタなしだと以下のようにむやみに白っぽくなります。



温帯フィルタやヨーロッパフィルタはまだマシなのですが。
アドリア海沿岸じゃないんだから、とか思いながらもうちょっと落ち着いた色調なフィルタを求めてあれこれ試しているのですが、それでもまだ白っぽく感じてしまい、どうもしっくりくるものがありません。
逆に言えばフィルタだけでいろいろな種類が出るくらい自由度が高いソフトウェアなので,
自由度と引き換えに制御権を得ようとして失敗したEAとかが歯噛みして悔しがってるんじゃないかしら、などといらんことを思ったり。

このゲーム、渋滞対策に飽きたら街並みを眺め、街並みを眺めるのに飽きたらズームアウトして大局的な拡張計画を立て、拡張計画に煮詰まったら住人視点(Enhanced Zoomは夜間もチラつかないのでお勧めです)で移動中の景色を楽しみ、それに飽きたら街並みを拡張し、渋滞対策にまたもどる、と、SimCity2013のようなイマイチ感もなく、SimCity4RushHourの時のような楽しさと虚しさ(長時間渋滞対策や区画設計と向かい合った後の「なにやってたんだろ、自分は」というあの虚しさ・・・お分かりいただけますでしょうか)を十二分に満喫できます。

こないだ本体をsteamで50%offセールで買いましたが、近いうちにハロウィンかクリスマスでどーんとセールしてくれるんじゃないでしょうか。もともと安いにもかかわらず、定価で買いたくないでござる病(私です)に罹患していてもそのシーズンは期待できるので、After Dark、10%offでもいいから来ないかなあ。
背中を押してくれればいいのでござる。

2015年10月8日木曜日

Cities: Skylinesをやってみた

Steamで半額セール中だったので買ってみました。

確かにスバラシイ。私はこの手のゲームが大好きなもので、思わず時間を忘れてプレイしてしましました。
ですが、それこそあちこちの紹介記事やblogなどで大絶賛されているほどのものかと、現状では正直微妙でした。

たしかに、SimCity(2013、以下年号を省きます)をやっていると大変に不満に思う点はマップサイズなのですが、その点に関してはまるでSimCity4の時のような自由な開発が可能なのと、SimCity4より優秀なのはいちいちマップを切り替えなくても、マシンスペック次第(とオブジェクト数)では広大な地域を切り替えなしで開発できる点は、やっぱりゲームとしての楽しさとして重要な要素だと強く再確認しました。

ですが、どうも・・・うーん。

SimCityで満足している点がCities: Skylinesでは行えず、Cities: Skylinesで満足している点がSimCityでは行えなくて、というモヤモヤ感はどうしてもぬぐえません。

正直言ってSimCityで不満な点はマップサイズと椅子取りゲーム。それがないからCities: Skylinesは優れている!
というわけにはいかないのが困ったところ。

各種データの見せ方や操作方法、遊び心(犯罪率が上がると建物に落書きが増えるとか)などはSimCityが一日の長どころか断然優れています。その他も含め、まさにこなれたつくりです。
一方、まだまだ路面電車はないし高架の駅もモノレールもありませんが、Cities: Skylinesはマップ内で鉄道が意味を持つとか(日本の首都圏に住むと鉄道の重要性を災害が起きるたびに再確認させられるのもあってか、道路だけだと味気ない)、I/Fの改善も含めてコミュニティレベルの開発が活発でSimCity4でいうMODとかBATが多くあるのも魅力ですし、そもそもマップが広く田舎町と都会を表現できるのはこの手のゲームとして極めて重要だということは論を待ちません。

それに価格差。SimCityとCoTを定価のまま買ってしまったのに、もともとの価格がCities: Skylinesは安いのに今回は半額で買ってしまったので、もう何をか況や、ですが、この手のジャンルを担うのは現在のところこれしかないのです。

SimCityはもうMaxisが解散していますし、CD版SimCity4もDRMの関係で動きませんし(Windows10にした私が悪いのです)、もうEAがなぜか本気になってMaxis以外に作らせてSimCityを復活させる、なんてことはまず期待薄ですから、このCities: Skylinesが育ってくれないと、この手のゲーム好きにとって甚だ困りますが、作っているスタジオはそれこそ零細ですから、Paradox次第です。パブリッシャとしてのParadoxにそこまでの気合と体力があるのかどうか。

なんだかCPUとGPUのファンのうなりがものすごいことになるゲームなんて久しぶりで(ミドルウェアが無駄に使ってんだろうと思いますが、各OS向けに同時開発出来て低価格でリリースしてくださってるんだから文句のつけようがありません)、愉しくてしょうがないのですが、やっぱり自分の街づくりのセンスがないことに真正面から向き合うマゾいゲームなのはSimCity4から変わらず、選挙も経ていない市長として強権を発動しまくって市民の皆さんには大変申し訳ございません(が思い通りに都市開発しちゃいます)。

市議会がなくてよかった。