Skip to content

Setup

Overview

The Figgy workflow begins in the global FiggySetup() function, which acts as the library's main entry point. This is where you create your Windows, Sections, Groups, Value and Decor Widgets that shape both the Interface and the underlying config data layout for your game.

The Setup process is built around Widgets - modular building blocks that define what appears in your debug view and how it's reflected in your game's config data struct.


The Setup process is organized into the following categories:

  • Scope Widgets define new scopes (structs) and organize nested widgets.
  • Value Widgets represent editable data values such as numbers, strings, booleans, and colors. These correspond to in-game values like moveSpeed or attackRange that you'll be working with throughout your game's code.
  • Decor Widgets provide visual or interactive elements such as comments, buttons, and separators that are not related to any data and are there to enhance the interface and allow for additional controls.
  • OnChange allows you to assign callbacks for a set of Value Widgets that are triggered whenever you change your widgets' values.

❗ IMPORTANT

  • All Setup methods must be called inside the FiggySetup() function located in the FiggySetup script. Calling them outside the function will throw an error.
  • Figgy calls FiggySetup() internally during initialization. Do NOT remove, rename, or call FiggySetup() manually! Doing so will break initialization.

NAME FORMATTING

By default, Figgy removes all spaces when generating data entry names (e.g. "Move Speed" becomes "MoveSpeed" in code).

If you don't plan to use variable names with spaces in your interface, this can be disabled for performance gains by setting the FIGGY_REMOVE_SPACES config macro to false.

Organization

Figgy uses lightweight syntax for setup code - you don't need curly braces or manual struct definitions. Scope is defined entirely by the order of your Widget calls - any indentation or extra formatting is optional and is used purely for organization and readability.

Below are some common approaches you can use to organize your setup code. All of them are purely organizational and don't affect Figgy's scoping system in any way.

  • No Extra Formatting. All setup calls live directly inside FiggySetup() with no regions, helper functions, or grouping. This is fine for small projects or when you're just getting started, but can become harder to navigate as your configuration grows.
js
function FiggySetup() {
    Figgy.Window("Player");
        Figgy.NoScope().Section("Movement");
            Figgy.NoScope().Group("Horizontal");
                Figgy.Float("Walk Speed", 2, 0.1, 20);
                Figgy.Float("Run Speed", 4, 0.1, 20);
    Figgy.Window("Enemies");
        Figgy.Section("Slime");
            Figgy.Int("Health", 5, 1, 15);
            Figgy.Int("Damage", 1, 1, 10);
}
js
{
    Player: {
        WalkSpeed: 4,
        RunSpeed: 2,
    },
    Enemies: {
        Slime: {
            Health: 3,
            Damage: 1,
        }
    },
}
  • Regions. You can use #region and #endregion or simple {} blocks to visually group related setup code. Both provide code folding, with curly brackets taking less space.
js
function FiggySetup() {
    #region Player 

    Figgy.Window("Player");
        Figgy.NoScope().Section("Movement");
            Figgy.NoScope().Group("Horizontal");
                Figgy.Float("Walk Speed", 2, 0.1, 20);
                Figgy.Float("Run Speed", 4, 0.1, 20);

    #endregion 
    #region Enemies 

    Figgy.Window("Enemies");
        Figgy.Section("Slime");
            Figgy.Int("Health", 5, 1, 15);
            Figgy.Int("Damage", 1, 1, 10);

    #endregion 
}
js
function FiggySetup() {
    Figgy.Window("Player"); { 
        Figgy.NoScope().Section("Movement");
            Figgy.NoScope().Group("Horizontal");
                Figgy.Float("Walk Speed", 2, 0.1, 20);
                Figgy.Float("Run Speed", 4, 0.1, 20);
    } 
    Figgy.Window("Enemies"); { 
        Figgy.Section("Slime");
            Figgy.Int("Health", 5, 1, 15);
            Figgy.Int("Damage", 1, 1, 10);
    } 
}
  • Separate Setup Functions. For larger projects, you can move each category of configs (such as Player, Enemies, Items, World, etc.) into their own global functions stored in separate scripts. Then simply call these functions inside FiggySetup(). This keeps FiggySetup() clean and makes each configuration section easier to maintain.
