2012-03-01 3 views
0

저는 C++에서 2 톤의 데이터를 가지고 2D 게임을 디자인하고 있습니다. 기본적으로 무작위로 생성되고 블록이 많은 지형 (매우 큰 바이트 배열 형태로)이 특징입니다. Terraria의 스타일이며 (다른 여러 게임 개체 중에서) 괴물에 대한 상태를 저장해야합니다. 플레이어가 돌아 다니면서 게임 세계의 섹션이 디스크에로드/저장되어 게임 세계가 무한히 확장됩니다 (Minecraft와 유사).게임을위한 톤의 데이터 저장

디스크에 모든 것을 저장하는 최선의 방법은 무엇입니까? 나는 주로 효율성에 관심이있다. (따라서 사용자는 내용을 로딩 할 때까지 기다릴 필요가 없다.) 그러나 사용의 편의성과 유지 보수성은 아주 가깝다. 나는 Minecraft의 저장 방법에 익숙합니다. 저장 방법은 각각의 "Chunk"에 대해 별도의 파일이 있습니다. 그러나 Minecraft와 같은 파일을 지정해야합니까, 아니면 데이터베이스를 사용해야합니까? 다른 가능성은 무엇입니까? 파일을 사용하는 경우 OS에 원시 액세스 및 처리 (데이터베이스와 매우 유사)를 요청하여 상당한 성능 향상을 얻을 수 있습니까?

또한 프로젝트를 PC에서 Mac 및 콘솔로 이식 할 수 있기를 원합니다. 개별 플랫폼에 대한 대안이 좋으므로 플랫폼에 따라 메소드를 교환해야합니다.

감사합니다.

+2

[gamedev.se] (http://gamedev.stackexchange.com/)에서 더 좋은 질문 일 수 있습니다. –

답변

1

단일 파일은 조직을 위해 파일 시스템에 의존하는 것보다 훨씬 더 깨끗하고 물리적 디스크 공간을 덜 차지할 수 있습니다. 각 청크에 링크하기 위해 파일 시작 부분에 오프셋 테이블을 유지하십시오.

압축과 관련하여 런 랭스 인코딩을 적용하면 확실히 파일 크기가 줄어들고 Minecraft와 같은 경우 순차적으로 동일한 블록이 많이 생성됩니다. 보너스로 플래터 드라이브를 사용하는 컴퓨터에서 더 빨리로드됩니다. 두 블록은 각 블록에 대한 바이트를 읽지 않고 수천 블록과 같을 수 있기 때문입니다. 효과적인 실행 길이 인코딩을위한 빠른 팁은 다음과 같습니다. 명령 바이트를 사용합니다 (예 : 0x00). 다른 모든 바이트는 블록과 연관되지만 명령 바이트는 정보의 비 블록 비트를 나타냅니다.기존의 실행 길이 인코딩은 다음과 같습니다

Source: AAAABBBBBBBCDDDEFA 
Destination: 0x00044100074243444444454641. 
Plaintext: ..A..BCDDDEFA 

이 데이터의 "대리석"섹션에서 뚜렷한 장점이 있습니다

Source: AAAABBBBBBBCDDDEFA 
Destination: 0x0441074201430344014501460161 
Plaintext: .A.B.C.D.E.F.A 

의 크기를 증가시킬 것 시퀀스를 생략 명령 바이트를 사용.

다른 점은 little endian 형식 임에도 불구하고 midi 형식과 비슷한 숫자를 저장하는 시스템을 사용하는 것이 좋습니다. 인터넷 검색을 저장하기 위해 실제로 의미하는 것은 번호를 저장하는 데 사용하는 각 바이트에 대해 약간 희생하는 것입니다. 8 번째 비트가 설정되면 숫자에 또 다른 바이트가 있음을 의미하고 캐스 캐 이드합니다. 예 :

Storing: 65 
Stored as: 0x41 (01000001) //The eighth bit is not set, so this number only occupies 7 bits. 

Storing: 192 
Stored as: 0xC081 (11000000 10000001) //The eighth bit of the first byte is set, so the following byte is part of the number. The second byte doesn't have the eighth bit set, so the number ends there. 

Storing: 612453 
Stored as: 0x72D825 (11100101 1011000 00100101) //The eighth bit of the first two bytes are set, and the third is not, so this number occupies 3 bytes. 

나는 약간의 통찰력을 제공하는데 도움이되기를 바랍니다.

+0

굉장히 유용합니다. 전에 인코딩을 해본 적이 없지만 기본을 이해합니다. 나는 플래터 드라이브뿐만 아니라 그것에 조금 googling해야 할 것이다. 아마도 "특수한"블록 (예 : Minecraft의 TileEntities - 항목이있는 가슴을 원한다)에 대해 MIDI 스타일 인코딩을 사용할 것입니다. 감사! – Philip

+0

문제 없습니다. 필자는 여분의 바이트를 사용하여 숫자의 길이를 저장하는 형식으로 숫자를 저장했습니다. 그것은 더 간단하지만 7 바이트 이하를 차지하는 숫자의 경우 효율적이지 않으며 4 바이트보다 큰 숫자는 사용하지 않습니다. 미디 포맷을 살펴볼 때 가변 길이 번호를 저장하는이 독창적 인 방법에 만족했습니다. 나는 기쁘다 내가 도와 줬어 :) – Kaslai

