技術 約7分で読めます

IFしか知らない人が3か月でCivicSurvivalを作れた理由

いけさん目次

DEV Communityに、Cities: Skylines II向け大型mod「CivicSurvival」を3か月の実作業で作ったという記事が出ていた。
著者は自分のプログラミング背景を「IFしか知らない」と書いているが、成果物は小さなプロトタイプではない。C#が158,583行、TypeScript/Reactが31,219行、ECS systemsが542、UI componentsが369、custom Roslyn analyzersが300超、Git commitsが2,503。
読んでいて引っかかったのは、速さよりも、AIが壊しやすい場所をどれだけ外側から縛っているかだった。

原典は Valentyn Kurchenko-Hai の How I, knowing only IF, vibecoded CivicSurvival
2026-05-06公開で、CivicSurvivalは現時点ではclosed betaだとされている。

mod本体より周辺装置の話が濃い

CivicSurvivalは、Cities: Skylines IIに停電、発電機、汚職、パニック、防空、避難所、情報戦のような要素を足すtotal conversion modだ。
ゲーム側の説明だけでも重いが、記事の主役はゲームデザインそのものより開発環境だった。

スタックはC#、Unity DOTS/ECS、Burst、Harmony patches、Coherent UI、TypeScript/React。
その周囲にPython製のCivicRAG、MCP server、codebase indexing、SQLiteのvector searchとfull-text search、export scripts、report generators、audit用ツールが乗っている。
著者は「one mod fileではなくsmall ecosystem」と書いているが、数字を見ると本当にそういう規模だ。

この話は、以前書いた AIで80年代風ゲームを数日で作る、Phaser3と役割別スキル分割で回すdev.to記事 とかなり違う。
あちらは、短期間のブース向けゲームをデザイナー、Phaser実装、8bit音楽のスキルに割る話だった。
CivicSurvivalは、役割分割だけでは足りない規模まで行っていて、AIが読める索引、AIが破れないコンパイル時ルール、AIが嘘をつけないビルドログを積み上げている。

CivicRAGは便利検索というより迷子防止

記事で出てくるCivicRAGは、コードベース探索用の独自MCP serverだ。
普通の grep では、BlackoutState を誰が読むのか追いにくい。ComponentLookup<BlackoutState> がフィールドに隠れたり、ECS systemの実行順序やdomain間の接続が文字列検索だけでは見えなかったりする。

そこで著者は、542 systems、369 UI components、1,427 cross-domain linksを索引化した。
rag_query("blackout permanence") でsemantic searchし、rag_component("BlackoutState") でwriter、reader、execution orderを見る。
rag_styk("AirDefense", "Threats") のようにdomain間の接続面も調べる。

ここでのRAG(検索拡張生成)は、LLMに何でも知っているふりをさせるための飾りではない。
AIが隣のsystemを読まずに「たぶんこう」と補完するのを止めるための索引だ。

この方向は、YourMemoryは生物学的減衰でAIメモリの古い文脈を捨てる で見た個人用メモリとは別物に近い。
YourMemoryは作業中の記憶を呼び戻すためのMCPだったが、CivicRAGは大規模コードベースの接続関係をAIに再発見させるための道具になっている。
同じMCP/RAGでも、「過去の会話を思い出す」と「今のコード構造を取り違えない」はかなり違う。

300超のRoslyn analyzerがAIの自由を削る

一番実務に効くのは、Roslyn analyzerのくだりだった。
著者は、AIに300超のcustom Roslyn analyzerを作らせ、それを毎回のビルドで走らせている。

Unity DOTS/ECSは、普通のC#より事故りやすい。
EntityManager.SetComponentDataOnUpdate の中で呼ぶとsync pointになってFPSを落とす。
ComponentLookup<T>.Update(this) で更新し忘れるとruntime errorになる。
EntityQueryOnUpdate で作るとleakの原因になる。
C# compilerは、こういうプロジェクト固有の設計違反を捕まえない。

そこで CIVIC051OnUpdate 内の EntityManager 書き込みを禁止し、CIVIC310 はmagic numberを GameRate.SECONDS_PER_HOUR のような定数経由に寄せる。
CIVIC361 はdomainからdomainへのimportを止める。
AIがルールを忘れても、compilerとanalyzerが止める。

