This is a "cheat sheet" for the Bit Buffers extension by YellowAfterlife!

The extension can be downloaded from itch.io.

The source code can be found on GitHub.

Click on sections to expand/collapse them.
Quick display controls: Categories · Sections · Everything ·

Basics

Make a buffer and write some data to it:

buffer = buffer_create(64, buffer_fixed, 1);
var my_health = 7, win = true;
var output = new BitOutput(buffer);
output.writeInt(my_health, 0, 10);
output.writeBool(win);
output.finish(); // <- don't forget!

You can later read the data back from the buffer in the same order:

var input = new BitInput(buffer);
var my_health = input.readInt(0, 10);
var win = input.readBool();
input.finish();
show_debug_message(my_health);
show_debug_message(win);

And, as usual, don't forget to destroy your (GameMaker) buffers after you're done working with them!

BitOutput
BitOutput
new BitOutput(buf)

Creates a new bit writer to work with the given buffer.

buffer

Holds the buffer that you passed into the constructor.


writeBool(flag)

Writes a boolean value as a single bit.

writeInt(value, minInc, maxInc)

Writes an integer value between between minInc (inclusive) and maxInc (inclusive).

The value will be clamped to min..max range and rounded if necessary.

writeFixed(value, minInc, maxInc, steps)

Writes a fixed-point value between between minInc (inclusive) and maxInc (inclusive).

steps is the number of fixed-point values per integer, so output.writeFixed(0, 1, 4) would allow the value to be 0, 0.25, 0.5, 0.75, or 1.

The value will be clamped and snapped to the nearest step/increment as necessary.

finish()

Finishes writing and flushes any remaining bits into the buffer.

If the buffer is not empty, this will only overwrite the "new" bits on the final byte.


sizeof(minInc, maxInc, steps = 1)

Returns how many bits a fixed-point value will take up.

Omit steps or leave at 1 for measuring integers.


tell()​

Returns the writing position with bit precision.

This is buffer_tell(buffer) with a fractional offset (0 .. 0.875) to indicate the bits.

seek(pos)

Changes the writing position with bit precision.

This will call buffer_seek for the buffer and change the writer's bit offset.

If the buffer is not empty, this will only overwrite bits after the position.

BitInput
BitInput
new BitOutput(buf)

Creates a new bit writer to work with the given buffer.

buffer

Holds the buffer that you passed into the constructor.


readBool()​

Reads a boolean value as a single bit.

readInt(minInc, maxInc)​

Reads an integer value between between minInc (inclusive) and maxInc (inclusive).

The returned value is guaranteed to be within the range even if bits are malformed (like reading bits 111 as a value in range of 0..5).

readFixed(minInc, maxInc, steps)​

Reads a fixed-point value between between minInc (inclusive) and maxInc (inclusive).

Same as in writeFixed, steps indicate the number of steps per integer.

Same as above, the returned value is guaranteed to be within the range.

finish()

For consistency with BitOutput, this will skip to the end of the current byte, but does not do anything beyond that.


sizeof(minInc, maxInc, steps = 1)

Returns how many bits a fixed-point value will take up.

Omit steps or leave at 1 for measuring integers.


tell()​

Returns the reading position with bit precision.

This will be a fraction of a byte behind buffer_tell(buffer) as the reader has to fetch a byte from the buffer

This is buffer_tell(buffer) with a fractional offset (0 .. 0.875) to indicate the bit.

seek(pos)

Changes the reading position with bit precision.

This will call buffer_seek for the buffer and change the reader's bit offset.

Technical
Technical
Best practices

If you are writing/reading data that might change version to version (like leaderboard metadata as you add more content to the game), it is a good idea to reserve a couple bits for a format version.

Even if it's just a number between 0 and 3 that you flip back to 0 after the 3rd version, this would still allow you to avoid parsing incompatible metadata from nearby older/newer game versions.

Limitations

Effective value sizes (see sizeof) may not exceed 63 bits because GameMaker does not have an unsigned 64-bit integer type to do this quickly/conveniently.

If you need to write 64-bit integers, do so using the regular buffer functions outside of bit writes.