게임 세계 내에서 다량의 엔티티를 시뮬레이션하는 우아한 방법


33

일부 기능을 수행하는 많은 (많은) 엔티티가 있고 모든 프레임에서 항상 필요하거나 고려할 필요는없는 게임이 있다고 가정합니다. 이 문제가있는 구체적인 문제는 장기를 포함한 신체의 세부 시뮬레이션입니다.

게임에서 각 생물은 자신의 몸을 가지고 있으며, 몸은 작은 부분 (몸통, 다리 등)으로 분리되어 있으며 때로는 신체의 특정 기능을 수행하는 기관이 포함되어 있습니다. 장기가 현재 목적을 제공하는지 또는 활동 중인지 여부는 실제로 분명하지 않습니다. 결국, 동물은 공복이있을 수 있으므로 아무것도 소화 할 필요가 없습니다. 세계에 많은 생물체가있는 즉시 각 프레임의 모든 물체를 확인하거나 시뮬레이션하는 것은 매우 어리석은 일입니다. 그래서 업데이트가 필요한 객체와 그렇지 않은 객체를 현명하게 구별하는 방법에 대해 생각하고있었습니다.

내가 생각해 낸 것은 적어도 괜찮은 해결책 인 것 같습니다. 시뮬레이션해야 할 객체가 상주하는 "주의 스택"이라고하는 간단한 큐 / 스택 (필수는 각 요소가 읽히자 마자 제거됩니다. 순서는 관계가 없습니다)을 만듭니다. 주의를 기울여야하는 물체는 단순히 스택 위에 놓 이거나 다른 물체에 의해 쌓 입니다. 이 객체들은 아마도 simulate () 함수를 가진 간단한 인터페이스를 구현할 것입니다.

이전 소화 예제에 적용하면 다음을 의미합니다.

플레이어는 인벤토리에서 먹을 것을 선택하고 (빵이라고 가정) 캐릭터의 입에 넣고 입은주의 스택에 놓입니다. 다음 프레임에서는 입에서 스택을 가져 와서 그의 시뮬레이트 () 함수가 호출됩니다. 입 이니까 여기서 씹는 것을 시뮬레이션하는 것이 합리적입니다. 이것은 음식이 삼킬 준비가 될 때까지 입이 계속 쌓이는 몇 프레임 동안 계속 될 수 있습니다. 이 경우 입은 씹은 빵을 위장에 넣습니다 (직접 가지는 않지만 식도는 단순화를 위해 빠져 있습니다). 그런 다음 관심 스택에 놓입니다. 다음 프레임에서 소화 과정의 시뮬레이션이 시작됩니다. 나머지 필요한 장기도 마찬가지입니다.

이것에 대한 예측 가능한 문제는 유휴 개체입니다. 잠자는 동물이 좋은 예입니다. 잠자는 동물을 쌓아두고 깨어날 필요가있을 때마다 확인하여 이전에 설명한대로 수행 할 수 있지만, 이것이 유일한 일이기 때문에 낭비가되는 것 같습니다. 유휴 개체를보다 효율적으로 만들기 위해 특정 시간에 수행 할 작업을 저장하는 일정을 추가 할 계획이었습니다. 동물이 잠 들면 동물이 잠들기 시작한 후 일정 시간 동안 일정을 잡게됩니다. 이 작업은 잠자는 동물을주의 스택에 다시 넣는 것을 돌볼 것입니다. 주의 스택에 있지 않은 잠자는 동물은 인공 지능이 시뮬레이션되지 않았기 때문에 어떤 것에 의해 공격당하는 것을 놓칠 수 있다고 말할 수 있습니다.

나는 이것이 경험 부족으로 인해이 문제에 대한 우아한 해결책에 가까운 지 솔직히 모르겠습니다. 사용할 수있는 물건에 가까이 있습니까? 이것은 보통 어떻게 이루어 지거나 제안이나 더 나은 해결책이 있습니까?

답변:


10

이것이 바로 Stendhal 에서이 문제를 해결 한 방법 입니다. 우리의 경우에는 주기적으로 일어나는 일이 많이 있지만 모든 차례는 아닙니다. 치유 주문, 식물이 조금 더 자라며 시체가 퇴화되고 땅이 만료되는 아이템.

우리는 매 차례마다 증가하는 차례를 가지고 있습니다. 그리고 우리는 그 차례에 통보해야 할 일련의 객체를 가리키는 미래의 차례 번호의지도를 유지합니다.


그 동안 다른 물체가 물체와 상호 작용하면 어떻게됩니까? 예를 들어, 잠자는 동물은 치는 돌에 의해 깨어날 수 있습니다. 이 경우 동물의 일정을 제거해야합니까?
Emiliano

상황에 따라 다릅니다. 수행 된 작업이 무해한 경우 (이미 깨어있는 상태에서 깨어 난 것처럼) 우리는 그 일이 일어나도록 내버려 둡니다. 그러나 작업이 일부 리소스를 사용하는 경우 보류중인 큐를 검색하여 제거합니다.
Hendrik Brummermann

14

입력과 비슷한 문제처럼 들립니다. 키보드에는 100 개 이상의 키가 있지만 모든 프레임에서 각 개별 키를 확인하고 싶지 않으므로 어떻게해야합니까?

두 가지 답변 : 폴링 또는 시스템 메시지.

Polling = 게임에서 실제로 중요한 시점에서 키보드 키의 상태 (또는 귀하의 경우 객체)를 쿼리하십시오. 나머지 시간은 무시하십시오.

메시지 = 각 키보드 키 (개체)를 누르거나 놓을 때 (주의가 필요한 경우) 메시지 대기열에 무언가를 넣습니다. 게임 루프가 반복 될 때마다 대기열을 살펴보고 진행하기 전에 모든 메시지를 해결합니다.


