JAG

From RuneScape Classic Wiki
Jump to navigation Jump to search

JAG is a file format used by the RuneScape Classic game engine to store collected archives of compressed data. JAG archives are cached on the player's computer to speed up the game's load times, and use the .jag (for free-to-play content) and .mem (for pay-to-play content) file extensions. Initially, they are downloaded from the Jagex servers. They are similar in concept to a ZIP file, except they store very minimal data about files that the client already knows about in advance.

Like most RuneScape Classic file formats, JAG is a simple binary format using big endian byte order for integers.

Features

[edit | edit source]

Each individual file inside the JAG archive can be compressed with BZip2 independently, or the whole archive can be compressed, allowing flexibility in case different compression schemes are more efficient. BZip2 is a very slow algorithm, which results in increased load times even on modern computers, but its use makes sense in a context where most end-users are on dial-up and paying per kilobit. Jagex uses BZip2 without the magic number, version, or 100kB block size header, which is non-standard.

A JAG archive can store up to 65,535 entries. The maximum size of a file within a JAG archive is a quite small 16,777,215 bytes (16.78 MB).

Format

[edit | edit source]

Whole-archive header

[edit | edit source]

Each JAG archive begins with a header:

  • 24-bit integer: the size of the archive decompressed
  • 24-bit integer: the size of the archive compressed

If the two sizes are equal, the archive does not use whole-archive compression (it is probably using per-file compression, see below). Sprites use per-file compression, while other game assets mostly use whole-archive compression.

Per-file headers

[edit | edit source]

Metadata for each file is stored sequentially after a 16-bit integer containing the number of files:

  • 32-bit integer: the hash of the file name (see below)
  • 24-bit integer: the size of the file decompressed
  • 24-bit integer: the size of the file compressed

After the metadata for every file in the archive, compressed data is stored sequentially. There is a possibility for files to be stored uncompressed (i.e. using whole-archive compression) if the decompressed and compressed sizes are the same.

File name hashing

[edit | edit source]

Each file name inside the archive is stored as a hash generated using the following algorithm, represented here in C code:

#include <ctype.h>
#include <string.h>

int
hash(const char *s)
{
	int hash = 0;
	size_t i = 0;
	size_t len;

	len = strlen(s);
	for (i = 0; i < len; ++i) {
		hash = (hash * 61 + toupper(s[i])) - 32;
	}
	return hash;
}

See also

[edit | edit source]
  • JM and HEI, landscape file formats contained within JAG archives
  • OB3 and OB2, 3D model file formats contained within JAG archives
  • Sprite