engine-patterns

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

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)

实体-组件-系统(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.
游戏对象的结构因引擎而异:
引擎模型实体组件系统
Unity基于组件GameObjectMonoBehaviour管理器脚本或DOTS Systems
UnrealActor-ComponentAActorUActorComponentTick函数或子系统
Godot节点树Node子节点_process/_physics_process
Three.js场景图Object3DuserData / 自定义类游戏循环更新函数
Orleans虚拟ActorGrainGrain State / 接口Grain方法 + 计时器
何时使用完整ECS:包含数千个实体的性能关键系统(如Unity DOTS、自定义ECS)。对于大多数游戏玩法,引擎原生的组件模型已足够。

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):
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
  }
}
每个引擎都需要为实体、游戏流程和UI实现状态机:
引擎实现方式
Unity基于ScriptableObject的状态,或简单场景下使用Animator
UnrealGameplay Ability System,或自定义UObject状态类
Godot基于节点的状态,作为StateMachine节点的子节点
Three.js包含enter/exit/update方法的TypeScript类
OrleansGrain状态 + Grain方法中的显式状态转换
核心模式(所有引擎通用):
State {
  enter()    // 进入该状态时调用
  exit()     // 离开该状态时调用
  update(dt) // 处于该状态时每帧调用
}

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
实现系统间的解耦通信:
引擎机制
UnityC#事件、UnityEvent、ScriptableObject事件通道
Unreal委托(DECLARE_DELEGATE)、BlueprintAssignable事件
Godot信号(内置一等公民特性)
Three.jsEventDispatcher、自定义EventEmitter或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.
避免频繁创建销毁对象带来的内存分配/释放开销:
引擎策略
UnityQueue<GameObject>,调用SetActive(true/false)
UnrealFActorPoolingSystem或自定义TArray<AActor*>池
Godot节点数组,设置visible/process_mode
Three.jsObject3D数组,切换visible属性
Orleans不适用(Grain是虚拟的,始终“存在”)
何时使用对象池:投射物、粒子、敌人、视觉特效(VFX)、UI元素——任何在游戏过程中频繁创建/销毁的对象。

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
引擎内置支持模型
UnityNetcode for GameObjects、Mirror、FishNet服务器权威、客户端预测
Unreal内置复制机制服务器权威、属性复制、RPC
GodotMultiplayerPeer、MultiplayerSynchronizer服务器权威或点对点
Three.js无内置(使用WebSocket/WebRTC)自定义实现,通常为服务器权威
Orleans内置(虚拟Actor)设计上默认服务器权威
多人游戏核心原则
  1. 服务器拥有权威——绝不信任客户端状态
  2. 客户端本地预测以保证响应性
  3. 服务器协调并修正客户端状态
  4. 使用增量压缩最小化带宽消耗
  5. 优雅处理断开连接与重连

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)
引擎策略
UnityJsonUtility或自定义序列化到PlayerPrefs/文件
UnrealUSaveGame结合UGameplayStatics::SaveGameToSlot
GodotConfigFile或自定义JSON/Resource序列化
Three.jsJSON序列化到localStorage或服务器API
Orleans内置Grain持久化(结合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.
引擎系统
UnityNew Input System(InputAction)或旧版Input类
UnrealEnhanced Input System(UInputAction、UInputMappingContext)
Godot带命名动作的InputMap,使用Input.is_action_pressed()
Three.js基于DOM事件(键盘、鼠标、游戏手柄API)的自定义抽象
最佳实践:将物理输入映射到语义动作(如“跳跃”、“攻击”、“交互”),绝不在游戏玩法代码中直接检测原始按键。

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
引擎系统
UnityAudioSource + AudioListener,复杂项目使用FMOD/Wwise
UnrealSound Cues、MetaSounds(UE5)、Wwise集成
GodotAudioStreamPlayer2D/3D、AudioBus系统
Three.jsThree.js AudioListener + PositionalAudio,或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
引擎系统2D3D
UnityPhysX(3D)、Box2D(2D)Rigidbody2D、Collider2DRigidbody、Collider
UnrealChaos PhysicsN/A(使用Paper2D)UPrimitiveComponent物理
GodotGodotPhysics、JoltRigidBody2D、Area2DRigidBody3D、Area3D
Three.js无内置cannon-es、rapier2drapier3d、ammo.js

UI Architecture

UI架构

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
引擎系统技术栈
UnityUGUI(Canvas)或UI ToolkitC# + XML(UI Toolkit)或基于Inspector
UnrealUMG(Unreal Motion Graphics)Blueprints + Slate(C++)
Godot内置Control节点Theme资源 + GDScript
Three.jsHTML/CSS叠加层或drei/HtmlReact组件或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
对于新项目,建议
  • 在引入框架前先使用引擎原生模式
  • 仅在有可衡量的性能需求时才引入ECS
  • 在自行开发网络系统前优先使用引擎内置网络功能
  • 对于设计师需要调整的内容,优先采用数据驱动设计
  • 根据游戏实际需求保持架构尽可能简单