OFFICIAL GMS 2.3.0 BETA ANNOUNCEMENT

Status
Not open for further replies.
GML:
Array = [
    [
        [0,0,0],
        [1,2,3],
    ],
    [
        [3,2,6,7,8],
        [3,8]
    ],
    [
        [6,5,9,0],
        [5,1,1,2]
    ]
]
@drandula is right. Of course, you can do this if you need. Accessing data uses the same principle:

GML:
array[0] = [
    [
        [0, 0, 0],
        [1, 2, 3]
    ],

    // even with lists
    ds_list_create(),

    // or maps
    ds_map_create()
]

// array[0][1] == [1, 2, 3]

// array[0][1][0] == 1;
// array[0][1][1] == 2;
// array[0][1][2] == 3;

// array[1] == this is the list (so...)
// array[1][| 0] == this will be the first element of the list
// array[1][| 1] == this will be the seconds element of the list
// ...

// array[2] == this is the map
// array[2][? "something"] == this returns the element with key "something" on the map
 

K3fka

Member
So is there a way to get JSDoc comments to work if the function isn't being defined in a script? I'm defining a function in an object's create event, and I can't get autocomplete to recognize the JSDoc comments. Tried putting them above the function definition and even inside the function definition, but no luck. The function name does show up in autocomplete, but as a variable instead of a function (I'm not assigning the function to a variable, so that's not it).

GML:
/// @func findPath(x, y)
/// @desc Calculates a path from an entity's current position to another
/// @param {int} x
/// @param {int} y

function findPath(x, y) {
    // stuff
}
autocomplete.png
 

kburkhart84

Firehammer Games
So is there a way to get JSDoc comments to work if the function isn't being defined in a script? I'm defining a function in an object's create event, and I can't get autocomplete to recognize the JSDoc comments. Tried putting them above the function definition and even inside the function definition, but no luck. The function name does show up in autocomplete, but as a variable instead of a function (I'm not assigning the function to a variable, so that's not it).

GML:
/// @func findPath(x, y)
/// @desc Calculates a path from an entity's current position to another
/// @param {int} x
/// @param {int} y

function findPath(x, y) {
    // stuff
}
View attachment 31239
I'm going to guess that the autocomplete stuff only works that way simply because they haven't tried to implement it anywhere else. I'm also guessing that they aren't going to, as functions are so easy to throw around now that they have to keep things loose to make them work, at least without having a nice overhaul of the whole auto-complete system to handle it. I think its worth a topic in the beta forum though.
 
So I got the beta yesterday or so. It's pretty neat; unfortunately I can't compile a port of my current project due to a known bug (instance variables can't hold functions, says they're nonexistent by the IDE), so that sucks.
Still, kinda fun to do maintenance with the new features, even if it's a kinda blindly. I can finally make a proper "model" type instead of just relying off of raw vertex buffers, yay.

I am kinda curious if the new script system makes gml_pragma("global", "__myInit()"); redundant now though?
 

kburkhart84

Firehammer Games
Yeah, that's pretty much useless now, as any code you put in the scripts will automatically execute the same way the gml_pragma thing would have.
 
Probably the same way as now. I wonder whey they allow to use layer_id inside them, to know on which layer we are :p

doesn't it work if you use the variable layer inside the function you are calling?!

GML:
oneFunctionToRuleThemAll = function() {
    switch(layer)
    {
        case 'Instances': // stuff
            break;
        case 'Background': // stuff
            break;
    }
}
layer_script_begin('Background', oneFunctionToRuleThemAll);

and why not just split them?!


GML:
layer_script_begin('Instances', function() {
    // InstanceLayer
});
layer_script_begin('Background', function() {
    // BackgroundLayer
});
creating one function for each layer... then you know which layer your function corresponds to.
Sorry but as I don't know the use case I'm duelling to understand and to find alternatives :p
Can you please explain better what you are trying to achieve?
 
Yeah, that's pretty much useless now, as any code you put in the scripts will automatically execute the same way the gml_pragma thing would have.
There is one thing though!! you can mess with it and rerun the script file....
if you create a script file with functions inside and the function name is different from the file name,
you can still "call the file" like a script:

MyScriptFile();

This will actually work and will rerun the code inside it... (so be careful not to run duplicate code and run into memory leaks)


GML:
// THIS IS INSIDE A SCRIPT FILE NAMED MyScriptFile
global.Stuff = ds_list_create();
show_debug_message("Hello");

Now from inside an instance you can call:
GML:
MyScriptFile(); // "Hello" + this will create a list
MyScriptFile(); // "Hello" + this will create another list
MyScriptFile(); // "Hello" + this will create yet another list
 
I got in. Ticket 169691.

Is it safe to start developing a new major game in 2.3 or should I wait for it to become stable?

Edit: The beta said that it could corrupt your projects, I guess I got my answer lol.
 
Last edited:
169708, just got mine an hour ago! Sucks I'm not going to have time to tinker with it until at least Saturday evening, but I've waited this long, a few more days won't kill me!
 
Hello, thanks Yoyo for the beta invite and all the dope features. That said I'm curious about the best way to do something or if it's possible.

Can you pass optional parameters or literal values of a child struct call to the parent constructor? Sorta like ...

GML:
function parent(_req) constructor {
    required = _req;
    if(argument_count > 1)
        optional = argument[1];
}

function child(_req): parent(_req, argument[1]) constructor {
    //Other stuff...
}
//or
function child(_req): parent(_req, "value") constructor {
    //Other stuff...
}
So far, I have used setting the variable value just inside the child function body, but it helps to know that the value belongs to the parent foremost. I just wonder if there is an intended or better way to do it.


Edit: one other question :p is there any plan to add destructor functions? If structs can have data structures or be contained within them, it would be helpful to have a place to specify this teardown, just like the way the overridable toString function works.
 
Last edited:
Hello, thanks Yoyo for the beta invite and all the dope features. That said I'm curious about the best way to do something or if it's possible.

Can you pass optional parameters or literal values of a child struct call to the parent constructor? Sorta like ...

GML:
function parent(_req) constructor {
    required = _req;
    if(argument_count > 1)
        optional = argument[1];
}

function child(_req): parent(_req, argument[1]) constructor {
    //Other stuff...
}
//or
function child(_req): parent(_req, "value") constructor {
    //Other stuff...
}
So far, I have used setting the variable value just inside the child function body, but it helps to know that the value belongs to the parent foremost. I just wonder if there is an intended or better way to do it.


Edit: one other question :p is there any plan to add destructor functions? If structs can have data structures or be contained within them, it would be helpful to have a place to specify this teardown, just like the way the overridable toString function works.

GML:
function Parent(name, age) constructor
{
    myName = name;
    myAge = is_undefined(age) ? 18 : age
}


function Child(name, age) : Parent(name, age) constructor
{
    // if some of the parameters are not passed they will
    // be set to "undefined" by default.
    // so in other words parameters will ALWAYS have a value
    // even if you don't provide one.
}

var _child1 = new Child(); // name: undefined, age: 18
var _child2 = new Child("blah"); // name: blah, age: 18
var _child3 = new Child("blah", 22); // name: blah, age: 22

GML:
function Ball(size, color) constructor
{
    // do stuff
}


function BlueBall(size): Ball(size, c_blue) constructor {

    // Forcing a value to be passed to the parent constructor is also possible!
}
Some people are requesting destructors but I don't really thing they will implement those, at least not right away!
 
Last edited:
Really wishing scripts could have local variables usable for functions like Lua does, like this:
GML:
var repeated_value = 512;

var _my_method = function () begin
    var s = "My thing is " + string(my_var);
    s += ". Also this thing: " + string(repeated_value);
    return s;
end

function my_struct (_my_var) constructor begin
    my_var = _my_var;
    my_other_var = repeated_value;
    my_method = method(self, _my_method);
    
end
Would be a nice QoL thing.
 

Bruchpilot

Member
After poking at the beta for a bit (only the new GML features so far) this feels like a really big step up. I can imagine it will scare people who are new to programming in general, but it does feel like the gloves are coming off now and we will get serious.
 
GML:
function Parent(name, age) constructor
{
    myName = name;
    myAge = is_undefined(age) ? 18 : age
}


function Child(name, age) : Parent(name, age) constructor
{
    // if some of the parameters are not passed they will
    // be set to "undefined" by default.
    // so in other words parameters will ALWAYS have a value
    // even if you don't provide one.
}

var _child1 = new Child(); // name: undefined, age: 18
var _child2 = new Child("blah"); // name: blah, age: 18
var _child3 = new Child("blah", 22); // name: blah, age: 22

GML:
function Ball(size, color) : constructor
{
    // do stuff
}


function BlueBall(size): Ball(size, c_blue) constructor {

    // Forcing a value to be passed to the parent constructor is also possible!
}
Some people are requesting destructors but I don't really thing they will implement those, at least not right away!
Thank you for the assistance, but the editor tells me there is an error with the Ball example you posted. I did delete the extra colon and messed with it a bit, but no luck. It keeps telling me only functions that are declared as constructors can use inheritance, even with the keyword.
 
Thank you for the assistance, but the editor tells me there is an error with the Ball example you posted. I did delete the extra colon and messed with it a bit, but no luck. It keeps telling me only functions that are declared as constructors can use inheritance, even with the keyword.
Sorry, about that ":" didn't notice while typing! :p
I know the IDE shows an error but the code actually compiles and works.. this is a bug that is being addressed! :D
 
Last edited:

Cpaz

Member
Really wishing scripts could have local variables usable for functions like Lua does, like this:
GML:
var repeated_value = 512;

var _my_method = function () begin
    var s = "My thing is " + string(my_var);
    s += ". Also this thing: " + string(repeated_value);
    return s;
end

function my_struct (_my_var) constructor begin
    my_var = _my_var;
    my_other_var = repeated_value;
    my_method = method(self, _my_method);
   
end
Would be a nice QoL thing.
This. I would very much appreciate this.

But at the same time, I can see why they would opt to just have you pass that in as an argument instead. Maybe limit it to method variables?
For example:
GML:
var val = 0;
fn = function () {
      val ++;; // have this be possible.
}

function fn() {
      val ++;; // have this throw an error
}
I think that would make since as with() has access to local scope variables.
 

FrostyCat

Member
Like I said several pages back, bind the function to a struct carrying the closure scope like this:
GML:
var foo = "Hello, ";
var func = method({ greeting: foo }, function(name) {
    show_message(greeting + name);
});
func("World"); // Hello, World
YoYo has expressed no interest in carrying local variables into methods because of long-term implications this will cause for scope and the garbage collector. This struct-binding method was the one recommended to me earlier on, and it will be solution going forward.
 
GML:
function point(_necessary_var, _optional_var) constructor {
    var1 = _necessary_var;
    var2 = _optional_var == undefined ? 100 : _optional_var
}
variables not provided are assigned the value "undefined" by default! :)
Oooo that's perfect thanks! One more thing, can you leave blank commas on middle arguments that you want to use defaults for, or do you need to use the word "undefined"?:
GML:
entity = new Entity("Monster",,,true);//will this work to only set the last one? lol
entity = new Entity("Monster", undefined, undefined, true);//or would it be this?

//I saw FrostyKat's {"is_hostile: true"} code before which is likely what I'll use and I assume would let you skip a middle optional argument like so:
entity = new Entity("Monster", {strength: 100; is_hostile: true});
//...but I'm just curious about the default syntax lol
Ok I still don't have the beta yet but I tried some more exercises in roughing out how to refactor my game's code when I get the beta. I re-read some of the thread and it sounds like "other" points to the object calling the struct's function, so a quick question first on if this is how it would be used?
GML:
//--------------------------------------------------
//scr_points
//--------------------------------------------------
function Point(_index_, x_offset, _y_offset) constructor {
    index    = _index;
    x_offset = _x_offset;
    y_offset = _y_offset;
 
    static draw = function() {
        //can I use other.id here instead of having to pass the id to this function?:
        draw_circle(other.id.x + x_offset, other.id.y + y_offset, 10, true);
        //          ^^^^^                  ^^^^^
    }
}

//--------------------------------------------------
//obj_enemy
//--------------------------------------------------
//Create Event
point = new Point(0, 100, 100);

//Draw Event
point.draw();//would the point be drawn at this object's x + 100, y + 100?
Then I was thinking about how I'd do an object inspector, would the Inspector() function below work to show an instance's Entity struct info in a level editor Properties panel?
GML:
//--------------------------------------------------
//scr_points
//--------------------------------------------------
function default(_value, _default) {//trying to find a cleaner way to do argument defaults lol
    return (_value == undefined ? _default : _value);
}

function Entity(_name, _hp, _strength, _is_hostile) constructor {
    inspector  = new Inspector();
    name       = _name;
    hp         = default(_hp,             1);
    strength   = default(_strength,       1);
    is_hostile = default(_is_hostile, false);
}

function Inspector() constructor {//<--------------------------- THIS PART
    static debug_show_struct = function(_struct_id) {
        var _Names = variable_struct_get_names(_struct_id),
            _count = array_length(_Names);

        for (var _i = 0; _i < _count; _i++) {
            var _name  = _Names[_i],
                _value = variable_struct_get(_struct_id, _Names[_i];

            show_debug_message(_name + ": " + string(_value));
        }
    }
}

//--------------------------------------------------
//obj_enemy
//--------------------------------------------------
//Create Event
entity = new Entity("Old Man", 100, 10);
entity.inspector.debug_show_struct(entity);
Now this NEXT one was another big revelation moment for me...my save/load code was SO long and complicated looking before, and the code was spread out all over in like an obj_stage object using instance variables and a bunch of scr_stage_save() scr_stage_load() etc scripts, separate ones for the editor and the gameplay, and obj_ed_enemy versions of obj_enemy to add editor features (VS the editor struct I roughed out earlier in this thread that could just be dropped right into the gameplay obj_enemy when the game state is editing)

In my game's current code I had started with Juju Adam's "I love data" code which was fantastic but admittedly juggling an elaborate nesting of ds_maps and ds_lists got pretty frustrating to get working and keep track of when I was adding new stuff to save/load and trying to structure my JSON the way I wanted. Then I kept Juju's structure but used YellowAfterLife's TJSON which made it a lot easier and cleaner looking, but still with some bulk to it esp at the top & bottom of the scripts for the actual opening/saving/loading code.

But NOW...with the new GML features and FrostyCat's JsonStruct, it actually makes me chuckle to myself to look at how little code is needed to save/load with a nice clean organized looking JSON file (theoretically since I can't test it yet). I only expected to try the save stuff but it's so little code that I was like "I wonder how hard loading would be" and then I wanted to try an overall game finite state machine just to kind of think out how it'd go.
GML:
//--------------------------------------------------
//scr_stage
//--------------------------------------------------
function Stage() constructor {
    data = {};

    static save = function() {
        //get stage info
        data.info.name   = get_string("Stage Name:",   "Untitled");
        data.info.author = get_string("Stage Author:",  "Unknown");

        //get enemies
        var _i = 0;
        with (obj_enemy) {//save each enemy's data
            other.data.Enemies[_i++] = {
                object_index : object_index;
                x            : x;
                y            : y;
                Waypoints    : Waypoints;//array of Waypoints for AI
            };
        }

        //save using FrostyCat's JsonStruct
        jsons_save("STAGE.JSON", jsons_encode(data));
    }

    static load = function() {
        //clear current stage
        with (obj_enemy) {instance_destroy();}

        //load using FrostyCat's JsonStruct
        data = jsons_decode(jsons_load("STAGE.JSON"));

        //spawn enemies
        for (var _i = 0; _i < array_length(data.Enemies); _i++) {
            var _enemy = data.Enemies[_i];
            instance_create_layer(_enemy.x, _enemy.y, "enemies", _enemy.object_index);
        }
    }

    static draw_info = function() {
        draw_text(0,  0, data.info.name);
        draw_text(0, 10, data.info.author);
    }
}

function Enemy(_object_index, _x, _y, _Waypoints) constructor {
    object_index = _object_index;
    x            = _x;
    y            = _y;
    Waypoints    = _Waypoints;
}

function Waypoint(_x, _y) constructor {
    x = _x;
    y = _y;
}

function Game(_state) constructor {
    state = _state;
}

//--------------------------------------------------
//obj_game
//--------------------------------------------------
//Create Event
game  = new Game("GAMEPLAY_INIT");
stage = new Stage();

//Step Event
switch(game.state) {
    case "GAMEPLAY_INIT":
        stage.load();
        game.state = "GAMEPLAY";
    case "GAMEPLAY":
        //gameplay stuff...
        if (keyboard_check_pressed(vk_tab)) {game.state = "EDITOR_INIT";}
    break;

    case "EDITOR_INIT":
        stage.load();
        game.state = "EDITOR";
    case "EDITOR":
        //editor stuff...
        if (mouse_check_button_pressed(mb_left)) {
            instance_create_layer(mouse_x, mouse_y, "enemies", obj_enemy);
        }

        if (keyboard_check_pressed(ord("S"))) {stage.save();}
        if (keyboard_check_pressed(ord("L"))) {stage.load();}
        if (keyboard_check_pressed(vk_tab))   {game.state = "GAMEPLAY_INIT";}
    break;
}

//Draw Event
stage.draw_info();

//--------------------------------------------------
//obj_enemy
//--------------------------------------------------
//Create Event
enemy = new Enemy(
    obj_enemy, x, y, [
        new Waypoint(  0,   0),
        new Waypoint(100,   0),
        new Waypoint(100, 100),
        new Waypoint(  0, 100),
        new Waypoint(  0,   0)
    ]
);
One question I ended up with after all this: is there a way to do "with all objects that contain this struct type"? Something like:
GML:
with (all) {
    if (struct_exists("Enemy")) {
        //do stuff to these ones...
    }
}
Or would the best way of doing this be to keep a ds_list somewhere like in the Stage struct like:
GML:
//--------------------------------------------------
//obj_game
//--------------------------------------------------
//Create Event
stage          = new Stage();
stage.Entities = new List();//using FrostyCat's Lightweight Data Structures

//Step Event
for (var _i = 0; _i < stage.Entities.size; _i++) {
    with (stage.Entities[_i++]) {
        //do stuff to these ones...
    }
}

//--------------------------------------------------
//obj_enemy
//--------------------------------------------------
//Create Event
obj_game.stage.Entities.add(id);

//Cleanup
obj_game.stage.Entities.remove(id);
Big thanks to all the advanced guys who've been helping answer everyone's questions and the tutorial makers putting their stuff up on YouTube the last couple weeks!

This is seriously so much fun and I don't even have the beta yet...but every time I'm roughing these things out and I spot something I can use a new feature for and chop out huge chunks of code or entire scripts or bulky arrays of enums it feels like when you bomb a wall in Zelda and find a secret cave lol
 

matharoo

Udemy Instructor
Hi guys :) I have two videos out on Sequences, which I thought I'd share here:

Part 1: Basic introduction to the Sequence Editor, and basic usage of Sequences with GML

Part 2: Overriding Sequence objects with your own instances

Do note that my videos are always intended for beginners, so they may be boring for the more experienced users here :D
 
Couple questions:
1) How long will there be support for what is now the current version of GMS2 beyond release of the new version?

2) Regarding the new origin marker for sprites in the sprite editor, will changing a project over to the new version disrupt the placement of assets which had previously been dragged into rooms in the former GMS2 version?

3) Will the grid/grid "snapping" means of manual room/sprite editing still be available in the new version...? For example, I have the room grid set on snap 128x128 for my assets layer and 64x64 for my instances layer... Will that still work?

thx
 
Oooo that's perfect thanks! One more thing, can you leave blank commas on middle arguments that you want to use defaults for, or do you need to use the word "undefined"?:
GML:
entity = new Entity("Monster",,,true);//will this work to only set the last one? lol
entity = new Entity("Monster", undefined, undefined, true);//or would it be this?

//I saw FrostyKat's {"is_hostile: true"} code before which is likely what I'll use and I assume would let you skip a middle optional argument like so:
entity = new Entity("Monster", {strength: 100; is_hostile: true});
//...but I'm just curious about the default syntax lol
Ok I still don't have the beta yet but I tried some more exercises in roughing out how to refactor my game's code when I get the beta. I re-read some of the thread and it sounds like "other" points to the object calling the struct's function, so a quick question first on if this is how it would be used?
GML:
//--------------------------------------------------
//scr_points
//--------------------------------------------------
function Point(_index_, x_offset, _y_offset) constructor {
    index    = _index;
    x_offset = _x_offset;
    y_offset = _y_offset;

    static draw = function() {
        //can I use other.id here instead of having to pass the id to this function?:
        draw_circle(other.id.x + x_offset, other.id.y + y_offset, 10, true);
        //          ^^^^^                  ^^^^^
    }
}

//--------------------------------------------------
//obj_enemy
//--------------------------------------------------
//Create Event
point = new Point(0, 100, 100);

//Draw Event
point.draw();//would the point be drawn at this object's x + 100, y + 100?
Then I was thinking about how I'd do an object inspector, would the Inspector() function below work to show an instance's Entity struct info in a level editor Properties panel?
GML:
//--------------------------------------------------
//scr_points
//--------------------------------------------------
function default(_value, _default) {//trying to find a cleaner way to do argument defaults lol
    return (_value == undefined ? _default : _value);
}

function Entity(_name, _hp, _strength, _is_hostile) constructor {
    inspector  = new Inspector();
    name       = _name;
    hp         = default(_hp,             1);
    strength   = default(_strength,       1);
    is_hostile = default(_is_hostile, false);
}

function Inspector() constructor {//<--------------------------- THIS PART
    static debug_show_struct = function(_struct_id) {
        var _Names = variable_struct_get_names(_struct_id),
            _count = array_length(_Names);

        for (var _i = 0; _i < _count; _i++) {
            var _name  = _Names[_i],
                _value = variable_struct_get(_struct_id, _Names[_i];

            show_debug_message(_name + ": " + string(_value));
        }
    }
}

//--------------------------------------------------
//obj_enemy
//--------------------------------------------------
//Create Event
entity = new Entity("Old Man", 100, 10);
entity.inspector.debug_show_struct(entity);
Now this NEXT one was another big revelation moment for me...my save/load code was SO long and complicated looking before, and the code was spread out all over in like an obj_stage object using instance variables and a bunch of scr_stage_save() scr_stage_load() etc scripts, separate ones for the editor and the gameplay, and obj_ed_enemy versions of obj_enemy to add editor features (VS the editor struct I roughed out earlier in this thread that could just be dropped right into the gameplay obj_enemy when the game state is editing)

In my game's current code I had started with Juju Adam's "I love data" code which was fantastic but admittedly juggling an elaborate nesting of ds_maps and ds_lists got pretty frustrating to get working and keep track of when I was adding new stuff to save/load and trying to structure my JSON the way I wanted. Then I kept Juju's structure but used YellowAfterLife's TJSON which made it a lot easier and cleaner looking, but still with some bulk to it esp at the top & bottom of the scripts for the actual opening/saving/loading code.

But NOW...with the new GML features and FrostyCat's JsonStruct, it actually makes me chuckle to myself to look at how little code is needed to save/load with a nice clean organized looking JSON file (theoretically since I can't test it yet). I only expected to try the save stuff but it's so little code that I was like "I wonder how hard loading would be" and then I wanted to try an overall game finite state machine just to kind of think out how it'd go.
GML:
//--------------------------------------------------
//scr_stage
//--------------------------------------------------
function Stage() constructor {
    data = {};

    static save = function() {
        //get stage info
        data.info.name   = get_string("Stage Name:",   "Untitled");
        data.info.author = get_string("Stage Author:",  "Unknown");

        //get enemies
        var _i = 0;
        with (obj_enemy) {//save each enemy's data
            other.data.Enemies[_i++] = {
                object_index : object_index;
                x            : x;
                y            : y;
                Waypoints    : Waypoints;//array of Waypoints for AI
            };
        }

        //save using FrostyCat's JsonStruct
        jsons_save("STAGE.JSON", jsons_encode(data));
    }

    static load = function() {
        //clear current stage
        with (obj_enemy) {instance_destroy();}

        //load using FrostyCat's JsonStruct
        data = jsons_decode(jsons_load("STAGE.JSON"));

        //spawn enemies
        for (var _i = 0; _i < array_length(data.Enemies); _i++) {
            var _enemy = data.Enemies[_i];
            instance_create_layer(_enemy.x, _enemy.y, "enemies", _enemy.object_index);
        }
    }

    static draw_info = function() {
        draw_text(0,  0, data.info.name);
        draw_text(0, 10, data.info.author);
    }
}

function Enemy(_object_index, _x, _y, _Waypoints) constructor {
    object_index = _object_index;
    x            = _x;
    y            = _y;
    Waypoints    = _Waypoints;
}

function Waypoint(_x, _y) constructor {
    x = _x;
    y = _y;
}

function Game(_state) constructor {
    state = _state;
}

//--------------------------------------------------
//obj_game
//--------------------------------------------------
//Create Event
game  = new Game("GAMEPLAY_INIT");
stage = new Stage();

//Step Event
switch(game.state) {
    case "GAMEPLAY_INIT":
        stage.load();
        game.state = "GAMEPLAY";
    case "GAMEPLAY":
        //gameplay stuff...
        if (keyboard_check_pressed(vk_tab)) {game.state = "EDITOR_INIT";}
    break;

    case "EDITOR_INIT":
        stage.load();
        game.state = "EDITOR";
    case "EDITOR":
        //editor stuff...
        if (mouse_check_button_pressed(mb_left)) {
            instance_create_layer(mouse_x, mouse_y, "enemies", obj_enemy);
        }

        if (keyboard_check_pressed(ord("S"))) {stage.save();}
        if (keyboard_check_pressed(ord("L"))) {stage.load();}
        if (keyboard_check_pressed(vk_tab))   {game.state = "GAMEPLAY_INIT";}
    break;
}

//Draw Event
stage.draw_info();

//--------------------------------------------------
//obj_enemy
//--------------------------------------------------
//Create Event
enemy = new Enemy(
    obj_enemy, x, y, [
        new Waypoint(  0,   0),
        new Waypoint(100,   0),
        new Waypoint(100, 100),
        new Waypoint(  0, 100),
        new Waypoint(  0,   0)
    ]
);
One question I ended up with after all this: is there a way to do "with all objects that contain this struct type"? Something like:
GML:
with (all) {
    if (struct_exists("Enemy")) {
        //do stuff to these ones...
    }
}
Or would the best way of doing this be to keep a ds_list somewhere like in the Stage struct like:
GML:
//--------------------------------------------------
//obj_game
//--------------------------------------------------
//Create Event
stage          = new Stage();
stage.Entities = new List();//using FrostyCat's Lightweight Data Structures

//Step Event
for (var _i = 0; _i < stage.Entities.size; _i++) {
    with (stage.Entities[_i++]) {
        //do stuff to these ones...
    }
}

//--------------------------------------------------
//obj_enemy
//--------------------------------------------------
//Create Event
obj_game.stage.Entities.add(id);

//Cleanup
obj_game.stage.Entities.remove(id);
Big thanks to all the advanced guys who've been helping answer everyone's questions and the tutorial makers putting their stuff up on YouTube the last couple weeks!

This is seriously so much fun and I don't even have the beta yet...but every time I'm roughing these things out and I spot something I can use a new feature for and chop out huge chunks of code or entire scripts or bulky arrays of enums it feels like when you bomb a wall in Zelda and find a secret cave lol
This bit of code:
GML:
//get enemies
var _i = 0;
with (obj_enemy) {//save each enemy's data
    other.data.Enemies[_i++] = {
    object_index : object_index;
    x            : x;
    y            : y;
    Waypoints    : Waypoints;//array of Waypoints for AI
    };
}
Try to use this instead:

GML:
//get enemies
var _i = instance_count(obj_enemy);
with (obj_enemy) {    //save each enemy's data
    other.data.Enemies[--_i] = {
    object_index : object_index;
    x            : x;
    y            : y;
    Waypoints    : Waypoints;//array of Waypoints for AI
    };
}
Doing this simple change will make you code way more performant.

[TIP] When creating an array by iteration, always try to do it in reverse order!!
 
This bit of code:
GML:
//get enemies
var _i = 0;
with (obj_enemy) {//save each enemy's data
    other.data.Enemies[_i++] = {
    object_index : object_index;
    x            : x;
    y            : y;
    Waypoints    : Waypoints;//array of Waypoints for AI
    };
}
Try to use this instead:

GML:
//get enemies
var _i = instance_count(obj_enemy);
with (obj_enemy) {    //save each enemy's data
    other.data.Enemies[--_i] = {
    object_index : object_index;
    x            : x;
    y            : y;
    Waypoints    : Waypoints;//array of Waypoints for AI
    };
}
Doing this simple change will make you code way more performant.

[TIP] When creating an array by iteration, always try to do it in reverse order!!
Awesome, I had no idea but that makes complete sense now that I see it lol thanks!
 

Bruchpilot

Member
I can't seem to find the hidden beta forums. I have access to the 2.3 beta.
It's a separate forum, not part of the regular community. You have to log into your yoyo account (NOT the forum account, but the one you use for buying/downloading).
In your Beta acceptance email there is a link "How to report issues" which leads to a blog posting, which then has a link to the beta forum.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Does anyone know when will the stable, production-ready version of 2.3 will arrive?
Impossible to say, sorry! It'll go full public open beta first then it'll go into stable, so it all depends really on how well the public beta goes... The current beta is going well, so I don't think the full open beta will show up many bugs or issues that will delay the full stable release, but it's very much a case of "wait and see". Hopefully it'll be sooner rather than later though!
 
Impossible to say, sorry! It'll go full public open beta first then it'll go into stable, so it all depends really on how well the public beta goes... The current beta is going well, so I don't think the full open beta will show up many bugs or issues that will delay the full stable release, but it's very much a case of "wait and see". Hopefully it'll be sooner rather than later though!
Nice, is there a release window on open 2.3 beta then? Since that is the very next step
 

Cameron

Member
Nice, is there a release window on open 2.3 beta then? Since that is the very next step
Yeah it was originally Q4 of 2019. So, we are a bit behind. The point isn't to disparage YoYo, only to say you can't really trust a release window. That being said, it seems invites are being extended at an exponential rate which only bodes well for the beta being completely open soon. Other than that, I think Nocturne basically answered this already when he said it's a case of wait and see. Until official notice is released by YoYo anything else is just speculation at best.
 

NightFrost

Member
By the way, since YYG might be having a look at the room editor soon, what would be the proper place to drop some enhancement suggestions?
 

Arvel

Member
Impossible to say, sorry! It'll go full public open beta first then it'll go into stable, so it all depends really on how well the public beta goes... The current beta is going well, so I don't think the full open beta will show up many bugs or issues that will delay the full stable release, but it's very much a case of "wait and see". Hopefully it'll be sooner rather than later though!
Hmm, that's a shame..:( I really look forward to using 2.3 for production. Would that mean not even starting a project fresh from the ground not recommended with 2.3 (for production)?
 

Arvel

Member
I feel like indeed the current beta is going quite well. I've been stress testing 2.3 to the grim and haven't found any deal-breaker issue so far. This creates an itch for me to actually make a new project with 2.3, although still sitting in the sidelines wondering if it's a good idea or not.
 

kburkhart84

Firehammer Games
They fixed the bug that I had with the corrupt asset browser. They won't officially recommend you start a fresh production project in the beta, but as long as you do it with an open mind you are probably fine.
 

Arvel

Member
Eh, forgot to ask. Only Windows is supported atm? Tried a couple days ago with HTML5 and it didn't work, not sure about now.
 

FrostyCat

Member
Eh, forgot to ask. Only Windows is supported atm? Tried a couple days ago with HTML5 and it didn't work, not sure about now.
Windows VM and Android VM are thus far the only two exports in the beta I have found to be viable. As of the time of writing, here are all the export-specific problems I have found in the beta thus far:
  • 2 completely dead exports due to defects in the build routine (UWP and Ubuntu)
  • String leaks and other isolated compiling issues on Mac VM
  • A dead HTML5 F6
  • Constant type loss on Windows and Android YYC (several reports of "adding number to string" when there is no number, in one case even working_directory)
  • Android YYC still has exceptions disabled when exceptions are now part of GML
 
Is it possible to use the current version to start writing complex projects or could other major changes arrive before the release of the official version?

another question ... I have not read any user who in recent days has received access to the beta but my ticket is 169776 and it seemed that I was close enough but maybe they have stopped releasing other accesses for the beta version?
 

kburkhart84

Firehammer Games
I'm not sure if the current version is going to have any major changes. But I think you are probably OK to start a project, as long as you are aware that things could change. There is never any guarantees of course.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
By the way, since YYG might be having a look at the room editor soon, what would be the proper place to drop some enhancement suggestions?
You can file suggestions through the form: https://accounts.yoyogames.com/contact-us If you go there after signing in with your YoYo Account, you'll see there is now a "Request a GMS 2 Feature" option from the menu.

Is it possible to use the current version to start writing complex projects or could other major changes arrive before the release of the official version?
The current 2.3.0 is feature locked, but that doesn't mean there won't be minor tweaks between now and stable release whcih could have larger knock-on effects for large projects. I'd stick to testing and prototyping ideas for now rather than start a full project.
 

Joh

Member
Anyone has an opinion on using the native data structures vs wrapping them into custom structs to turn them more like objects?
list.append(x)
list.pop() etc

Having to ds_blabla everywhere is a bit annoying, but I don't know if that minor annoyance is worth coding a simple (at least in my head) wrapper. also maybe I'm missing some potential issues with such an approach.
 
Status
Not open for further replies.
Top