소스엔진 멀티플레이어 네트워크 : 엔티티 딕셔너리


edict_t 라고도 한다.
이전에 번역한 Networking Entities 문서에서 언급된 키워드인데 정확히 알지 못한 개념이라 정리하는 겸 번역한다.


edict_t (“엔티티 딕셔너리”)는 엔티티들이 서버와 클라리언트 사이를 교차할 수 있도록 하는 인터페이스 구조체이고 이게 붙은 엔티티는 서버와 클라이언트에서 같은 인덱스를 갖게 된다. 엔티티 딕셔너리는 해당 엔티티의 데이터 테이블의 상태를 다루고 모든 DLL에 공통된 표현을 제공하지만 클라이언트에서 사용할 수는 없다.

Note: 엔티티 딕셔너리는 언제라도 엔티티에서 해체되거나 다른 엔티티에 재할당 될 수 있으므로 게임의 프레임에서 다루기엔 신뢰할 수 없다. 길게 다뤄야 한다면 CHandle을 대신 사용하라.

Warning: edict_tCBaseEdict를 절대 수정하지 말 것.
둘 중 하나라도 메모리 풋프린트에 변동이 있다면 엔진의 DLL에서 유효하지 않은 주소를 참조하게 된다.

엔티티 딕셔너리의 제한

소스엔진에서는 최대 2048개의 엔티티 딕셔너리를 동시에 수용할 수 있다. 여기서 더 넘어가면 에러 메세지와 함께 종료된다.

딕셔너리 생성 회피

엔티티 딕셔너리는 CBaseEntity::PostConstructor()를 통해 할당되지만 해당 엔티티가 클라이언트에게 전송되지 않을거라면 생성자를 이렇게 작성할 수 있다.

CMyEntity() : CBaseEntity(true) { /* 생성자 코드 */ }

Tip: CServerOnlyEntity은 이미 이렇게 처리된다.  CLogicalEntity가 상속되는 Valve의 논리 엔티티들이나 VPhysics 제약에는 딕셔너리가 붙지 않는다.

딕셔너리가 없는 엔티티의 수는 네트워크에 연결되지 않은 엔티티의 수에 따로 집계된다. 이것도 갯수 제한은 최대 2048개다.

Getting

edict_t* CBaseEntity::edict()

  • 단순한 접근자, 엔티티에 딕셔너리가 없다면 null을 반환한다.

edict_t* INDEXENT( int iEdictNum )
int ENTINDEX( edict_t* pEdict )

  • 엔티티에 붙은 딕셔너리와 엔티티 인덱스를 변환한다.

int GetEntityCount()

  • 현재 할당된 딕셔너리의 수를 반환 (엔티티 수가 아님)
SETTING

void CBaseEntity::NetworkProp()->AttachEdict(edict_t* pRequiredEdict);

  • 딕셔너리를 엔티티의 CServerNetworkProperty에 할당, 특정 딕셔너리가 필요한 것이 아니라면 NULL을 넣을 것.

void CBaseEntity::NetworkProp()->DetachEdict()

  • 엔티티에 붙여둔 딕셔너리를 빼고 재사용 될 수 있게 딕셔너리 목록로 다시 이동시킴.
주요 멤버들

CBaseEntity* GetUnknown()->GetBaseEntity()

  • 해당 엔티티가 로컬에서 표시되는 포인터

char* GetClassName()

  • 할당된 엔티티의 클래스 이름 (엔티티 클래스 이름)

bool IsFree()

  • 딕셔너리가 다른 엔티티에 할당되었으면 false를 반환함

float freetime

  • 마지막으로 딕셔너리가 해체 된 시점의 타임스탬프
    딕셔너리가 해체되자마자 재할당되는 것을 피하는데 사용될 수 있다.

bool HasStateChanged()

  • DataTable 내에서 전송이 필요하다면 true를 반환함

void StateChanged()

  • 변경된 딕셔너리가 엔티티의 DataTable에 전송이 필요하다고 알림.

IServerEntity* GetIServerEntity()
IServerNetworkable* GetNetworkable()
ICollideable* GetCollideable()

  • 유용한 인터페이스 접근자들
, ,

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다