js
function FiggySetup() {
    PlayerConfigs(); 
    EnemiesConfigs(); 
    // ...
}
js
function PlayerConfigs() { 
    Figgy.Window("Player");
        Figgy.NoScope().Section("Movement");
            Figgy.NoScope().Group("Horizontal");
                Figgy.Float("Walk Speed", 2, 0.1, 20);
                Figgy.Float("Run Speed", 4, 0.1, 20);
}
js
function EnemiesConfigs() { 
    Figgy.Window("Enemies");
        Figgy.Section("Slime");
            Figgy.Int("Health", 5, 1, 15);
            Figgy.Int("Damage", 1, 1, 10);
}

Scope Widgets

Scope Widgets define new scopes (structs) and are used to organize other nested widgets.

  • Visually, they serve as containers that organize other widgets within the DBG interface.
  • Internally, they create new structs (unless explicitly marked as unscoped with .NoScope()), and all subsequent widgets are added within their scope, until the scope is changed with another Scope Widget.

There are 3 Scope Widgets, each defining a different scope level, from highest to lowest:

  1. .Window() is the highest-level Scope Widget. It creates a DBG View with a struct in the Root scope, and serves as a container for Sections, Groups, Value Widgets, and Decor Widgets.
  2. .Section() comes second after .Window() and creates a DBG Section with a struct in the current (Root or Window) scope, and serves as a container for Groups, Value Widgets and Decor Widgets.
  3. .Group() is the third and lowest scope level. It creates a new DBG Text Separator with a struct in the current (Root, Window, or Section) scope. It serves as a container for Value Widgets and Decor Widgets.

TIP

Each Scope Widget can also be optionally specified as unscoped via .NoScope(). This prevents a struct from being created, keeps the current scope unchanged, and makes the Widget behave as a purely visual DBG View.


.Window()

Figgy.Window(name, [visible?], [x], [y], [width], [height])Struct.Figgy

Creates a struct at the Root scope, represented as a DBG View.

Once called, the Root scope becomes inaccessible. All following Widgets will be created in the context of the current Window. Call this method again to switch scope to another Window.

TIP

Call .NoScope() before .Window() to mark the upcoming Window as unscoped. This prevents a struct from being created, keeps the current scope unchanged, and makes the Window behave as a purely visual DBG View.

ParameterTypeDescription
nameStringThe window name
[visible?]BoolWhether the window should start visible (true) or not (false) [Default: FIGGY_WINDOW_DEFAULT_START_VISIBLE]
[x]RealThe x position of the window [Default: FIGGY_WINDOW_DEFAULT_X]
[y]RealThe y position of the window [Default: FIGGY_WINDOW_DEFAULT_Y]
[width]RealThe width of the window [Default: FIGGY_WINDOW_DEFAULT_WIDTH]
[height]RealThe height of the window [Default: FIGGY_WINDOW_DEFAULT_HEIGHT]
js
function FiggySetup() {
    // Creates a Player window with default parameters:
    Figgy.Window("Player"); 
        // Sections, Groups and Value Widgets here...

    // Creates an "Enemy" window at the top-right corner of the game window, hidden by default.
    var _width = 300;
    var _xPad = 8;
    var _x = window_get_width() - _width - _xPad;
    Figgy.Window("Enemy", false, _x, FIGGY_WINDOW_DEFAULT_Y, _width); 
        // Sections, Groups and Value Widgets here...
}
js
{
    Player: { 
       // Section/Group structs and Value Widget values here...
    },
    Enemy: { 
        // Section/Group structs and Value Widget values here...
    },
}
js
// In objPlayer's Create event, store the config struct for future use:
cfg = Figgy.GetCurrent().Player; 

// In objEnemy's Create event, store the config struct for future use:
cfg = Figgy.GetCurrent().Enemy; 

.Section()

Figgy.Section(name, [scoped?], [open?])Struct.Figgy

Creates a struct in the current scope (Root or Window), represented as a DBG Section.

Once called, the previous non-Section scope (Root or Window) becomes inaccessible. All following Widgets will be created in the context of the current Section. Call this method again to switch scope to another Section.

TIP

Call .NoScope() before .Section() to mark the upcoming Section as unscoped. This prevents a struct from being created, keeps the current scope unchanged, and makes the Section behave as a purely visual DBG Section.

