Skip to content
Michael edited this page Feb 23, 2024 · 6 revisions

Sometimes in games, you find yourself wanting to generate various kinds of noise. Here's a little library that does that for you!

See here for some recommended usage.

API

macaw_version()

Returns: N/A

Prints the version information to the console.

macaw_set_seed(seed)

Returns: N/A

Parameter Type Description
seed * The random seed to use

Sets the random seed to use. The input type can be absolutely anything you want; the numerical seed actually set will be (part of) the MD5 hash of the input.

This can be useful if you want to allow your users to enter their own profanity-laden custom seeds for world generation in a roguelike, or something of that nature.

Note that the same seed will produce different random results in the GML and DLL versions, since the RNG algorithm used by GameMaker is (currently) different from the RNG algorithm used by the Microsoft Visual C++ compiler.

macaw_generate(w, h, octaves, amplitude)

macaw_generate_dll(w, h, octaves, amplitude)

macaw_generate_shader(w, h, smoothness, amplitude)

Returns: struct

Parameter Type Description
w integer The width of the noise field
h integer The height of the noise field
octaves (or smoothness) integer (or a real for smoothness) The number of generation octaves to run (CPU) or the smoothness value (shader)
amplitude number The maximum value in the noise field

You can probably guess what the difference between these three functions are. (Hint: one runs in a DLL and one of them runs in a shader.)

This is where the interesting part happens. It will return a struct containing:

Property Type Description
noise buffer A buffer of size (w * h * 4) containing floating point values (fixed size, alignment of 1). The values in the buffer are stored in column-major order, although to be honest, the orientation of a noise field is kinda irrelevant.
width integer The width of the noise field.
height integer The height of the noise field.
amplitude real The maximum value in the noise field.

The struct also possesses a handful of methods:

macaw::Get(x, y)

Returns: real

Parameter Type Description
x integer The horizontal coordinate to look up
y integer The vertical coordinate to look up

Returns the noise value at pixel coordinates (x, y) in the noise field. If the coordinate lies outside the boundaries of the noise field, it will be clamped to the edge.

macaw::GetNormalized(u, v)

macaw::GetNormalised(u, v)

Returns: real

Parameter Type Description
u real The horizontal coordinate to look up
v real The vertical coordinate to look up

The same as ::Get, but instead of returning a value at an exact pixel coordinate, it returns the value at a relative coordinate. (0, 0) corresponds to the upper-left, and (1, 1) corresponds to the bottom-right - if you've done anything with texture coordinates before, this should look very familiar indeed.

The GetNormalised alias exists for localizations who have an aversion to the letter z.

macaw::ToSprite()

macaw::ToSpriteDLL()

Returns: sprite

Converts the noise buffer to a sprite. As with all runtime sprites, remember to call sprite_delete() on it when you're finished using it.

macaw::ToVbuff()

macaw::ToVbuffDLL()

Returns: vertex buffer

Converts the noise buffer to a (non-frozen) vertex buffer. This is probably not something you'll be using very often. The vertex format used contains only a 3D position - no normal, color, or texture information is included. I use this for showing off noise for use in terrain building in the demo program, but if you're planning on using this in an actual game you'll likely need more than that.

If you do invoke this for whatever reason, as with all vertex buffers, remember to delete it when you're finished with it.

Notes about performance

The project comes in both native GML (cross-platform) and DLL (Windows-only) forms. The native GML implementation performs reasonably well, at least on small scales. Here are some numbers (6 octaves):

Dimensions GML VM GML YYC DLL
64x64 40 ms 10 ms 0.34 ms
128x128 700 ms 150 ms 5 ms
2048x2048 45,500 ms 10,000 ms 310 ms

More octavse are also more expensive.

(The DLL version is finished before the GML version even gets out of bed.)

For small noise-related tasks the native GML version is perfectly fine, although if you're doing anything exotic you probably want to use the DLL.

Clone this wiki locally