AchReactive
가이드

핵심 컨셉

트리거·조건·효과와 도메인 무관 데이터 모델.

곱셈을 덧셈으로

도메인마다 전용 시스템(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 는 스킬이 쓰든 아이템이 쓰든 같은 코드 하나입니다.

통합 경계

게임은 두 인터페이스만 구현합니다.

  • IEntityId, Position, Stats(StatSheet), IsAlive
  • IWorldSpawn, 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();
}

목차