Senior Architect for Data-Driven Design using ScriptableObjects. Create SO-based event channels, runtime sets, and configuration data.
Decouple gameplay data and signals from MonoBehaviour logic using ScriptableObjects as the "Single Source of Truth" for design constants and event broadcasting.
┌─────────────────────────────────────────────────────────────┐
│ ScriptableObject Asset │
│ (WeaponConfigSO) │
├─────────────────────────────────────────────────────────────┤
│ [SerializeField] private float _damage = 10f; │
│ [SerializeField] private float _fireRate = 0.5f; │
│ [SerializeField] private GameObject _projectilePrefab; │
│ │
│ public float Damage => _damage; │
│ public float FireRate => _fireRate; │
└─────────────────────────────────────────────────────────────┘
↓
Shared by multiple weapons without duplication
┌──────────────┐ ┌──────────────────┐
│ Trigger │ Raise() │ GameEventSO │
│ (Door opens) │ ─────────→│ (OnDoorOpened) │
└──────────────┘ └────────┬─────────┘
│
┌─────────────────────┼─────────────────────┐
↓ ↓ ↓
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ AudioManager │ │ UI Manager │ │ Quest System │
│ (Listener) │ │ (Listener) │ │ (Listener) │
└───────────────┘ └───────────────┘ └───────────────┘
| Component | Purpose |
|---|---|
GameEventSO | SO-based event for inspector-assignable broadcasts |
GameEventListener | MonoBehaviour that listens to GameEventSO |
RuntimeSetSO<T> | Dynamic collection of active objects |
ConfigSO | Base for configuration data containers |
[SerializeField] private with public getters[Range], [Min])[CreateAssetMenu] with hierarchical pathsOnDisable for editor play modeUser: "Create configurable weapon stats for the RPG."
Agent:
[CreateAssetMenu(menuName = "Game/Combat/WeaponConfig")]
public class WeaponConfigSO : ScriptableObject
{
[Header("Damage")]
[SerializeField, Min(1)] private float _baseDamage = 10f;
[SerializeField] private DamageType _damageType;
[Header("Timing")]
[SerializeField, Range(0.1f, 2f)] private float _attackSpeed = 1f;
public float BaseDamage => _baseDamage;
public DamageType DamageType => _damageType;
public float AttackSpeed => _attackSpeed;
}
User: "Door should play sound and update UI without coupling."
Agent:
// 1. Create GameEventSO asset "OnDoorOpened"
// 2. Door.cs calls: _onDoorOpenedEvent.Raise();
// 3. AudioManager has GameEventListener pointing to same SO
// 4. UI has another GameEventListener pointing to same SO
User: "Track all active enemies for wave completion check."
Agent:
[CreateAssetMenu(menuName = "Game/Runtime/EnemySet")]
public class EnemyRuntimeSetSO : RuntimeSetSO<Enemy> { }
// Enemy.cs
void OnEnable() => _enemySet.Add(this);
void OnDisable() => _enemySet.Remove(this);
// WaveManager.cs
bool IsWaveComplete => _enemySet.Count == 0;
@event-bus-system - Static alternative to SO events@advanced-design-patterns - Patterns using SO data@di-container-manager - Injecting SO dependenciestemplates/GameEventSO.cs.txt - Event channeltemplates/GameEventListener.cs.txt - Event listenertemplates/RuntimeSetSO.cs.txt - Active object tracking39:["$","$L3f",null,{"content":"$40","frontMatter":{"name":"scriptableobject-architecture","description":"Senior Architect for Data-Driven Design using ScriptableObjects. Create SO-based event channels, runtime sets, and configuration data.","version":"1.0.0","tags":["architecture","scriptableobject","data-driven","events","configuration"],"argument-hint":"type='event' name='OnPlayerDamaged' OR type='data' name='WeaponConfig'","disable-model-invocation":false,"user-invocable":true,"allowed-tools":["run_command","list_dir","write_to_file"]}}]