Using hxscout with Snow/Luxe

sign up sign in

Update 1/8/2015: Added some tips on how to get going at the end of the post
Update 22/10/2015: Made snowhxt as a convenience - Sven

hxscout is a neat little hxcpp/flash profiler developed by Jeff Ward which allows you to profile frame time, object allocations and gc usage. This is particularly useful when working on mobile targets where GC can become an issue and result in long frame times.

A word of advice: Unless you are experiencing performance issues, don't waste your time hunting every little allocation. It's pretty much an unavoidable problem to some degree.

So how can we get it up and running with Snow/Luxe? Thankfully the instructions the official website are fairly comprehensive.

Environment Setup

First go and download the appropriate version of hxscout from their website and install it. Next, we need to make a couple of changes to the haxe dev environment:

1. hxtelemetry

You need hxtelemetry installed. Run this in your cmd line:

haxelib install hxtelemetry

2. hxcpp

In order to use hxscout you currently have to work with the dev version of hxcpp. Clone the latest from github to a folder of your choice. Then we need to tell haxelib to work with this version of hxcpp:

haxelib dev hxcpp /path/to/repository

(note: if you want to reverse the above, simply type haxelib dev hxcpp to disable the dev mode)

Next we need to rebuild hxcpp for our platform. Navigate to the hxcpp repository folder in your cmd-line change to the project folder. Run neko build.n

Project Configuration

Once you have your dev environment setup we need to make a few adjustments to the project setup to get hxtelemetry working.

1. Update the .flow file

If you are using snow/luxe you are probably familiar with flow. Flow is the underlying build system that is being used whenever you build/run a snow/luxe project. Open up your project's flow file and you'll typically find something like this:

project : {  
    name : 'luxe.draw',
    version : '1.0.0',
    author : 'luxeengine',

    app : {
      name : 'luxe_test_draw',
      package : 'com.luxeengine.testdraw'
    },

    build : {
      dependencies : {
        luxe : '*',
      }
    },

    files : {
      assets : 'assets/'
    }
  }

The section that's of interest to us is the 'build' object. We add hxtelemetry as a dependency to the project:

...
    build : {
      dependencies : {
        luxe : '*',
        hxtelemetry : '*'
      }
    },
...

Next we define two compiler flags that will tell hxcpp to output telemetry data. The full build section should look like this now:

...
    build : {
      dependencies : {
        luxe : '*',
        hxtelemetry : '*'
      },
      defines:['HXCPP_STACK_TRACE','HXCPP_TELEMETRY']
    },
...
2. Update main loop file

The last step is to include a few calls in the application's entry point. In luxe/snow you typically have a main.hx with a class that extends luxe.Game or in case of snow snow.App. A very barebones version would look like this:

class Main extends luxe.Game {

    override function ready() {
        // ... all your init code
    }

    override function update(dt:Float) {
       // ... all your update code
    }
}

This is where you want to add a couple of things to make hxtelemetry send data to hxscout:

class Main extends luxe.Game {  
    var hxt:hxtelemetry.HxTelemetry;

    override function ready() {
        // ... all your init code

        var cfg = new hxtelemetry.HxTelemetry.Config();
        cfg.allocations = true;
        cfg.app_name = "Luxe";
        hxt = new hxtelemetry.HxTelemetry(cfg);
    }

    override function update(dt:Float) {
       // ... all your update code

       hxt.advance_frame();
    }
}

And that's it. hxtelemetry will do the rest of the magic.

3. Profile!

Now that you're ready to start profiling, make sure you run the hxscout app first as you'll otherwise get an error when running your luxe/snow app. Once hxscout is running run your luxe/snow app and switch to hxscout. You should start seeing frame times, object allocations etc. come through:

This quick write-up describes a very barebones integration with hxscout. There's a lot more that can be done with activities etc. Maybe I'll go into that in another write-up. I'm sure luxe/snow will one day support integration with hxscout out of the box, so all this might not be necessary for too much longer :)

If you think hxscout is a useful tool, consider supporting the dev on his patreon.

Jeff added some useful tips to get going in the comments below, here they are for reference:

- Using the UI: Select some frame(s) to view the statistics for those of those frame(s).

- Look in the profiler tab for items taking the most self time. Try: expand all, turn off hierarchy, sort by self time, select a row (must click on text), then turn hierarchy back on.

- The GC runs periodically, typically indicated by red spikes in the timing graph. Select a frame with a red spike and look in the collections tab for items being thrown away in large quantities.

- Allocation tracking is most expensive and causes runtime overhead, if you're not looking at allocations/collections specifically, you can turn it off (leaving the profiler, activities, trace.)

Any problems/questions, let me know :)

Tags
snowluxehxscouthxtelemetry