It has been mentioned throughout the thread that it is first-come, first-served, so I'm guessing they just stopped issuing access before your ticket number got picked :/Here #169776 and I haven't received access yet ((
I would like to try to understand the criterion used for the priority for access to the beta...
*adjusts glasses*Here #169776 and I haven't received access yet
Not exactly fancy, but still a great look at the features and how people will use them. End result is pretty cool too and shows a bit of the potential for them:Any fancy animations made using sequences already ? I thought we gonna have a showcase here...
function basic() constructor{ static function val(){ throw("You should call me!!!!!!"); } }
function overload1(): basic() constructor{}
function overload2(): basic() constructor{ static function val(){ throw("Why do you call me????"); } }
function basic() constructor{ static val = function(){ throw("You should call me!!!!!!"); } }
function overload1(): basic() constructor{}
function overload2(): basic() constructor{ static val = function(){ throw("Why do you call me????"); } }
function test(){
var test1 = new overload1();
test1.val();
}
From what I've observed during the beta, function declarations in function name(...) { ... } form get pulled to the top level to become scripts, while those in name = function(...) { ... } form stay localized where they are. So your first sample starts with one implementation and then overwrites it with another down the line, while the second sample has two distinct implementations.What's the different between the codes below?
Code with Error message show the "Why do you call me????"!!!!!
Code with Normal message..... show the "You should call me!!!!!!"GML:function ICondition() constructor{ static function val(){ throw("You should call me!!!!!!"); } } function IConditionEle(): ICondition() constructor{} function OConditions_Err(): ICondition() constructor{ static function val(){ throw("Why do you call me????"); } }
The test code................GML:function ICondition() constructor{ static val = function(){ throw("You should call me!!!!!!"); } } function IConditionEle(): ICondition() constructor{} function OConditions_Err(): ICondition() constructor{ static val = function(){ throw("Why do you call me????"); } }
GML:function test(){ var test1 = new IConditionEle(); test1.val(); }
Yes, during the test, I find the same named inner functions overwrite the upper each other.From what I've observed during the beta, function declarations in function name(...) { ... } form get pulled to the top level to become scripts, while those in name = function(...) { ... } form stay localized where they are. So your first sample starts with one implementation and then overwrites it with another down the line, while the second sample has two distinct implementations.
One important note to keep in mind when exploring OOP in GMS 2.3 is to STOP thinking of it as static-type OOP found in C++/C#/Java. It is a duck-typed, JS-like kind of OOP.
From what I've observed during the beta, function declarations in function name(...) { ... } form get pulled to the top level to become scripts, while those in name = function(...) { ... } form stay localized where they are. So your first sample starts with one implementation and then overwrites it with another down the line, while the second sample has two distinct implementations.
One important note to keep in mind when exploring OOP in GMS 2.3 is to STOP thinking of it as static-type OOP found in C++/C#/Java. It is a duck-typed, JS-like kind of OOP.
function basic() constructor{
function val(){ throw("You should call me!!!!!!"); }
}
function overload1(): basic() constructor{
}
function overload2(): basic() constructor{
function val(){ throw("Why do you call me????"); }
}
function basic2() constructor{
function a(){
function val(){ throw("what the f111111111"); }
}
}
function val(){ throw("what the f22222222"); }
function test(){
var test1 = new overload1();
show_debug_message( test1.val() );
}
If you don't want to make your own system, you can still get it working within minutes with a quick tutorial, Google search, or marketplace download, there's no need to berate the engine because it doesn't have everything you need built-in@FrostyCat / @Yal
So in my opinion, GameMaker is very well suited for beginners who do not have much programming experience. So you usually start with DnD. But now the legitimate question arises why a game engine from the 21st century doesn't support ramps, although a game from 1991 already did this(Sonic). Or is it officially approved that you have to buy missing standard features, buy and fix obvious bugs yourself (or buy something that fixes it)? Why you defend this model is now clear to me, it's about money and the prestige of being better than others. But YoYo certainly thinks as a company and since they live to a large extent from new customers, they surely see it a little bit differently than you (at least I hope so).
Good business my friends,
Miradur
That's because GMS 2 is a general-purpose engine, not a genre-specific drop-and-go engine. Making ramps is a narrow need specific to the platformer genre, and one that isn't difficult to handle if you check out tutorials like this. And to boot, tile collisions is a top recommended result on that video. It's GameMaker, not PlatformerMaker.@FrostyCat / @Yal
So in my opinion, GameMaker is very well suited for beginners who do not have much programming experience. So you usually start with DnD. But now the legitimate question arises why a game engine from the 21st century doesn't support ramps, although a game from 1991 already did this(Sonic). Or is it officially approved that you have to buy missing standard features, buy and fix obvious bugs yourself (or buy something that fixes it)? Why you defend this model is now clear to me, it's about money and the prestige of being better than others. But YoYo certainly thinks as a company and since they live to a large extent from new customers, they surely see it a little bit differently than you (at least I hope so).
Good business my friends,
Miradur
Everything needed to incorporate slopes is already present. What's the complaint again?...
But now the legitimate question arises why a game engine from the 21st century doesn't support ramps, although a game from 1991 already did this(Sonic).
...
For those of us who've only used GML, would you be able to briefly explain what you mean by this? I googled but the explanations are either super vague or jump right into code-heavy examples and it's hard to tell if YoYo's execution of this stuff is the exact same as other languages or if trying to learn from Java tutorials is just going to throw me off (like how GameMaker's "objects" are different from other languages "objects" etc)One important note to keep in mind when exploring OOP in GMS 2.3 is to STOP thinking of it as static-type OOP found in C++/C#/Java. It is a duck-typed, JS-like kind of OOP.
Learning OOP from Java will teach you the static-typed variety of OOP, which is the most commonly taught. Static-type means every value has a developer-specified type that strictly determines whether A counts as B (e.g. if you declare int foo = 5;, you cannot turn around and put a string in foo later), and OOP means there are reusable units of code (classes) that have their own formally associated properties and actions.For those of us who've only used GML, would you be able to briefly explain what you mean by this? I googled but the explanations are either super vague or jump right into code-heavy examples and it's hard to tell if YoYo's execution of this stuff is the exact same as other languages or if trying to learn from Java tutorials is just going to throw me off (like how GameMaker's "objects" are different from other languages "objects" etc)
In GML 2020, using static means you want every instance built from the constructor to have the exact same implementation of the marked function. There are times when you want individual instances to have varying implementations, where you would NOT use static.And for you or anyone else: I'm still trying to understand what kind of situations a person would decide to use or not use "static" in their function declarations in actual application for a game, I think I understand static variables but it seems like you would pretty much always want to use static functions, but if anyone could provide an example of a scenario where you'd want to use a static function and use a non-static function in like, a Mario game or Pac-Man or RPG or something, that would be a huge help!
I feel like having function, constructor AND static, 3 new keywords that all seem to work together in various combinations for various results, is probably the most confusing leap for someone who's just been using normal GML scripts for years so it's hard to grasp at first and figure out "ok what kind of situations would I want to use these different combinations if I'm making a game instead of just doing programming concept exercises?" So any help would be awesome!
function Delayer(_action, _ticks) constructor {
action = _action;
ticks = _ticks;
static tick = function() {
if (--ticks == 0) action();
};
}
nextRoomAction = new Delayer(function() {
room_goto_next();
}, room_speed*2);
nextRoomAction.tick();
My dude, you are in the wrong thread writing to the wrong audience about the wrong problems.@FrostyCat / @Yal
So in my opinion, GameMaker is very well suited for beginners who do not have much programming experience. So you usually start with DnD. But now the legitimate question arises why a game engine from the 21st century doesn't support ramps, although a game from 1991 already did this(Sonic). Or is it officially approved that you have to buy missing standard features, buy and fix obvious bugs yourself (or buy something that fixes it)? Why you defend this model is now clear to me, it's about money and the prestige of being better than others. But YoYo certainly thinks as a company and since they live to a large extent from new customers, they surely see it a little bit differently than you (at least I hope so).
Good business my friends,
Miradur
function basic2() constructor{
static abc = 0;
static val = function(){
abc++;
show_debug_message(abc);
}
}
function test(){
var test1 = new basic2();
var test2 = new basic2();
test1.val();// output 1
test2.val();// output 1 but want to print 2
}
I traced this mentally and also expected 1 and 2 (since both test1 and test2 should in theory share the same abc and increment it once each), but like you I also saw 1 for both. You can report this as a topic on the hidden beta forum (you should have a link to that as part of your invitation), and ask if this behaviour is intended functionality or a bug.@FrostyCat
How to operate the out variable in the inner nested-function?
GML:function basic2() constructor{ static abc = 0; static val = function(){ abc++; show_debug_message(abc); } } function test(){ var test1 = new basic2(); var test2 = new basic2(); test1.val();// output 1 test2.val();// output 1 but want to print 2 }
I used the account of my friend, my id is 196514 and still for waiting.I traced this mentally and also expected 1 and 2 (since both test1 and test2 should in theory share the same abc and increment it once each), but like you I also saw 1 for both. You can report this as a topic on the hidden beta forum (you should have a link to that as part of your invitation), and ask if this behaviour is intended functionality or a bug.
26 people accepted since last Thursday, going by the posts.Here #169776 and I haven't received access yet ((
I would like to try to understand the criterion used for the priority for access to the beta...
I've filed it on your behalf and cross-linked it to your post. I will let you know if someone replies.I used the account of my friend, my id is 196514 and still for waiting.
Could you post this issue to the beta forum stuff or maybe they have realized this?
This is a bug that already been reported. It as to do with the fact that:It will show the basic2's "what the f111111111" while not the latest outside val() which throws "what the f22222222"GML:function basic() constructor{ function val(){ throw("You should call me!!!!!!"); } } function overload1(): basic() constructor{ } function overload2(): basic() constructor{ function val(){ throw("Why do you call me????"); } } function basic2() constructor{ function a(){ function val(){ throw("what the f111111111"); } } } function val(){ throw("what the f22222222"); } function test(){ var test1 = new overload1(); show_debug_message( test1.val() ); }
function basic2() constructor{
static abc = 0;
static val = function(){
abc++;
show_debug_message(abc);
}
}
function test(){
var test1 = new basic2();
var test2 = new basic2();
test1.val();// output 1
test2.val();// output 1 but want to print 2
}
This is actually NOT a bug.. that's how static is supposed to work... when you create the struct (using new) you are making the abc variable static but as soon as you call the val() function that specific instance gets a copy of the static one and changes the value.@xDGameStudios
That issue can be avoideded and understood。
But this bug is a headache without any solution right now.
GML:function basic2() constructor{ static abc = 0; static val = function(){ abc++; show_debug_message(abc); } } function test(){ var test1 = new basic2(); var test2 = new basic2(); test1.val();// output 1 test2.val();// output 1 but want to print 2 }
function basic2() constructor{
// this ASSIGNMENT is run only once (the first time you create the struct)
static abc = 0;
// this runs for every single instance
abc++;
show_debug_message(abc);
}
a = new basic2() // 1
b = new basic2() // 2
c = new basic2() // 3
d = new basic2() // 4
show_debug_message(a.abc ) // 4
show_debug_message(b.abc ) // 4
show_debug_message(c.abc ) // 4
show_debug_message(d.abc ) // 4
But this will prevent the member function to operate the member variables.......This is actually NOT a bug.. that's how static is supposed to work... when you create the struct (using new) you are making the abc variable static but as soon as you call the val() function that specific instance gets a copy of the static one and changes the value.
if you want to make a change to static variable value you need to do so in the constructor itself...
GML:function basic2() constructor{ // this ASSIGNMENT is run only once (the first time you create the struct) static abc = 0; // this runs for every single instance abc++; show_debug_message(abc); } a = new basic2() // 1 b = new basic2() // 2 c = new basic2() // 3 d = new basic2() // 4 show_debug_message(a.abc ) // 4 show_debug_message(b.abc ) // 4 show_debug_message(c.abc ) // 4 show_debug_message(d.abc ) // 4
function DebugBox(){
static _inst = noone;
if( noone == _inst ){
_inst = function(){};
_inst.Err_Interface = function(){ throw("Invalide Interface Call"); }
_inst.Err_InvalidType = function(){ throw("Invalide Type"); }
}
return _inst;
}
#macro DBG_BOX DebugBox()
function ICondition() constructor{
static val = function(){ DBG_BOX.Err_Interface(); }
}
function IConditionEle():ICondition() constructor{
_checkresult = false;
_triggercheck = true;
static reset = function(){ _triggercheck = true; }
static val = function(){
if( _triggercheck ){
_triggercheck = false;
_checkresult = check();
}
return _checkresult;
}
static check = function(){ DBG_BOX.Err_Interface(); }
}
function IConditions():ICondition() constructor{
_eles = [];
_chks = [];
static pushcondition = function(ele,chk){
_eles[array_length(_eles)] = ele;
_chks[array_length(_chks)] = chk;
}
}
function OConditionsAND():IConditions() constructor{
static val = function(){
var ret = true;
for( var i=0; i<array_length(_eles); ++i ){
if( _eles[i].val() != _chks[i] ){ ret = false; break; }
}
return ret;
}
}
function OConditionsOR():IConditions() constructor{
static val = function(){
var ret = false;
for( var i=0; i<array_length(_eles); ++i ){
if( _eles[i].val() == _chks[i] ){ ret = true; break; }
}
return ret;
}
}
function OConditionEleManager() constructor{
_eles = [];
static pushele = function(ele){
if( string_pos(instanceof(ele),"IConditionEle") != 0 ){ return DBG_BOX.Err_InvalidType(); }
_eles[array_length(_eles)] = ele;
}
static reset_eles = function(){
for( var i=0; i<array_length(_eles); ++i ){
_eles[i].reset();
}
show_debug_message(array_length(_eles));
}
}
function OConditionEle1():IConditionEle() constructor{
static check = function(){
return false;
}
}
function OConditionEle2():IConditionEle() constructor{
static check = function(){
return true;
}
}
function test(){
var mana = new OConditionEleManager();
var a = new OConditionEle1();
var b = new OConditionEle2();
mana.pushele(a);
mana.pushele(b);
mana.reset_eles();
var CondAnd1 = new OConditionsAND();
var CondOR1 = new OConditionsOR()
CondAnd1.pushcondition(a,false);
CondAnd1.pushcondition(b,true);
CondOR1.pushcondition(a,true);
CondOR1.pushcondition(b,false);
CondOR1.pushcondition(CondAnd1,true);
show_message(CondOR1.val());
}
I got a reply. Here it is:But this bug is a headache without any solution right now.
GML:function basic2() constructor{ static abc = 0; static val = function(){ abc++; show_debug_message(abc); } } function test(){ var test1 = new basic2(); var test2 = new basic2(); test1.val();// output 1 test2.val();// output 1 but want to print 2 }
So not only is there a shared quality to the static keyword, past the point of the constructor there is also a copy-on-write quality to it. The best practice would be to treat static methods/properties as read-only, not just as singular.The read of the first abs comes from the static but when it is written a member variable is written so the static value of abc remains at 0, because test1 gets a variable added called abc that has the value 1 and then test2 reads the static variable (set to 0) of abc and then that is incremented and test2 gets a variable called abc that has the value 1.
Only the constructor function itself can write to the static member variable.
if you did
before and after your invocations of .val() then you would see those changes mentioned above.GML:show_debug_message( test1 ); show_debug_message( test2 );
This is not a bug and is intended behaviour.
Russell
It won't. Member functions can operate normally on other non-static fields. The member functions themselves are not changed in the process.But this will prevent the member function to operate the member variables.......
function demo(n) constructor{
abc = [n];
static push = function(){
abc[0]++;
}
static show = function(){
return abc[0];
}
}
function test(){
var a = new demo(2);//a.abc=[2]
var b = new demo(5);//b.abc=[5]
a.push(); show_debug_message(a.show());//a.abc=[3]
a.push(); show_debug_message(a.show());//a.abc=[4]
b.push(); show_debug_message(b.show());//b.abc=[6]
b.push(); show_debug_message(b.show());//b.abc=[7]
}
function demo(n) constructor{
static abc = [n];
static push = function(){
abc[@ 0]++;
}
static show = function(){
return abc[0];
}
}
function test(){
var a = new demo(2);//abc=[2]
var b = new demo(5);//abc=[2]
a.push(); show_debug_message(a.show());//abc=[3]
a.push(); show_debug_message(a.show());//abc=[4]
b.push(); show_debug_message(b.show());//abc=[5]
b.push(); show_debug_message(b.show());//abc=[6]
}
You're right. GMS 2.3 is far more urgent.lt's not like you are awaiting a kidney transplant.
...so that all that code runs when you first make a New() from the constructor...or when you make a constructor is it purely just assigning values to variables like how defining enums is limited? I don't know what you would use this for, I'm just curious lol I assume a normal function would be fine but for a constructor...?GML:function basic2() constructor{ // this ASSIGNMENT is run only once (the first time you create the struct) static abc = 0; // this runs for every single instance abc++; // CAN OTHER CODE GO HERE?? LIKE: with (obj_someObj) { if (image_xscale > 0.5) {image_alpha = 0.1;} show_message("something"); } surf = surface_create(blah blah); surface_set_target(surf); draw_set_color(c_green); draw_text(x, y, "blah"); surface_reset(); surface_destroy(surf); // etc... static val = function() { abc++; show_debug_message(abc); } }
// --------------------------
global.shader_stack = ds_stack_create();
function shader_stack_push( _shader )
{
ds_stack_push( global.shader_stack, _shader );
_shader.use();
}
function shader_stack_pop()
{
var num = argument_count > 0 ? argument[ 0 ] : 1;
repeat ( num )
ds_stack_pop( global.shader_stack );
if ( not ds_stack_empty( global.shader_stack ) )
{
ds_stack_top( global.shader_stack ).use();
}
else
{
shader_reset();
}
}
// --------------------------
function s_shader() constructor
{
static shader = undefined;
static use = function()
{
show_debug_message( "Implementation required in dervied class" );
};
}
function s_shader_red( _strength ) : s_shader() constructor
{
static shader = shader_red;
static uniform_strength = shader_get_uniform( shader, "u_strength" );
strength = _strength;
static use = function()
{
shader_set( shader );
shader_set_uniform_f( uniform_strength, strength );
};
}
// --------------------------
global.my_red_shader = new s_shader_red( 1.0 );
global.my_dim_red_shader = new s_shader_red( 0.5 );
shader_stack_push( global.my_red_shader );
// draw
shader_stack_push( global.my_dim_red_shader );
// draw
shader_stack_pop( 2 );
You don't need to use the argument stuff... you can do this:I really wish default variables existed instead of the argument stuff
function my_func( _value ) {
_value = is_undefined(_value) ? 10 : _value;
}
Still a bit more verbose thanYou don't need to use the argument stuff... you can do this:
So any argument that is in the function, but doesn't actually get used will be passed through as undefined, which you can then check for and so keep using named arguments.GML:function my_func( _value ) { _value = is_undefined(_value) ? 10 : _value; }
function my_func( _value = 10 ) {
}
--Like this
function model_load_obj (path)
local function split_line (str)
--Do stuff
end
end
--Or this
function model_load_obj (path)
local split_line = function (str)
--Do stuff
end
end
//Like this
function model_load_obj (path)
{
var function split_line (str)
{
//Do stuff
}
}
//Or this
function model_load_obj (path)
{
var split_line = function (str) {
// do stuff
}
}
if model_load_obj is only an actual function that you run using:Are functions just definable as any other value?
Like, in Lua I can do something like this
Can I do that in GM2.3 either likeCode:--Like this function model_load_obj (path) local function split_line (str) --Do stuff end end --Or this function model_load_obj (path) local split_line = function (str) --Do stuff end end
GML://Like this function model_load_obj (path) { var function split_line (str) { //Do stuff } } //Or this function model_load_obj (path) { var split_line = function (str) { // do stuff } }
model_load_obj(path);
function model_load_obj (path)
{
// This exists inside the function call scope
var split_line = function (str) {
// do stuff
}
// You can use it like so (inside the function call)
var s = split_line(path);
}
var model = model_load_obj("Path/To/File.txt");
function model_load_obj (path)
{
// This exists both inside and ouside the function call scope (after it has been called)
split_line = function (str) {
// do stuff
}
// You can still use it like so
var s = split_line(path);
}
var model = model_load_obj("My/Path/To/File.txt");
// as the definition was not made local using the 'var' keyword it now exists outside after you call the function
split_line("Blah");
function MyFunction()
{
var t = get_timer();
get_age = function()
{
return age;
}
}
objMyFirstObject
--> [CREATE EVENT]age = 10;
MyFunction();
age
-> which is a number with value 10get_age
-> which is a method (note that I didn't say function.. because it is BOUND to this instance).t
is local to the function so it won't exist outside it.objMyFirstObject
--> [CREATE EVENT]MyFunction();
show_debug_message(get_age()); // 10
objMySecondObject
--> [CREATE EVENT]// lets create a variable name with the same name:
age = 100;
// lets get the method reference
otherObjGetAge = objMyFirstObject.get_age;
show_debug_message(otherObjGetAge()); // 10 <-- this is the value from the other instance
// this is because what you are actually doing is:
show_debug_message(objMyFirstObject.get_age());
age
it returns the one from where it is bound to.objMySecondObject
--> [CREATE EVENT]// lets create a variable name with the same name:
age = 100;
// lets get the method reference
otherObjGetAge = objMyFirstObject.get_age;
show_debug_message(otherObjGetAge()); // 10 <-- this is the value from the other instance
// because what you are actually doing is:
show_debug_message(objMyFirstObject.get_age());
// lets call our first function here too (this will create a 'get_age' method bound to THIS instance)
MyFunction();
show_debug_message(get_age()); // 100 <-- this is the age value from this instance
function demo(n) constructor{
static abc = [n];
static push1 = function(){
abc[@ 0]++;
}
static push2 = function(){
abc[0] += 2;
}
static show = function(){
show_debug_message(abc);
}
}
function test(){
var a = new demo(2);//public.abc = [2], a.abc is the public one.
var b = new demo(5);//public.abc = [2], b.abc is the public one and will not be initialed again
a.push1();//public abc[0] = 2+1, a.abc is the public one.
a.show();// show pulic abc = [3]
a.push2();//private a.abc[0] = public abc[0] + 2; a has his private abc now, the abc below is not the pulic one and be initialed from the public.
a.show();// show private a.abc = [5]
a.push1();//private a.abc[0]++
a.show();// show private a.abc = [6]
a.push2();//private a.abc[0]+=2
a.show();// show private a.abc = [8]
b.push1();//public abc[0] = 3+1, , b.abc is the public one.
b.show();// show pulic abc = [4]
b.push2();//private b.abc[0] = public.abc[0] + 2; b has his private abc now, the abc below is not the pulic one and be initialed from the public.
b.show();// show private b.abc = [6]
b.push1();//private b.abc[0]++
b.show();// show private b.abc = [7]
b.push2();//private b.abc[0]+=2
b.show();//show private b.abc = [9]
}
You can use extension with ffmpeg library.a bit oot... but any news inside the beta about a native video player?