HTML5 Issues And Differences

In this article we have compiled a list of known issues or problems that people usually meet when working on the HTML5 target platform. When compared to the rest of the GameMaker: Studio target modules, there are certain differences between how things look and work on HTML5 (and JS modules in general) and what you may expect. These differences will also vary depending on whether you have WebGL enabled for the target or not. In general, with WebGL enabled, your game should run almost exactly the same as it would for the other target modules like Windows or Android and it is recommended that you leave this option to either Enabled or Automatic in the Global Game Settings.

Running The index.html Locally

It is not recommended that you run your index.html file locally (ie: from your own computer) as you will find that things do not work as expected. In fact, trying to run the game locally will show a warning dialogue advising you to use a web server setup instead.

This is because browsers will fail to load assets or run your game due to of cross-site scripting, often shortened to XSS, which is a protection system within the browser designed to block a website's code affecting a local machine negatively. If the html file is local, it will be very strict with the protection. Typically, this will result in your game assets failing to load and possibly your game code being ignored also, leading to crashes, however the major browsers do differ in how strict they enforce this and your game may run. If you would like to read up on the details of XSS, start here: http://en.wikipedia.org/wiki/Cross-site_scripting.

Text/Sprites/Backgrounds do not colour correctly

If you do manage to get your game running locally, you may then experience issues with your images (text, backgrounds and sprites) not being drawn or coloured correctly. Image blending isn't actually available in HTML5, so GameMaker: Studio "cheats" a little and copies the image, locks its pixels, and re-colours that using JavaScript code to blend every pixel individually. There are a few tricks involved in the engine to speed to speed things up, but being able to get at the bits of an image is vital for this to work.

However... certain browsers (like Firefox and Chrome) have security settings which don't let us modify images when they have been loaded from a local source. They deem this as a security threat and just don't allow it. This means that you are stuck using the original image and, on things like fonts, that means a white font. There is nothing we can do about this, and we recommend that HTML5 content be loaded via a web server, which is GameMaker: Studio comes with a web server built in for you to view your games. So rather than clicking on the file, you really should view it via the built in web server, or it will probably not look correct (ie: use the "play" button from the GMS interface).

Image Blending

If you do not have WebGl enabled, image blending on HTML5 can be a costly process. As mentioned above, GameMaker: Studio has to create copies of the sprite - one for each colour. Now, if you have, for example, a random coloured sprite using

image_blend = make_colour_hsv(random(255), 255, 255);

Then you will quickly find that your game slows down and has issues.

The solution is to use only a fixed number of colours and also to set the sprite cache for the correct number. You can get further information from the manual here: sprite_set_cache_size(). Be warned however, each sprite you colour will use memory, so you probably shouldn't just set all them to large numbers as you'll be back to having bad things happen. This also causes issues for blending fonts, so care must be taken with them as well.

Colour Gradients

If you are not using WebGL then you may notice that your forms drawn using the GameMaker: Studio functions (like draw_rectangle_colour(), for example) are being drawn with only a single fill colour. This is because gradients just cannot be done correctly on the standard HTML5 target for technical reasons. Therefore, should your game rely on these effects, you should think about either making WebGL a required option (from the Global Game Settings) or using pre-rendered sprites.

Note that this will also affect how fonts are drawn too, so without WebGL enabled you won't get any types of gradient effect for them either.

Message Boxes

Unlike windows, HTML5 message boxes are not skinable and they are fixed to 2 buttons which say "OK" and "CANCEL". You can't set the font, background, colour or number of buttons, making them very limited. Normally, we would take over the game loop and write the message box using GameMaker: Studio functions, but browsers don't let you do that. This means to keep the same mechanic, we're stuck using the very simple, and basic message boxes that come with each browser.

This said.... standard message boxes really aren't a good game play experience, and if you need a message box, you should really write one yourself so that it pops up with a much better look and feel.

<, > And = Don't Give The Same Results

When doing comparisons in GameMaker: Studio, you should be aware that all numbers are actually treated as floating point values. So checking what appears to be an integer value may give different results on different platforms, and this is especially true of the HTML5 target which has less precision than, say, the Windows target. For example, you maybe want to check the image index of a sprite with an image speed of 0.5. you would expect that by adding o.5 each step, every second step the image_index would have an integer value... but it may not.

0.5 + 0.5 does not equal 1 with floating point maths, and it may be that 1 is actually 1.000000000001 or something, so the the expression will never return true. If you want to find out more about why this happens, see the article here: http://floating-point-gui.de/

There are a number of ways to get around this. You can check to see if a value is greater than or equal to another, or you can use the floor() or round() functions to generate a fixed integer value.