For the complete documentation index, see llms.txt. This page is also available as Markdown.

서버리스 멀티플레이어

플레이어 간에 씬 상태를 동기화합니다.

Decentraland는 플레이어의 익스플로러 인스턴스에서 씬을 로컬로 실행합니다. 기본적으로 플레이어들은 서로를 볼 수 있고 직접 상호작용할 수 있지만, 각 플레이어는 환경과 독립적으로 상호작용합니다. 기본적으로 환경의 변경 사항은 플레이어 간에 공유되지 않습니다.

플레이어들이 더 의미 있는 방식으로 상호작용하려면 같은 상태의 동일한 콘텐츠를 보는 것이 매우 중요합니다.

모든 플레이어가 동일하게 볼 수 있도록 씬 상태를 동기화하는 방법은 세 가지가 있습니다:

앞의 두 옵션은 이 문서에서 다룹니다. 서버가 필요 없으므로 더 간단합니다. 단점은 플레이어의 연결 속도에 더 많이 의존하게 되고, 모든 플레이어가 씬을 떠나면 씬 상태가 유지되지 않는다는 점입니다.

엔티티를 동기화됨으로 표시하기

의 크리에이터 허브, 엔티티에 다음을 추가하여 동기화됨으로 표시합니다: Multiplayer 컴포넌트 를 추가합니다. 엔티티의 다른 각 컴포넌트에 대한 체크박스가 포함되어 있어, 어떤 항목을 업데이트할지 선택할 수 있습니다.



코드로 엔티티를 동기화됨으로 표시하려면 다음을 사용하세요: syncEntity 함수:

이 syncEntity 함수는 다음 입력을 받습니다:

  • entityId: 동기화할 엔티티에 대한 참조

  • componentIds: 해당 엔티티에서 동기화해야 하는 컴포넌트 목록입니다. 필요한 만큼의 컴포넌트를 포함할 수 있는 배열입니다. 모든 값은 다음이어야 합니다: componentId 속성.

  • entityEnumId: (선택 사항) 모든 플레이어가 일관되게 사용하는 고유 ID입니다. 참조: enum id에 대해.

모든 엔티티나 컴포넌트가 동기화될 필요는 없습니다. 같은 자리에 그대로 있는 나무 같은 정적 요소는 동기화가 필요하지 않습니다. 동기화하는 엔티티의 경우, 시간에 따라 변경되는 컴포넌트만 동기화해야 합니다. 예를 들어, 큐브가 클릭될 때 색이 바뀐다면 MeshRenderer나 Transform이 아니라 Material 컴포넌트만 동기화해야 합니다. 이들은 절대 변경되지 않기 때문입니다.

💡 팁: 공유하려는 데이터가 컴포넌트로 존재하지 않는다면, 다음을 정의하세요: 사용자 정의 컴포넌트 그 데이터를 담는 컴포넌트.

enum id에 대해

이 entityEnumId 엔티티의 값은 고유해야 합니다. 이는 다음에 할당되는 로컬 entityId와는 관련이 없습니다: engine.addEntity(), 이는 자동으로 생성되며 동일한 씬을 실행하는 플레이어마다 다를 수 있습니다. 엔티티의 entityEnumId는 코드에서 명시적으로 정의되어야 하며 고유해야 합니다.

경쟁 조건으로 인해 씬의 한 부분이 다른 부분보다 먼저 로드되는 경우 불일치를 피하려면 이 ID를 명시적으로 설정하는 것이 중요합니다. 예를 들어 플레이어 A에게는 씬의 문이 엔티티 512, 하지만 플레이어 B에게는 같은 문이 엔티티 513. 이 경우 플레이어 A가 문을 열면 플레이어 B는 대신 건물 전체가 움직이는 것을 보게 됩니다.

💡 팁: 씬에 enum을 만들어 씬의 각 동기화 가능한 id를 명확하게 참조하세요.

여기서 EntityEnumId enum은 엔티티에 고유 식별자를 태그하는 데 사용되며, 생성 순서와 관계없이 모든 클라이언트가 수정된 엔티티를 인식하도록 보장합니다.

플레이어가 생성한 엔티티

플레이어 상호작용의 결과로 엔티티가 생성되었고 이 엔티티를 다른 플레이어와 동기화해야 한다면, entityEnumId는 필요하지 않습니다. 다음을 사용할 수 있습니다: syncEntity() 엔티티와 컴포넌트 목록만 전달합니다. entityEnumId의 고유 값은 자동으로 뒤에서 할당됩니다.

씬 시작 시 인스턴스화되는 모든 엔티티에는 수동으로 할당한 ID가 있어야 합니다. 이는 모든 플레이어가 각각 동일한 ID를 사용하도록 보장하기 위해서입니다. 한 명의 플레이어만 엔티티 인스턴스화를 담당하는 경우에는 명시적 ID가 필요하지 않습니다. 다른 플레이어들은 이미 ID가 할당된 이 새 엔티티에 대한 업데이트를 받으므로 ID 불일치 위험이 없습니다.

예를 들어, 눈싸움 씬에서 플레이어가 눈덩이를 던질 때마다 다른 플레이어와 동기화되는 새 엔티티를 인스턴스화합니다. 눈덩이에는 고유한 entityEnumId가 필요하지 않습니다.

부모가 연결된 엔티티

엔티티의 부모는 일반적으로 다음을 통해 정의됩니다: parent 의 속성 Transform 컴포넌트. 하지만 이 속성은 부모의 로컬 엔티티 id를 가리키며, 이는 달라질 수 있습니다. 참조: enum id에 대해. 동기화가 필요한 엔티티를 부모로 설정하거나, 동기화가 필요한 자식을 가진 엔티티를 부모로 설정하려면 다음을 사용하세요: parentEntity() 함수 대신 다음을 사용하세요: Transform.

부모와 자식 모두 다음과 함께 동기화된다는 점에 유의하세요: syncEntity, 따라서 모든 플레이어가 두 엔티티에 사용되는 id를 공통적으로 이해하게 됩니다. 부모의 컴포넌트가 결코 변경될 필요가 없더라도 이것은 필요합니다. 이 예제에서는 syncEntity 불필요한 컴포넌트를 동기화하지 않도록 비어 있는 컴포넌트 배열을 포함합니다.

엔티티가 다음을 통해 부모로 지정되면 parentEntity() 함수, 다음 보조 함수들도 사용할 수 있습니다:

  • removeParent(): 다음의 효과를 되돌립니다: parentEntity(). 자식 엔티티만 전달해야 합니다. 엔티티의 새 부모는 씬의 루트 엔티티가 됩니다. 원래 부모 엔티티는 씬에서 제거되지 않습니다.

  • getParent(): 전달한 엔티티의 부모 엔티티를 반환합니다.

  • getChildren(): 전달한 엔티티의 자식 목록을 iterable로 반환합니다.

  • getFirstChild(): 전달한 엔티티의 목록에서 첫 번째 자식을 반환합니다.

동기화 상태 확인

플레이어가 씬에 막 들어왔을 때, 주변의 다른 플레이어와 아직 동기화되지 않았을 수 있습니다. 동기화되기 전에 플레이어가 게임 상태를 변경하기 시작하면 게임에 문제가 생길 수 있습니다. 플레이어가 씬의 어떤 것도 편집할 수 있도록 허용하기 전에 항상 동기화 여부를 확인할 것을 권장합니다.

플레이어가 씬의 parcel 밖으로 나가면, 밖에 있는 동안에도 씬과 동기화되지 않게 됩니다. 따라서 플레이어가 근처에 있는 동안에도 씬은 계속 실행되므로, 씬의 시스템이 그 상황을 처리하는 것도 중요합니다. 플레이어가 다시 들어오면 씬 상태의 변경 사항이 자동으로 업데이트됩니다.

다음을 통해 현재 플레이어의 씬 상태가 동기화되어 있는지 확인할 수 있습니다: isStateSyncronized() 함수. 이 함수는 boolean을 반환하며, 플레이어가 이미 씬과 동기화된 경우 true입니다.

예를 들어 이 확인을 시스템에 포함하고, 이 함수가 false를 반환하면 모든 상호작용을 차단할 수 있습니다.

명시적 MessageBus 메시지 전송

메시지 버스 초기화

플레이어 간 메시지를 보내고 받는 데 필요한 메서드를 처리할 메시지 버스 객체를 생성합니다.

메시지 보내기

다음을 사용하세요 .emit 메시지 버스의 명령을 사용해 씬의 다른 모든 플레이어에게 메시지를 보냅니다.

각 메시지는 두 번째 인수로 payload를 포함할 수 있습니다. payload의 타입은 Object, 그리고 보내고 싶은 관련 데이터를 무엇이든 포함할 수 있습니다.

💡 팁: 하나의 메시지에 둘 이상의 변수 데이터를 포함해야 한다면, 이 모든 데이터를 하나의 객체에 담는 사용자 정의 타입을 만드세요.

메시지 받기

그 씬의 다른 모든 플레이어로부터 오는 메시지를 처리하려면 다음을 사용하세요: .on. 이 함수를 사용할 때는 메시지 문자열을 제공하고 실행할 함수를 정의합니다. 일치하는 문자열을 가진 메시지가 도착할 때마다 지정한 함수가 한 번 실행됩니다.

전체 MessageBus 예제

이 예제는 메인 큐브가 클릭될 때마다 메시지 버스를 사용해 새 메시지를 보내고, 무작위 위치에 새 큐브를 생성합니다. 메시지에는 새 큐브의 위치가 포함되어 있어 모든 플레이어가 이 새 큐브를 같은 위치에서 보게 됩니다.

멀티플레이어 장면을 로컬에서 테스트하기

장면 미리보기를 실행하고 이를 두 개 이상의 서로 다른 Explorer 창에서 열면, 열린 각 창은 별도의 플레이어로 해석되며, 모의 통신 서버가 이 플레이어들을 동기화 상태로 유지합니다.

한 창에서 장면과 상호작용한 다음 다른 창으로 전환하여 해당 상호작용의 결과가 그곳에도 표시되는지 확인하세요.

Creator Hub에서 Preview 버튼을 두 번째로 클릭하면 두 번째 Decentraland 익스플로러 창이 열립니다. 두 창 모두 서로 다른 주소로 연결해야 합니다. 씬이 다시 로드되어도 동일한 세션은 계속 열려 있습니다.



대안으로, 브라우저 URL에 다음을 입력하여 두 번째 Decentraland explorer 창을 열 수 있습니다:

decentraland://realm=http://127.0.0.1:8000&local-scene=true&debug=true&multi-instance=true

싱글 플레이어 씬

씬이 다음에 배포되어 있다면: Decentraland World, 싱글 플레이어 씬으로 만들 수 있습니다. 플레이어는 서로를 볼 수 없고, 채팅할 수 없으며, 서로의 행동 효과도 볼 수 없습니다.

이렇게 하려면 씬의 다음을 구성하세요: scene.json 파일에서 다음을 설정하세요: fixedAdapter 를 offline:offline. 씬에는 Communication Service가 전혀 없으며, 그 월드에 참여하는 각 사용자는 항상 혼자 있게 됩니다.

예시:

마지막 업데이트