YoYoGames / GameMaker-Bugs

Public tracking for GameMaker bugs
24 stars 8 forks source link

In-Game: [HTML5] Bug in the static context, possibly introduced by #7537 #7610

Closed biyectivo closed 1 month ago

biyectivo commented 1 month ago

Description

(sorry for the long text)

New runtime 2024.8.1.218 has introduced a new bug in the static context for HTML.

Context

This was discovered by tests I've been running trying to use Scribble and Input libraries in HTML.

The last number of runtimes (and specifically 2024.8.0.216) fixed some bugs that allowed Scribble to run again in HTML5. I reported bug #7537 because I traced crashes in the Input library and that has now been successfully fixed.

Bug

The latest runtime, 2024.8.1.218 seems to have introduced a bug with the static context in HTML5. The symptom was that Scribble stopped working again, however I managed to get it working. Specifically, the original code was, in the Draw event:

scribble("Hi world").draw(10, 10);

which just draws the string. However, this failed in HTML5 in the latest runtime (works in the other platforms I've tested - Windows, GX.games, Android). After debugging for a little bit, I found out that the following DOES work:

var _ref = scribble("Hi world");
_ref.draw(10, 10);

After further diagnosing I saw that Scribble basically does this:

1) it has a "factory" function named scribble which returns a new constructed struct from the constructor __scribble_class_element. 2) said constructor has a static method draw 3) the static method draw calls another static method __get_model before actually submitting the vertex

What I did is recreate that behavior without Scribble using a simple constructor class and a factory function:

function __scrib_class(_x) constructor { // Actual constructor
    self.x = _x;
    self.info = function() {
        show_debug_message(self.x);
    }

    self.ext_info = function() {
        self.info();
    }

    static get_model = function() {
        show_debug_message(self.x);
    }
    static draw = function() {
        get_model();
    }
}

function scrib(_x) {    // "Factory" function
    return new __scrib_class(_x);
}

After this, I created tests that create structs and call the methods with three distinct approaches:

1) Directly using new to create a constructed struct and calling the methods; 2) Creating a ref to store the constructed struct and then calling the methods with the ref; and 3) Using the "factory" function that returns a constructed struct and chaining the method call.

The tests are described below in the "Steps to Reproduce" as well as in the included project, but the summary is that 1 and 2 work in all platforms, 3 for statics either returns the incorrect value or fails in HTML5 with the latest runtime (which is essentially what happens when trying to use Scribble).

Lastly, I figured out that the root cause seems to be that the static context in #3 is the OBJECT instead of the constructor class. This is why I created an x variable of the constructor, which has the same name as an existing variable of the object. If you run #3 in the previous runtime, it returns the correct value (same value as other platforms too) and does not crash. If you run it in the latest runtime, it will return the x value of the object instead, and the last call will crash.

Steps To Reproduce

I included the sample project, but in case you want to recreate it from scratch:

1) add an object and add the code above to the Create event 2) add these tests:

// Tests

show_debug_message("-----------------------------------------------------------------------");
show_debug_message("1 Directly call the constructor and chain each method call");
show_debug_message("1.1 Info - call a normal method");
(new __scrib_class(123)).info();
show_debug_message("1.2 Ext Info - call a normal method from another normal method");
(new __scrib_class(123)).ext_info();
show_debug_message("1.3 Get Model - call a static method");
(new __scrib_class(123)).get_model();
show_debug_message("1.4 Draw - call a static method from another static method");
(new __scrib_class(123)).draw();

show_debug_message("-----------------------------------------------------------------------");
show_debug_message("2 Assign to a variable then call the methods");
var _ref = new __scrib_class(123);
show_debug_message("2.1 Info - call a normal method");
_ref.info();
show_debug_message("2.2 Ext Info - call a normal method from another normal method");
_ref.ext_info();
show_debug_message("2.3 Get Model - call a static method");
_ref.get_model();
show_debug_message("2.4 Draw - call a static method from another static method");
_ref.draw();

show_debug_message("-----------------------------------------------------------------------");
show_debug_message("3 Using a 'factory' function that returns a constructed struct and chain each method call");
show_debug_message("3.1 Info - call a normal method");
scrib(123).info();
show_debug_message("3.2 Ext Info - call a normal method from another normal method");
scrib(123).ext_info();
show_debug_message("3.3 Get Model - call a static method"); // Wrong static context in HTML5 2024.8.1.218! targeting the object's x instead of the constructed struct's x  /   Correct static context in 2024.8.0.216
scrib(123).get_model();
show_debug_message("3.4 Draw - call a static method from another static method"); // Throws error in HTML5 2024.8.1.218, since the static context is the object's and not the constructed struct, thus it cannot find the method  /   Works with correct static context in 2024.8.0.216
scrib(123).draw();

Which version of GameMaker are you reporting this issue for?

IDE v2024.8.1.171 Runtime v2024.8.1.218

Which operating system(s) are you seeing the problem on?

Windows 10.0.22631.0

Which platform(s) are you seeing the problem on?

HTML5

815bbde5-abfa-48ba-b0b3-eec698853caf

Grisgram commented 1 month ago

Can confirm this. In my raptor library i have like some dozen places like those shown above, things like var x = new Animation(foo,bar).run_delayed(...) <-- the ".run_delayed" does not work in html 5, when the former call in the chain is a constructor function.

YYDan commented 1 month ago

Scribble not working on HTML5 is already covered in https://github.com/YoYoGames/GameMaker-HTML5/issues/519 for 2024.10, so I wonder if this is related/the root cause of that issue.

biyectivo commented 1 month ago

Scribble not working on HTML5 is already covered in YoYoGames/GameMaker-HTML5#519 for 2024.10, so I wonder if this is related/the root cause of that issue.

Not entirely sure (different symptom but could be the same root issue) but If you can add it to a beta soon it would be great, to make sure it fixes both Grisgram and my issue. Thanks

Grisgram commented 1 month ago

Thing is, it's not only scribble -- it's more "entire gml, as soon as you use constructors". tbh, for my taste, it's too big to let go for two months.

rwkay commented 1 month ago

I cannot repro the bug in the current HEAD of 2024.10/2024.11

biyectivo commented 1 month ago

I cannot repro the bug in the current HEAD of 2024.10/2024.11

Can we test in the upcoming beta? When is that due?

YYDan commented 1 month ago

"Soon" - exact dates are not given.

alicemoretti commented 1 month ago

@biyectivo @Grisgram I was unable to reproduce the issue in the current Beta (Beta IDE v2024.1100.0.626 Runtime v2024.1100.0.652). Can you please confirm if that is the case for you as well?

Thank you.

biyectivo commented 1 month ago

@biyectivo @Grisgram I was unable to reproduce the issue in the current Beta (Beta IDE v2024.1100.0.626 Runtime v2024.1100.0.652). Can you please confirm if that is the case for you as well?

Thank you.

For me it is indeed working in the aforementioned beta IDE/runtimes! Great news! I will keep testing but sounds good.

alicemoretti commented 1 month ago

Closing as per comments. Thank you.