Abstract
데이터 노드는 게임 어디서나 읽고 쓸 수 있는 "칠판"입니다. "Session/LastScore" 같은 경로에 값을 적어 두면, 서로를 모르는 다른 시스템이 같은 경로로 읽어 갑니다. static 변수나 싱글톤에 값을 얹어 두던 것을 대신하는 용도이고, 메모리에만 있어서 게임을 끄면 사라집니다.
실무에서 필요한 순간
•
Procedure 사이에 값을 넘길 때. 로비에서 고른 스테이지 번호를 전투 Procedure 가 알아야 하는데, 두 Procedure 는 서로의 인스턴스를 모릅니다
•
서로 참조하고 싶지 않은 시스템끼리 상태를 공유할 때. 튜토리얼 시스템이 "인벤토리를 한 번이라도 열었나"를 알고 싶을 때
•
디버그용 스위치. "Debug/GodMode" 를 치트 창에서 켜고 전투 코드가 읽는다
직접 해 보기 — 한 판의 결과를 게임오버 화면으로 넘기기
DataNodeComponent dataNode = GameEntry.GetComponent<DataNodeComponent>();
// ProcedureMain 을 떠날 때: 적어 둔다
dataNode.SetData<VarInt32>("Session/LastScore", finalScore);
dataNode.SetData<VarString>("Session/Character", characterKey);
// ProcedureGameOver 에 들어올 때: 읽는다
int lastScore = dataNode.GetData<VarInt32>("Session/LastScore");
string character = dataNode.GetData<VarString>("Session/Character");
// 새 판을 시작할 때: 가지째 지운다
dataNode.RemoveNode("Session");
C#
복사
VarInt32, VarString 은 값을 감싸는 상자입니다. int
VarInt32 처럼 암시적 변환이 양방향으로 정의돼 있어 위처럼 그냥 대입하면 됩니다. 종류는 VarBoolean, VarInt32, VarSingle(float), VarString, VarVector3, VarGameObject 등 30가지가 준비돼 있습니다.
VarInt32 처럼 암시적 변환이 양방향으로 정의돼 있어 위처럼 그냥 대입하면 됩니다. 종류는 VarBoolean, VarInt32, VarSingle(float), VarString, VarVector3, VarGameObject 등 30가지가 준비돼 있습니다.비슷한 것들과의 구분
DataNode | Setting | 이벤트 | FSM 의 SetData | |
성격 | 전역 칠판 | 저장되는 설정 | "일어났다"는 알림 | FSM 하나 안의 칠판 |
수명 | 실행 중 (직접 지울 때까지) | 디스크에 영구 | 한 번 전달되고 끝 | 그 FSM 이 파괴될 때까지 |
맞는 용도 | "지금 값이 얼마인가" | 다음 실행에도 남아야 하는 값 | "방금 무슨 일이 있었나" | 상태끼리만 공유할 임시 값 |
"점수가 올랐다"는 이벤트로, "지금 점수가 몇 점인가"는 데이터 노드(또는 그것을 가진 객체)로 — 이렇게 나누면 헷갈리지 않습니다.
ToyboxNightmare 에서는
쓰지 않습니다. 한 판의 상태는 SurvivalGame 객체가 들고 있고, 화면에 필요한 값은 이벤트로 전달합니다. Procedure 가 둘뿐인 규모에서는 그편이 단순합니다. 스테이지 선택·상점·결과 화면처럼 Procedure 가 늘어나 값을 들고 건너가야 할 때 쓰기 시작하면 됩니다.
자주 걸리는 곳
•
경로는 문자열이라 오타를 컴파일러가 잡아 주지 못합니다. "Session/LastScore" 같은 경로는 상수 클래스 한곳에 모으세요.
•
없는 경로를 GetData 하면 예외입니다. 있을지 확실하지 않으면 GetNode(path) 가 null 인지 먼저 봅니다.
•
넣을 때와 다른 타입으로 꺼내면 예외입니다(VarInt32 로 넣고 VarSingle 로 꺼내기).
•
무엇이든 넣을 수 있다 보니 전역 변수의 단점을 그대로 가집니다. 누가 언제 바꿨는지 추적하기 어렵습니다. "여러 시스템이 공유해야 하는 소수의 값"에만 쓰고, 한 객체가 책임질 수 있는 상태는 그 객체에 둡니다.
•
게임 코드에서는 본문의 dataNodeManager 대신 GameEntry.GetComponent<DataNodeComponent>() 를 씁니다. 메서드 이름은 같습니다.
•
본문 예제의 타입 이름을 이 에디션에 맞게 고쳤습니다. VarInt → VarInt32, VarFloat → VarSingle, 그리고 new VarInt32(100) 같은 생성자는 없어서 암시적 변환으로 바꿨습니다.
Data Nodes (데이터 노드 시스템)
관련 소스 파일
•
GameFramework/Base/Variable/GenericVariable.cs
•
GameFramework/Base/Variable/Variable.cs
•
GameFramework/DataNode/DataNodeManager.DataNode.cs
•
GameFramework/DataNode/DataNodeManager.cs
•
GameFramework/DataNode/IDataNode.cs
•
GameFramework/DataNode/IDataNodeManager.cs
•
GameFramework/Fsm/FsmBase.cs
•
GameFramework/Fsm/IFsm.cs
•
GameFramework/Fsm/IFsmManager.cs
소개
Data Nodes 시스템은 Game Framework 내에서 트리 형태의 계층적 구조로 게임 데이터를 저장하고 조회할 수 있게 해주는 관리 시스템입니다.
다양한 타입의 데이터를 구조적으로 저장할 수 있으며, 게임 상태 관리, 런타임 설정, 계층적 데이터 관리에 이상적입니다.
주요 활용 예시:
•
계층적인 게임 설정 관리
•
런타임 게임 상태 추적
•
서로 다른 서브시스템 간 데이터 공유
•
관련된 데이터를 논리적으로 조직화
시스템 개요
Data Node 시스템은 트리 구조를 구현합니다.
각 노드는 값(데이터)을 저장할 수 있으며 여러 자식 노드를 가질 수 있습니다.
•
노드는 파일 시스템처럼 경로(path) 로 식별됩니다.
•
경로 기반 탐색으로 직관적인 데이터 접근이 가능합니다.
핵심 구성 요소
DataNodeManager
•
데이터 노드 작업의 주요 진입점
•
GameFrameworkModule을 상속하고 IDataNodeManager를 구현
•
단일 루트 노드를 유지하며, 탐색/생성/수정 기능을 제공
DataNode
•
IDataNode 인터페이스의 구현체
•
계층 내 단일 노드를 표현
구성 요소:
•
이름(name)
•
부모 노드(루트 제외)
•
선택적 자식 노드
•
선택적 데이터(Variable 타입)
Variable
•
Variable 클래스와 제네릭 확장 클래스 Variable<T> 는 노드 안의 데이터 저장에 사용
•
다양한 데이터 타입을 안전하게 저장 가능
노드 계층 및 경로 탐색
노드 구조
•
트리는 <Root>라는 루트 노드에서 시작
•
각 노드는 형제 노드들 간에 고유한 이름을 가짐
•
변수 데이터(선택 사항), 여러 자식 노드를 가질 수 있음
경로 탐색
•
경로 문자열을 사용해 탐색
•
구분자: ., /, \
•
예: "Player/Stats/Health" → Player 노드 → Stats 노드 → Health 노드
Data Node 다루기
노드 접근 및 생성
•
GetNode(path): 경로에 해당하는 기존 노드 반환
•
GetOrAddNode(path): 존재 시 반환, 없으면 새로 생성
데이터 관리
•
SetData<T>(path, data): 해당 경로의 노드에 데이터 저장
•
GetData<T>(path): 해당 노드의 타입 안전 데이터 반환
노드 제거
•
RemoveNode(path): 해당 노드 및 자식 전체 제거
•
Clear(): 루트를 제외한 모든 노드 제거
예시 사용 패턴
게임 상태 저장/조회
// 플레이어 체력 저장
// VarInt32 는 int 에서 암시적으로 변환된다 (인자 있는 생성자는 없다)
dataNodeManager.SetData<VarInt32>("Player/Stats/Health", 100);
// 플레이어 체력 조회
VarInt32 health = dataNodeManager.GetData<VarInt32>("Player/Stats/Health");
int healthValue = health.Value; // 100 (int healthValue = health; 로도 쓸 수 있다)
C#
복사
설정 데이터 구성
// 그래픽 설정
dataNodeManager.SetData<VarString>("Settings/Graphics/Resolution", "1920x1080");
dataNodeManager.SetData<VarBoolean>("Settings/Graphics/Fullscreen", true);
// 오디오 설정
// float 용 타입의 이름은 VarFloat 가 아니라 VarSingle 이다
dataNodeManager.SetData<VarSingle>("Settings/Audio/MasterVolume", 0.8f);
dataNodeManager.SetData<VarSingle>("Settings/Audio/MusicVolume", 0.5f);
C#
복사
다른 프레임워크 시스템과의 통합
FSM(Finite State Machine) 통합
•
FSM은 상태 데이터를 저장할 때 Variable 시스템을 사용
•
Data Node와 동일한 방식으로 데이터 관리 가능
Reference Pool 통합
•
Data Node는 Reference Pool 시스템을 활용해 메모리 관리 최적화
•
노드와 변수는 풀링되어 재사용되므로 GC 부담을 최소화
성능 고려사항
경로 해석
•
문자열 분리 작업이 자주 발생하므로 비용이 클 수 있음
•
자주 접근하는 노드는 경로 탐색 대신 캐싱 권장
메모리 관리
•
Reference Pool 사용으로 GC 최소화
•
직접 인스턴스화하지 말고, 프레임워크 메서드를 통해 노드 생성/삭제
노드 구조
•
트리는 가능하면 너무 깊지 않게 유지
•
관련 데이터를 그룹화하여 논리적 구조 유지
요약
Data Nodes 시스템은 계층적 데이터 관리에 유연한 방법을 제공합니다.
트리 구조와 경로 기반 접근 방식을 통해, 게임 전반에서 상태·설정·서브시스템 간 공유 데이터를 깔끔하고 조직적으로 관리할 수 있습니다.