AIコーディングエージェントを本番に載せるための設計原則 では、Stripe MinionsのDevboxやToolshedを見ながら「モデルが間違えたときにどこまで壊れるか」を制御する話を書いた。
CivicSurvivalは企業の本番運用ではないが、発想は近い。
違いは、インフラの爆発半径ではなく、コードベース内部の設計違反をcompile-timeで潰している点だ。

CLAUDE.mdのような文章ルールだけだと、AIはよく横から抜ける。
「sync pointを作るな」と書いても、便利helperの内側で同じことをやる。
analyzerに落とすと、その抜け道の一部がコンパイルエラーになる。

目で見るバグにAIは弱かった

記事の後半で、著者はdrone renderingに2週間近く溶かした話を書いている。
Unity ECS、DOTS、CS2のrender pipeline、BatchRendererGroup、HDRP、motion vectors、temporal smoothing、Coherent UI、custom .cok models、decompiled Game.dll が絡んだバグだ。

ログ上は正しそうに見える。
ECS componentsもstock objectと合っている。
CPU-side dataの座標もstock carと同じように見える。
それでも画面上のdroneは加速時に脈打つ。

AIはdiagnostic systemを作り、Harmony patchを書き、decompiled codeを整理するところでは役に立った。
しかし、画面を見て「これは数学的なjitterではなくmotion blurのpulsationだ」と切り分ける部分は苦手だった。
最終的には、CS2 1.5.5でmotion vector flagsをうまく制御できない経路を諦め、速度が1xを超えたときだけHDRP Volume overrideでmotion blurを0にする回避策に落ち着いた。

ここはAI開発記事としてかなり健全だと思った。
「AIなら巨大modも作れる」で終わらず、「ログに出ない視覚的な違和感をAIは取り違える」と書いている。
ゲーム開発では、動く、正しい、気持ちいいが別々に存在する。
AIは最初の2つに寄りやすく、最後の1つは人間の目と手触りが残る。

AI監査は数で押してから固定ルールへ落とす

CivicSurvivalでは、AI agentをstatic testerのように大量投入している。
記事中では、AUDIT_HISTORY.md に約9,700件超のclaimed findings、5,500件超のfixedが記録されていると説明されている。
March aloneで約1,500 debugger-agent reports、約2,600 unique findingsという数字も出てくる。

この数字だけ見ると怪しい。
AIの指摘は重複するし、誤検知も混ざる。
著者もそこは分かっていて、agentが疑いを出し、別agentが確認し、fixがbuildを通り、繰り返し出る種類の問題をanalyzerへ昇格させる流れとして扱っている。

AI auditを「大量の目視レビュー」として信じるのではなく、「ルール候補の発見器」として使う。
一度見つけた危険パターンをRoslyn analyzerに移せば、次からはAIの気分ではなくcompilerが止める。

tmuxでClaude CodeとCodexを連携させて一晩放置でゲームを作らせる(実践編) では、Claude Codeに実装させてCodexにレビューさせる自動ループを試した。
あれは小規模ゲームを一晩回す実験だったので、レビュー結果はその場の修正に閉じていた。
CivicSurvivalの話は、その先にある。
何度も出る指摘を、人間が読む報告書ではなくコンパイル時の禁止事項に変換している。

「IFしか知らない」は責任を持たないという意味ではない

原典のタイトルは強い。
「IFしか知らない自分が、AIで158K行のmodを作った」と読める。
ただ、本文を読むと、著者はコードの意味への責任を手放していない。

自分でC# syntaxを全部書けない。
それでも、どのdomainが状態を書き、どのsystemが読むか、変更がsave migrationに触れるか、UI bindingが必要か、analyzerを追加すべきかは見ている。
AIが出したplanを1回で通さず、何度も読み直させ、risks、forbidden actions、expected behavior、具体的なfilesを入れさせる。

これは planning-with-files のようなファイルベース計画管理にも近い。
ただしCivicSurvivalでは、計画ファイルだけでは足りず、CivicRAGとanalyzerとbuild logまで含めて「AIが迷子にならない外部状態」を作っている。

この事例で使えるのは、「知らないsyntaxをAIに任せる」と「知らない構造までAIに任せる」を分けているところだ。
前者は成立する。後者をやると、5,000行あたりで崩れる、というのが著者の線引きになっている。

参考