game-development について
複数プラットフォーム向けのゲーム開発ガイドで、アーキテクチャ、描画、物理、AI、マルチプレイヤー、最適化を扱います。一般的なパターンとコード例に加え、ゲームエンジンや関連スキルも紹介します。
主な機能
- 01ゲームループと ECS アーキテクチャ
- 022D アニメーションと衝突判定
- 03ステートマシン、ビヘイビアツリー、経路探索
- 04マルチプレイヤー通信と状態同期
- 05描画とメモリの最適化
- 06ゲームエンジンのリファレンス
活用シーン
- 01ゲームループとエンティティシステムの設計
- 022D 衝突判定とキャラクターアニメーションの実装
- 03敵 AI と経路探索の計画
- 04描画とオブジェクトのメモリ使用量の最適化
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ miles990/ claude-software-skills --skill game-developmentインストール後、Claude Code で/game-developmentを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
flame/flame-templates/references/platformer.mdroguelike.mdrpg.md詳細
ゲーム開発
概要
クロスプラットフォームでゲームを開発するためのパターンと実践。アーキテクチャ、レンダリング、物理演算、AI、マルチプレイヤー、最適化を扱います。
ゲームアーキテクチャ
ゲームループ
┌─────────────────────────────────────────────────────────────┐
│ Game Loop │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Input │ ─→ │ Update │ ─→ │ Physics │ ─→ │ Render │ │
│ │ Process │ │ Logic │ │ Step │ │ Frame │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ ↑ │ │
│ └─────────────────────────────────────────────┘ │
│ Next Frame │
└─────────────────────────────────────────────────────────────┘
固定タイムステップと可変タイムステップ
| 種類 | ユースケース | コードパターン |
|---|---|---|
| 固定 | 物理演算、決定論 | while (accumulator >= dt) { update(dt); } |
| 可変 | レンダリング、アニメーション | update(deltaTime); |
| ハイブリッド | ほとんどのゲーム | 固定の物理演算、可変のレンダリング |
// Hybrid game loop
let accumulator = 0;
const FIXED_DT = 1/60;
function gameLoop(currentTime: number) {
const deltaTime = currentTime - lastTime;
accumulator += deltaTime;
// Fixed timestep for physics
while (accumulator >= FIXED_DT) {
physicsUpdate(FIXED_DT);
accumulator -= FIXED_DT;
}
// Variable timestep for rendering
const alpha = accumulator / FIXED_DT;
render(alpha); // Interpolate between states
requestAnimationFrame(gameLoop);
}
Entity Component System(ECS)
┌─────────────────────────────────────────────────────────────┐
│ ECS Architecture │
│ │
│ Entity: Just an ID │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │ 1 │ │ 2 │ │ 3 │ │
│ └─────┘ └─────┘ └─────┘ │
│ │
│ Components: Pure Data │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Position │ │ Velocity │ │ Sprite │ │
│ │ x, y, z │ │ vx, vy │ │ texture │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ Systems: Logic │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ MovementSystem │ │ RenderSystem │ │
│ │ Position+Vel │ │ Position+Sprite│ │
│ └────────────────┘ └────────────────┘ │
└─────────────────────────────────────────────────────────────┘
// Component definitions
interface Position { x: number; y: number; }
interface Velocity { vx: number; vy: number; }
interface Sprite { texture: string; width: number; height: number; }
// System
function movementSystem(entities: Entity[], dt: number) {
for (const entity of entities) {
if (entity.has(Position) && entity.has(Velocity)) {
const pos = entity.get(Position);
const vel = entity.get(Velocity);
pos.x += vel.vx * dt;
pos.y += vel.vy * dt;
}
}
}
2D ゲーム開発
スプライトアニメーション
interface Animation {
frames: string[]; // Texture names
frameDuration: number; // Seconds per frame
loop: boolean;
}
class AnimatedSprite {
private currentFrame = 0;
private elapsed = 0;
update(dt: number) {
this.elapsed += dt;
if (this.elapsed >= this.animation.frameDuration) {
this.elapsed = 0;
this.currentFrame++;
if (this.currentFrame >= this.animation.frames.length) {
this.currentFrame = this.animation.loop ? 0 : this.animation.frames.length - 1;
}
}
}
get texture(): string {
return this.animation.frames[this.currentFrame];
}
}
衝突判定
| 手法 | 計算量 | ユースケース |
|---|---|---|
| AABB | O(n²) → O(n log n) | ボックス、単純な図形 |
| 円 | O(n²) | 発射物、キャラクター |
| SAT | O(n²) | 複雑な凸多角形 |
| ピクセルパーフェクト | 高コスト | 正確な衝突判定 |
// AABB collision
function aabbIntersect(a: AABB, b: AABB): boolean {
return a.x < b.x + b.width &&
a.x + a.width > b.x &&
a.y < b.y + b.height &&
a.y + a.height > b.y;
}
// Spatial hash for broad phase
class SpatialHash {
private cells = new Map<string, Entity[]>();
private cellSize: number;
insert(entity: Entity) {
const key = this.getKey(entity.position);
if (!this.cells.has(key)) this.cells.set(key, []);
this.cells.get(key)!.push(entity);
}
query(position: Vector2): Entity[] {
// Check neighboring cells
const nearby: Entity[] = [];
for (let dx = -1; dx <= 1; dx++) {
for (let dy = -1; dy <= 1; dy++) {
const key = this.getKey({ x: position.x + dx * this.cellSize, y: position.y + dy * this.cellSize });
nearby.push(...(this.cells.get(key) || []));
}
}
return nearby;
}
}
ゲーム AI
有限状態機械
interface State {
enter(): void;
update(dt: number): void;
exit(): void;
}
class EnemyAI {
private states = new Map<string, State>();
private currentState: State;
transition(stateName: string) {
this.currentState?.exit();
this.currentState = this.states.get(stateName)!;
this.currentState.enter();
}
}
// Example: Patrol → Chase → Attack
class PatrolState implements State {
enter() { this.setAnimation('walk'); }
update(dt: number) {
this.patrol();
if (this.canSeePlayer()) {
this.fsm.transition('chase');
}
}
exit() {}
}
ビヘイビアツリー
┌─────────────────────────────────────────────────────────────┐
│ Behavior Tree │
│ │
│ [Selector] │
│ / \ │
│ [Sequence] [Patrol] │
│ / \ │
│ [CanSee?] [Attack] │
│ │ │
│ [Chase] │
└─────────────────────────────────────────────────────────────┘
経路探索(A*)
function aStar(start: Node, goal: Node): Node[] {
const openSet = new PriorityQueue<Node>();
const cameFrom = new Map<Node, Node>();
const gScore = new Map<Node, number>();
const fScore = new Map<Node, number>();
gScore.set(start, 0);
fScore.set(start, heuristic(start, goal));
openSet.enqueue(start, fScore.get(start)!);
while (!openSet.isEmpty()) {
const current = openSet.dequeue()!;
if (current === goal) {
return reconstructPath(cameFrom, current);
}
for (const neighbor of getNeighbors(current)) {
const tentativeG = gScore.get(current)! + distance(current, neighbor);
if (tentativeG < (gScore.get(neighbor) ?? Infinity)) {
cameFrom.set(neighbor, current);
gScore.set(neighbor, tentativeG);
fScore.set(neighbor, tentativeG + heuristic(neighbor, goal));
openSet.enqueue(neighbor, fScore.get(neighbor)!);
}
}
}
return []; // No path found
}
マルチプレイヤーゲーム
ネットワークアーキテクチャ
| モデル | レイテンシ | 複雑さ | ユースケース |
|---|---|---|---|
| ピアツーピア | 低 | 中 | 対戦格闘ゲーム、小規模なロビー |
| クライアントサーバー | 中 | 高 | ほとんどのオンラインゲーム |
| 権威サーバー | 高め | 最も高い | 競技性の高いゲーム |
ラグ補償
// Client-side prediction
class NetworkedPlayer {
private pendingInputs: Input[] = [];
private serverState: PlayerState;
update(input: Input) {
// 1. Apply input locally (prediction)
this.applyInput(input);
this.pendingInputs.push(input);
// 2. Send to server
this.sendInput(input);
}
onServerUpdate(state: PlayerState, lastProcessedInput: number) {
// 3. Reconcile with server
this.serverState = state;
// 4. Re-apply unprocessed inputs
this.pendingInputs = this.pendingInputs.filter(i => i.id > lastProcessedInput);
for (const input of this.pendingInputs) {
this.applyInput(input);
}
}
}
状態同期
// Delta compression
interface StateDelta {
timestamp: number;
changes: Map<EntityId, ComponentChanges>;
}
function computeDelta(prev: GameState, curr: GameState): StateDelta {
const changes = new Map();
for (const [id, entity] of curr.entities) {
const prevEntity = prev.entities.get(id);
if (!prevEntity || hasChanged(prevEntity, entity)) {
changes.set(id, getChangedComponents(prevEntity, entity));
}
}
return { timestamp: curr.timestamp, changes };
}
ゲームの最適化
レンダリングの最適化
| 手法 | メリット | 実装 |
|---|---|---|
| バッチング | ドローコールを削減 | 同じテクスチャのスプライトを結合 |
| カリング | 不可視オブジェクトをスキップ | 視錐台カリング、オクルージョンカリング |
| LOD | ポリゴン数を削減 | 距離ベースのモデル切り替え |
| インスタンシング | 複製を効率化 | 繰り返しオブジェクトに GPU インスタンシング |
メモリの最適化
// Object pooling
class ObjectPool<T> {
private pool: T[] = [];
private factory: () => T;
acquire(): T {
return this.pool.pop() ?? this.factory();
}
release(obj: T) {
this.reset(obj);
this.pool.push(obj);
}
}
// Usage
const bulletPool = new ObjectPool(() => new Bullet());
function fireBullet() {
const bullet = bulletPool.acquire();
bullet.init(position, direction);
activeBullets.add(bullet);
}
function onBulletHit(bullet: Bullet) {
activeBullets.delete(bullet);
bulletPool.release(bullet);
}
ゲームエンジンリファレンス
| エンジン | 言語 | 最適な用途 | プラットフォーム | スキル |
|---|---|---|---|---|
| Unity | C# | モバイル、インディー、VR | すべて | - |
| Unreal | C++、Blueprint | AAA、リアル志向 | PC、コンソール | - |
| Godot | GDScript、C# | インディー、2D | すべて | - |
| Flame | Dart | Flutter 2D、カジュアル | すべて | flame/ |
| Phaser | JavaScript | Web 2D | ブラウザ | - |
| Three.js | JavaScript | Web 3D | ブラウザ | - |
| Bevy | Rust | パフォーマンス | デスクトップ | - |
| LÖVE | Lua | シンプルな 2D | デスクトップ | - |
Flame エンジン(Flutter)
Flutter 開発者向けに設計された 2D ゲームエンジンです。詳細なドキュメントは flame/SKILL.md を参照してください:
- flame-core/ - コンポーネント、入力、衝突、カメラ、アニメーション、サウンド、パーティクル
- flame-systems/ - 14 のゲームシステム(クエスト、ダイアログ、インベントリ、戦闘など)
- flame-templates/ - RPG、Platformer、Roguelike テンプレート
関連スキル
- [[performance-optimization]] - 一般的な最適化
- [[realtime-systems]] - WebSocket、ネットワーキング
- [[cpp]] - パフォーマンスが重要なコード
- [[javascript-typescript]] - Web ゲーム
コメント
Markdown 対応