小さな数式とルールから、思いもよらない多様性が生まれるのを、画面の中で見守る時間が何より楽しいです。
自然の生態系は、無数の生き物が関わり合いながら成り立っています。
その複雑さを少しでも再現したくて、Rustとゲームライブラリ「Macroquad」を使い、進化するエコシステム・シミュレーションを作りました。

テーマは「見た目の色が、性質や行動に影響する世界」。
HSV(色相・彩度・明度)で表した色を、そのまま生き物の能力に結びつけています。
たとえば、赤系の個体は肉食で速く、緑系は植物、青系は腐肉食。色そのものが生態を決めるのです。
色が決める生き物たち
このプロジェクトでは、「色」という抽象的な概念を行動の源にしました。
色相のわずかな違いが、捕食や繁殖の関係を変え、世界の形を変えていきます。
人間が決めたアルゴリズムなのに、まるで意志を持つように変化していくのです。
シミュレーションでは、すべての個体がHSVで表されます。
- 肉食系(赤〜赤紫):素早く、他の生き物を狩る
- 草食系(黄〜青):中速で、植物を食べる
- 植物系(緑〜青緑):動かず、光合成でエネルギーを得る
- 腐肉食(青紫):遅いが、死体を分解する
RGB値にも意味を持たせています。
赤成分は索敵範囲、緑は繁殖力、青は移動速度に影響します。
つまり、見た目の色がそのまま能力パラメータを表しているのです。
捕食と繁殖:シンプルな関係から生まれる多様性
捕食は「色相差」で決まります。
ある生き物が、30〜90度ほど離れた色相の相手を見つけると捕食が発生します。
また、赤成分(R値)が高いほど強い個体になります。
捕食で得られるエネルギーは一定量で、これが生命の循環を生みます。
繁殖は「似た色相(±20°)」同士でのみ発生します。
植物も同じ仕組みを持ちますが、動物と異なり、エネルギーコスト制で制御しています。
具体的には、植物が繁殖するときに breed_energy を消費し、その半分を子に渡します。
親はエネルギーを失い、子は成長のために少しずつ光合成を始めます。
感染と死:病原体も生態の一部
世界には病原菌も存在します。
一つの種が増えすぎたときの負のフィードバックになると考えたからです。
それ自体は独立した個体ではなく、宿主に寄生します。
感染は接触で起こり、病原菌が「R値(免疫力)」よりも強い場合に成立します。
感染すると、宿主のエネルギーが1フレームごとに少しずつ減っていきます。
腐肉食の個体が感染した死体を食べると、病原菌が再び移ることもあります。
画面上では、感染した個体の上に青紫の小さな円が重なります。
これにより、画面全体がまるで生命の顕微鏡映像のようになります。
システムの骨格:RustとMacroquad
開発環境はRust 1.76、ゲーム描画はMacroquad 0.4。
ウィンドウサイズは1600×1000ピクセル。左に「世界」、右に300ピクセルのUIパネルを置きました。
生き物の描画や当たり判定などを、すべてRustの構造体で管理しています。
Rustの強みは「安全性」と「速度」の両立にあります。
エコシステムのような大量の並行処理を扱うとき、
メモリ破壊の心配がないことは大きな安心です。
Rustはメモリ安全性が高く、数百〜数千の個体を同時に扱っても安定して動きます。
ただし、借用チェック(borrow checker)に何度も阻まれました。
感染処理のように「同時に2体を参照する」場面では、split_at_mut で可変参照を分ける実装に落ち着きました。特に、複数の個体間で相互作用する箇所では、
「どちらがどのタイミングで参照されているか」を明確に示す必要がありました。
パフォーマンスとの戦い:FPSを保つ工夫
個体数が増えると処理は一気に重くなります。
FPSが30を下回ると、繁殖や植物の生成を一時的に止める仕組みを追加しました。
この制御により、描画は安定し、世界が「自壊」することを防げます。
また、一定フレームごとにフレーム時間や処理ペア数をログ出力するようにして、
ボトルネックを把握できるようにしました。
大量の個体をリアルタイムに扱うには、計算負荷の可視化が不可欠です。
行動選択で、周りの個体を検索する時間がネックだったので、毎フレームではなく間引くようにすると、かなり高速化しました。