Pattern trong Game Engine
Game engine đẩy các pattern tới giới hạn — mỗi frame đều quan trọng khi chạy 60fps.
| Pattern | Dự án | Ở đâu | Tác dụng |
|---|---|---|---|
| Object Pool | Godot | core/templates/pooled_list.h | Pool dựa trên freelist cho entity, particle, physics body |
| Double Buffering | SDL | src/render/SDL_render.c | Hoán đổi front/back buffer cho render không tearing |
| Free List | Godot | core/templates/pooled_list.h | Allocator freelist không xen cho cấp/giải phóng entity O(1) |
| Ring Buffer | Audio game | Nhiều engine | Buffer streaming audio lock-free giữa main thread và audio thread |
| State Machine | Godot | scene/animation/animation_tree.h | State machine animation cho blending hoạt cảnh nhân vật |
| Arena Allocator | Frame allocator | Pattern phổ biến | Bump allocator mỗi frame — reset mỗi frame, chi phí giải phóng bằng 0 |
| Flyweight | Godot | servers/rendering/ | Tài nguyên mesh/texture chia sẻ được tham chiếu bởi nhiều instance |
| Batch Processing | Godot / Unity | Render batching | Gom các draw call để giảm tối đa thay đổi state GPU |
| Tagged Union | Godot | variant.h | Enum Variant::Type + union — mọi giá trị GDScript đều là một Variant |
| Dirty Flag | Godot / Unity | Hệ transform | Dirty flag trên transform cha vô hiệu ma trận thế giới của con — tính lại chỉ khi truy cập |
| Event Loop | Godot | main_loop.h | Vòng lặp game chính — xử lý input, update, render theo chu kỳ bước cố định |
Cách chúng kết hợp: Một frame game
Ở 60fps, mỗi frame có ~16ms. Nhiều pattern phối hợp trong khoảng thời gian đó:
Frame N starts▼The main loop ticks: process input, run physics, update game state, render. Fixed timestep ensures deterministic simulation.
Spawning a bullet grabs a slot from the pool (O(1)), not malloc. Destroyed entities return to the free list.
Moving a parent transform marks children dirty. Only recompute world matrices for nodes that actually changed this frame.
Character animation transitions (idle → run → jump) driven by state machine. Each state knows its blend tree and exit rules.
Draw calls are batched by material/texture to minimize GPU state changes. 100 sprites with same texture = 1 draw call.
The back buffer is swapped to front atomically. Players see a complete frame, never a half-drawn one.
Per-frame temp allocations (particles, debug draws) use a bump allocator. At frame end: reset pointer to zero. Done.
Insight then chốt: game engine giảm tối đa overhead mỗi object. Pool tránh malloc, dirty flag tránh tính lại, batching tránh GPU call và arena tránh giải phóng từng object. Tất cả đều chia sẻ cùng triết lý thiết kế — trả O(1) mỗi thao tác, hoãn hoặc phân bổ công việc tốn kém.
Đọc thêm
- Godot Engine (GitHub) · SDL (GitHub)
- Game Programming Patterns (sách) của Robert Nystrom