GameMaker Studio is a great tool but still leaves room for improvement when exporting games to HTML5.

If you want to know how to improve mobile touch, resolution and performance for your Game Maker games for HTML5, these two steps will help:

Optimising the default index.html file

Game Maker uses a default index.html file when exporting to HTML5. You can use their one as a template and replace it with your own custom one by adding it to the /datafiles directory in your project, and then selecting it from Game Options>HTML5>General “Included file as index.html”

HTML5 Settings in Game Maker

Mobile touch

On Google Chrome and Safari on iOS, when tapping on a default Game Maker HTML5 game the whole game canvas is selected as shown in this video:

Adding these CSS rules to your index.html file will stop that behaviour:

CSS
body {
    -webkit-touch-callout:none;
    -webkit-user-select:none;
    -khtml-user-select:none;
    -moz-user-select:none;
    -ms-user-select:none;
    user-select:none;outline:0;
}
canvas {
    -webkit-touch-callout:none;
    -webkit-user-select:none;
    -khtml-user-select:none;
    -moz-user-select:none;
    -ms-user-select:none;
    user-select:none;
    outline:0;
    -webkit-tap-highlight-color:rgba(255,255,255,0);
}

When tapping and holding down, iOS can still show a magnified preview. To stop that we can add some javascript to our file just below the <div class="gm4html5_div_class" id="gm4html5_div_id"></div> tag:

HTML
<script>
    document.addEventListener('touchstart', e => {
        e.preventDefault();
    }, { passive: false })
</script>

Resolution

To match the game resolution to your device, you can use javascript to update the meta viewport tag. Place this code in the same script added above:

JavaScript
document.querySelector("meta[name=viewport]").setAttribute('content', 'width=device-width, initial-scale=' + (1 / window.devicePixelRatio) + ', maximum-scale=1.0, user-scalable=0');

This will scale the game down to match the device width, but only scale it up to the maximum game resolution, avoiding blurry upscaling.

To center the game in the browser window, we can add some more css:

CSS
.gm4html5_div_class {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
}

Full example of custom HTML document

Here’s the full example – note you will have to change the filename ‘myAwesomeGameName’ in the second last script to your game name:

HTML
<!DOCTYPE html>
<html lang="en">
    <head>
        <!-- Generated by GameMaker:Studio http://www.yoyogames.com/gamemaker/studio -->
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta http-equiv="pragma" content="no-cache"/>
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <meta name ="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
        <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
        <meta charset="utf-8"/>

        <!-- Set the title bar of the page -->
        <title>Created with GameMaker</title>

        <!-- Set the background colour of the document -->
        <style>
            body {
                background: #0;
                color:#cccccc;
                margin: 0px;
                padding: 0px;
                border: 0px;
                -webkit-touch-callout:none;
                -webkit-user-select:none;
                -khtml-user-select:none;
                -moz-user-select:none;
                -ms-user-select:none;
                user-select:none;outline:0;
            }
            canvas {
                image-rendering: optimizeSpeed;
                -webkit-interpolation-mode: nearest-neighbor;
                -ms-touch-action: none;
                margin: 0px;
                padding: 0px;
                border: 0px;
                -webkit-touch-callout:none;
                -webkit-user-select:none;
                -khtml-user-select:none;
                -moz-user-select:none;
                -ms-user-select:none;
                user-select:none;
                outline:0;
                -webkit-tap-highlight-color:rgba(255,255,255,0);
            }
            :-webkit-full-screen #canvas {
                 width: 100%;
                 height: 100%;
            }
            div.gm4html5_div_class
            {
              margin: 0px;
              padding: 0px;
              border: 0px;
            }
            /* START - Login Dialog Box */
            div.gm4html5_login
            {
                 padding: 20px;
                 position: absolute;
                 border: solid 2px #000000;
                 background-color: #404040;
                 color:#00ff00;
                 border-radius: 15px;
                 box-shadow: #101010 20px 20px 40px;
            }
            div.gm4html5_cancel_button
            {
                 float: right;
            }
            div.gm4html5_login_button
            {
                 float: left;
            }
            div.gm4html5_login_header
            {
                 text-align: center;
            }
            /* END - Login Dialog Box */
            :-webkit-full-screen {
               width: 100%;
               height: 100%;
            }
        </style>
    </head>

    <body>
        <div class="gm4html5_div_class" id="gm4html5_div_id">
            <script>
                document.addEventListener('touchstart', e => {
                    e.preventDefault();
                }, { passive: false })

				document.querySelector("meta[name=viewport]").setAttribute('content', 'width=device-width, initial-scale=' + (1 / window.devicePixelRatio) + ', maximum-scale=1.0, user-scalable=0');
            </script>
            <!-- Create the canvas element the game draws to -->
            <canvas id="canvas" width="1366" height="768" >
                     <p>Your browser doesn't support HTML5 canvas.</p>
            </canvas>
        </div>

        <!-- Run the game code -->
        <script type="text/javascript" src="html5game/myAwesomeGameName.js?C=0"></script>
        <script>window.onload = GameMaker_Init;</script>
    </body>
</html>

Adjust settings in GameMaker

Graphics are a big reason for performance slow-downs.

Make sure to properly size your game assets, taking into account the smaller screens for mobile (1920×1080 may be too large depending on your game).

Limit using blend_modes (unless using WebGL) as they are expensive to run on HTML5. From the docs: “When performing image blending, HTML5 cannot do it dynamically in the same way an executable could be performed. Therefore GameMaker has to temporarily save a blended copy of the image and load it in.”

To keep your game speed consistent across devices with different hardware and refresh rates, using delta time instead of the built-in room_speed can help.

Reduce texture page swaps

All your game sprites are packed together over 1, usually more, texture pages. When the game requests a sprite on page 2, it has to load the whole file which slows it down.

Under Tools>Texture Groups, you can manually add texture pages (groups):

Texture Groups in Game Maker

Then in each sprite adjust which page it’s on, aiming to keep related sprites together:

Each sprite has a ‘Texture Settings’ menu where you can choose which Group the sprites texture is stored

A handy function in Game Maker to see when texture pages are loaded is texture_debug_messages(true);

Dynamic texture pages can also be used to load resources only when they’re needed.

Conclusion

There are many steps you can take to fix problems with the HTML5 export, hopefully YoYo Games continues to improve the HTML5 export and provide more value for the HTML5 platform.


Further Reading

Comment

Note: Comments are moderated, URLs not permitted.