가이드
핵심 컨셉
트리거·조건·효과와 도메인 무관 데이터 모델.
곱셈을 덧셈으로
도메인마다 전용 시스템(SkillSystem, MonsterSystem, …)을 만들면
도메인 × 동작 매트릭스를 매번 채워야 합니다. AchReactive 는 동작 풀을 모든 도메인이
공유하게 만들어 이를 도메인 + 동작 으로 바꿉니다.
- 새 도메인 추가 → 데이터 클래스 1개 (시스템 코드 0)
- 이미 있는 동작 재사용 → 코드 0, 데이터만
- 진짜 새 동작 → 함수 1개, 이후 모든 도메인이 공유
4개의 레이어
Data Layer IData · IDataLoader<T> · DataBase<T> (제네릭, 패키지 제공)
Reaction Layer Reaction · ReactionEngine · Registry (제네릭, 패키지 제공)
Behavior Pool [Effect("damage")] [Condition("alive")] (게임 작성, 도메인 무관)
Domain Data SkillData · MonsterData · ItemData (데이터, 코드젠 가능)위 두 레이어는 패키지가 제공하며 바뀌지 않습니다. 아래 두 레이어만 채우면 됩니다.
리액션 = 트리거 → 조건 → 효과
모든 도메인은 같은 언어로 표현됩니다.
Reaction
├─ trigger "on_use" | "on_hit" | "on_hp_below" ...
├─ conditions AND 로 평가 (alive, hp_below, chance ...)
└─ effects 순서대로 실행 (damage, heal, add_modifier ...)도메인이 달라도 형태는 동일합니다.
// 스킬 — 사용 시 피해
{ "trigger": "on_use",
"effects": [{ "type": "damage", "params": { "power": 1.8 } }] }
// 몬스터 — HP 30% 이하에서 광폭화
{ "trigger": "on_hp_below", "triggerParams": { "threshold": 0.3 },
"effects": [{ "type": "add_modifier", "params": { "stat": "atk", "modifier": "percent_add", "value": 0.5 } }] }
// 아이템 — 장착 시 오라
{ "trigger": "on_equip",
"effects": [{ "type": "add_modifier", "params": { "stat": "def", "modifier": "flat", "value": 5 } }] }add_modifier 는 스킬이 쓰든 아이템이 쓰든 같은 코드 하나입니다.
통합 경계
게임은 두 인터페이스만 구현합니다.
IEntity—Id,Position,Stats(StatSheet),IsAliveIWorld—Spawn,Collect
effect/condition 은 ReactionContext 를 통해 Source/Target/Targets/World 에 접근합니다.
typeof 를 쓰지 않는다
여러 도메인을 묶을 때 Dictionary<Type, object> 같은 타입-키 서비스 로케이터를 쓰지 않습니다.
각 DataBase<T> 를 명시적으로 보유하고, 크로스 도메인 참조가 필요한 effect 는
수동등록 + 클로저 캡처로 해결합니다.
public sealed class GameDataContext
{
public readonly DataBase<SkillData> Skills = new();
public readonly DataBase<MonsterData> Monsters = new();
}