programming-architecture について
ゲーム開発者向けのアーキテクチャ資料です。代表的なパターンや階層構造、結合度の低減とテスト性向上の実践を扱います。
主な機能
- 01ステートマシン、オブジェクトプール、オブザーバー、コマンドパターン
- 02ゲームの階層型アーキテクチャ
- 03依存性注入とイベント通信
- 04データ駆動設計とインターフェース抽象化
活用シーン
- 01新しいゲームシステムの設計
- 02既存ゲームコードの結合度低減
- 03取り消し、リプレイ、イベント駆動動作の追加
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ pluginagentmarketplace/ custom-plugin-game-developer --skill programming-architectureインストール後、Claude Code で/programming-architectureを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/architecture_config.yamlreferences/ARCHITECTURE_GUIDE.mdscripts/arch_analyzer.py詳細
ゲームプログラミングのアーキテクチャ
ゲーム向けデザインパターン
1. ステートマシン
最適な用途:キャラクターの状態、AI、ゲームの進行
// ✅ Production-Ready State Machine
public abstract class State<T> where T : class
{
protected T Context { get; private set; }
public void SetContext(T context) => Context = context;
public virtual void Enter() { }
public virtual void Update() { }
public virtual void Exit() { }
}
public class StateMachine<T> where T : class
{
private State<T> _current;
private readonly T _context;
public StateMachine(T context) => _context = context;
public void ChangeState(State<T> newState)
{
_current?.Exit();
_current = newState;
_current.SetContext(_context);
_current.Enter();
}
public void Update() => _current?.Update();
}
// Usage
public class PlayerIdleState : State<Player>
{
public override void Enter() => Context.Animator.Play("Idle");
public override void Update()
{
if (Context.Input.magnitude > 0.1f)
Context.StateMachine.ChangeState(new PlayerMoveState());
}
}
2. オブジェクトプール
最適な用途:弾丸、パーティクル、敵
// ✅ Production-Ready Object Pool
public class ObjectPool<T> where T : Component
{
private readonly Queue<T> _pool = new();
private readonly T _prefab;
private readonly Transform _parent;
public ObjectPool(T prefab, int initialSize, Transform parent = null)
{
_prefab = prefab;
_parent = parent;
for (int i = 0; i < initialSize; i++)
_pool.Enqueue(CreateInstance());
}
public T Get(Vector3 position)
{
var obj = _pool.Count > 0 ? _pool.Dequeue() : CreateInstance();
obj.transform.position = position;
obj.gameObject.SetActive(true);
return obj;
}
public void Return(T obj)
{
obj.gameObject.SetActive(false);
_pool.Enqueue(obj);
}
private T CreateInstance() => Object.Instantiate(_prefab, _parent);
}
3. オブザーバーパターン(イベント)
最適な用途:UI の更新、実績、ダメージ通知
// ✅ Production-Ready Event System
public static class GameEvents
{
public static event Action<int> OnScoreChanged;
public static event Action<float> OnHealthChanged;
public static event Action OnPlayerDied;
public static void ScoreChanged(int score) => OnScoreChanged?.Invoke(score);
public static void HealthChanged(float health) => OnHealthChanged?.Invoke(health);
public static void PlayerDied() => OnPlayerDied?.Invoke();
}
// Subscribe
GameEvents.OnScoreChanged += UpdateScoreUI;
// Always unsubscribe in OnDestroy
private void OnDestroy() => GameEvents.OnScoreChanged -= UpdateScoreUI;
4. コマンドパターン
最適な用途:元に戻す/やり直し、入力の再生、ネットワーク通信
public interface ICommand
{
void Execute();
void Undo();
}
public class MoveCommand : ICommand
{
private readonly Transform _target;
private readonly Vector3 _direction;
private Vector3 _previousPosition;
public MoveCommand(Transform target, Vector3 direction)
{
_target = target;
_direction = direction;
}
public void Execute()
{
_previousPosition = _target.position;
_target.position += _direction;
}
public void Undo() => _target.position = _previousPosition;
}
アーキテクチャのレイヤー
┌─────────────────────────────────────────────────────────────┐
│ GAME LAYER │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Managers (GameManager, UIManager, AudioManager) │ │
│ └─────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Systems (Combat, Movement, Inventory, Quest) │ │
│ └─────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Components (Health, Weapon, CharacterController) │ │
│ └─────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ ENGINE LAYER │
│ Physics │ Rendering │ Audio │ Input │ Networking │
└─────────────────────────────────────────────────────────────┘
🔧 トラブルシューティング
┌─────────────────────────────────────────────────────────────┐
│ PROBLEM: Spaghetti code / tight coupling │
├─────────────────────────────────────────────────────────────┤
│ SOLUTIONS: │
│ → Use dependency injection │
│ → Communicate via events, not direct references │
│ → Follow single responsibility principle │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ PROBLEM: Hard to test game systems │
├─────────────────────────────────────────────────────────────┤
│ SOLUTIONS: │
│ → Separate logic from MonoBehaviour │
│ → Use interfaces for dependencies │
│ → Create testable pure functions │
└─────────────────────────────────────────────────────────────┘
ベストプラクティス
| 実践項目 | メリット |
|---|---|
| 疎結合 | システムをそれぞれ独立して変更できます |
| データ駆動設計 | 再コンパイルせずにバランスを調整できます |
| インターフェースの抽象化 | モックやテストが容易になります |
| 単一責任 | クラスの役割が明確になり、焦点が絞られます |
このスキルを使用する場面:システムを設計するとき、コード構造を改善するとき、またはパフォーマンスを最適化するとき。
コメント
Markdown 対応