GMS 2 [SOLVED] camera_set_view_pos Silently Freezes on HTML5 Target

Discussion in 'Programming' started by Gunnar the Clovis, Aug 16, 2019.

  1. Gunnar the Clovis

    Gunnar the Clovis Member

    Joined:
    Apr 4, 2018
    Posts:
    4
    Hello,

    Whenever I run the function camera_set_view_pos on the HTML5 target, the game image silently freezes (meaning no errors are given). The game is still running as inputs are read and sounds can be played when inputs are made, the game can be restarted, but the image is completely frozen permanently after camera_set_view_pos is called.

    I've isolated the problem to this specific line, as when I comment it out the game functions perfectly (other than the camera not updating obviously). I do not have this error on the Windows, Mac, Ubuntu, Android, iOS, or Amazon Fire targets, only HTML5. On all other platforms the camera works perfectly as intended. This is a pretty simple boilerplate tweening camera. I've had this exact problem over multiple projects but only just pinpointed it to this function.

    The following code is all code concerning the camera. No other object references the camera object or its variables; there is no interference, everything is completely isolated, and again this runs like a dream on all target platforms except HTML5.

    obj_camera Step Event:
    Code:
    /// @desc Follow Object Within Region Bounds and Screen Shake
    
    // Update destination
    if(instance_exists(follow_target))
    {
        xTo = follow_target.x;
        yTo = follow_target.y;
    }
    
    // Update object position
    x += (xTo - x) * tween_speed;
    y += (yTo - y) * tween_speed;
    
    // Keep camera inside boundaries
    x = clamp(x, boundary_left, boundary_right);
    y = clamp(y, boundary_top, boundary_bottom);
    
    // Screen shake
    x += random_range(-shake_remain, shake_remain);
    y += random_range(-shake_remain, shake_remain);
    shake_remain = max(0, shake_remain - shake_magnitude / shake_length);
    
    camera_set_view_pos(cam, x - view_w_half, y - view_h_half);
    obj_camera Create Event:
    Code:
    /// @desc Initialize Camera and Screen Shake
    
    #macro NO_CAMERA_ASSIGNED -1
    if(view_camera[0] == NO_CAMERA_ASSIGNED)
    {
        view_camera[0] = camera_create_view(0, 14592, 1024, 768);
        show_debug_message("NEW CAMERA CREATED");
    } else show_debug_message("NO NEW CAMERA CREATED");
    
    // Basic camera properties
    cam = view_camera[0];
    tween_speed = 0.14;
    view_w_half = camera_get_view_width(cam) * 0.5;
    view_h_half = camera_get_view_height(cam) * 0.5;
    follow_target = obj_player; // Object for the camera to follow
    
    // Camera boundaries
    boundary_left = view_w_half;
    boundary_right = room_width - view_w_half;
    boundary_top = view_h_half;
    boundary_bottom = room_height - view_h_half;
    
    // Snap to follow target
    x = follow_target.x;
    y = follow_target.y;
    
    // Snap camera inside boundaries
    x = clamp(x, boundary_left, boundary_right);
    y = clamp(y, boundary_top, boundary_bottom);
    
    // Set our next position to our current position
    xTo = x;
    yTo = y;
    
    // Screen shake properties
    shake_length = 0;     // in frames
    shake_magnitude = 0; // in pixels
    shake_remain = 0;     // in pixels
    And here are some screenshots for good measure:

    https://imgur.com/a/XJytl0Z

    Study of Docs
    I've studied the docs quite heavily, specifically the general cameras page and the page on camera_set_view_pos and related functions; I can't find anything that references some special use case or requirements for HTML5 or what might be causing this specific issue.

    Setup of Room
    This is a very simple game project this is running in, with virtually no moving parts (just a player with its isolated internal movement, lifeless blocks with no code for the player to collide against, and this camera), though it's the exact same in other, much larger projects. The room has Viewports Enabled, does not have Clear Viewport Background enabled (though I've tried it with it on just to test), Viewport 0 is visible (the only viewport used), the camera and viewport have the same dimensions, there is no object following. Again, this exact code and build works perfectly on all platforms besides HTML5.

    Research into This Problem
    I extensively researched this forum and various others for an answer to this issue, and was unable to find any. The only other case I can find online of someone with the same problem as me is the thread below, which features the exact same issue as far as I can tell but offers no real solution. I tried to follow the one answerer's thought process, but their suggestion gave no help. I did add the "if(view_camera[0] == NO_CAMERA_ASSIGNED)" code as per their idea that the camera was not valid, but this gave no change, as on all platforms (including HTML5) the camera already existed on "view_camera[0]", so "cam = view_camera[0];" always returned successfully and all calculations afterward were valid.

    https://forum.yoyogames.com/index.php?threads/html5-freeze-bug.48169/

    Errors Thrown
    This issue has never thrown any errors to the console for me, and when I've printed out the associated variables at all stages, they all are in order. On the HTML5 platform I correctly looked at the Console Output within the Web Browser Developer Tools, which consistently outputted the exact same thing as the GameMaker Studio 2 console for Windows builds, etc.

    Things I've Tried
    • As I said, I added the code to create a new camera if one did not exist, but this turned out to be not of any import since the camera always existed on view_camera[0] by default.
    • I've made a toggle to make the camera_set_view_pos line run or not based on whether I hit the spacebar, and this further confirmed much of what I said prior, how this specific line freezes the game, how the game functions perfectly when this line is never run, but as soon as it's run once the game freezes permanently on the HTML5 platform.
    • I've printed all variables to the command console, and they all were correct and as expected.
    • I've initialized cam to noone and its associated variables (view_w_half, the boundary variables, etc.) to 0 initially, and then set cam to view_camera[0] and calculated the associated values in the Step event if cam == noone, instead of in the Create event, in case the game needed the Create event/Game Start event to sort itself out before being able to do this on the HTML5 platform for whatever reason.
    • I've commented out just the camera_set_view_pos line, which again makes the game run normally on all platforms except for the camera not working due to the lack of this line.
    • I've removed the camera object, which expectedly acts the same as the above test.
    • I've added the camera back in, to no change, ensuring that this isn't some freak problem with just this one specific placed instance of the camera.
    • I've removed or disabled the camera object and instead used the built-in Object Following feature from the Room Editor, which behaves normally and as expected across all platforms.
    • I tried enabling Clear Viewport Background in the Room Editor.
    • Probably some other quick tests I've forgotten.
    Any help would be immensely appreciated. This is a huge problem for me across multiple projects when porting to HTML5, which is hugely important for itch.io online game jams, and growing in importance for my day-job as well. I've thrown my head against the wall on this for a while and am pretty stumped at the time of this writing.

    Thank you for reading and your help,
    [​IMG]
     
  2. Gunnar the Clovis

    Gunnar the Clovis Member

    Joined:
    Apr 4, 2018
    Posts:
    4
    I have stumbled across the solution in my experimentation! Thanks to Chrono Vortex on the GameMaker Discord (https://discord.gg/By6u9pC) for helping me out and sending me down the path to finding this solution.

    To fix the problem, simplify add
    Code:
    if(shake_remain > 0)
    to the block of screenshake code in the Step Event. This is a minor optimization on all other platforms other than HTML5, as the code to add a random value between -shake_remain and +shake_remain was always returning 0 when shake_remain was 0 (
    Code:
    random_range(-0, 0)
    ), meaning screenshake was currently unused, as was the case in all of my testing. It makes no difference... except on HTML5. For whatever reason with HTML5's wonky math problems (as JavaScript is prone to), when the value returned from random_range(-0, 0) was added to the obj_camera's x & y variables, and then those x & y variables were used in camera_view_set_pos, the game was freak out, freeze, and crash. I assume it has something to do with -0 and JavaScript having a math-panic attack. Placing this screenshake code block in an if-statement check to ensure this doesn't happen fixes the problem perfectly.

    Code:
    if(shake_remain > 0)
    {
       // Screen shake
       x += random_range(-shake_remain, shake_remain);
       y += random_range(-shake_remain, shake_remain);
       shake_remain = max(0, shake_remain - shake_magnitude / shake_length);
    }
    
    camera_set_view_pos(cam, x - view_w_half, y - view_h_half);
    While this is a fixable and avoidable problem, this certainly isn't expected or desired behavior on the part of the HTML5 exporter, so I believe I will still file a bug report per Chrono Vortex's suggestion.
     
  3. Ricardo

    Ricardo Member

    Joined:
    Jun 20, 2016
    Posts:
    178
    Great discovery! I've got some random crash reports from players that I never was able to reproduce, and I just noticed my project also uses camera_set_view_pos for a screen shake effect.
    Have you filled a bug for this issue yet? This kind of unexpected and hard-to-debug problems have to be properly reported.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice