Skip to content

t1k:unity:base:game-patterns

FieldValue
Modulebase
Version2.2.2
Effortmedium
Tools

Keywords: architecture, design patterns, game patterns, unity

/t1k:unity:base:game-patterns

  • Implementing game mechanics or systems (MonoBehaviour context)
  • Setting up object pooling, state machines
  • Designing save/load systems
  • Managing scenes (additive loading, transitions)
  • Handling input (New Input System, touch)
  • Creating data-driven systems with ScriptableObjects
TaskReference
Object pooling, state machines, commandCore Patterns
ScriptableObjects, config, save systemsData & Persistence
Scene management, input, coroutine alternativesSystems
Project hierarchy, scene architecture, canvas configMobile Setup
Player settings, quality/physics/audio, perf budgetsMobile Optimization

Note: System.Linq is forbidden in runtime code (GC alloc). Use foreach in runtime; System.Linq only in editor/tests.

  1. Pool everything that spawns/despawns frequently — Use UnityEngine.Pool.ObjectPool<T>
  2. ScriptableObjects for data — Config, items, levels, balancing — NOT MonoBehaviours
  3. State machines for complex state — Game states, AI, UI flow
  4. New Input System — Always use for cross-platform (touch + gamepad + keyboard)
  5. UniTask over coroutines — Async/await with cancellation support
  6. VContainer for DI — All services via constructor injection (see theone-studio-patterns)
  7. No System.Linq at runtime — GC alloc; use foreach or ZLinq (see zlinq skill)
public sealed class BulletPool : IInitializable, IDisposable
{
readonly ObjectPool<Bullet> _pool;
public BulletPool(Bullet prefab)
{
_pool = new ObjectPool<Bullet>(
createFunc: () => Object.Instantiate(prefab),
actionOnGet: b => b.gameObject.SetActive(true),
actionOnRelease: b => b.gameObject.SetActive(false),
defaultCapacity: 20, maxSize: 100);
}
public Bullet Get() => _pool.Get();
public void Release(Bullet b) => _pool.Release(b);
public void Dispose() => _pool.Dispose();
}
public abstract class GameState { public abstract UniTask Enter(); public abstract void Exit(); }
// States: MenuState, PlayState, PauseState, GameOverState
// Managed via GameStateService with VContainer
  • Unity fake null: Never use ?? or is null with UnityEngine.Object — Unity overrides == to detect destroyed objects, but ??/is null bypasses this and treats destroyed objects as non-null
  • Coroutine on disabled GO: StartCoroutine() throws if the MonoBehaviour or its GameObject is inactive. Check gameObject.activeInHierarchy before starting
  • ScriptableObject shared in builds: SO assets are shared instances — mutating fields at runtime affects all references. Clone with Instantiate() if per-instance data is needed
  • theone-studio-patterns — VContainer DI, SignalBus events, service patterns
  • theone-unity-standards — Code quality, naming conventions
  • unity-mobile-ui — UI state management, input handling
  • zlinq — Zero-alloc LINQ alternative for runtime code
  • dots-ecs — ECS patterns (DOTS context, not MonoBehaviour)