Wiki

Clone wiki

NuclearThroneTogether / Scripting / Mods / area.gml

Starting with v9905, Nuclear Throne Together allows to define custom areas.

It is a very powerful mechanism, allowing both to define new areas and to replace existing ones with custom areas.

This is done by creating a yourareaname.area.gml file in game's "mods" directory and loading it via /loadarea yourareaname.

The file can #define the following scripts to be called by the game:

area_name(subarea, loops)

Should return area code for display on map/loading screens (e.g. "6-?").

" L#"/" H#" are appended automatically.

area_secret

May return "true" if the area is in fact a secret area.

area_sprite(sprite)

Is called with a number of area #1 sprites and should return the new sprite for them.

Used to determine sprites for floors, walls, and debris.

#define area_sprite(q)
switch (q) {
    case sprFloor1: return sprFloor0;
    case sprFloor1B: return sprFloor0;
    case sprFloor1Explo: return sprFloor0Explo;
    case sprWall1Trans: return sprWall0Trans;
    case sprWall1Bot: return sprWall0Bot;
    case sprWall1Out: return sprWall0Out;
    case sprWall1Top: return sprWall0Top;
    case sprDebris1: return sprDebris0;
}

area_setup

Is executed prior to anything being generated. A good time to set seed/etc.

area_make_floor

Is called by FloorMaker instances as they advance around. Should create floor(s) relative to current position (x, y) as well as adjusting the instance' direction. For example,

#define area_make_floor
instance_create(x, y, Floor);
var turn = choose(0, 0, 0, 0, 0, 0, 0, 0, 0, 90, -90, 90, -90, 180);
direction += turn;
if (turn == 180 && point_distance(x, y, 10016, 10016) > 48) {
    // turnarounds - weapon chests spawn in such
    instance_create(x, y, Floor);
    instance_create(x + 16, y + 16, WeaponChest);
}
if (random(19 + instance_number(FloorMaker)) > 22) {
    // dead ends - ammo chests spawn in such
    if (point_distance(x, y, 10016, 10016) > 48) {
        instance_create(x + 16, y + 16, AmmoChest);
        instance_create(x, y, Floor);
    }
    instance_destroy();
} else if (random(4) < 1) {
    // branching
    instance_create(x, y, FloorMaker);
}

area_pop_enemies

Is called for floors when they may spawn an enemy. Usually are to be spawned at (x + 16, y + 16).

area_pop_props

Is called for floor tiles when it's time to spawn props. Example:

#define area_pop_props
if (random(5) < 1
    && point_distance(10016, 10016, x, y) > 100
    && !place_meeting(x, y, NOWALLSHEREPLEASE)
) {
    // quarter-walls (optional)
    var myx = x + choose_w(0, 16);
    var myy = y + choose_w(0, 16);
    if (!place_meeting(myx, myy, hitme)) {
        instance_create(myx, myy, Wall);
        instance_create(x, y, NOWALLSHEREPLEASE);
    }
} else if (random_w(12) < 1) {
    instance_create(x, y, Cactus);
}

area_pop_chests

Called after numerous chests have been plucked onto the level and before the extras are cleaned up. Can modify a number of variables: * gol: Base quantity of any chest. * wgol: Extra weapon chests * agol: Extra ammo chests * rgol: Extra radiation canisters / Rogue canisters

area_pop_extras

Used for spawning extra things such as wall decals or doing area-specific postfixes, e.g.

with (Floor)
if (!place_free(x - 32, y) && !place_free(x + 32, y) && place_free(x, y)) {
    for (var i = -1; i <= 1; i += 2)
    for (var k = 0; k <= 1; k += 1) {
        with (instance_create(x + (1 - i) * 16, y + k * 16, Bones)) {
            image_xscale = i;
            sprite_index = sprBones;
        }
    }
}

area_start

Executed when everything finishes generating in the custom area.

area_finish

Is called by GameCont on room end of the area. Should change area/subarea accordingly. For example, if you wanted to have the game go to 2-1 after your area, you could do

#define area_finish
area = 2;
subarea = 1;

area_transit

Called by GameCont just after calculating the next area in a normal way. Can be used to insert areas by deciding whether to change area to yours based on lastarea, lastsubarea, area, subarea. For example, if you wanted to insert your area before 2-1, you could do

#define area_transit
if (lastarea != "test" && area == 2) {
    area = "test";
}

area_mapdata(lastx, lasty, lastarea, lastsubarea, subarea, loops)

Can return [x, y] or [x, y, showdot] or [x, y, showdot, showline] for use on map. For secret areas you'll usually want to just return [argument0, 9].

Example (test.area.gml)

#define area_name
return "ZZZ";

#define area_sprite(q)
switch (q) {
    case sprFloor1: return sprFloor0;
    case sprFloor1B: return sprFloor0;
    case sprFloor1Explo: return sprFloor0Explo;
    case sprWall1Trans: return sprWall0Trans;
    case sprWall1Bot: return sprWall0Bot;
    case sprWall1Out: return sprWall0Out;
    case sprWall1Top: return sprWall0Top;
    case sprDebris1: return sprDebris0;
}

#define area_transit
if (lastarea != "test" && area == 2) {
    area = "test";
}

#define area_finish
area = 2;
subarea = 1;

#define area_setup
goal = 40;
background_color = make_color_rgb(106, 122, 175);
BackCont.shadcol = c_black;
TopCont.fog = sprFog2;

#define area_make_floor
instance_create(x, y, Floor);
var turn = choose(0, 0, 0, 0, 0, 0, 0, 0, 0, 90, -90, 90, -90, 180);
direction += turn;
if (turn == 180 && point_distance(x, y, 10016, 10016) > 48) {
    // turnarounds - weapon chests spawn in such
    instance_create(x, y, Floor);
    instance_create(x + 16, y + 16, WeaponChest);
}
if (random(19 + instance_number(FloorMaker)) > 22) {
    // dead ends - ammo chests spawn in such
    if (point_distance(x, y, 10016, 10016) > 48) {
        instance_create(x + 16, y + 16, AmmoChest);
        instance_create(x, y, Floor);
    }
    instance_destroy();
} else if (random(4) < 1) {
    // branching
    instance_create(x, y, FloorMaker);
}

#define area_pop_enemies
if (random(4) < 1) instance_create(x + 16, y + 16, Bandit);

#define area_pop_props
if (random(4) < 1) instance_create(x + 16, y + 16, NightCactus);

#define area_mapdata(lx, ly, lp, ls, ws, ll)
return [lx, 9];

Snippets

Spawning proto statues

#define area_pop_extras
if (GameCont.subarea == 1) {
    var _floor = instance_furthest(10016, 10016, Floor);
    with (instance_nearest(
        (_floor.x * 2 + 10016) / 3 + random_w(128) - 64,
        (_floor.y * 2 + 10016) / 3 + random_w(128) - 64,
    Floor)) instance_create(x + 16, y + 16, ProtoStatue);
}

Updated