OFFICIAL GMS 2.3.0 BETA ANNOUNCEMENT

Yal

🐧 *penguin noises*
GMC Elder
Do you guys have a problem with particles not showing up? This was a problem I have in 2.2 and is still problem in 2.3 One way I fixed this is to run on admin and make a new copy of the game but the problem keeps reoccurring. I wish it could just work, no running on admin, no making a new copy. This problem seems to only happen with the windows and not html5 (I've only tested both)
What's the depth of the particle system? Anything outside the range +/- 16,000 will have undefined sorting relative to each other, so it might e.g. end up behind the background layer. If you carry over GMS1 code to define it (where 1,000,000 was the default depth for tile layers so most people stuck to depths in that range) it's more likely than not that you're giving your particle systems depths in that range. (There's a new function to place a particle system on a particular layer, too, but if you're like me and have one or two global particle systems that stick around between rooms, it might get annoying to reassign it in every room)
 

gnysek

Member
I never had issue with part_system_drawit(), so... hard to tell without project. Maybe try to simplify it and share with us, and then we can tell it's a bug or no?
 
It seems to be circumstantial and not everybody experiences it, even with the same code. I was able to solve my problem by running as admin and make a new/save as project while as admin. My concern though is not solving it but rather that people shouldn't be experiencing such problems in the first place.

If you want to recreate the problem, make a new project and put this code in the keypress-enter event on a new object and drop that object right in the middle of the room.
GML:
effect_create_above(ef_explosion, x, y, 2, c_red);
This is the same code used in the thread shared earlier. It should create some particle explosion effect when you press enter. However, when I make a new project on 2.3 (2.2 as well), it doesn't work, but it does when I run as admin.
 

Amon

Member
It seems to be circumstantial and not everybody experiences it, even with the same code. I was able to solve my problem by running as admin and make a new/save as project while as admin. My concern though is not solving it but rather that people shouldn't be experiencing such problems in the first place.

If you want to recreate the problem, make a new project and put this code in the keypress-enter event on a new object and drop that object right in the middle of the room.
GML:
effect_create_above(ef_explosion, x, y, 2, c_red);
This is the same code used in the thread shared earlier. It should create some particle explosion effect when you press enter. However, when I make a new project on 2.3 (2.2 as well), it doesn't work, but it does when I run as admin.
I'm not running as admin and did as you instructed and get no error. I get an explosion at the point where I placed the object in the middle of the room.
 

Ednei

Member
Hello people. I will make a small contribution. I updated GM2 to the beta version released today IDE v23.1.1.172 Runtime v23.1.1.165 and it is running very light on my Dell Inpiron Core I7 16 GB machine.

The previous version of GM2.3 - Beta was very stuck on my machine, especially when you tried to edit a script, it was impossible to drag the bottom scroll bar of the window.

In this version this problem has been solved. The GM is very light to work with and without crashes.

But I also have to make an observation. Coincidentally, today I updated Window 10 from version 1909 to the latest version 2004.

So I don't know if the improvement in GM performance happened due to the new version of GM 2.3 - Beta or my Windows 10 update.

Thank you.
 

gnysek

Member
It's not a Windows, I've update to 2004 month ago and performance didn't changed. With v12 update IDE is much more robust, and text editors seems to work faster (besides scrollbars, doubleclick was working for me very slow too, now it works normally).
 

newt2

Member
Hi,

I have a question regarding struct inheritance. The manual explicitly states that structs support "single level inheritance". From my understanding of other languages, single "level" means that for any given struct, it can have only one parent, and that parent cannot have another parent. However, based on testing, multiple levels of inheritance fully works. For example, code such as the following works fine:

Code:
function A(_a) constructor{
    a = _a;
}

function B(_a, _b) : A(_a) constructor {
    b = _b;
}

function C(_a,_b,_c) : B(_a, _b) constructor {
     c = _c;
}
var test = new C(1,2,3);
show_debug_message([test.a, test.b, test.c]);
Other combinations of methods and static methods also work. Perhaps the documentation isn't referring to single 'level" inheritance, but just single inheritance (as opposed to multiple-inheritance, as in structs being able to have multiple parents), because multi-level inheritance works just fine. Am I understanding this correctly?
 

gnysek

Member
Yeah, seems that there should be "simple/single inheritance" instead of "single level inheritance". Also, there may be no "multiple inheritance" but there is "multilevel inheritance" from what I understand. It's a thin line between all those meanings...
 

Ednei

Member
Hello people. I will make a small contribution. I updated GM2 to the beta version released today IDE v23.1.1.172 Runtime v23.1.1.165 and it is running very light on my Dell Inpiron Core I7 16 GB machine.

The previous version of GM2.3 - Beta was very stuck on my machine, especially when you tried to edit a script, it was impossible to drag the bottom scroll bar of the window.

In this version this problem has been solved. The GM is very light to work with and without crashes.

But I also have to make an observation. Coincidentally, today I updated Window 10 from version 1909 to the latest version 2004.

So I don't know if the improvement in GM performance happened due to the new version of GM 2.3 - Beta or my Windows 10 update.

Thank you.

I didn't even start testing IDE version v23.1.1.172 Runtime v23.1.1.165 and today IDE v23.1.1.1724 is now available?

What a surprise. Well, today I can't complain about the delay for updates.
 

gnysek

Member
Yeah, they updated notes on helpdesk forum, however title is same, so it's hard to notice that. It's only IDE update, no runtime changes (which doesn't happen so often).
 
That is indeed the official recommendation. However, in my experience if you just do work in smaller than usual chunks and make sure you are backing up more often than usual, its usually fine.
I started a brand new project and within 30 minutes to an hour my project got corrupted and also the game would fail to run every time. I will use 2.2.5 for now and wait until 2.3 becomes more stable.
 

kburkhart84

Firehammer Games
I started a brand new project and within 30 minutes to an hour my project got corrupted and also the game would fail to run every time. I will use 2.2.5 for now and wait until 2.3 becomes more stable.
I guess you have some bad luck. Its not that unstable for me honestly. I've done several hours of work in this project and it hasn't corrupted on me. I've seen others with experiences similar to mine so I'm not sure exactly what you are doing that is causing it. Have you reported bugs about it?
 

Yal

🐧 *penguin noises*
GMC Elder
Don't forget to at least have a local Git repo just in case, the time spent learning the basic commands will pay back tenfold in all the time you save on command-line backups and being able to go back in the timeline whenever you feel like it.
 

kburkhart84

Firehammer Games
Don't forget to at least have a local Git repo just in case, the time spent learning the basic commands will pay back tenfold in all the time you save on command-line backups and being able to go back in the timeline whenever you feel like it.
I'm personally using Github Desktop...seems to be fine for me. It does a local repo along with the free cloud one. Even better, I have it in a dropbox, AND it auto-backups locally to an external drive. I guess besides more of the same backups, the only other thing I can really do it if I did backups to a friend's PC(some backup software does this actually), but I think I'm pretty well covered as it is.

In the past, I'd maybe push to a repo once every few days of work...with 2.3 right now I'm commiting once for a short day of work, twice or thrice if I'm able to get hours of work in. If I have to lose work due to beta 2.3, its going to only be a small amount.
 

gnysek

Member
Using dropbox/gdrive/others for GMS project isn't a best idea, as if you start to do something on another PC, all can corrupt outside of IDE cause of delayed file sync.
 

kburkhart84

Firehammer Games
Using dropbox/gdrive/others for GMS project isn't a best idea, as if you start to do something on another PC, all can corrupt outside of IDE cause of delayed file sync.
You are right...but in my case I've never had issues with it. I only ever do any actual work on my GMS2 stuff on a single PC though, I'm not trying to use it as any sort of version control or anything crazy like that. In fact, I've opened projects up on other PCs through the dropbox and I never get issues there. The trick is to always make sure you work with the single latest version, don't open a project on another PC until the dropbox is fully updated. And make sure that whatever you do gets sent to dropbox before you shut down, and that it gets downloaded before you open on the other PC. So its basically one at a time, and being 100% sure its always the right version. In any case, I also have the local external hard drive plug github backup/versioning as well so I'm not risking much, and the automatic cloud backup is worth it.
 

nephewtom

Member
How can I get the 2.3.0 beta for Windows?
Whenever I go to Downloads page, the only available is Current Version: 2.2.5.481
Best regards.
 

FrostyCat

Member
Only people on non-trial licenses are allowed to use the open beta.

Take this time to learn the foundations of GMS 2 and GML, not drive-testing betas.
 

Joh

Member
so with GM2.3 structs, how would one go about instances(heavy object) of a struct?
I used structs to define "Units" say
GML:
tower() contructor
{
hp = 100
name = tower
x  =  0
y = 0
}
this essentially has all the info for that unit. For it to concretely (collisions) exist in the world I would need to associate it with a game instance.
I do it by creating a struct instance [ new tower() ] , giving it to a object instance [ instance_create(x,y, obj_tower) ] and then transfer all variables values from the struct to the instance. (a script heavily lifted from FrostyCat's struct_merge() but copying to instance instead)
This works nicely: it creates game instances that automatically get all the variables from the unit structs i make.
But I'm realising now that it creates a duplication of all variables: the struct and the instance copy and they are not synchronised. This makes sense but it feels inefficient. In theory, I only need to change the instance's variables, since that is what acts and exists in the world. But it feels off to keep an out of date associated struct. Also, when/if saving comes in line, the struct it would be usefull to keep the struct updated (easier to save).

Anyone encountered this design situation? How do you handle it?
  • I can see how I could not even copy the struct variables and simply operate on the struct variables. ie: if collision mystruct.hp -= 10 but stat would be a mess and all instance code would always need "mystruct" prefix
  • Not use instances, do all code from struct. but that loses all the benefits from built in instances.(events)
  • Let variables desynchronise, synchronise them manually when needed.
I know this is more of a design question, but I've seen a lot of discussion on good ways to use the structs and I like to think the situation I've described has been encountered here?
 

FrostyCat

Member
so with GM2.3 structs, how would one go about instances(heavy object) of a struct?
I used structs to define "Units" say
GML:
tower() contructor
{
hp = 100
name = tower
x  =  0
y = 0
}
this essentially has all the info for that unit. For it to concretely (collisions) exist in the world I would need to associate it with a game instance.
I do it by creating a struct instance [ new tower() ] , giving it to a object instance [ instance_create(x,y, obj_tower) ] and then transfer all variables values from the struct to the instance. (a script heavily lifted from FrostyCat's struct_merge() but copying to instance instead)
This works nicely: it creates game instances that automatically get all the variables from the unit structs i make.
But I'm realising now that it creates a duplication of all variables: the struct and the instance copy and they are not synchronised. This makes sense but it feels inefficient. In theory, I only need to change the instance's variables, since that is what acts and exists in the world. But it feels off to keep an out of date associated struct. Also, when/if saving comes in line, the struct it would be usefull to keep the struct updated (easier to save).

Anyone encountered this design situation? How do you handle it?
  • I can see how I could not even copy the struct variables and simply operate on the struct variables. ie: if collision mystruct.hp -= 10 but stat would be a mess and all instance code would always need "mystruct" prefix
  • Not use instances, do all code from struct. but that loses all the benefits from built in instances.(events)
  • Let variables desynchronise, synchronise them manually when needed.
I know this is more of a design question, but I've seen a lot of discussion on good ways to use the structs and I like to think the situation I've described has been encountered here?
Structs at this point are best used for abstract data management. Anything with a concrete component in room or event space is still supposed to be done with object instances. For active agents in action games, I would still recommend doing it the traditional way with objects, GMS 2.3 has not changed the paradigm on that.

The most direct compromise I can think of is setting up methods in the object's Create event to use later:
GML:
loseHp = function(loss) {
    corestruct.hp -= loss;
};
GML:
if (place_meeting(x, y, oEnemy)) {
    loseHp(10);
}
This is better suited for non-action games and UI components, especially when some parts of the data do not map verbatim. For example, in a grid setup, the struct will hold the abstract grid position in cells, while the live instances will hold the in-room position in pixels.
 

kburkhart84

Firehammer Games
I agree with the above on using objects appropriately. One place structs can be useful for is if you want to have a LOT of similar objects, like if you made your own particle system. It could be more efficient to loop through all the structs in the same draw command to draw them than actually having thousands of instances, and you can also have a single function call loop through them and move them based on their parameters too.
 

Joh

Member
You can also put draw functions in your struct, and make them draw during draw events. This is the power of structs. You can make one object control thousands of struct "instances"
Yes, I do that actually. But I still call it from instances. There is only one object, but the "draw" it will call varies from instance to instance depending on the struct associated.
Structs at this point are best used for abstract data management. Anything with a concrete component in room or event space is still supposed to be done with object instances. For active agents in action games, I would still recommend doing it the traditional way with objects, GMS 2.3 has not changed the paradigm on that.

The most direct compromise I can think of is setting up methods in the object's Create event to use later:
GML:
loseHp = function(loss) {
    corestruct.hp -= loss;
};
GML:
if (place_meeting(x, y, oEnemy)) {
    loseHp(10);
}
This is better suited for non-action games and UI components, especially when some parts of the data do not map verbatim. For example, in a grid setup, the struct will hold the abstract grid position in cells, while the live instances will hold the in-room position in pixels.
I agree, in my situation however I have a mix of both: Units have to exist "abstractly" before they are bought/ created and concretely when on field being acted upon. Giving the object methods acting on its struct is a great idea.
I build a database with all units stats as structs (1 struct per unit type). I feel this is an improvement in readability and accessibility over one massive array/grid with first index being "unit type" and second index being all the stats.. and then make an associated enum for it to be understandable.
With the above approach you only need one generic unit object, and each instance take a different form

my game does make use of grid and indeed, i have a grid_x/y and real x/y. In my case both the instance and the struct have both, but thats only because I blindly copy everything. I am conscious some variables & methods are only relevant in one of them.

One cool thing I've found is you can give the method of a struct to an instance and when you do that the method will use the instances variable. (this is normal behavior, I just find it useful to realize)
myAimFunction = corestruct.structAimFunction
myAimFunction() will use the instances variables
 

DanTheCan

Member
After the questions on whether to use constructors or objects, I thought I'd share my flowchart for choosing which to use (yea I know, lol) Any thoughts?

Should I use a constructor, a singleton struct pattern, or an object to represent an entity?
Does the entity need complex collisions, the GM physics system, or any other build-in object functions that are extremely difficult to code yourself?
Yes:
--Use an object.
No:
--Does the entity need a step or draw function/event at any point?
----Yes:
------Does the entity 'belong to' or 'exist for' any other entity? (e.g. an inventory or map 'belongs to' a player entity)
--------Yes:
----------Use a constructor. (its step or draw events can be called in its parent object)
--------No:
----------Use an object.
----No:
------Should there only be a single instance of the entity?
--------Yes:
----------Use a singleton struct pattern.
--------No:
----------Use a constructor.
 
Last edited:

Selek

Member
After the questions on whether to use constructors or objects, I thought I'd share my flowchart for choosing which to use (yea I know, lol) Any thoughts?
I'm new to GMS and pretty new to programming in general, so forgive me if my question is clueless. But I'm wondering where arrays would fit into your flowchart. For learning purposes, I've made a Tetris clone and now a chess clone using GMS 2.2, and for the chess game in particular, I'm getting ready to refactor using the 2.3 beta. Right now my game uses ds_lists to store move lists, which get manipulated thousands of times as the AI considers move after move, but I've got memory leaks. I'm inclined to rewrite using 2.3's new multidimensional arrays to contain move info (piece, old position, new position, other data for special cases like pawn promotion and castling). But reading your flowchart makes me wonder whether I should be using a struct, as it's garbage-collected the same way an array is, yes?
 
Last edited:

DanTheCan

Member
I'm new to GMS and pretty new to programming in general, so forgive me if my question is clueless. But I'm wondering where arrays would fit into your flowchart. For learning purposes, I've made a Tetris clone and now a chess clone using GMS 2.2, and for the chess game in particular, I'm getting ready to refactor using the 2.3 beta. Right now my game uses ds_lists to store move lists, which get manipulated thousands of times as the AI considers move after move, but I've got memory leaks. I'm inclined to rewrite using 2.3's new multidimensional arrays to contain move info (piece, old position, new position, other data for special cases like pawn promotion and castling). But reading your flowchart makes me wonder whether I should be using a struct, as it's garbage-collected the same way an array is, yes?
Yes, structs are garbage-collected just like arrays. Ideally, once structs are fully optimized, most data structures should be structs. That way, they are much easier to visualize, add functions to, and inherit from each other. If you are using ds_lists and are having garbage-collection problems, I've got a constructor that might help: Arraylist. It uses an array to mimic the functionality of a ds_list. The main issue with structs as data structures is that they are slower to use than gamemaker's data structures. This isn't a problem in most normal projects, but if you need to do thousands of changes and accesses a second, there will be a noticeable difference.

As to your move info and unique special cases, make it easy on yourself and use a constructor. It's an object that is purely data, perfect for storing and accessing data in an easy-to-understand, object-oriented way.
 

Ednei

Member
Guys, are you managing to compile the projects for Android correctly?
The configuration of my machine is the same as described in this article:

SDK

This configuration works perfectly for version v2.2.5.481 using Runtimes v2.2.5.378.

However in this beta version the project is compiled but is not opening on my Android 8.1.0 smartphone.

I would like to know if there is any other configuration that I have to follow. I assume the above tutorial is out of date.

Thank you.
 

Selek

Member
I've got a constructor that might help: Arraylist.
Thanks for the link. That looks very helpful. I actually don't need full ds_list functionality, as I just need to access the array sequentially, from start to finish. I was thinking of simply declaring an array with 120 values or so, longer than the number of chess moves available at even the most complex position. But your constructor looks very useful.
As to your move info and unique special cases, make it easy on yourself and use a constructor. It's an object that is purely data, perfect for storing and accessing data in an easy-to-understand, object-oriented way.
Thanks also for this suggestion. I'll give it a try.
 

Toque

Member
In the room editor with 2.2 you can command + - short cut to zoom in and zoom out. Would be nice if you could do that in sequences...... Hmmm I think its just broken (on mac). When you hover it does show the short cut.

2.3 does freeze up on me frequently and have to force quit. But having fun with sequences.

edit Every morning when I wake my mac and 2.3 is running. Its frozen and have to quit.
 
Last edited:

gnysek

Member
does anyone has a clue when 2.3 will be out of beta?
Yes, when all critical bugs will be fixed :)

They keep most of those hidden on bugtracker, so no one have idea how much left. But from my crystal ball, tarot deck, and according to start alignment at night - I believe it will be in 2-3 weeks :squirrel:.
 
I had a thought. Now that we have structs and methods, wouldn't it be cool if the gms data structures acted like structs as well?

Instead of doing the following:
GML:
list = ds_list_create();
ds_list_add(list,"Hello World");
num = ds_list_size(list);
We can do something like this:
GML:
list = new ds_list();
list.add("Hello World");
num = list.size();
This feels more intuitive and I think it would attract more devs to use GMS. What do you guys think?
 
Last edited:

FrostyCat

Member
I had a thought. Now that we have structs and methods, wouldn't it be cool if the gms data structures acted like structs as well?

Instead of doing the following:
GML:
list = ds_list_create();
ds_list_add("Hello World");
num = ds_list_size(list);
We can do something like this:
GML:
list = new ds_list();
list.add("Hello World");
num = list.size();
This feels more intuitive and I think it would attract more devs to use GMS. What do you guys think?
There isn't enough time in the GMS 2.3 timeframe to retrofit any of the existing ID-based resources, including data structures. That is why I wrote this.
 

gnysek

Member
They always say "if you can do something by writing a script, then we won't add this as a feature in GML". Moving ds into struct isn't that hard, except they don't want add destructors, which in that case would allow to have garbage collected structures. Of course this is still possible in some way, but you need to use arrays in struct, and to not slow down GM on array resize, it's preferred to use array_create(10000, 0) for example to reserve memory, which waste RAM (for ds_map two arrays may be needed), and performance will be slower.
 

kburkhart84

Firehammer Games
They always say "if you can do something by writing a script, then we won't add this as a feature in GML". Moving ds into struct isn't that hard, except they don't want add destructors, which in that case would allow to have garbage collected structures. Of course this is still possible in some way, but you need to use arrays in struct, and to not slow down GM on array resize, it's preferred to use array_create(10000, 0) for example to reserve memory, which waste RAM (for ds_map two arrays may be needed), and performance will be slower.
I REALLY wish they would have added destructors too...they would have come in handy for everything that isn't already garbage collected....maybe they are planning to eventually make data structures an actual type and garbage collect them?!?! If they did, it would leave buffers and surfaces as far as I remember the only things that don't self garbage collect.
 

Erik Leppen

Member
I have the following problem that I find a bit hard to explain. I have a function with multiple arguments, say xyxy_draw_button(xyxy, text) and I want to define several buttons that use this draw function, where text will be fixed, but xyxy will be a variable.

So, in the main menu I do
GML:
playbutton.draw = function (xyxy) {xyxy_draw_button(xyxy, "Play");};
quitbutton.draw = function (xyxy) {xyxy_draw_button(xyxy, "Quit");};
This way, playbutton.draw is a function with only 1 argument (xyxy), and the button text is fixed. This way I can "reuse" the more generic function xyxy_draw_button.

This all goes well.

But in the level choose menu, I want to create a range of buttons: one for each level. So I do
GML:
for (var lev = 1; lev <= number_of_levels; lev += 1) {
    levelbutton[lev].draw = function (xyxy) {xyxy_draw_button(xyxy, string(lev));};
}
Now a problem arises. For level 3, the levelbutton[3]'s draw function is now calling xyxy_draw_button(xyxy, string(lev)) (giving an error, because lev does not exist in the function). But I want it to call xyxy_draw_button(xyxy, string(3)).
Stated otherwise, GM uses the variable lev in the anonymous function, but I want it to use its value.
Stated again otherwise, right now, GM only "evaluates" the variable lev when the function is called, but I want it to "evaluate" lev when the function is defined.

How do I do that?

Edit: not sure why this was moved, but whatever.
I tried using self.lev or other.lev; both didn't work.

Edit 2: I solved it for the time being by adding the code levelbutton[lev].lev = lev; and then using self.lev in the function definition, and using method() to assign the function to the instance. But adding this extra variable is not a very nice solution and I'd still like to hear a more general solution to this. :)
 
Last edited:

FrostyCat

Member
@Erik Leppen

GML 2020 uses struct closure methods to handle the use case you described. This is another obscure but foundational book line that YoYo staff taught me when I raised a similar issue on the helpdesk.

In your generic script, take only the non-fixed xyxy as an argument. But use text as though it exists anyways.
GML:
function xyxy_draw_button(xyxy) {
    /* Use xyxy and text here */
}
Then when you declare the methods, bind the script to a struct literal, and provide text through one of its keys.
GML:
playbutton.draw = method({ text: "Play" }, xyxy_draw_button);
quitbutton.draw = method({ text: "Quit" }, xyxy_draw_button);
Finally when you call it, you can provide just the dynamic xyxy through an argument.

Notice that this will change self to that of the struct literal. If you want to keep access to the current instance, stick the id in the struct closure as well, and use that to backdoor into the instance later.
GML:
playbutton.draw = method({ text: "Play", this: id }, xyxy_draw_button);
 

Ednei

Member
Where can I find the SDK's required for 2.3.0? Or are these exactly the same as for 2.2.5?

It's not on this page: https://help.yoyogames.com/hc/en-us/articles/227860547-GMS2-Required-SDKs
Where can I find the SDK's required for 2.3.0? Or are these exactly the same as for 2.2.5?

In my case I'm using the same settings as 2.2.5 in 2.3.0 and I'm having problems on Android Module. You can compile the project but you cannot open it.
The project compiled in 2.2.5 works perfectly, but in 2.3.0 it doesn't work.
When I try to open the Bluestacks emulator, this message appears:

erro.png
 
Top