ParameterTypeDescription
nameStringThe section name
[open]BoolWhether the section starts open (true) or not (false) [Default: FIGGY_SECTION_DEFAULT_OPEN]
js
function FiggySetup() {
    // Creates a scoped Skeleton Section inside the Enemies window:
    Figgy.Window("Enemies");
        Figgy.Section("Skeleton"); 
            // Groups and/or Value Widgets here...
}
js
{
    Enemies: {
        Skeleton: { 
            // Group structs and Values here...
        }
    },
}
js
// In objEnemySkeleton's Create event, store the config struct for future use:
cfg = Figgy.GetCurrent().Enemies.Skeleton; 

.Group()

Figgy.Group(name, [align])Struct.Figgy

Creates a struct in the current scope (Root, Window or Section), represented as a DBG Text Separator.

Once called, all following Value Widgets will be created in the context of the current Group. Call this method again to switch scope to another Group.

TIP

Call .NoScope() before .Group() to mark the upcoming Group as unscoped. This prevents a struct from being created, keeps the current scope unchanged, and makes the Group behave as a purely visual DBG Text Separator.

ParameterTypeDescription
nameStringThe group name
[align]RealThe group name alignment. 0 is left, 1 is center, 2 is right [Default: FIGGY_GROUP_DEFAULT_ALIGN]
js
function FiggySetup() {
    // Creates Dash, Slam and Uppercut scoped groups inside the Player window,
    // grouped under an unscoped Abilities section:
    Figgy.Window("Player");
        Figgy.NoScope().Section("Abilities");
            Figgy.Group("Dash"); 
                // Value Widgets here...
            Figgy.Group("Slam"); 
                // Value Widgets here...
            Figgy.Group("Uppercut"); 
                // Value Widgets here...
}
js
{
    Player: {
        Dash: { 
            // Values here...
        },
        Slam: { 
            // Values here...
        },
        Uppercut: { 
            // Values here...
        },
    },
}
js
// In objPlayer's Create event, store the config struct for future use:
cfg = Figgy.GetCurrent().Player; 

// Access relevant ability configs when needed:
var _dashCfg = cfg.Dash; 
var _slamCfg = cfg.Slam; 
var _uppercutCfg = cfg.Uppercut; 

.NoScope()

Figgy.NoScope()Struct.Figgy

Marks the next .Window(), .Section() or .Group() call as unscoped, treating it as a purely visual interface element. This applies only to the immediately following Scope Widget call and resets automatically afterward.

js
function FiggySetup() {
    // Creates a General unscoped window in the Root scope:
    Figgy.NoScope().Window("General");
        Figgy.Int("Difficulty", 0.75, 0, 1, 0.05); 

    // Creates an unscoped Abilities section in the Player window:
    Figgy.Window("Player");
        Figgy.NoScope().Section("Abilities"); 
            Figgy.Group("Dash");
                // Value Widgets here...
}
js
{
    Difficulty: 0.75,
    Player: {
        Dash: {
            // Values here...
        },
    },
}
js
var _dashCfg = Figgy.GetCurrent().Player.Dash;

Value Widgets

Value Widgets represent editable data values - numbers, strings, booleans, and colors. These map directly to gameplay variables such as moveSpeed or attackRange that you'll reference throughout your code.

You can place Value Widgets anywhere within your setup. Their parent scope is determined by the most recently used Scope Widget. If no Scope Widgets have been called yet, Value Widgets are placed in the Root scope.

All Value Widgets start with a name, which is how you reference them in your code. They also support an optional [onChange] callback that lets you run custom logic whenever the value is modified.


Value Widgets include the following:


.Int()

Figgy.Int(name, value, min, max, [step], [onChange])Struct.Figgy

Creates a Real value (number) in the current scope (Root, Window, Section or Group), represented as a DBG Slider Int.

