Snowkit Alpha 2 Release


Another popular Haxe based 2D game engine, Snowkit just release Alpha 2. image

The update notes are rather sprawling so I have excerpt the majority of the changes below.  Go check out the full post for even more details:


Woo, there’s a lot to cover.

I’ll state this right up top for clarity:
I believe it’s important to understand how your tools are made, and what features they offer.A lot of the changes below won’t break your game code dramatically or anything – But it’s good to pay attention to the details. It’s totally fine if a lot of this is stuff you’ll never need to interact with directly.

It’s also worth noting there are so many changes that I probably missed listing some here, or chose not to because the compiler will tell you about them. The most important stuff is covered below!

core changes

The most important change of course is that the snow core itself is now written entirely in Haxe! On native targets uses the linc libraries directly to handle the platform specifics as needed.

An important point of this is that all of the linc libraries that are dependencies of snow, are available at your disposable. For instance, you may now call SDL directly from Haxe, directly from your game. This is true for snow and luxe users of course. There are a number of new APIs available, and this aspect will continue to improve over time – but keep in mind that they change the nature of your code for the platforms you’re targeting – this doesn’t magically allow you to call SDL APIs on the web platform. The linc libraries are C++ target specific, and some of them get more specific by platform (like Desktop OpenGL calls on mobile are not viable). You have the tools to deal with that of course, but keep it in mind.

There’s is some deep diving though process below the bullet lists if you’re interested.

my favourite improvements

It’s hard to even pick from the list because of the amount of changes and improvements that have gone in but here are some of my favourites:

Debugging Haxe native code via NDK tools in Android studio

With some minor configuration Android Studio lets you debug native code and java code at the same time. Since this is about Android Studio, it’s worth mentioning the Gradle based build workflow, Android build specifics in the IDE, access to android frameworks and libraries and much more.

Zero runtime allocations by snow itself

Since the new version is significantly closer to beta than before – that goes for tightening up the performance profile of the core framework. Lots of performance improvements and consistency fixes all around.

Much tighter native integration

Having everything accessible makes a big difference, and allows much easier access to important native functionality. This is part of the much mentioned ongoing native features, and is what allowed us to easily use Android/iOS native services from Haxe without much effort at all. Here’s a teaser of a (nearly ready) linc library that leverages this for example:

Common changes
Haxe version requirements

As mentioned in a previous dev log – maintaining legacy code during alpha and active development makes no sense in practice. From this update:

  • Haxe 3.2+ is required
    • Haxe 3.1.x is no longer explicitly supported
  • hxcpp versions above 3.2.x are required

This decision while pragmatic is also dictated by Haxe and hxcpp features, there are things required in the newer code that just don’t run on older versions.

hxcpp compile cache
I’d also encourage you to try out the newer hxcpp cache features, which significantly speeds up C++ builds. They share files built by projects in a smart way, which means you only have to build files used by all your projects when they change and not every time they need to be built. Here’s an example of a clean rebuild of a snow sample that took ~4 seconds, a lot of that time spent in the Haxe compiler on the code than the c++ build.

To use it, for now you have to set an environment variable pointing HXCPP_COMPILE_CACHE to a path to use. The path must exist before it will work, so create the folder manually first.

If you have issues using this (I haven’t with months of use, across projects large and small) file an issue on the hxcpp repo with the necessary steps to reproduce.

You can set this up really easily inside of the hxcpp_config.xml file (Mac & Linux ~/.hxcpp_config.xml, Windows C:UsersUSER.hxcpp_config.xml). Just add the path as a setenv node inside the vars section.

...  <section id="vars">        <setenv name="HXCPP_COMPILE_CACHE" value="/Users/sven/.hxcpp_cache/"/>  ...  
dependency changes

Since snow now depends on a number of linc libraries – you have to install these before using the new. Luckily installing them is easy, just run the following:

haxelib git linc_openal    haxelib git linc_timestamp    haxelib git linc_stb    haxelib git linc_ogg    haxelib git linc_sdl    haxelib git linc_opengl    

It’s important to note that if you clone them directly, be sure to use git clone --recursiveand if you already cloned without that run git submodule update --init in the folders. If you don’t you’ll get build errors as the submodules files are missing.

The setup process will be more automated soon ish.

native setup stuff

snow no longer has any prebuilt components and includes the c++ directly into your app in a clean way. This removes the ndll folder and its set up step entirely, so don’t worry about that any more.

If you ran into previous Visual studio/MSVC version inconsistency issues with snow previously this should be resolved now because of the above changes too.

  • Added Desktop GL 1.0 to 4.5 APIs via linc_opengl
    • Call desktop GL directly from your Haxe code, now you can use more than just the ES2.0 portable implementation – but remember these are desktop only, for cross platform portability the best API is still the ES2.0 abstraction at snow.modules.opengl.GL like before
    • This includes GLEW API for querying versions and extensions
    • Further APIs will be added for GL ES, there might be endpoints that are incorrect and more – please see the linc_opengl readme for full details
  • Added gles profile to OpenGLProfile config for runtime checking of the rendering profile. Later this will be used to request ES on desktop like the other two (core/compatibility) are used now.
  • snow OpenGL is now fully native externs, reimplemented in linc_opengl, which is much faster, cleaner, and aligns closer to WebGL spec. It has some WIP endpoints but these will be addressed soon (nothing majorly blocking).
  • Added proper High DPI support and handling
    • ALL window related sizes in snow and luxe refer to rendering size in pixels, only
    • See the section on High DPI below for details
  • Implemented a whole new Audio API
    • added AssetAudio containing AudioData
    • implemented a new Web Audio implementation for web platform
    • very close to final API, chance of the API changing again at all are low
    • added AudioSource, AudioInstance, AudioData
    • added AudioHandle as a disposable Int for simplicity/performance
    • complete parity with native, including audio_data_from_bytes, and more
    • separated the query from the setting of attributes for clarity
    • simplified audio events, added new ones like when a source is destroyed
    • solves many issues on native, like
      • playing multiple instances from a single source
      • proper cleanup of data and sound buffers
    • encapsulates audio implementation details directly in the module
      • better portability in the abstractions
      • no more hoops and opaque types needed
      • allows modules to self contain their dependencies
    • cleaned up custom streaming interfaces
      • with added example for native
      • allows generative streaming sounds and synths efficiently
  • App clean up and consistency pass
    • moved control over main to user space
    • clarify naming of all app timing flags
    • added snow_no_main and snow_native_no_tick_sleep defines
    • made AppFixedTimestep a runtime flag, not compile time flag so you can now toggle and compare details while running
  • Leverage snow flow project config nodes
    • allows setting log levels, runtimes, modules, disabling the config.json file or changing it’s name and so on
  • Clarified and fixed the update vs tick concepts framework wide
    • tick is the raw update event fired from the runtime
    • update is the app level event that respects the app timing flags
    • this allows handling tick updates that are relevant when the app is paused or not ready yet (like timers and so on) and gives you access to the runtime tick rate separate from the app update timings
  • Added initial snow.core.Extension interface
    • This is part of the ongoing snow sdk/extension implementation
  • Added snow.api.Emitter, moved lower from luxe
    • an efficient macro based event emitter, used in the core now
  • Added new samples for feature specifics
    • audio
    • audio_custom_stream (native only)
    • config
  • Lots and lots of clean up and tweaking
    • There are no longer any runtime allocations in snow
    • Fixed consistency issues in many API endpoints and config nodes
    • Removed a lot of needless abstractions
  • Changed snow.system to plural for consistency
  • Changed config.render.depth and config.render.stencil to Int
    • This removes the bool redundancy of asking for a depth buffer and having to specify the bits separately, if the bits are > 0 it will request it now.
  • Changed how easy it is to disable the config.json
    • set a blank name for it in the snow config node in the flow file