10

구현에서 한 걸음 물러서서 디자인 관점에서 질문을 검토하겠습니다. 이 시뮬레이션에 포함하려는 모든 세부 사항을 표시하기위한 확실한 계획이 있습니까?

예를 들면 다음과 같습니다.

  • 공복이있는 동물과 가득한 동물의 차이를 플레이어가 알 수 있습니까?
  • 그들이 게임 내에서 상호 작용을 선택할 때이 정보가 어떤 식 으로든 중요합니까?
  • 동물을보고있는 플레이어가 시뮬레이션 된 이벤트의 결과를 일관되게 예측할 수 있습니까, 아니면 임의의 숫자로 충분합니까?

기본적으로 경험 법칙은 시뮬레이션을 출력보다 더 복잡하게 만들지 않는 것입니다. 하루가 끝나면 양을위한 유일한 애니메이션이 방목, 잠, 도망가는 것입니다. 그렇다면 어떤 국가를 선택해야하는지 결정하는 데 얼마나 많은 요소가 필요한지는 중요하지 않습니다. 모든 플레이어는 밤에 잠을 자고 위험에서 도망쳐 낮에 먹는 양을 보게됩니다.

행동 시뮬레이션은 작업하기에 매우 재미 있지만 항상 최종 사용자 경험을 염두에 두십시오.


그렇습니다. 플레이어는 그 차이를 말할 수 있으며 이것이 게임 플레이에 미치는 영향은 몇 가지 있지만, 지금은 재미를위한 '특수 효과'입니다. Dwarf Fortress의 상처 시스템과 비슷하지만 매우 상세하지만 무시할 수 있습니다. 그러나 이미 언급했듯이 작업하는 것은 많은 즐거움이며 지금은 저의 주요 초점입니다.
Marc Müller 5

9

몇 년 전 일한 게임에서 비슷한 문제가 발생했습니다. 물체의 시뮬레이션은 복잡하여 세계의 모든 물체에 대해 세부적으로 수행 할 수 없었습니다.

해결책은 LOD 개념을 시뮬레이션에 사용하는 것이 었습니다. 플레이어가 볼 수있는 오브젝트는 전체 시뮬레이션을 실행합니다. 플레이어와 멀리 떨어진 물체는 주기적으로 매우 단순화 된 시뮬레이션을 실행했습니다. 객체가 플레이어의 시야에 들어 오면 코스는 주기적 시뮬레이션 업데이트에서 상세하고 정기적 인 업데이트로 전환됩니다.


2

일정이있는 솔루션이 좋습니다. 모든 엔티티는 향후 조치에 대한 포인터 목록을 가져야하며, 필요한 경우 향후 조치를 무효화 할 수 있습니다. 즉. 잠자는 동물은 공격 당하면 즉시 깨어나므로 나중에 깨우기 동작을 무효화해야합니다.


1

이에 대한 디자인 패턴이 있습니다. 데이터베이스 객체라고 생각합니까?

기본적으로, 당신은 게임 세계에서 모든 비 특별 양을 대표 할 수있는 하나의 "템플릿"양을 유지하고, 양의 위치 및 / 또는 시간 표와 같은 템플릿 개체 내에 고유 한 데이터를 유지하면서 같은 방식으로 그립니다. -전단부터. 그런 다음 양을 고유하게 만들어야 할 때마다 고유 한 양을 추적하는 특정 인스턴스를 만들 수 있습니다.

애니메이션도 마찬가지입니다. 모든 인스턴스에 공통적 인 유휴 애니메이션 또는 이벤트 인 경우 템플릿 인스턴스에 상주 할 수 있으며,보다 구체적인 애니메이션을 별도로 예약 할 수 있습니다.

오래 전에 저는 메인 루프가 방금 전체 장면에서 animate ()라고하는 프로그래밍 콘테스트를위한 게임을 작성했습니다. 함수 포인터를 사용하여 필요에 따라 유휴 애니메이션을 다른 애니메이션으로 대체하고 상속 된 애니메이션을 지원하는 기술을 사용했습니다 (예 : 회전 디스크에 서있는 캐릭터 회전).

이는 애니메이션에 델리게이트를 사용하는 것과 본질적으로 유사합니다.


3
플라이급 패턴인가요?
topright

0

상태 머신이 작동합니까? 동물은 예를 들어 수면 상태, 섭식 상태, 달리기 상태 등입니다. 각 상태에 대해 활성 장기 목록을 연결합니다. 따라서 각 프레임을 방문하면 각 동물을 방문하고 상태를 켜고 해당 상태에 대한 장기 검색 목록을 작성하고 각 장기에 대한 업데이트를 실행합니다.


동물 내에서 여러 가지 일이 발생할 수 있기 때문에 문제가 복잡하다고 생각합니다. 예를 들어, 위가 무언가를 소화한다고해서 심장 박동이 멈추거나 동물이 걷는 것을 멈추는 것은 아닙니다. 물론 각각의 기능을 고려한 상태 집합을 정의 할 수 있지만 상태의 양은 엄청나게 클 것입니다.
Marc Müller

모든 활성 장기를 상태에 저장하고 각 프레임마다 하나씩 실행하기 때문에 상태마다 여러 가지 일이 발생할 수 있습니다. 시뮬레이션에서 발생하는 많은 것들이 상태 전이에 맞는 것 같습니다. 예 : 씹기-> 소화. 그러나 동물이 하나의 상태만을 가질 수는 없다고 생각합니다. 소화 시스템에서 발생하는 상태 전이와 관련이없는 팔다리에서 발생하는 상태 전이가 있습니다. 그러나 아마도 당신이 가진 것보다 더 복잡 할 수도 있습니다. 고려해야 할 수도 있다고 생각했습니다.
Erik Engheim
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.