Ninja Boss Fight said:
I came to a conclusion that there must be a way for me to properly organize and protect my game resources such that they are easily accessible, difficult to tamper with, easily independently updateable and perhaps efficient. Research has brought me to custom binary file formats which I am interested in for the java platform.
I would like to better understand:
- How I can define a custom format with Java code as an example
- How I can convert my data in to a file that uses this format and back with Java
- What should I watch out for
So reading that slowly, I see you are looking for 7 items.
1> organize and protect my game resources so that they are easily accessible
Organize in a structure that works well for your game. Exactly how you organize your assets will depend on your game.
You might keep them organized by object, so perhaps a per-creature basis, with textures, sounds, animations, and other resources in a directory per creature. Or you might do it by level, the ice level having all their textures, sounds, animations, and other resources, the fire level having its own directory, the water level having its own directory, and similar.
Many tools have organizational patterns that are common, and well documented within those tools. For example, Unity has frequently-used patterns that keep animations, audio, materials, models, textures, scenes, etc., all in their own trees. Unreal has it's own frequently-used patterns for the content folder, often with maps, characters, environment object, sound, vehicles, weapons, etc., which were popularized from the ShooterGame template.
2> difficult to tamper with
By whom? Anyone running your game will have the ability to view the decoded files eventually. Sooner or later you must send models and textures to the graphics hardware, you must send audio to the audio card, and both of those can be intercepted. You must decode whatever animation data you have, you can never overcome the analog hole.
Some companies in history have invested fortunes in a cat-and-mouse game trying to protect assets. Most people recognize it is futile and pointless beyond a legal requirement, so we stick with basic encryption when required. If your game is popular whatever protections you create will be inadequate. If your game isn't popular nobody will bother.
Most good formats incorporate techniques like checksums or CRCs, and cryptographic hashes. Those detect most data corruption. Simple password protection on the zip file can protect against basic naive tampering in addition to CRCs.
3> easily independently updatable
What's your distribution method?
Steam does it automatically for you, and they do a great job. Just update your files in the directory tree, publish the patch, and they do the hard work.
If you're building installers you're going to need to figure that out before you get too far along. If you don't have fancy tools that can to incremental patches, I recommend compressed archives that can be swapped out wholesale with updates. Unity and Unreal can both help you prepare patched package files, but they take some time to get it right. But you're not using those if you're asking about Java.
4> perhaps efficient
Efficient in what way? For spinny disks and SSD drives it is historically faster to use compressed formats. The time to read from disk required far more time than the decompression time. A few NVMe drives have broken that history, but they take some seriously high speeds to do it.
Compress it, or use a library that compresses it.
Big game engines use compression algorithms optimized for rapid decoding. Smaller projects use zip files.
5> How I can define a custom format with Java code as an example
There are tons of tutorials, like this paid one. You might be familiar enough with the language to skip the first few, but from your questions most of them have useful content.
That chain of examples starts with simple serialization from plain text, to simple text data formats, grows to a directory tree containing XML and PNG images, and grows to showing you how to use the io classes to write your own arbitrary binary files.
You can also use official tutorials like this one about automatically generating the data files. Creating a ZipInputStream (with optional password protection) and using JAXB to automatically process it is straightforward with tons of examples and documentation.
6> How I can convert my data in to a file that uses this format and back with Java
That's the same topic of serialization. It's a huge topic. I recommend AGAINST implementing it yourself unless you have to. Do you want to spend your time making a game, or spending your time rewriting serialization libraries?
Graphics cards take well-established formats, like DDS, ETC, PVRTC, ASTC or similar. Artists can work directly with them in tools like Photoshop, cards use them directly.
At this point it's far easier to use Java's built in serializers. Add a few annotations and you get XML for free. Use the tutorial above and the XML is kept in zip files for free, which has CRC protections built in. You get it all for free, or you can spend months (or years) re-inventing the wheel.
7> What should I watch out for
Be careful that you spend your time doing what is most valuable to your goal. Don't waste your time on things you don't actually need. Is your goal to make a game?
If you are making a game, you DO need the ability to easily serialize data to and from storage. You DO need a way to organize data for distribution. You DO need data formats that can be directly used by your tools and your game.
Fortunately, as mentioned above, those are all provided for your in Java's own serialization libraries. As mentioned, the built-in zip streaming (with optional password protection) and automatic XML serialization with JAXB and annotations are all built in,
But if you are making a game you DO NOT need to write your own encryption, you DO NOT need to write your own obfuscation, you DO NOT need to invent your own graphics formats, you DO NOT need fancy encodings that save a few bytes of data on machines that have terabytes of storage and gigabytes of ram. Those are certainly interesting research topics if your goal is to research them, but they're completely unnecessary if your goal is to make a game.