롤백 제약 사항
롤백 시스템에는 알아야 할 몇 가지 제약 사항이 있습니다. 이러한 제약 사항을 위반하면 오류가 발생하여 문제가 무엇인지 알려줍니다.
브라우저 지원
롤백 멀티플레이어는 WebTransport API를 사용하며, 모든 브라우저에서 지원되지 않을 수 있습니다. 현재 데스크탑에서는 Safari, Firefox 및 Internet Explorer가 지원되지 않습니다. 모바일에서는 Chrome, Firefox 및 Safari도 지원되지 않습니다.
방(Rooms)
멀티플레이어 게임이 활성화된 상태에서 방을 변경할 수 있으며, 모든 플레이어가 연결되어 있어야 합니다. 방을 변경하면 게임이 동기화 프로세스를 다시 실행합니다. 관리되는 객체의 데이터는 방이 변경될 때 자동으로 전달되지 않습니다. 글로벌 변수, 지속 객체를 사용하거나 로컬 플레이어의 정보를 파일에 저장하여 수동으로 전달할 수 있습니다. 이러한 옵션을 사용하여 방이 끝나기 전에 플레이어의 정보를 저장하고, 새로운 방에서 플레이어 인스턴스가 생성될 때 다시 적용할 수 있습니다.
이벤트 순서
멀티플레이어 게임이 시작될 때 다음 이벤트가 주어진 순서로 실행됩니다:
- 방 시작
- 정의된 플레이어에 대한 생성 이벤트
- 롤백 시작 (rollback_event_param.first_start는 true)
멀티플레이어 게임 중간에 방을 변경하면 다음 이벤트가 주어진 순서로 실행됩니다:
- 방 종료
- 정의된 플레이어에 대한 정리 이벤트
- 방 시작
- 정의된 플레이어에 대한 생성 이벤트
- 롤백 시작 (rollback_event_param.first_start는 false)
파괴 이벤트
인스턴스의 파괴 이벤트는 일반적으로 인스턴스가 파괴되자마자 실행됩니다. 그러나 멀티플레이어 게임에서는 즉시 실행되지 않을 수 있습니다. 잘못된 예측으로 인해 instance_destroy() 호출이 실행되면 인스턴스의 파괴가 곧 롤백될 수 있습니다. 따라서 인스턴스의 파괴 이벤트는 인스턴스가 실제로 파괴되었음을 확인한 후에만 호출됩니다. 이로 인해 플레이어 화면에서 인스턴스가 파괴되는 데 약간의 지연이 발생할 수 있습니다. 클라이언트 화면에서 인스턴스가 파괴되는 것과 동시에 어떤 일이 발생하도록 하려면, 사용자 정의 함수를 생성하고 instance_destroy()와 함께 호출하는 것이 좋습니다. 이는 인스턴스가 파괴될 때 실행되는 정리 이벤트에도 적용됩니다.
상태 관리
롤백 멀티플레이어는 클라이언트 간의 게임 "상태"를 관리합니다. 여기에는 관리되는 인스턴스와 그 변수들이 포함됩니다. 이러한 관리되는 게임 부분은 롤백 시스템의 잘못된 예측이 발생할 경우 롤백될 수 있습니다. 관리되는 인스턴스를 생성하거나 파괴하거나 속성/변수를 수정할 때 게임의 상태를 업데이트합니다. 이 상태는 다른 플레이어에게 전송되지 않으며, 모든 클라이언트에 대해 입력만 공유됩니다.
롤백 시작 전 상태
각 플레이어가 동일한 게임 상태에서 시작해야 합니다. 즉, 롤백 시작 이벤트가 발생할 때 모든 플레이어의 게임 및 관리되는 인스턴스에 대한 모든 것이 동일해야 합니다. 그 시점 이전에 관리되는 인스턴스에 대한 생성 또는 설정 코드를 실행할 수 있으며, 모든 클라이언트에 대해 정확히 동일한 방식으로 수행해야 합니다. 게임이 시작되었는지 확인하려면 rollback_game_running을 사용하세요. 시작/참여 호출과 롤백 시작 이벤트 사이의 시간을 사용하여 대기 중인 플레이어에게 로딩 화면을 표시할 수 있습니다.
플레이어는 게임을 떠날 때 동일한 상태로 돌아오며, 게임이 연결되어 있는 동안에만 게임 로직이 실행되도록 하기 위해 rollback_game_running을 사용하는 것이 필요합니다.
글로벌 상태
게임 상태에 영향을 미치는 글로벌 변수를 사용할 수 없습니다. 글로벌 변수는 플레이어 간에 동기화되지 않기 때문입니다. 필요한 모든 변수는 관리되는 객체 내에 있어야 합니다.
드로우 이벤트 상태
드로우 이벤트에서 상태를 변경할 수 없으며, 그 목적은 이전 이벤트에서 설정된 상태에 따라 그래픽을 그리는 것입니다. 모든 관리되는 객체는 드로우 이벤트 동안 읽기 전용이 되므로, 그 안의 변수를 변경할 수 없으며, 관리되는 객체의 인스턴스를 생성하거나 파괴할 수 없습니다.
시간 변수
current_time 또는 get_timer()와 같은 변수를 사용하여 게임 로직에 영향을 미치지 마세요. 대신 rollback_current_frame이라는 관리 변수를 사용할 수 있습니다. 이는 멀티플레이어 게임이 시작된 이후로 경과한 프레임 수를 반환합니다. 알람 이벤트는 관리되는 객체에서 안전하게 사용할 수 있습니다. delta_time을 사용하지 않도록 하세요. 이는 게임을 실행하는 시스템에 따라 크게 달라지며, 플레이어 간에 동기화될 수 없습니다.
인스턴스 참조
관리되는 인스턴스에 저장된 인스턴스 ID는 관리되는 인스턴스를 가리켜야 합니다. 관리되는 인스턴스가 비관리 인스턴스를 참조하면 클라이언트 상태 간에 불일치가 발생합니다. 비관리 인스턴스에 대한 변경 사항은 관리되지 않으며 롤백할 수 없기 때문입니다. 예를 들어, 관리되는 obj_workstation 인스턴스가 obj_anvil 인스턴스를 참조하는 경우, obj_anvil은 관리되는 객체여야 합니다.
잃어버린 인스턴스 참조
관리되는 인스턴스 내의 변수에 다른 관리되는 인스턴스에 대한 참조가 포함되어 있는 경우, 참조된 인스턴스가 파괴되면 해당 변수는 정의되지 않게 됩니다. 즉, 지속 관리되는 인스턴스의 변수에 비지속 관리되는 인스턴스에 대한 참조가 포함되어 있는 경우, 방이 변경될 때 해당 변수는 정의되지 않게 됩니다.
랜덤 숫자
랜덤 숫자 생성(RNG) 상태는 플레이어 간에 관리되므로, 게임 로직에 랜덤 함수를 사용하는 것은 완전히 안전합니다. 롤백 시스템은 각 플레이어가 게임의 동일한 시점에서 동일한 랜덤 숫자를 받도록 보장합니다. 드로우 이벤트는 별도의 RNG 상태를 사용합니다. 따라서 드로우 이벤트에서 호출된 랜덤 함수는 다른 이벤트의 일반 RNG 상태에 영향을 미치지 않으며, 서로 다른 플레이어 간에 동일하지 않을 수 있습니다.
시드
randomise() 또는 random_set_seed()를 사용하여 RNG 시드를 변경할 수 없습니다. 이는 롤백 시스템에 의해 관리되기 때문입니다. 관리되는 RNG 상태는 롤백 시작이 호출될 때만 시작됩니다. 멀티플레이어 게임이 시작될 때입니다. 그 시점 이전에 시드를 변경할 수 있지만, 시작 시점 이후에는 아무런 영향을 미치지 않습니다.
추가 읽기
롤백 시스템에 대한 자세한 정보는 다음 페이지를 참조하세요:
- 롤백 이벤트
- 멀티플레이어 게임 생성
- 롤백 시스템
- 입력 정의
제목 | 설명 |
---|---|
롤백 이벤트 | 롤백 시스템의 이벤트에 대한 설명입니다. |
멀티플레이어 게임 생성 | 멀티플레이어 게임을 만드는 방법에 대한 가이드입니다. |
롤백 시스템 | 롤백 시스템의 작동 방식에 대한 설명입니다. |
입력 정의 | 입력을 정의하는 방법에 대한 정보입니다. |
활용 예제
// 방을 변경하기 전에 플레이어 정보를 저장하는 예제
global.playerData = playerData;
// 방 변경 후 플레이어 정보를 복원하는 예제
playerData = global.playerData;
// 인스턴스를 파괴하기 전에 사용자 정의 함수 호출
function customDestroyFunction() {
// 파괴 전 수행할 작업
}
customDestroyFunction();
instance_destroy();
// 드로우 이벤트에서 그래픽을 그리는 예제
draw_sprite(sprite_index, image_index, x, y);
// 랜덤 숫자를 생성하는 예제
var randomValue = random(100);
// 알람 이벤트를 사용하는 예제
alarm[0] = room_speed * 5; // 5초 후 알람 발생
// 게임 상태를 확인하는 예제
if (rollback_game_running) {
// 게임이 실행 중일 때의 로직
}