PlutoEngine とは
ようこそ、PlutoEngine の世界へ。
PlutoEngine(プルートエンジン)は、**「ブラウザ上で10万〜30万体以上のエンティティを、60FPS / 144FPSで安定して滑らかに動かす」**ことを追求した、データ指向(Data-Oriented Design / SoA)2D WebGPUゲームエンジンです。
+-------------------------------------------------------+
| PlutoEngine |
+-------------------------------------------------------+
| | |
[ Zero-Allocation ] [ Data-Oriented SoA ] [ WebGPU ]
毎フレームのGCゼロ 連続TypedArray配置 Instanced Draw転送
| | |
+----------------------+----------------------+
|
100,000〜300,000+ スプライトが 144 FPS で躍動なぜ PlutoEngine が必要なのか?
現代のブラウザゲーム開発において、**「大群(スウォーム)サバイバー」「超高密度弾幕シューティング」「大規模シミュレーション」**といったジャンルは、従来のHTML5/JavaScriptゲームエンジンにとって難所でした。
従来のエンジンが直面する「GCの壁」
PixiJS や Phaser などの成熟したエンジンは、直感的なオブジェクト指向(OOP)とシーングラフ構造を採用しています。しかし、エンティティ数が数千〜数万に達すると、以下の問題が顕在化します:
- ガベージコレクション(GC)スパイク: 毎フレーム無数に生成・破棄される小さなオブジェクト(
Vector2、パーティクル、スプライトハンドル)がブラウザのV8エンジンに負荷を与え、数秒おきにフレームが落ちる(スタッター)。 - CPUキャッシュミスの多発: 個々のオブジェクトがヒープ上のバラバラなアドレスに散らばるため、CPUのL1/L2キャッシュラインにデータが乗らず、メモリレイテンシの遅延が累積する。
- 描画ドローコールの爆発: オブジェクトごとに状態を切り替えて描画するとGPUコマンドのオーバーヘッドが増大する。
PlutoEngine は、これらの問題をアーキテクチャの根本から覆すことで解決しました。
3つのコア設計思想
1. ゼロアロケーション (Zero-Allocation)
ゲームの実行中(update や render のクリティカルパス)、ヒープメモリの動的確保(new、{}、[]、.push())は一切行われません。 すべてのエンティティやトゥイーン、物理演算データは、起動時にあらかじめ確保された固定容量のアリーナ(InstanceBufferArena)内で循環再利用されます。
TIP
毎フレームのアロケーションがゼロであるため、ブラウザのガベージコレクタは完全に沈黙します。何時間連続でプレイしても、フレーム落ちのないシルキースムーズな描画が持続します。
2. データ指向設計 (Data-Oriented Design / SoA)
エンティティを「オブジェクト(クラスのインスタンス)」として持つのではなく、配列の集合(Structure of Arrays)として保持します。
// 従来のオブジェクト指向 (AoS: Array of Structures) - キャッシュ効率が悪い
const enemies = [
{ x: 10, y: 20, vx: 1, vy: 2, hp: 100 },
{ x: 15, y: 25, vx: 1, vy: 2, hp: 100 },
];
// PlutoEngine (SoA: Structure of Arrays) - 驚異的なキャッシュ局所性
class InstanceBufferArena {
posX = new Float32Array(100000);
posY = new Float32Array(100000);
scale = new Float32Array(100000);
facing = new Float32Array(100000);
tint = new Uint32Array(100000);
}位置の更新処理は単一の Float32Array を一直線にループスキャンするため、CPUキャッシュラインを効率よく満たし、SIMDライクな高速演算を実現します。
3. フライウェイト・ハンドル (Flyweight Pattern)
開発者が直感的なコードを書けるよう、Sprite などのクラスは薄いラッパー(Flyweight Handle)として機能します。
// sprite はアリーナ内の ID(インデックス数値)だけを保持する軽量ハンドル
const sprite = this.add.sprite(100, 200, 'textureKey').setDisplaySize(32, 32);
sprite.x += 5; // 内部では arena.posX[sprite.id] += 5 に直接変換されるグラフィックス: WebGPU 完全統合
PlutoEngine のレンダラーは、インスタンシング描画(Hardware Instanced Drawing)を前提に最適化されており、WebGPU で 30万体(300,000+)の同時描画を安定してサポートします。
- WebGPU 完全対応: WGSL によるモダンな描画パイプラインを実装。ライトスルー同期(Write-Through)によりCPU側のパッキング負荷を排除し、
writeBufferによる転送サイズを最適化。IPC キュー過負荷によるクラッシュ限界を克服し、30万体の極限パフォーマンスを発揮します。 - ゼロアロケーション SoA 連携: SoA アリーナデータを、毎フレームのヒープ確保ゼロで VRAM へダイレクトにストリーミングします。
4つの配布・利用形態
PlutoEngine はあらゆるプロジェクト規模・環境に対応できるよう設計されています:
| 形態 | 説明 | 用途 |
|---|---|---|
| 1. GitHub ソースコード | モノレポ(Bun workspaces)をクローンして独自にエンジンを拡張 | エンジン自体のカスタマイズ、コア開発 |
| 2. TypeScript インポート | @pluto-engine/core を npm / bun 経由で導入し、完全な型推論を享受 | Vite、Next.js、Nuxt などのモダンWeb制作 |
| 3. トランスパイル済み ESM | ビルド済み pluto.esm.js をインポート | バンドラーなしのモダンブラウザ環境 |
4. <script> タグ (CDN) | 単一の pluto.global.js をHTMLに埋め込むだけ | プロトタイピング、CodePen、ブログ埋め込み |
他のエンジンとの比較
| 項目 | PlutoEngine | Phaser 3 | PixiJS v8 |
|---|---|---|---|
| 同時スプライト数 (60FPS) | 100,000〜300,000+ | 約 3,000〜5,000 | 約 10,000〜20,000 |
| メモリ設計 | 完全 SoA (TypedArray) | オブジェクト指向 (AoS) | シーングラフ (AoS) |
| 実行時GCアロケーション | 0 バイト (Zero-Alloc) | フレームあたり多数 | フレームあたり少量 |
| 物理エンジン | 超軽量 XPBD ソルバ | Arcade / Matter.js | 外部ライブラリ依存 |
| 空間分割探索 | 内蔵 Morton ハッシュ | なし (自作必要) | なし |
| DX (開発体験) | Phaserライクな直感API | 直感的で成熟 | レンダリング特化 |
次のステップ
まずは インストールとセットアップ に進んで、開発環境を構築しましょう。 すぐに動くコードを見たい方は Hello World をご覧ください。