+0

하나의 파일 건에 관해서는, 나는 나의 덩어리가 디스크의 가변 크기 인 경우, 내 부서 스킬에 의지해야 할 것이다. 파일의 시작 부분에 색인이있는 페이징 시스템? 페이징 인덱스를 페이징해야한다면 어떻게해야합니까 ?? * faints * – Philip

3

데이터베이스의 목적은 복잡한 검색 속도를 높이는 것입니다. 당신은 계속 진행중인 검색을 필요로하지 않습니다. 메모리에 들어가야하는 데이터 블록이 있습니다. 데이터베이스는이 작업을 위해 절대 가치가 없습니다.

당신이 정말로 필요한 것은 당신이 말하는 데이터의 양과 플랫폼에 특정한 당신이 원하는 방식에 달려 있습니다. 당신은 2D 게임에 대해 이야기하는 것처럼 보입니다. 따라서 덩어리는 이 될 수 없으므로이 커집니다. 일반 C 또는 C++ 파일 IO 기능으로는 충분할 것입니다. 최악의 경우 비동기 파일 IO 및 처리를 위해 스레드에 붙여야 할 수도 있습니다.

정말 뻔한 일을 시작하십시오. 문제가되는 경우 간단한 스레딩 구성으로 비동기로 만듭니다. 당신은 아마 그것보다 너무 멀리 갈 필요가 없습니다.

+0

흠, 괜찮습니다. 그렇다면 데이터베이스에는 없습니다. Ehhhh 청크 크기는 가변적이지만 크기가 클수록 다른 것들은 빠릅니다 (설명하기 어렵습니다). 그들은 현재 1024x1024 (무려 1MB)이지만 512x512와 256x256은 확실히 옵션입니다. – Philip

+0

1 메가 바이트가 백 푸딩 일 때 알려 드리겠습니다. – fazo

+0

@Philip : 1MB짜리 덩어리에 대해 이야기하고 있다면,별로 특별 할 필요가 없습니다. 그들을로드하고 처리하십시오. 응답 성이 문제인 경우 다시 스레드를 사용하십시오. –

1

제 경험상, 실제로 많은 요소에 따라 달라집니다. 우리 그룹에는 수백 또는 수천 개의 파일을 데이터베이스에 저장하는 시스템이 있었으며 성능이 향상되었습니다. 이러한 파일은 작았 기 때문에 디스크 드라이브가 회전하기를 기다리는 대기 시간이나 운영 체제가 파일 시스템을 개별 파일로 탐색하는 데 비해 읽기 및 쓰기가 짧았습니다.

4KB 페이지보다 작은 수천 개의 파일이 있다면 데이터베이스와 함께 갈 것입니다. 파일이 그보다 더 크면 파일로 이동하십시오. 데이터베이스는 처리량에 도움이되지 않으며 대기 시간 만 지원합니다.

+0

감사합니다. 디스크 대기 시간을 고려하지 않았습니다. 그때 데이터베이스에 따라 달라질 수 있습니다. 데이터베이스가 처리량에 영향을 줄 수 있습니까? – Philip

+0

TAR 또는 Zip 파일에 이러한 느슨한 파일을 고정하여 동일한 이점을 얻을 수 있습니다. –

+0

타르 또는 지퍼의 단점은 모든 것을 읽어야한다는 것입니다. 그는 한 번에 데이터의 일부만을 메모리로 읽어 들이기를 원한다고 말했습니다. 따라서 단일 파일을 사용하지 않을 것입니다. 운영 체제는 모든 것을로드하고 디스크 캐시에 보관해야합니다. – danimator