How to mock and test game UI made with Coherent GT in Google Chrome?
One of the neat features of the newly released Coherent GT 1.1 is the support for what we call ‘browser mocking’. Iteration time has always been very fast with any of the Coherent products but now with this new feature we take it a step further. ‘Mocking’ refers to the ability to decouple your UI from the game and test it independently while still being able to see how the UI will interact with it, albeit with dummy data.
A problem we have encountered while working with designers is that naturally, they would like to test their HTML5-based UI in a browser. Besides being a familiar environment, testing the UI in Chrome provides great advantages over testing the UI in the game itself, such as:
-
- Clear separation of UI and game logic
This improves code modularity as bad dependencies can be easily detected.
-
- Much faster iteration time
Testing the UI in the game under normal circumstances requires (re)starting the game and navigating to the level or area that the UI is used in whereas pressing F5 in the browser suffices to get the job done.
Of course, there’s one big problem with running your code in the browser, namely that you cannot see how your UI behaves when there’s noone to trigger your events or update your data! Sure, you can manually call whatever functions are necessary and generate dummy data but that adds complexity to the problem.
Well, with Coherent GT 1.1 we bring two major improvements of the user experience when testing pages built for Coherent GT in Chrome. The first is that coherent.js will now properly detect whether it’s being executed in the browser or in a Coherent GT environment and will take appropriate action to continue working. And secondly…
coherent.mock.js
The coherent.mock.js and the accompanying coherent.css are two additional files distributed with our package which will help you easily mock your UI. They can be found under native_file_path, ue4_file_path or u3d_file_path.
Include both files in your page (with coherent.mock.js included after coherent.js and after the <body> tag has been created):
1 2 3 4 5 6 7 8 9 10 |
<!DOCTYPE html> <html> <head> <link href="coherent.css" rel="stylesheet"> </head> <body> <script src="coherent.js"></script> <script src="coherent.mock.js"></script> </body> </html> |
This will create an overlay containing this panel in your page:
The panel can be used to simulate any communication running between the C++ and the JS code. To trigger any of the handlers, simply click on the name of the event / function. For example, clicking the GameStarted button will trigger the handler any handlers that you’ve attached to that event using engine.on . If you need to pass any arguments, simply write them down in the textbox next to the corresponding button, and separate them by commas. Your arguments can be any valid expression – even function expressions!
Functions are added to the overlay panel in two ways:
- If the function is a JS handler to a C++ event, attached using engine.on it will automatically appear under the Call this C++ event / function in the panel.
- If the function is a C++ handler to a JS function, it must be mocked via the newly added engine.mock function. For example, consider the following C++ function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
void StartGame() { view->TriggerEvent("GameStarted"); } // ... view->RegisterForEvent("StartGame", Coherent::UIGT::MakeHandler(StartGame)); It can be mocked by using the following JS code: // isAttached is true only when the script is executed in the Coherent GT runtime if (!engine.isAttached){ var startGameMock = function () { engine.trigger("GameStarted"); }; engine.mock("StartGame" /* The name of the event to listen for */, startGameMock /* The mock callback */, true /* True if this mock is triggered by engine.trigger. False if it should be triggered by engine.call.*/); } |
Finally, assume that this is the code that starts the game:
1 2 3 |
document.getElementById("start-game-button").addEventListener("click", function () { engine.trigger("StartGame"); }); |
With this sample code shown above, it doesn’t matter if the script runs in the browser or in the game. For all intents and purposes your UI will behave in exactly the same way when your start game button is clicked!
Tips & tricks
With great iteration time, comes great responsibility. The following list contains some things you should keep in mind when working in the browser.
- Be careful with browser-specifics properties
As Coherent GT is based on WebKit, you should use a Blink/WebKit-based browser (Chrome, Chromium, Safari). Otherwise, usage of any non-standard CSS properties and / or JS code might not work or work not as expected in the Coherent GT runtime. - Write your code with performance in mind
A browser has much different performance requirements compared to your game. Don’t be fooled into creating an animation that looks smooth in the browser but takes 16ms per frame because you’ll be setting up the stage for a nasty surprise should you try the same code in the game. - Hide the mocking panel if it gets in your way
If the mocking panel is taking too much space from your page, click the Dock me! button to squash it to the left. If that still bothers you, open your console and call engine.hideOverlay() which will hide it completely. If you later decide you want it back, call engine.showOverlay() - Mock all you want!
After you are done mocking in the browser, you don’t need to comment out all calls to engine.mock or engine.hideOverlay , they won’t do anything if the engine is attached (that is, running in the Coherent GT runtime) so mocking won’t get in your way of testing the UI in the actual game.
Did that get you excited? Revisit the list of features that we shipped in Coherent GT 1.1 to make sure you didn’t miss any other exciting new thing.
Now, go mock all your HTML and tell us what you think about it as a comment below, on Twitter or on the forums.