Create Custom Binary File Formats for Your Game's Data

Your game has data - sprites, sound effects, music, text - and you need to store it somehow. Sometimes you can encapsulate everything into a single SWF, .unity3d or EXE file, but in some cases that won't be suitable. In this technical tutorial, we'll look at using custom binary files for this purpose.

Note: This tutorial assumes you have a basic understanding of bits and bytes. Check out An Introduction to Binary, Hexadecimal, and More and Understanding Bitwise Operators on Activetuts+ if you need to revise!


 

There are a few pros and cons to using custom binary file formats.

Creating something like a resource container (as this tutorial will do) will reduce disk/server thrashing and will typically make resource loading a lot easier because multiple files will not need to be loaded. Custom file formats can also add an extra layer of security in the form of obfuscation to game resources.

On the flip side you will need to actually generate the custom files one way or another before you can use them in a game, but that is not as difficult as it might sound -- especially if you or someone you know can create something like a JAR file that can be dropped into a build process with relative ease.


 

Before you can begin to design your own binary file formats you will need an understanding of the primitive data types (building blocks) that are available to you. The number of primitive data types is actually limitless but there is a common set that most programmers are familiar with and use, and these data types typically represent multiples of 8 bits.

As you can see, these primitive data types provide a wide range of integer values and you will find them at the core of most binary file specifications. There are a few more primitive data types, such as floating point numbers, but the integer data types listed above are more than adequate for this introduction and for most binary file formats.


 

Structured data types (or complex data types) represent specific elements (chunks) of a binary file, and they consist of primitive data types or other structured data types.

You can think of structured data types as objects or class instances in a programming language, with each object declaring a set of properties. Structured data types can be visualised using simple object notation.

Here is an example of a fictitious file header:

So here the structured data type is named HEADER and it has three properties labeled signature, version and length. Each property in this example is declared as a primitive data type but properties can also be declared as structured data types.

If you are a programmer you are probably beginning to realise how easy it would be to represent a binary file in an OOP based programming language; let's take a quick look at how this HEADER data type could be represented in Java:


 

At this point you should be familiar with the basics of binary file structures, so now is the time to take a look at the process of designing a working custom file format. This file format will be designed to hold a collection of game resources including images and sounds.

The first thing that should be designed is a data structure for the file header so the file can be identified before the remainder of the file is loaded into memory. Ideally the file header should at least contain a signature field and a version field:

The file signature you choose to use is up to you: it can be any number of bytes, but most file formats have a human-readable signature containing three or four ASCII characters. For my purposes, the signature field will hold the character codes of three ASCII characters (one byte per character) and will represent the string "RES" (short for "RESOURCE"), so the byte values will be 0x52, 0x45 and 0x53.

The version field will initially be 0x01 because this is Version 1 of the file format.

The resource file itself is actually a structured data type which contains a header and will later contain other elements. It currently looks like this:

The next thing will we take a look at is the data structure for images.

The resource file will store an array of ARGB colour values (one per pixel) and allow that data to be optionally compressed using the ZLIB algorithm. The image dimensions will also need to be included in the file along with an identifier for the image (so the image can be accessed after it has been loaded into memory):

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

There are a couple of things in that structure that need your attention; the first is the U8[dataLength] part of the structure and the second is the STRING data structure used for the id, which was not defined in the table of data types above.

The former is basic array notation -- it simply means that dataLength number of U8 values need to be read from the file. The data field contains the image pixels, and the compressed field indicates whether the the data field is compressed. If the compressed value is 0x01 then the data field is ZLIB compressed, otherwise the file decoder can assume the data field is not compressed. The benefit of using ZLIB compression here is the IMAGE file structure will end up being a similar size to a PNG encoded version of the image.

The STRING data structure is as follows:

For this file format all strings will be encoded as UTF-8 and the bytes of the encoded string will be located in the data field of the STRING data structure. The dataLength field indicates the number of bytes in the data field.

The resource file structure now looks like this:

As you can see the file now contains a header, a new imageCount field that indicates the number of images in the file, and a new imageList field for the images. This in itself would be a useful file format to store multiple images, but it would be even more useful if it held multiple resource types, so will will now take a look at adding sounds to the file.

Sounds will be stored in the file in a similar way to images, but instead of storing raw pixel colour values the file will store raw sound samples in varying bit resolutions:

Oh my goodness, conditional statements! Because the dataFormat field indicates the bit rate of the sound, the format of the data field needs to be variable, and that is where the simple and programmer friendly conditional statement syntax comes into play.

Looking at the data structure you can easily see which format the data field values (sound samples) will be using, given a specific dataFormat value. When adding fields like dataFormat to a data structure the values those fields can contain is entirely up to you. The values 0x01, 0x02 and 0x03 are being used in this example simply because they are the first unused values available in the byte.

The resource file structure now looks like this:

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
28 [Linux programming][turbo c] The libXbgi Library file 졸리운_곰 2023.02.05 248
27 [unix][linux][compiler] Yacc와 Lex 시작하기 file 졸리운_곰 2021.09.08 261
26 [Visual Studio 2019] Visual Studio로 Linux 원격 개발하기(Ubuntu 설치부터 SSH 서버접속까지) file 졸리운_곰 2021.08.29 235
25 [unix][emacs] 이맥스와 함께하는 개발환경 . emacs 튜토리얼 file 졸리운_곰 2021.08.18 319
24 [Linux][C/C++] cmake 사용법과 활용 file 졸리운_곰 2020.11.08 552
23 [CMake] Linux C/C++ cmake 시작하기 졸리운_곰 2020.11.08 398
22 [C++] CMake Build System file 졸리운_곰 2020.11.08 328
21 Windows 10에 한국어 입출력이 가능한 리눅스 데스크톱 설치하기 file 졸리운_곰 2020.06.29 289
20 wxwidgets 과 codeblock 설치(리눅스) 졸리운_곰 2019.12.25 228
19 ubuntu 18.04.2 LTS 개발환경 세팅 졸리운_곰 2019.12.25 223
18 Ubuntu 16.04 개발환경 세팅하기! 졸리운_곰 2017.03.21 356
17 tcl/tk 자료 secret 졸리운_곰 2017.02.23 0
16 CentOS xrdp 설정 (원격데스크탑) 졸리운_곰 2017.02.01 453
15 Five lightweight Linux desktop worlds for extreme open-sourcers file 졸리운_곰 2016.05.12 1022
14 Logging every shell command 졸리운_곰 2016.05.11 581
13 How to keep a detailed audit trail of what’s being done on your Linux systems file 졸리운_곰 2016.05.11 467
12 Docker의 소개와 간단한 사용법 file 졸리운_곰 2015.11.24 804
11 Make Self-Extracting Archives with makeself.sh 졸리운_곰 2015.11.07 363
10 리눅스 간단 배포 Linux simple deploy 제작 : make self file 졸리운_곰 2015.11.07 352
9 Joinc: Linux 커널에서의 디바이스 드라이버 작성 졸리운_곰 2015.06.16 833
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED