• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

OFFICIAL GMS 2.3.0 BETA ANNOUNCEMENT

Status
Not open for further replies.
I have a small question. Will the syntax for the following still work?

myArray[0,0] = "hello world";

or will I have to automatically change it to

myArray[0][0] = "hello world"

asking for a friend
 

Hyomoto

Member
So, is there a reason why "constructor" doesn't just replace "function" for those calls? Given what it does, the two are not equivalent, so it seems odd to chain them together. That is to say,
GML:
function foo() constructor {
  x = 0;
}
function bar() {
  x = 0;
}
They do not do the same thing. It seems like
GML:
constructor foo() {
}
Separates them out better and makes it clear the difference. Is there a technical reason why it works this way? Future expansion plans?
 

Cpaz

Member
Tried logging in and getting setup, I noticed it doesn't try and transfer over the workspace from the project.
That makes sense for the asset manager, but not even open code tabs?

Another point is how properties weren't copied over either. So all of my text formatting is reset to default.
Will it try and convert these settings over like normal during the actual update?
If so, is there a way to manually copy settings over into the beta?
 

Zhanghua

Member
So, is there a reason why "constructor" doesn't just replace "function" for those calls? Given what it does, the two are not equivalent, so it seems odd to chain them together. That is to say,
GML:
function foo() constructor {
  x = 0;
}
function bar() {
  x = 0;
}
They do not do the same thing. It seems like
GML:
constructor foo() {
}
Separates them out better and makes it clear the difference. Is there a technical reason why it works this way? Future expansion plans?
I think so,you should consider the inherition..
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Will it try and convert these settings over like normal during the actual update?
No. As far as I am aware the project conversion does not carry anything like that over.
If so, is there a way to manually copy settings over into the beta?
Make a post in the beta forums about this and see if something is being done or if there is a manual way to do it (there probably is but I don't know it).
 

Yal

🐧 *penguin noises*
GMC Elder
Yes, it till still work, but you really _should_ get used to the new way of using arrays.
Are old-style 2D arrays automatically converted to new-style 2D arrays (or rather, array of arrays) or is this something that needs to be manually done when importing a pre-2.3 project?
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Are old-style 2D arrays automatically converted to new-style 2D arrays (or rather, array of arrays) or is this something that needs to be manually done when importing a pre-2.3 project?
No, there is no auto conversion of arrays. You have to do this if you want to, but they should work fine un-converted (although there will be a slight extra overhead IIRC). That said all new projects should use the new system.
 

Hyomoto

Member
Do we have "this" like behavior? Self works as expected, but it seems like it would do this in context.
GML:
function foo( value ) constructor {

  this.value = value;

}
This is kind of a small issue, but it makes sense why all the documentation uses `_value` instead. Nonetheless, it does ... create an awkward situation where you want your variables to be named after the values being set, but you can't because doing that would force them out of the namespace. Unless I'm missing a tool?

EDIT: Maybe it's just a problem with the function display. It does look like you can override the display arguments, which makes this a moot issue. Earlier when I tried to override the argument display with /// @param value it ended up spitting out something like function( value,,_value )
 
Last edited:
D

Deleted member 45063

Guest
Self works as expected
Are you implying self has that same behavior for you? Because adding this:
GML:
function T1(x) constructor {
  self.x = x;
}

function T2(x) constructor {
  x = x;
}

show_debug_message("T1: " + string(new T1(123)));
show_debug_message("T2: " + string(new T2(123)));
To a room creation events yields
Code:
T1: {  }
T2: {  }
Which is a shame, because I really wanted to try a scenario of a struct that assigned dynamic variables to itself (...for Java-style enums).
 

NightFrost

Member
Wohoo, very excited for 2.3 release. I can see myself using functions a lot. I have lots of scripts in projects that are essentially like methods of a class, that is they create funtionality to a specific object. I can start cleaning up those huge resource trees under Script category and dumping them into create events. More generic scripts I'll start merging in logical groups into single files which should further shrink the list. This has the added benefit of greater portability as there's less chance of forgetting something important when creating local packages. In optimal case the local package is just a single object as it will contain everything necessary. Similarly, I can see a lot of use for structs when creating data storage, as they can carry methods too...

Speaking of structs, I didn't see it mentioned whether they are a value type or a reference type. So when I do oneStruct = anotherStruct, is that a copy or a reference? I assume there's also no OOP style inheritance, since nothing's been said about it.
 

Cpaz

Member
Wohoo, very excited for 2.3 release. I can see myself using functions a lot. I have lots of scripts in projects that are essentially like methods of a class, that is they create funtionality to a specific object. I can start cleaning up those huge resource trees under Script category and dumping them into create events. More generic scripts I'll start merging in logical groups into single files which should further shrink the list. This has the added benefit of greater portability as there's less chance of forgetting something important when creating local packages. In optimal case the local package is just a single object as it will contain everything necessary. Similarly, I can see a lot of use for structs when creating data storage, as they can carry methods too...

Speaking of structs, I didn't see it mentioned whether they are a value type or a reference type. So when I do oneStruct = anotherStruct, is that a copy or a reference? I assume there's also no OOP style inheritance, since nothing's been said about it.
I believe it's all pass by value. I don't think much of anything in GMS has been pass by reference. Which makes sense given how everything is structured.
 

Hyomoto

Member
@Rui Rosário - So "self" is ... to some degree the same as "id" in that scenario. So the "x" that gets set in the first one is at the "self" scope, and the second one is a local scope so nothing happens. However, it turns out you can do this:
GML:
/// @func foo( value )
/// @param value
function foo( _value ) constructor {
  value = _value;
}
Which addresses my specific issue, but your example highlights why "this" is desirable, as it provides a recognizable scope for the thing being operated on. Though it seems like outside of your example, the "this" is implied. Because, as the example above shows, the result is as expected, the constructor returns the proper value. Self is needed because that is how you can "reach back" to the calling scope which may not be the same as the defined scope. It's a little abstract sometimes, such as a global function appears to resolve the scope of the calling instance, but a function inside of a struct will resolve to the struct, unless you use self. So basically it works the same as it did before unless you use the new stuff and then scope becomes more complex. I mean, self used to be a fairly irrelevant keyword but now it has some real value.
 

Khao

Member
No, there is no auto conversion of arrays. You have to do this if you want to, but they should work fine un-converted (although there will be a slight extra overhead IIRC). That said all new projects should use the new system.
Just out of curiosity, for old projects where I use a ton of arrays and will continue to do so, can I just mix both array styles?

Like, if an array is defined as blabla[x, y], can I access it as blabla[x][y]?

Either way, it's probably better to just spend a day updating to the new format. Just to get used to it. Functionality should stay the same, right?
 
D

Deleted member 45063

Guest
@Rui Rosário - So "self" is ... to some degree the same as "id" in that scenario. So the "x" that gets set in the first one is at the "self" scope, and the second one is a local scope so nothing happens. However, it turns out you can do this:
GML:
/// @func foo( value )
/// @param value
function foo( _value ) constructor {
  value = _value;
}
Which addresses my specific issue, but your example highlights why "this" is desirable, as it provides a recognizable scope for the thing being operated on. Though it seems like outside of your example, the "this" is implied. Because, as the example above shows, the result is as expected, the constructor returns the proper value. Self is needed because that is how you can "reach back" to the calling scope which may not be the same as the defined scope. It's a little abstract sometimes, such as a global function appears to resolve the scope of the calling instance, but a function inside of a struct will resolve to the struct, unless you use self. So basically it works the same as it did before unless you use the new stuff and then scope becomes more complex. I mean, self used to be a fairly irrelevant keyword but now it has some real value.
I am aware of that, just that for my particular experiment that is not really what I want. I ended up doing something like:
GML:
function v1() {}
function v2() {}
function v3() {}

function Enum() constructor {
  _values = undefined;
  _names  = undefined;
  _length = undefined;
}

function make_enum() {
  var e = new Enum();
  e._values = array_create(argument_count);
  e._names  = array_create(argument_count);
  e._length = argument_count;
 
  for (var i = 0; i < argument_count; i++) {
    var value = argument[i], name = script_get_name(value);
    e._values[i] = value;
    e._names[i]  = name;
    variable_struct_set(e, name, value);
  }
 
  return e;
}

show_debug_message(make_enum(v1, v2, v3));
When I wanted to do something like:
GML:
function v1() {}
function v2() {}
function v3() {}

function Enum() constructor {
  _values = array_create(argument_count);
  _names  = array_create(argument_count);
  _length = argument_count;
 
  for (var i = 0; i < argument_count; i++) {
    var value = argument[i], name = script_get_name(value);
    _values[i] = value;
    _names[i]  = name;
    variable_struct_set(this, name, value);
  }
}

show_debug_message(new Enum(v1, v2, v3));
And in both cases get:
Code:
{ _values : [ 100003,100004,100005 ], _names : [ "v1","v2","v3" ], _length : 3, v1 : 100003, v2 : 100004, v3 : 100005 }
 

Alice

Darts addict
Forum Staff
Moderator
@NightFrost @Cpaz Just to properly show that structs are indeed passed by reference:
GML:
s1 = { a: "Lorem", b: "ipsum" };
show_debug_message(s1);
s2 = s1;
s2.a = "Hello";
s2.b = "world";
show_debug_message(s1); // note that I output the original struct
The output I get is:
Code:
{ a : "Lorem", b : "ipsum" }
{ a : "Hello", b : "world" }
@Hyomoto I definitely agree that something like "this" keyword would be very needed.

As it is now, I don't see a trivial way to pass the struct itself around, in particular from its own functions. I came up with a workaround...
GML:
Foo = function (_content) constructor {
    content = _content;
    static fluentPrint = function () {
        show_debug_message(content);
        return this;
    }
}

createFoo = function (_content) {
    var instance = new Foo(_content);
    instance.this = instance;
    return instance;
}

createFoo("bar")
    .fluentPrint()
    .fluentPrint();

createFoo("baz")
    .fluentPrint()
    .fluentPrint()
    .fluentPrint();
...but the output I get seems to increase exponentially with subsequent .fluentPrint() calls (1 for 1, 3 for 2, 7 for 3 and 15 for 4, instead of one print per call), so I guess it's something to make a bug report of...

--- EDIT ---

After more testing, I've found that:
- self apparently is no longer a -1 in disguise, so it seems to be a viable implementation of "this" at least
- the problem is with chaining methods returning structs (or maybe chaining methods in general, but only a struct or an object can have its method chained, anyway)
- people have already reported a similar problems, so I guess I will wait for these to be resolved
 
Last edited:

xDGameStudios

GameMaker Staff
GameMaker Dev.
Can somebody tell me if this is possible:

GML:
function Child constructor {
    _owner = undefined;
}

function Owner constructor {
    static addChild = function(child) {
        child._owner = self;
    }
}

var _child = new Child();
var _owner = new Owner();

_owner.addChild(_child);
does self refere to the Owner instance? does it work as this
or instead of self use id ...does structures have id? they might!
 
Last edited:
D

dcm

Guest
does anyone know if they are going to keep accepting people over the weekend? I feel like I just missed their cutoff
 
H

Homunculus

Guest
@Alice there is definitely something wrong there, I reported something similar today. In short, you can use self as a return value for struct methods, so it seems to be possible to chain methods like you are doing above, but it's not working properly. As an example:

GML:
function Number(_n) constructor {
    n = _n;
    static add = function() { n+= 1; return self; }
}

number = new Number(10);
number.add().add();
In the above, the add function correctly returns its struct using self, but the value of n is 11, not 12 as you would expect. Every method call after the first is simply ignored.

Moreover, if you do this:

GML:
number = new Number(10);
(number.add()).add();
You get 13, like the method gets called one extra time.

@Rui Rosário I suppose you can't use the second variant because in variable_struct_set(self, name, value); , self references the constructor, and not the struct being created, am I right?
 

XanthorXIII

Member
does anyone know if they are going to keep accepting people over the weekend? I feel like I just missed their cutoff
I did too somehow. I don't really see why they're keeping it so limited when we've been waiting for a year, got pushed a month from what I can tell due to this Covid thing and then if you happened to have been working at the time the announcement was made feel like the train left the station before I could get a chance to buy the ticket when they were made available even though that train left the following day and could pull additional cars very easily. To be honest they need to have a lot more people testing it than just the few that it seemed like it went out to.
 

Alice

Darts addict
Forum Staff
Moderator
@Homunculus Yeah, after playing around with my scenario it seems that it's methods chaining that's broken somehow. Hopefully they'll get it resolved, somehow.
 
A horse, a horse, my kingdom for a horse...

and by horse I mean GMS 2.3 beta key!

Please refer to me by my beta key number, from now on, I will be know simply as.... No. 169379!!!!

EDIT : Received the auto-response with my ticket number email @ Fri, Apr 24 at 4:30 AM CST
 

❤️×1

Member
@Nocturne the "known issues" page seems not to work for me, they are assigned manually per user?
Still no working link for the know issues? Have you PMed Nocturne?

I can fatal error the IDE reliably in at least two different ways but I still don't know if it should be reported or not.
 

xDGameStudios

GameMaker Staff
GameMaker Dev.
does anyone know if they are going to keep accepting people over the weekend? I feel like I just missed their cutoff
they are based in the UK... the timezone is the same as mine here it is 10pm... they closed the office 5 hours ago :(
my ticket is 169190-ish... and I didn't get the email either.. so they are just above 169144 and below 169190

only Monday now... I'm gonna cry thy the corner of my room!
 

❤️×1

Member
they are based in the UK... the timezone is the same as mine here it is 10pm... they closed the office 5 hours ago :(
my ticket is 169190-ish... and I didn't get the email either.. so they are just above 169144 and below 169190

only Monday now... I'm gonna cry thy the corner of my room!
They allowed over a hundred people today! If they keep on this rhythm, you'll be in in no time!
 

gnysek

Member
So, is there a reason why "constructor" doesn't just replace "function" for those calls? Given what it does, the two are not equivalent, so it seems odd to chain them together. That is to say,
GML:
function foo() constructor {
  x = 0;
}
function bar() {
  x = 0;
}
They do not do the same thing. It seems like
GML:
constructor foo() {
}
Separates them out better and makes it clear the difference. Is there a technical reason why it works this way? Future expansion plans?
I just wanted to say that they not doing same.

BUT! I made some tests and.... you can also use new keyword on function without constructor. And it will become a struct!

So, seems that all those 4 things give structs:
GML:
function foo() constructor {a = 1;};
function bar() {b = 2;};
function foobar() {return {c: 3}};


a = new foo();
b = new bar();
c = foobar(); // without "new"
d = {d: 4}; // regular struct
Constructor keyword seems to be used only by interpreter in IDE/compiler, to know, that it can be used for inheritance.
 

Hyomoto

Member
It seems the part that needs the most work in the beta, from my experience so far, is the autocomplete/syntax highlighter. It's pretty inconsistent and allows things that 2.2 would have called you out on. Like
GML:
foo = function( x, y ) {
    return x + y;
   
}
foo()
This will crash, but it doesn't call out that x and y weren't defined, however,
GML:
function foo( x, y ) {
    return x + y;
 
}
foo()
Will call it out as expected. Other people have obviously had some greater issues, but from a language standpoint things look in good shape with the exception that the autocomplete and syntax highlighting will probably see quite a few patches.
 

Dragonite

Member
This has been like waiting for Christmas as a kid, except about 8x harder, because it's something that's actually important.

It's great so far! I was expecting all kinds of unusual issues to crop up, but after 4-5 hours of use I've only ran into a few astonishingly minor very things. I'll put these in the bug tracker as well, but Nocturne suggested I log them in the forum thread for good measure.

- Color coding on certain variables are global when they shouldn't be: "name," "position," "value" variables of sequence-related structs are highlighted anywhere (unless they're defined as local variables, in which case they'll be highlighted like local variables) even though they're only intended to be used in sequence-related structs; there may be others as well, but those are the ones I've found

- If you F1 or middle click over said sequence variables they just open to the main Documentation page, even though they should perhaps go to the page on Sequences?

- Static functions are inaccessible if you have not instantiated the struct

- Game Maker will show a "the project directory has changed, would you like to save or reload?" message after global find-and-replace; upon selecting either, it seems to re-save the entire project

- Nested map data structure accessors cause errors:

map = ds_map_create();
ds_map_add(map, "inner", 0);
map2 = ds_map_create();
ds_map_add(map2, "key", "inner");

show_message(map[? map2[? "key"]]);
___________________________________________
############################################################################################
ERROR in
action number 1
of Create Event
for object program:

unable to convert string "inner" to int64
at gml_Object_program_Create_0 (line 22) - show_message(map[? map2[? "key"]]);
############################################################################################
gml_Object_program_Create_0 (line 22)

- If you try to save a file that's open by another program outside Game Maker (an image editor, a text editor, anything that would cause Windows to block access to it) it will silently fail instead of alerting you - I'm 99% sure this was an issue before now, but just for good measure

Other than that, I'm amazed. I was expecting to not be able to use this for my current projects for weeks, if not months, but after 20-25 minutes of fiddling around and making a few minor adjustments I had a 40,000-line project running almost perfectly.

edit: okay you guys are moving way too fast, I don't know if any of these have been reported already, but in any case.
 

gnysek

Member
edit: okay you guys are moving way too fast, I don't know if any of these have been reported already, but in any case.
They wish to report on helpdesk forum (link attached in email). This one with ds_maps looks like worth reporting, and I can confirm that it won't work without using some temp var.
 

Alice

Darts addict
Forum Staff
Moderator
It seems the part that needs the most work in the beta, from my experience so far, is the autocomplete/syntax highlighter. It's pretty inconsistent and allows things that 2.2 would have called you out on. Like
GML:
foo = function( x, y ) {
    return x + y;
  
}
foo()
This will crash, but it doesn't call out that x and y weren't defined, however,
GML:
function foo( x, y ) {
    return x + y;

}
foo()
Will call it out as expected. Other people have obviously had some greater issues, but from a language standpoint things look in good shape with the exception that the autocomplete and syntax highlighting will probably see quite a few patches.
I think this behaviour is because constant functions are constant, and variable functions are variable. Functions defined with name will permanently bind that name to this function. When you assign function to a variable, however, you have no guarantee that variable won't change.

For example, you could do something like this:
Code:
foo = function(x, y) {
    return x + y;
}

foo = function() {
    show_debug_message("whatever");
}

foo();
...and it's a valid call, even if it wouldn't be valid if the second "foo" assignment was gone. So whether this function call is valid or not is not trivially detected.

Technically speaking, compiler could try to recognize the special case of variable function calls immediately following their assignment, but I think it's way too much effort for way too little benefit.
 

gnysek

Member
I think this behaviour is because constant functions are constant, and variable functions are variable. Functions defined with name will permanently bind that name to this function. When you assign function to a variable, however, you have no guarantee that variable won't change.
What's fun, if you use JSDOC, then GMS seems to treat it as constant function, and even detects number of arguments, so writing /// @func foo() or /// @func foo(a,b,d,c,whatever) will still show number of arguments that you put in function, not in JSDOC....
1587767606990.png
 

Coded Games

Member
Is there any way to see a version of the updated manual without being in the beta? @Nocturne?

Edit: Nevermind, just saw your post on the previous page about it potentially coming on Monday?
 
Last edited:

gnysek

Member
I once shared the docs of latest versions on github, so it would be easier to see the changes between version, but they sadly asked me to take it down, as they said that images are copyrighted. So I would like to share beta docs with you, but it seems it's not possible.
 
Status
Not open for further replies.
Top