ParameterTypeDescription
nameStringThe variable name
valueRealThe default value
minRealThe minimum slider value
maxRealThe maximum slider value
[step]RealThe slider step [Default: FIGGY_INT_DEFAULT_STEP]
[onChange]Id.FunctionThe function to call when the value is changed [Default: .OnChangeSet() callback if set, or FIGGY_CHANGES_DEFAULT_CALLBACK]
js
function FiggySetup() {
    Figgy.Window("Player");
        // Creates a JumpSpeed value in the Player window:
        Figgy.Int("Jump Speed", 15, 10, 20); 
    
    Figgy.Window("Camera");
        // Creates DeadzoneX and DeadzoneY values in the Camera window
        // with a step of 10, for easier editing in a wider 0-200 range:
        Figgy.Int("Deadzone X", 100, 0, 200, 10); 
        Figgy.Int("Deadzone Y", 100, 0, 200, 10); 

    Figgy.Window("Terrain");
        // Creates an Octaves value in the Terrain window,
        // and regenerate the terrain when the value is changed:
        Figgy.Int("Octaves", 6, 4, 10, 1, function(_octaves) { 
            with (objTerrain) {
                Regenerate();
            }
        });
}
js
{
    Player: {
        JumpSpeed: 15, 
    },
    Camera: {
        DeadzoneX: 100, 
        DeadzoneY: 100, 
    },
    Terrain: {
        Octaves: 6
    },
}
js
var _jumpSpeed = Figgy.GetCurrent().Player.JumpSpeed; 
var _deadzoneX = Figgy.GetCurrent().Camera.DeadzoneX; 
var _deadzoneY = Figgy.GetCurrent().Camera.DeadzoneY; 
var _octaves = Figgy.GetCurrent().Terrain.Octaves; 

.Float()

Figgy.Float(name, value, min, max, [step], [onChange])Struct.Figgy

Creates a Real value (number) in the current scope (Root, Window, Section or Group), represented as a DBG Slider.

ParameterTypeDescription
nameStringThe variable name
valueRealThe default value
minRealThe minimum slider value
maxRealThe maximum slider value
[step]RealThe slider step [Default: FIGGY_FLOAT_DEFAULT_STEP]
[onChange]Id.FunctionThe function to call when the value is changed [Default: .OnChangeSet() callback if set, or FIGGY_CHANGES_DEFAULT_CALLBACK]
js
function FiggySetup() {
    Figgy.Window("Player");
        Figgy.NoScope().Section("Movement");
			Figgy.NoScope().Group("Horizontal");
                // Creates a RunSpeed Float value in the Player window.
                // Movement Section and Horizontal Group are unscoped:
                Figgy.Float("Run Speed", 5, 0.1, 10); 
        Figgy.Section("Light");
            // Creates an Intensity Float value in the scoped Light section:
			Figgy.Float("Intensity", 1, 0.1, 2); 
    Figgy.Window("Display");
        // Creates a ResolutionScale Float value in the Display window with a
        // 0.5 step, and resizes application_surface when changed:
		Figgy.Float("Resolution Scale", 2, 0.5, 4, 0.5, RefreshAppSurf); 
}
js
{
    Player: {
        RunSpeed: 5, 
        Light: {
            Intensity: 1
        },
    },
    Display: {
        ResolutionScale: 2, 
    },
}
js
// In objPlayer's Create event, store the config struct for future use:
cfg = Figgy.GetCurrent().Player; 

// In objPlayer's Step event, use the RunSpeed config to move:
xSpd = xInput * cfg.RunSpeed; 

// In objPlayer's Step event, use the Light.Intensity config to adjust the
// intensity of the player light:
light.intensity = cfg.Light.Intensity; 

// In our application_surface refreshing function:
function RefreshAppSurf() {
    // Grab the resolution scale from the Display config:
    var _scale = Figgy.GetCurrent().Display.ResolutionScale; 
    surface_resize(application_surface, BASE_WIDTH * _scale, BASE_HEIGHT * _scale);
}

.Real()

Figgy.Real(name, value [onChange])Struct.Figgy

Creates a Real value (number) in the current scope (Root, Window, Section or Group), represented as a Real-filtered DBG Text Input.

ParameterTypeDescription
nameStringThe variable name
valueRealThe default value
[onChange]Id.FunctionThe function to call when the value is changed [Default: .OnChangeSet() callback if set, or FIGGY_CHANGES_DEFAULT_CALLBACK]
js
function FiggySetup() {
    Figgy.Window("Weapons");
        Figgy.Section("Katana");
            Figgy.Real("Cost", 50); // Creates a Cost Real value.
}
js
{
    Weapons: {
        Katana: {
            Cost: 50, 
        },
    },
}
js
var _katanaCost = Figgy.GetCurrent().Weapons.Katana.Cost; 

.Bool()

Figgy.Bool(name, value, [onChange])Struct.Figgy

Creates a Bool value in the current scope (Root, Window, Section or Group), represented as a DBG Checkbox.

