AgentSkillsCN

engine-patterns

游戏开发中的跨引擎设计模式对比,涵盖ECS、状态机、网络通信与常见架构

SKILL.md
--- frontmatter
name: engine-patterns
description: Cross-engine design pattern comparison for game development including ECS, state machines, networking, and common architectures

Cross-Engine Design Patterns

A reference for implementing common game patterns across different engines. Use this when deciding on architecture or translating patterns between engines.

Entity-Component-System (ECS)

How game objects are structured varies by engine:

EngineModelEntityComponentSystem
UnityComponent-BasedGameObjectMonoBehaviourManager scripts or DOTS Systems
UnrealActor-ComponentAActorUActorComponentTick functions or Subsystems
GodotNode TreeNodeChild Nodes_process/_physics_process
Three.jsScene GraphObject3DuserData / custom classesGame loop update functions
OrleansVirtual ActorGrainGrain State / InterfacesGrain methods + Timers

When to use full ECS: Performance-critical systems with thousands of entities (Unity DOTS, custom ECS). For most gameplay, the engine's native component model is sufficient.

State Machines

Every engine needs state machines for entities, game flow, and UI:

EngineImplementation
UnityScriptableObject-based states, or Animator for simple cases
UnrealGameplay Ability System, or custom UObject state classes
GodotNode-based states as children of StateMachine node
Three.jsTypeScript classes with enter/exit/update methods
OrleansGrain state + explicit transitions in grain methods

Core pattern (all engines):

code
State {
  enter()    // Called when entering this state
  exit()     // Called when leaving this state
  update(dt) // Called every frame while in this state
}

StateMachine {
  currentState: State
  transition(newState) {
    currentState.exit()
    newState.enter()
    currentState = newState
  }
}

Observer/Event Pattern

Decoupled communication between systems:

EngineMechanism
UnityC# events, UnityEvent, ScriptableObject event channels
UnrealDelegates (DECLARE_DELEGATE), BlueprintAssignable events
GodotSignals (built-in, first-class)
Three.jsEventDispatcher, custom EventEmitter, or RxJS
OrleansOrleans Streams, IGrainObserver

Object Pooling

Avoid allocation/deallocation overhead for frequently created objects:

EngineStrategy
UnityQueue<GameObject>, SetActive(true/false)
UnrealFActorPoolingSystem or custom TArray<AActor*> pool
GodotArray of nodes, set visible/process_mode
Three.jsArray of Object3D, toggle visible property
OrleansNot applicable (grains are virtual, always "exist")

When to pool: Projectiles, particles, enemies, VFX, UI elements - anything created/destroyed frequently during gameplay.

Networking Models

EngineBuilt-inModel
UnityNetcode for GameObjects, Mirror, FishNetServer-authoritative, client prediction
UnrealBuilt-in replicationServer-authoritative, property replication, RPCs
GodotMultiplayerPeer, MultiplayerSynchronizerServer-authoritative or peer-to-peer
Three.jsNone (use WebSocket/WebRTC)Custom, typically server-authoritative
OrleansBuilt-in (virtual actors)Server-authoritative by design

Core multiplayer principles:

  1. Server is authoritative - never trust client state
  2. Client predicts locally for responsiveness
  3. Server reconciles and corrects client state
  4. Use delta compression to minimize bandwidth
  5. Handle disconnection and reconnection gracefully

Save/Load Patterns

EngineStrategy
UnityJsonUtility or custom serialization to PlayerPrefs/files
UnrealUSaveGame with UGameplayStatics::SaveGameToSlot
GodotConfigFile or custom JSON/Resource serialization
Three.jsJSON serialization to localStorage or server API
OrleansBuilt-in grain persistence (automatic with IPersistentState)

Input Abstraction

EngineSystem
UnityNew Input System (InputAction) or legacy Input class
UnrealEnhanced Input System (UInputAction, UInputMappingContext)
GodotInputMap with named actions, Input.is_action_pressed()
Three.jsCustom abstraction over DOM events (keyboard, mouse, gamepad API)

Best practice: Map physical inputs to semantic actions ("jump", "attack", "interact"), never check raw keys in gameplay code.

Audio Architecture

EngineSystem
UnityAudioSource + AudioListener, FMOD/Wwise for complex projects
UnrealSound Cues, MetaSounds (UE5), Wwise integration
GodotAudioStreamPlayer2D/3D, AudioBus system
Three.jsThree.js AudioListener + PositionalAudio, or Howler.js

Physics

EngineSystem2D3D
UnityPhysX (3D), Box2D (2D)Rigidbody2D, Collider2DRigidbody, Collider
UnrealChaos PhysicsN/A (use Paper2D)UPrimitiveComponent physics
GodotGodotPhysics, JoltRigidBody2D, Area2DRigidBody3D, Area3D
Three.jsNone built-incannon-es, rapier2drapier3d, ammo.js

UI Architecture

EngineSystemTechnology
UnityUGUI (Canvas) or UI ToolkitC# + XML (UI Toolkit) or Inspector-based
UnrealUMG (Unreal Motion Graphics)Blueprints + Slate (C++)
GodotControl nodes (built-in)Theme resources + GDScript
Three.jsHTML/CSS overlay or drei/HtmlReact components or DOM

Pattern Selection Guide

For new projects, consider:

  • Start with the engine's native patterns before adding frameworks
  • Only add ECS when you have measurable performance needs
  • Use the engine's built-in networking before rolling your own
  • Prefer data-driven design for anything designers need to tune
  • Keep architecture as simple as possible for the game's actual needs