본문으로 건너뛰기

© 2026 Molayo

HN요약2026. 05. 20. 01:46

Show HN: NPC를 위한 신경 정동 행렬 (Neural emotion matrix for NPCs)

요약

Neural Affect Matrix는 NPC에게 단순한 조건부 로직 대신 지속적인 감정과 역동적인 성격을 부여하는 API 시스템입니다. Russell의 원형 모델을 활용하여 감정을 Valence와 Arousal 좌표로 매핑하며, 상호작용을 통해 감정적 기억을 형성하고 성격이 진화하도록 설계되었습니다.

핵심 포인트

  • Russell의 원형 모델을 사용하여 감정을 2D 좌표계(Valence, Arousal)로 정밀하게 매핑
  • 상호작용을 통해 감정적 기억을 축적하고 캐릭터의 성격이 시간에 따라 진화함
  • 텍스트 입력, ML 모델, 메모리 검색, 문맥적 재평가를 거치는 프로세스 흐름 제공
  • 모든 게임 엔진 및 모딩 도구에서 사용할 수 있는 간단한 API 형태 지원

NPC를 위한 신경 정동 행렬 (Neural Affect Matrix For NPCs)

[] (https://opensource.org/licenses/MIT)
[] (https://www.rust-lang.org/)

각 NPC에게 상호작용을 통해 진화하는 지속적인 감정과 역동적인 성격을 부여하세요.


Neural Affect Matrix란 무엇인가?

전통적인 NPC는 조건부 로직 (conditional logic)에 의존하며 자신의 행동 근거를 이해하지 못합니다. 이는 종종 버그나 일관성 없는 결정을 초래하여 몰입감을 깨뜨리고 캐릭터를 인위적으로 느껴지게 만듭니다. 목표는 감정을 행동의 중요한 근원으로 부여함으로써 NPC를 더욱 인간답게 만드는 것입니다. 감정은 시간이 지나도 지속되며, 경험을 통해 고유한 성격을 형성합니다.

이 시스템은 모든 게임 엔진 (game engine)이나 모딩 도구 (modding tools)를 위한 간단한 API로 작동합니다. 특정 캐릭터나 엔티티 (entity)에 대해 NPC가 어떻게 느끼는지 즉시 확인할 수 있으며, 해당 감정 데이터를 사용하여 더욱 믿을 수 있는 상호작용을 만들 수 있습니다.

NPC를 특별하게 만드는 요소는 다음과 같습니다:

  • 🧠 감정적 이해 (Emotional Understanding): NPC는 대화와 행동 뒤에 숨겨진 감정적 의미를 파악합니다.
  • 💭 감정적 기억 (Emotional Memory): 모든 상호작용은 미래에 그들이 느끼는 방식에 영향을 미칩니다.
  • 🎭 진화하는 성격 (Evolving Personalities): 캐릭터는 경험을 바탕으로 변화하고 성장합니다.
  • 🔄 복잡한 관계 (Complex Relationships): NPC는 실제 사람처럼 어떤 캐릭터나 엔티티는 좋아하고 다른 대상은 싫어할 수 있습니다.

감정의 작동 방식

인간이 작동하는 방식을 생각해 보세요. 우리는 먼저 느끼고, 그 후에 결정을 합리화합니다. NPC도 같은 방식으로 작동해야 합니다.

우리는 인간의 감정을 단순한 2D 좌표계에 매핑하는 검증된 과학적 프레임워크인 **Russell의 원형 모델 (Russell's Circumplex Model)**을 사용합니다:

  • 쾌락가 (Valence) (X축): 감정이 얼마나 즐거운지 또는 불쾌한지 (-1 ~ +1)
  • 각성 (Arousal) (Y축): 감정이 얼마나 에너지가 넘치는지 또는 차분한지 (-1 ~ +1)

이를 통해 모든 감정을 정밀하게 매핑하고 시간에 따라 추적할 수 있는 감정적 풍경 (emotional landscape)을 생성합니다.

🔗 감정 시각화: <a href="https://valence-arousal-visualizer.vercel.app/" target="_blank">대화형 Valence-Arousal 탐색기 (Interactive Valence-Arousal Explorer)</a>

프로세스 흐름 (The Process Flow)

[ 입력 텍스트 (Input Text) ] → [ 신경 정동 ML 모델 (Neural Affect ML Model) ] → [ 메모리 검색 (Memory Retrieval) ] →
[ 문맥적 재평가 (Contextual Re-evaluation) ] → [ 정서적 반응 (Emotional Response) (Valence, Arousal) ]
  1. 텍스트로부터의 감정 (Emotion from text): 모델이 텍스트의 Valence/Arousal을 평가합니다.
  2. 메모리 통합 (Memory Integration): 관련 있는 과거 상호작용을 검색합니다.
  3. 감정 재평가 (Reevaluate Emotion): 메모리를 사용하여 Valence/Arousal을 재평가합니다.
  4. 로컬 저장소 (Local Storage): 새로운 정서적 데이터로 메모리를 업데이트합니다.

언어 지원 (Language Support): 현재 영어 텍스트에 최적화되어 있습니다.


시작하기 (Getting Started)

프로덕션 빌드 (Build for production)

대부분의 비디오 게임 엔진이 Windows에서 실행되므로, 통합을 최대한 간단하게 만들기 위해 빌드 프로세스를 간소화했습니다.

chmod +x build.sh
./build.sh

바이너리 찾기 (Find your binaries)

📁 dist/
├── npc_neural_affect_matrix.dll     # 메인 파일
├── onnxruntime.dll                  # AI 런타임 (AI runtime)
...

참고: build.sh를 실행하려면 Docker가 필요합니다.


개발 (Development)

프로젝트 구조 (Project Structure)

src/
├── api/              # C API 엔드포인트 (C API endpoints)
│   ├── services/     # 모듈과 통신하는 함수를 포함하는 파일들
...

API 레퍼런스 (FFI)

Neural Affect Matrix는 Unity, Unreal Engine 및 기타 C/C++ 애플리케이션과 같은 게임 엔진과의 원활한 통합을 위해 C API를 제공합니다.

initialize_neural_matrix

감정 예측을 구동하는 공유 신경 모델 (shared neural model)을 초기화합니다. AI 모델이 제대로 로드되고 사용할 준비가 되었는지 확인하기 위해, 다른 모든 API 함수를 사용하기 전에 이 함수를 반드시 호출해야 합니다.

ApiResult* initialize_neural_matrix();

응답 필드 (Response Fields):

  • Response (string): 모델 초기화 성공을 나타내는 확인 메시지

중요 참고 사항:

  • 이 함수는 애플리케이션 시작 시 한 번만 호출해야 합니다.
  • 모든 NPC 세션을 생성하기 전에 반드시 호출되어야 합니다.
  • 초기화에 실패하면 이후의 모든 API 호출도 실패합니다.
create_npc_session

고유한 감정 상태(emotional state)와 메모리 저장소(memory storage)를 가진 새로운 NPC 세션을 초기화합니다. 각 세션은 자신만의 관계, 기억, 그리고 감정적 진화(emotional evolution)를 유지할 수 있는 독립적인 NPC 인스턴스를 나타냅니다.

ApiResult* create_npc_session(
    const char* config_json,
    const char* npc_memory_json
...

매개변수 (Parameters):

  • config_json (const char*): NPC 설정(configuration)을 포함하는 JSON 문자열 (필수)
    • 설정 구조와 일치하는 유효한 JSON이어야 합니다.
    • NULL이거나 비어 있을 수 없습니다.
  • npc_memory_json (const char*): 기존 메모리 데이터를 포함하는 JSON 문자열 (선택 사항)
    • 이전 기록이 없는 새로운 NPC의 경우 NULL을 전달합니다.
    • 저장된 NPC를 복구하려면 get_npc_memory()에서 내보낸 메모리를 사용하십시오.

응답 필드 (Response Fields):

  • npc_id (string): NPC 세션의 고유 식별자(unique identifier), 이후의 모든 API 호출에 필수적입니다.

remove_npc_session

NPC 세션을 깔끔하게 제거하고 관련된 모든 메모리를 해제합니다. 이는 NPC의 감정 상태와 메모리 기록을 영구적으로 삭제합니다.

ApiResult* remove_npc_session(const char* npc_id);

매개변수 (Parameters):

  • npc_id (const char*): 고유 NPC 세션 식별자 (필수)
    • create_npc_session에서 반환된 유효한 UUID 문자열이어야 합니다.
    • NULL이거나 비어 있을 수 없습니다.

응답 필드 (Response Fields):

  • Response (string): 성공적인 제거를 나타내는 확인 메시지

evaluate_interaction

텍스트 입력을 신경 감정 예측 모델(neural emotion prediction model)을 통해 처리하고, 이를 NPC의 메모리와 통합하여 감정적 반응을 반환하는 핵심 함수입니다. 이 함수는 새로운 상호작용(interaction)을 통해 NPC의 메모리를 업데이트합니다.

ApiResult* evaluate_interaction(
    const char* npc_id,
    const char* text,
...

매개변수 (Parameters):

매개변수 (Parameters):

  • npc_id (const char*): NPC 세션 식별자 (required)
    • 활성화된 세션의 유효한 UUID여야 함
  • text (const char*): 처리할 입력 텍스트 (required)
    • 대화, 행동 또는 이벤트를 포함할 수 있음
    • 최대 512자까지 지원
    • 영어 텍스트에서 가장 잘 작동함
  • source_id (const char*): 이 상호작용을 유발하는 대상/사물의 식별자 (optional)
    • 익명 상호작용의 경우 NULL을 전달
    • 관계 추적을 위해 일관된 ID(예: "player", "merchant", "enemy_orc")를 사용

응답 필드 (Response Fields):

  • valence (float, -1.0 to 1.0): 응답의 정서적 쾌락/불쾌함 (pleasantness/unpleasantness)
  • arousal (float, -1.0 to 1.0): 응답의 정서적 에너지/차분함 (energy/calmness)

get_current_emotion

모든 기억의 가중 평균을 계산하여 NPC의 현재 전반적인 정서 상태를 가져옵니다. 이때 최근의 상호작용이 더 큰 영향을 미칩니다.

ApiResult* get_current_emotion(const char* npc_id);

매개변수 (Parameters):

  • npc_id (const char*): NPC 세션 식별자 (required)

응답 필드 (Response Fields):

  • valence (float, -1.0 to 1.0): 응답의 정서적 쾌락/불쾌함 (pleasantness/unpleasantness)
  • arousal (float, -1.0 to 1.0): 응답의 정서적 에너지/차분함 (energy/calmness)

get_current_emotion_by_source_id

해당 소스와의 상호작용만을 기반으로, 특정 캐릭터나 엔티티에 대한 NPC의 정서 상태를 가져옵니다.

ApiResult* get_current_emotion_by_source_id(
    const char* npc_id,
    const char* source_id
...

매개변수 (Parameters):

  • npc_id (const char*): NPC 세션 식별자 (required)
  • source_id (const char*): 특정 소스의 식별자 (required)

응답 필드 (Response Fields):

  • valence (float, -1.0 to 1.0): 응답의 정서적 쾌락/불쾌함 (pleasantness/unpleasantness)
  • arousal (float, -1.0 to 1.0): 응답의 정서적 에너지/차분함 (energy/calmness)

get_npc_memory

get_npc_memory

NPC의 모든 메모리 데이터를 JSON 형식으로 내보냅니다. 이는 저장/불러오기 (save/load) 시스템과 정서 상태 (emotional state) 디버깅에 필수적입니다.

ApiResult* get_npc_memory(const char* npc_id);

매개변수 (Parameters):

  • npc_id (const char*): NPC 세션 식별자 (필수)

응답 형식 (Response Format):

[
  {
    "id": "mem_001",
...

clear_npc_memory

NPC의 모든 메모리 항목을 영구적으로 삭제하며, 이를 통해 해당 NPC의 정서 상태 (emotional state)를 기본 성격 (base personality)으로 효과적으로 초기화합니다.

ApiResult* clear_npc_memory(const char* npc_id);

매개변수 (Parameters):

  • npc_id (const char*): NPC 세션 식별자 (필수)

free_api_result

메모리 누수 (memory leaks)를 방지하기 위해 모든 API 함수 호출 후에 반드시 호출해야 하는 **중요 함수 (Critical function)**입니다. 이 함수를 호출하지 않으면 메모리 누적이 발생합니다.

void free_api_result(ApiResult* result);

매개변수 (Parameters):

  • result (ApiResult*): 모든 API 함수로부터 반환된 포인터 (필수)

📊 타입 (Types)

ApiResult 구조체 (structure)

모든 함수는 오류 처리 (error handling) 및 데이터 관리 (data management)를 제공하는 ApiResult 구조체를 반환합니다:

typedef struct {
    bool success;       // 작업 성공 상태
    char* data;         // JSON 응답 데이터 (성공 시)
...

필드 설명 (Field Descriptions):

  • success (bool): 작업이 성공적으로 완료되면 true, 오류가 발생하면 false
  • data (char*): successtrue일 때의 JSON 형식 응답 데이터, 작업 실패 시 NULL
  • error (char*): successfalse일 때의 사람이 읽을 수 있는 오류 메시지, 작업 성공 시 NULL

설정 필드 (Configuration Fields):

  • identity.name (string): NPC의 표시 이름으로, 로깅 (logging) 및 디버깅 (debugging)에 사용됩니다.
  • identity.background (string): 정서적 반응에 영향을 미치고 상호작용의 맥락을 제공하는 캐릭터의 배경 이야기 (backstory)입니다.
  • personality.valence (float, -1.0 to 1.0): 쾌락/불쾌 (pleasant/unpleasant) 축에서의 기본 정서적 성향입니다. 양수 값은 낙관적인 캐릭터를, 음수 값은 비관적인 캐릭터를 생성합니다.
  • personality.arousal (float, -1.0 to 1.0): 차분함/흥분 (calm/excited) 축에서의 기본 에너지 수준입니다. 양수 값은 활기찬 캐릭터를, 음수 값은 차분한 캐릭터를 생성합니다.
  • memory.decay_rate (float, 0.0 to 1.0): 오래된 기억이 시간이 지남에 따라 희미해지는 비율입니다. 값이 높을수록 NPC가 더 빨리 잊으며, 값이 낮을수록 더 오래 지속되는 인상을 남깁니다.

NPC 설정 구조 (NPC Configuration Structure)

NPC는 다음과 같은 구조의 JSON을 사용하여 설정됩니다:

{
  "identity": {
    "name": "Village Guard",
...

기억 구조 (Memory Structure)

각 NPC는 상호작용에 대한 로컬 기억 (local memory)을 유지합니다:

{
  "source_id": "player_character",
  "content": "Thank you for saving my life",
...

필드 설명 (Fields Explained):

  • source_id: 이 정서적 기억을 유발한 대상/원인
  • valence/arousal: 이 특정 상호작용에 대한 정서적 좌표
  • past_time: 이 사건이 발생했을 때 경과된 게임 시간 (분 단위)
  • 기억은 decay_rate에 따라 시간이 흐름에 따라 자연스럽게 감쇠 (decays) 합니다.

기여하기 (Contributing)

기여를 환영합니다! 시작하는 방법은 다음과 같습니다:

  1. 저장소를 포크 (Fork) 합니다.
  2. 기능 브랜치 (feature branch)를 생성 (Create) 합니다: git checkout -b feature/amazing-feature
  3. 변경 사항을 작성 (Make) 하고 테스트를 추가합니다.
  4. 변경 사항을 테스트 (Test) 합니다: cargo test
  5. 풀 리퀘스트 (Pull Request) 를 오픈합니다.

리소스 및 연구 (Resources & Research)

AI 모델 (AI Models)

과학적 배경 (Scientific Background)

  • Russell의 정동 원형 모델 (Circumplex Model of Affect)
  • 기억 감쇠 (Memory decay) 및 정서 지속성 (Emotional persistence) 연구

라이선스 (License)

이 프로젝트는 MIT 라이선스 (MIT License)를 따릅니다. 자세한 내용은 LICENSE 파일을 참조하세요.


지원 (Support)

AI 자동 생성 콘텐츠

본 콘텐츠는 HN Game Dev의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0