Platform specifics
  • New cleaner, more customizable web runtime
    • redid windowing implementation
    • cleaned up gamepad implementation
  • New platform level Audio implementation
    • uses the native browser Web Audio API and HTML5 <audio>
    • gives you access to the Web Audio context to do advanced/custom processing
    • removes howlerjs dependency
  • Added ability to configure WebGL version and more
  • Fixed high DPI implementation details for the canvas/WebGL
  • Fix touch + mouse input bugs when page scrolls or zooms or has High DPI
  • Added ability to override fallback when WebGL isn’t found
  • Added window_id and window_parent config as js.html.Element
    • allows setting the <canvas id="window_id"> explicitly.
    • default is now app instead of window1 (which was generated by the window id)
    • allows controlling which element the <canvas> is appended to
  • Moved Android specific flow configuration to Android studio where it belongs
  • Migrated to the gradle build tool instead of older ant based
  • Migrated to Android Studio projects
    • Gives full access to all Android features directly
    • Allows more platform aligned workflow like it was with iOS
    • Build, edit and run from Android Studio
    • Manage signing and everything from the UI
  • Project specific Java integration with the IDE
    • Tools like library projects, jar files, code completion are first class
  • Moved iOS specific flow configuration to XCode where it belongs
  • Cleaned up the XCode project template further
    • depending on your project, it’s better to just generate a new one
    • if you’ve made extensive changes, you can backup the real one (which is always a good idea), then generate a new one and run a diff to see the minor changes.
  • Added XCode project generator
    • use flow build mac --generate-project
    • This allows debugging and profiling the app directly from XCode, much like iOS and allows tighter integration with the platform for later native integration.
    • Follows the same concept as iOS/Android projects (generate once)

Remember, most of these seem drastic but have 1:1 parallels from SDL or new linc libraries.

A lot of the pruning here is to finalize the API from it’s exploratory roots. Portability, maintainability and parity are important to me (and I’m sure many users). Every API endpoint that exists in the core API is an implicit statement about it’s support on all supported platforms and targets.

There were plenty endpoints where this wasn’t true, and many cases where it was just impossible (like setting the mouse cursor position on a browser will never be allowed due to security risks). If the user was making assumptions would end up being mislead into disappointment but the fault would partly be on the API.

In line with the vision and goals of snow, the best option was to remove all of that down to the absolute minimum that can be delivered upon consistently – which this update definitely gets close to achieving – and to make every non portable API endpoint much more explicit like the original module/API separation. Now you can always tell whenever the code you are calling is intended to be portable or not, making your code that interacts with snow more imperative and easier to reason about.

  • Removed the NDLL folder, and project folder for new implementations in Haxe
  • Removed snow.api.Libs which was legacy handling for NDLL stuff
  • Removed file dialog endpoints
  • Removed file watch and drop events
    • Use SDL for the drop event since that’s where it came from
    • Use linc_filewatch for the file watch API replacement, it’s cleaner
  • Removed most windowing/desktop windowing APIs
    • Only essentials like fullscreen/grab remain, since that have full parity on almost every platform
    • SDL provides all the desktop APIs plus many more snow didn’t expose, now you have much more to go on
  • Removed snow.api.File
    • replaced inside of the native io modules as file_handle and file_handle_from_memand associated file_*, since the snow.api are typically the user facing cross platform API helpers
  • Removed Input/Windowing modules
    • app.input system API remains the same
    • This removes multiple window support from the core API but you can create multiple windows in exactly the same way using SDL directly, and have far more control over them with the full SDL API on hand. This concept didn’t translate to web or mobile or consoles so it’s much better now
    • The runtime handles windowing now and is at app.runtime / Luxe.snow.runtime
    • Window API calls are now app.runtime.window_*
    • The window handle can be reached via app.runtime.window but note that it is not a snow.system.window.Window, it is now a raw runtime handle. On SDL runtime this is an sdl.Window and on js a js.html.CanvasElement
  • Removed Native and Web config specifics
    • These are handled by the RuntimeConfig instead now, which is defined by the runtime itself and strong typed by Haxe magic
  • Removed howlerjs implementation and lib files on web
    • replaced by pure js APIs
  • Removed all flow nodes regarding mobile
    • To be more specific, things like and – NONE of that exists any more. You configure your project in the platform specific way via the project formats (manifest xml, info.plist, IDE settings etc)

Scroll to Top