ParameterTypeDescription
nameStringThe variable name
valueBoolThe default value
[onChange]Id.FunctionThe function to call when the value is changed [Default: .OnChangeSet() callback if set, or FIGGY_CHANGES_DEFAULT_CALLBACK]
js
function FiggySetup() {
    Figgy.Window("Lighting");
        // Creates an Enabled Bool values inside the Lighting window:
		Figgy.Bool("Enabled", true); 
}
js
{
    Lighting: {
        Enabled: true, 
    },
}
js
{
    // In objLightingManager's Create event, store the config struct for future use:
    cfg = Figgy.GetCurrent().Lighting; 

    // In objLightingManager's Step Post Draw event, handle application_surface drawing:
    if (cfg.Enabled) { 
        // Draw appsurf with lighting applied.
    }
    else {
        // Draw appsurf normally.
    }
}

.String()

Figgy.String(name, value, [onChange])Struct.Figgy

Creates a String value in the current scope (Root, Window, Section or Group), represented as a DBG Text Input.

ParameterTypeDescription
nameStringThe variable name
valueStringThe default value
[onChange]Id.FunctionThe function to call when the value is changed [Default: .OnChangeSet() callback if set, or FIGGY_CHANGES_DEFAULT_CALLBACK]
js
function FiggySetup() {
    // Adds a WelcomeMessage String value in the Root scope:
    Figgy.String("Welcome Message", "Hey {0}, welcome to GameName!"); 
}
js
{
    WelcomeMessage: "Hey {0}, welcome to GameName!", 
}
js
{
    // Draw the welcome message on at the bottom center of the title screen:
    draw_set_halign(fa_center);
    draw_set_valign(fa_bottom);
    draw_text(GUI_W / 2, GUI_H - 4, Figgy.GetCurrent().WelcomeMessage); 
}

.Color()

Figgy.Color(name, value, [onChange])Struct.Figgy

Creates a :Constant.GMColor: value in the current scope (Root, Window, Section or Group), represented as a DBG Color.

