Bruchpilot
Member
This warrants a second press release.a feckin' strawberry milkshake, and he's not dropping it on a server.
This warrants a second press release.a feckin' strawberry milkshake, and he's not dropping it on a server.
I do realize that functions and scripts are nearly identical in function. The thing that I worry about is if functions will be indexed. For example right now I can easily find every script with a specific name prefix by looping through script IDs and checking their names. Will this be possible in 2.3 with functions? Right now many aspects of my game are defined by scripts with specific names.The image was here but it's taken down: http://www.mcvuk.com/.image/c_limit,cs_srgb,fl_progressive,q_auto:good/MTU5MzQzMzA2Mjc3Mzk4MTEy/gms2_sequences_press.jpg
From what I remember new resource among sequences was named "Animation Curves". Not sure what those are, but I believe it might be a resource similar to path, where you can define interpolation (so put a value on y-axis, where x-axis is always between 0 and 1). So you can define lines/curves and then use them to animate (tweening), for speed/percentage of changes between frames, so they aren't linear between A and B values. They seems to be separate resource so can be used outside of sequences too, so you can read values of those interpolations using gml too.
Might be a nice addon, however for non-sequence usage this can be easily done now using paths, or even just scripts (for some most-known easings, like bounce, quad, sin, etc., there are just mathematical functions - you will find those on marketplace in all tweenings examples, or can even reuse code from known JS libaries - it's not hard to rewrite it to GML).
Another example of how complex 2.3 update will be.
Let's say, you have "script0", which code is:It will become:Code:return argument0 + 5
More complex:Code:function script0(argument0) { return argument0 + 5; } // can be simplified manually to: function script0(a) { return a + 5; }
will become:Code:var a = argument[0], b = (argument_count > 1) ? argument[1] : 0; return a + b;
Nothing to break here on project opening, while in my opinion change is massiveCode:function script0(){ var a = (argument_count > 0) ? argument[0] : undefined, b = (argument_count > 1) ? argument[1] : 0; return a + b; }
I don't think they made a big improvement here, so same as you define variable in objects now and it's then coloured in all others (even if not yet defined for another object), same all variables from structs and function constructors will be colored everywhere (maybe only after a dot) as a regular variable, as it's hard to guess what function is assigned to which variable dynamically. Still, if you use "var" in same block of code, it will have different color then (yellow by default?). So no big changes here probably, except for new syntax (so keywords like struct/function/constructor/new).how documentation will be handled..
for example functions internal to light-weighted objects will they have autocomplete?
function A() {
// constructor for 'A' object
foo = 0;
bar = 1;
func = function() {
// stuff
}
};
function B() {
// constructor for 'B' object, inherits 'A'
A();
};
var a = new A(); // instance of 'A'
var b = new B(); // instance of 'B,' which inherits 'A'
var c = is_ancestor(a, b);
function B() {
// constructor for 'B' object, inherits 'A'
A();
func = function() {
base.func(); // or in any other way.... A.func()
// do stuff
}
};
You should be able to call a base method from a derived.Keeping on topic, one thing I didn't quite understand is the inheritance regarding lightweight objects.
Will inheritance features be a thing?!
I know we can probably do something like:
as stated by @NuxCode:function A() { // constructor for 'A' object foo = 0; bar = 1; func = function() { // stuff } }; function B() { // constructor for 'B' object, inherits 'A' A(); }; var a = new A(); // instance of 'A' var b = new B(); // instance of 'B,' which inherits 'A'
but will this give us the ability to do stuff like?
or even call a base method from within a "derived" lightweight object?Code:var c = is_ancestor(a, b);
I put this into consideration because even if you change the light object after you create it (modify the instance), its "prototype" is static so the functions/variable definitions are there.Code:function B() { // constructor for 'B' object, inherits 'A' A(); func = function() { base.func(); // or in any other way.... A.func() // do stuff } };
"A.func()" seems to be a valid approach, to me.
function A(x) {
a = x;
b = function() { return 7;}
}
function B(x, y) : A(x) {
// we already have a and b, if we want to rewrite b, probably the way is:
c = b; // assign old function to another variable
b = function() {
var _parent = c(); // this should be a parent function in fact
return _parent + 2;
}
}
(I wouldn't know, I was offered to join the beta but I haven't heard back from them since )
The reassignment will pollute the Lightweight object won't it?!There might be no constructors per se. That's why the called it structs created by function, or lightweight objects, not class. A constructor is a whole body of function like this, so when something will inherit, then "parent" code is executed first, then child. To override parent method, you probably need to do it this way:
That's how I see it.Code:function A(x) { a = x; b = function() { return 7;} } function B(x, y) : A(x) { // we already have a and b, if we want to rewrite b, probably the way is: c = b; // assign old function to another variable b = function() { var _parent = c(); // this should be a parent function in fact return _parent + 2; } }
function A() {
// constructor for 'A' object
foo = 0;
bar = 1;
func = function() {
// stuff
}
};
function B() {
// constructor for 'B' object, inherits 'A'
A();
func = function() {
A.func();
// NEW STUFF
}
};
A.func();
Ah, so that's what happened to struct suddenly becoming a reserved keyword a couple of years ago. I knew that was fishy.Wee FYI: There are no "lightweight objects" in the update. They're being called by their proper name which is "structs", so you should get used to using structs instead of LWO.
WOOWWee FYI: There are no "lightweight objects" in the update. They're being called by their proper name which is "structs", so you should get used to using structs instead of LWO.
a = struct {
v: 5,
s: "text"
}
function b() { // alternative: b = function() {
v = 5;
s = "text";
}
c = new b();
// we can get values by using: a.v, a.s, c.v, c.s, but not by b.s and b.v
I'm guessing probably, the function is just for functions and struct is just for "LWO".I'm wondering, wouldn't it be a mess:
if we call both "structs" just because we can access variables from them, while have different syntax. It looks weird.Code:a = struct { v: 5, s: "text" } function b() { // alternative: b = function() { v = 5; s = "text"; } c = new b(); // we can get values by using: a.v, a.s, c.v, c.s, but not by b.s and b.v
function b() { // alternative: b = function() {
v = 5;
s = "text";
}
b();
struct b() { // no alternative {
v: 5,
s: "text"
}
var c = new b();
var a = struct {
a: 2,
b: "hello"
}
We can make value objects with LWO's. So probably; yes we can make very slow and cumbersome datatypesAny plans for smaller datatypes like int32 or char?
At least with what we know now, it just doesn't make sense.So basically, no. I do think the engine is moving more and more towards (real) native datatypes though..
Why? Internally the variable will still be a union of all possible types, so it would take just as much space!Well a smaller datatype would be useful in large grids eg obstacle maps.
You mean like a dllOne way I see this happening is by adding a new resource type much like "shaders" where we could code at lower level
I was leaning more towards strict types like integer, float, string, array, null, perhaps boolean and the like. Typehinting in objects as well as interfaces / extendability and visibility would be awesome. But we're a long road from that.We wouldn't see any real world benefits from smaller types.
Exactly BUT all built into the IDE and with automatic cross-compilation to all platformsYou mean like a dll
Yes, keep crushing my dreamsWhy? Internally the variable will still be a union of all possible types, so it would take just as much space
I too think strict typing will help with hinting and catching problems at compile time, that has never been my objection (in fact that isn't even my quote, it's GMWolf's). But it's perfectly possible to talk about strict typing without talking about non-Boolean sub-32-bit types such as bytes and shorts, which outside of integration with native libraries I also see relatively little utility.I was leaning more towards strict types like integer, float, string, array, null, perhaps boolean and the like. Typehinting in objects as well as interfaces / extendability and visibility would be awesome. But we're a long road from that.
The fact that I said I think we're moving there are based on the is_ functions https://docs2.yoyogames.com/source/_build/3_scripting/3_gml_overview/checking_data_types/index.html
Oops, I knew something was off when I clicked "insert quotes" and I saw a different text, sorry *facepalm*I too think strict typing will help with hinting and catching problems at compile time, that has never been my objection (in fact that isn't even my quote, it's GMWolf's). But it's perfectly possible to talk about strict typing without talking about non-Boolean sub-32-bit types such as bytes and shorts, which outside of integration with native libraries I also see relatively little utility.
Has strong typing been considered? Are there any future plans for it?
ANSWER - Yes. Not currently.
* When chained accessors were last discussed, the promotion of data structures to true types was stated as a prerequisite. Has this been done?
ANSWER - We have found a way to do it without that as a prerequisite, this is good as that is a lot of work that would just delay these features.
* Are any existing resource types (e.g. data structures, buffers, etc.) retrofitted to support the OOP way of initialization?
ANSWER - Not in our first iteration, we will be revamping these in the future.
var s = {
my_var: 10000;
}
s.my_other_var = 300;
var s = { }
s.var1 = 100;
s.var2 = 300;
This has already been answered in the AMA:QUESTION:
Will it be possible to define variables inside structs dynamically?
for example:
or evenCode:var s = { my_var: 10000; } s.my_other_var = 300;
Thank you so much for the time.Code:var s = { } s.var1 = 100; s.var2 = 300;
The AMA answers article said:* What happens if you set a previously inexistent field for a lightweight object after it has been instantiated? Example:
ANSWER - This will just be added to the lightweight object in the same way as it currently works in GML, the lightweight object is not sealed.Code:function Vec2(_x, _y) { x = _x; y = _y; } var foo = new Vec2(0, 0); foo.z = 0; // What will the runner do about this?
The problem with dlls is the overhead of calling them in certain cases. While calling a dll function once to calculate a path in the c++side is very fast, constantly fetching values can be cumbersome. For example, in the pathfinding example, you can have the path nodes defined as structs in c++. However in gamemaker there are cases where you need to access them outside of pathfinding multiple times, like when creating a higher-hierarchy region. Calling node_get_x() 256 times just to fetch a x value is the dll approach bottleneck.GML is a simple scripting language for writing game logic and in terms of speed it's nowhere near native code. If performance is your concern, I would recommend you to write dynamic libraries in C++ or whatever.
sorry didn't see it there, my bad!This has already been answered in the AMA:
Garbage collected like arrays.sorry didn't see it there, my bad!
Regarding room transitions... will structs be like Instances (and get destroyed) or behave like arrays and be permanent?
I'm guessing the later but just wanted to be sure!
Depending on how far you're willing to go you could create a buffer in GM that you supply to the C++ side as the whole memory that it has available and then you have access to the raw state of the DLL by poking at the buffer from GML. Just an idea I had, didn't actually test it although I'm intrigued about it's usability so I might test it soon-ishThe problem with dlls is the overhead of calling them in certain cases. While calling a dll function once to calculate a path in the c++side is very fast, constantly fetching values can be cumbersome. For example, in the pathfinding example, you can have the path nodes defined as structs in c++. However in gamemaker there are cases where you need to access them outside of pathfinding multiple times, like when creating a higher-hierarchy region. Calling node_get_x() 256 times just to fetch a x value is the dll approach bottleneck
Your idea made my smile a little.. because it's actually awesome!!Depending on how far you're willing to go you could create a buffer in GM that you supply to the C++ side as the whole memory that it has available and then you have access to the raw state of the DLL by poking at the buffer from GML. Just an idea I had, didn't actually test it although I'm intrigued about it's usability so I might test it soon-ish
I have also thought about it. It's...not a very good idea for a large project.Depending on how far you're willing to go you could create a buffer in GM that you supply to the C++ side as the whole memory that it has available and then you have access to the raw state of the DLL by poking at the buffer from GML. Just an idea I had, didn't actually test it although I'm intrigued about it's usability so I might test it soon-ish
It's not that slow either.One of the problems with the buffer is that it's not that fast to read on the GML side.
Yes, there is a thread I made about pathfinding, but of course a simulation game poses other challenges as well. But this is not about this specific project. Since this is an AMA I am asking these questions in a more general manner to see if there are any plans for GML to go that way in the future.One of the problems with the buffer is that it's not that fast to read on the GML side. Something like a "native_array", with specific C++ data type and its pointer available, would be much handier to have.
@vdweller Seems like your project has very specific needs, but we don't know much about it. Did you make a thread here, discussing the path finding problem? Or do you care to make one? We may come up with something practical if we put our heads together.
function MyAlgorithm()
{
// constructor
data = ds_map_create();
// destructor
delete = function() {
ds_map_delete(data);
}
}
var alg = new MyAlgorithm();
delete alg;
var alg = new MyAlgorithm();
alg.delete();
delete alg;
That's the worst of both worlds!Or make your own struct that wraps maps and provides these methods...
Dangling handles are a thing that YoYo had been making GM users deal with since the day it took over. That's not much of a step up from dangling pointers.Unless dangling pointers are a thing YYG are comfortable having GM users deal with (I'm sure they are not)
var s = {a: ds_map_create();}
var s = {a: 1}
ds_map_delete(s.a);
delete s;
I guess that's true.Dangling handles are a thing that YoYo had been making GM users deal with since the day it took over. That's not much of a step up from dangling pointers.