ParameterTypeDescription
nameStringThe variable name
valueConstant.ColorThe default value
[onChange]Id.FunctionThe function to call when the value is changed [Default: .OnChangeSet() callback if set, or FIGGY_CHANGES_DEFAULT_CALLBACK]
js
function FiggySetup() {
    Figgy.Window("Lighting");
        // Creates an AmbientColor Color value in the Lighting window:
        Figgy.Color("Ambient Color", #191919); 
}
js
{
    Lighting: {
        AmbientColor: 1644825,
    },
}
js
// In objLightingManager's Create event, store the config struct for future use:
cfg = CFG.Lighting; 

// In objLightingManager's Step event, update the ambient color:
renderer.ambientColor = cfg.AmbientColor; 

.Any()

Figgy.Any(name, value, values, [names], [onChange])Struct.Figgy

Creates a value of any type in the current scope (Root, Window, Section or Group), represented as a DBG Dropdown.

ParameterTypeDescription
nameStringThe variable name
valueAnyThe default value
valuesArray of AnyThe array of option values
[names]Array of StringThe array of option names [Default: values]
[onChange]Id.FunctionThe function to call when the value is changed [Default: .OnChangeSet() callback if set, or FIGGY_CHANGES_DEFAULT_CALLBACK]
js
function FiggySetup() {
    Figgy.Window("Player");
        global.playerSkins = ["Green", "Pink", "Purple", "Yellow"];
        // Creates a Skin String value in the Player window and updates
        // objPlayer's sprite when the value is changed:
        Figgy.Any("Skin", global.playerSkins[0], global.playerSkins, undefined, function() { 
            with (objPlayer) {
                UpdateSprite();
            }
        });
}
js
{
    Player: {
        Skin: "Green",
    },
}
js
// In objPlayer's Create event, store the config struct for future use:
cfg = CFG.Player; 

// In objPlayer's UpdateSprite method, changes sprite by updating sprite_index to a
// sprite based the current skin and state and resets image_index:
UpdateSprite = function() {
    sprite_index = sprites[$ cfg.Skin][$ fsm.get_current_state()]; 
	image_index = 0;
};

Decor Widgets

Decor Widgets like Comments, Buttons and Separators are purely visual and do not map to any underlying data. They exist to improve readability. add structure, and provide optional interface controls.


.Button()

Figgy.Button(name, callback, [width], [height], [sameLine?])Struct.Figgy

Creates a button that triggers the given callback function when pressed, represented as a DBG Button.

ParameterTypeDescription
nameStringThe button name
callbackId.FunctionThe function to call when the button is pressed
[width]RealThe button width [Default: automatic DBG default]
[height]RealThe button height [Default: automatic DBG default]
[sameLine?]BoolWhether the button should be placed on the same line with the last widget (true) or not (false) [Default: FIGGY_BUTTON_DEFAULT_SAME_LINE]
js
function FiggySetup() {
    Figgy.Window("World");
        Figgy.Float("Miniboss Chunk Chance", 0.1, 0, 1, 0.01);
        Figgy.Float("Treasure Chunk Chance", 0.05, 0, 1, 0.01);
        Figgy.Float("Tree Density", 0.1, 0, 1, 0.01);
        // Adds a Button widget that regenerates the world when pressed: 
        Figgy.Button("Regenerate", WorldRegenerate); 
}

.Comment()

Figgy.Comment(string, [sameLine?])Struct.Figgy

Creates a text comment, represented as a :DBG Text:.

ParameterTypeDescription
stringStringThe string to display in the comment
[sameLine?]BoolWhether the comment should be on the same line with the last widget (true) or not (false) [Default: :FIGGY_COMMENT_DEFAULT_SAME_LINE:]
js
function FiggySetup() {
    Figgy.Window("World");
        Figgy.Float("Miniboss Chunk Chance", 0.1, 0, 1, 0.01);
        // Adds a Comment describing the Float value above:
        Figgy.Comment("The chance to spawn a Miniboss chunk, as a 0-1 percentage."); 
}

.Separator()

Figgy.Separator([name], [align])Struct.Figgy

Creates a horizontal line separator with an optional name, represented as a DBG Separator.

This is practically just an unscoped Group under a different name.

ParameterTypeDescription
[name]StringThe separator name [Default: no name]
[align]RealThe separator name alignment. 0 is left, 1 is center, 2 is right. [Default: FIGGY_SEPARATOR_DEFAULT_ALIGN]
js
function FiggySetup() {
    Figgy.Window("Player");
        // Creates a Separator with an optional name:
        Figgy.Separator("Horizontal Movement"); 
            Figgy.Float("Walk Speed", 2, 0.1, 20);
            Figgy.Float("Run Speed", 4, 0.1, 20);
            // Creates a Separator with no name:
            Figgy.Separator(); 
            Figgy.Float("Acceleration", 1, 0.1, 1);
            Figgy.Float("Friction", 0.5, 0.1, 20);
            
}

OnChange

In addition to all individual Value Widgets having an optional [onChange] callback that triggers you change the value, you can define a callback for a group of Value Widgets using .OnChangeSet(), and reset it afterwards with .OnChangeReset().

This is especially useful when you want the same callback applied to multiple Value Widgets without repeating it for each one.


.OnChangeSet()

Figgy.OnChangeSet(callback)Struct.Figgy

Sets the default onChange callback for all following Value Widgets, though each individual widget can still override this setting with its own optional OnChange callback.

Call .OnChangeReset() to reset the callback.

The callback function receives 3 arguments: (new value, old value, variable name).

ParameterTypeDescription
callbackId.FunctionDescription
js
function FiggySetup() {
    Figgy.Window("Terrain");
        // Calls the TerrainGenerate() function each time Frequency, Amplitude or
        // Octaves are changed:
        Figgy.OnChangeSet(TerrainGenerate); 
        Figgy.Float("Frequency", 0.1, 0.1, 4);
        Figgy.Float("Amplitude", 150, 50, 250);
        Figgy.Int("Octaves", 2, 1, 6);
        Figgy.OnChangeReset(); // Resets the callback.
}

.OnChangeReset()

Figgy.OnChangeReset()Struct.Figgy

Resets the OnChange callback previosly set with .OnChangeSet().

js
function FiggySetup() {
    Figgy.Window("Terrain");
        // Calls the TerrainGenerate() function each time Frequency, Amplitude or
        // Octaves are changed:
        Figgy.OnChangeSet(TerrainGenerate); 
        Figgy.Float("Frequency", 0.1, 0.1, 4);
        Figgy.Float("Amplitude", 150, 50, 250);
        Figgy.Int("Octaves", 2, 1, 6);
        Figgy.OnChangeReset(); // Resets the callback.
}