A Closer Look At Wave Engine


Welcome to the next section in the ongoing Closer Look at series, a series of guides aimed at helping you decide which game engine is right for you.  Each closer look at entry is a cross between a review and a getting started tutorial that should give you a good idea if a game engine is a good fit for you.  Today we areCloserLook going to be looking at the Wave Engine.  The Wave Engine started life in 2011 and is a C# based 2D/3D engine that runs on Mac, Linux and Windows and is capable of targeting all of those plus iOS, Android and Windows Mobile, although a Xamarin license may be required for some mobile targets.  There is no cost to develop using the current version of Wave Engine, however you are required to show a splash screen on application start.


As always there is an HD video version of this guide available here.


Meet Wave Engine


With the release of version 2, Wave Engine now includes a level editing tool to help you quickly compose scenes.  Judging by the number of “Wave Engine vs Unity” or “Wave Engine vs Unreal Engine” searches on Google, this was a heavily requested feature.  Do be aware though that the editor is quite young, and it certainly shows sometimes.


As mentioned earlier, Wave Engine is C# based game engine and games can be written entirely in Visual Studio or MonoDevelop/Xamarin Sutdio if you prefer.  The editor however can make like a great deal easier and integration between your code and the editor is well done and makes heavy use of reflection.  This makes your requirement to a editing support to your own classes extremely easy as we will see shortly.


As is quickly becoming the norm, Wave Engine is built around a entity/component model.  Your scene is a series of entities, and those entities are in turn composed of components, behaviours and drawables (renderers).  These can be composed using either the editor or entirely in code.  Let’s take a look at the editor.


Wave Visual Editor




Let’s take a quick tour around the editor.


Asset Management


This is where the various assets ( textures, models, materials, scenes ) that make up your game are managed.  You can often, but not always, create an instance of an asset by dragging it on to the viewport.  Options here are fairly simple, mostly limited to renaming and deleting assets.  A bit of a warning, I ran into some issues when deleting assets, especially when I deleted an asset then added a new version with the same name.  Hopefully these behaviours will be ironed out in time.  Not that a scene, which is where you assemble your various assets for display in the game, is in fact an asset itself.


Depending on the type of asset, double clicking it will either invoke a built in tool, such as the material editor or 3D model viewer, or invoke the native application if no behaviour is defined.




This is where your various levels of debug information are displayed.  You can filter between errors, warnings, informational and debug logs and of course you can clear it all out.


Scene Graph



The Entity hierarchy is the scene graph of your game scene.  Each scene has it’s own hierarchy.  All the assets in the hierarchy are entities which in turn are holders for various components.  Entities can be parented to other entities and will inherit their transforms.  There are several kinds of entities that can be created, depending on if you are in 2D or 3D mode.  To create an entity simply click the + icon.

The 3D entities:



The 2D Entities:



You can effectively built any of the pre-existing entity types by using an empty entity and adding all of the same components and behaviors.  Speaking of which, with an entity selected you can then access the Entity details, where you configure components and add more.  Here for example is the 3D camera’s details:



New components or behaviours can be added using the + icon.  For visible objects such as models or sprites, a Drawable component also needs to be added.  Here for example is the process of adding a film grain to our camera:



Select Components, then FilmGrainLens, then OK:



You should now be able to configure the amount of film grain in the Entity Details panel:






This is the area where you place entities within your scene.  It is also the aspect of Wave Engine editor that by far needs the most work.  When an object is selected ( using the Entity Hierarchy, direct selection rarely works ) a widget appears for translation, scaling or rotation depending on the settings in the toolbar at the top.  In the top right corner is a widget enabling you to switch between the different camera views.  If your camera is selected you can see the camera’s viewing frustum as well as a preview of what the camera sees, like the image shown above.  You can zoom using the scroll wheel, pan with middle mouse button and rotate the view using the right mouse button.  There does not appear to be an orbit ability, which is frustrating.


The major current flaws are the selection mechanics ( left click works sometimes ), manipulators dont work if you click on the arrow portion, there is only one view at a time and selecting and position a camera is a rage inspiring prospect.  The single viewport with poor viewport controls makes positioning entities far more frustrating than it should be.  In fact, I tend to position entities using direct numeric entry because the viewport is so frustrating to use.  Hopefully these areas are improved soon, as all are fairly easy things to fix.



A fair bit of functionality is packed into the toolbar, as shown below:



Tools and Editors


As mentioned earlier, there are a few tools built directly in to Wave Editor.  Some of these are invoked by selected an asset in the asset viewer.  Others are invoked when creating new assets in the Assets menu:




Model Viewer



Material Editor



SpriteSheet Tool


Create Font



Coding in Wave Engine


So we’ve looked at the editor in some depth, now let’s take a look at the coding experience.  As the editor is actually a fairly recent addition, Wave Engine can obviously has pretty solid code support.  Let’s take a look at the process of creating a camera and adding film grain to it like we did earlier in the editor.  The results of the Editor are two fold, a series of file formats that the engine can understand and a CSharp project that you can edit.  You can load the solution from the File menu:



Your project should look like this:



The first project is the bootstrap for your game, it’s the second project where your code goes.


#region Using Statements  using System;  using WaveEngine.Common;  using WaveEngine.Common.Graphics;  using WaveEngine.Framework;  using WaveEngine.Framework.Services;  #endregion    namespace ProgrammaticCamera  {      public class Game : WaveEngine.Framework.Game      {          public override void Initialize(IApplication application)          {              base.Initialize(application);          ScreenContext screenContext = new ScreenContext(new MyScene());         WaveServices.ScreenContextManager.To(screenContext);          }      }  }  



#region Using Statements  using System;  using WaveEngine.Common;  using WaveEngine.Common.Graphics;  using WaveEngine.Common.Math;  using WaveEngine.Components.Cameras;  using WaveEngine.Components.Graphics2D;  using WaveEngine.Components.Graphics3D;  using WaveEngine.Framework;  using WaveEngine.Framework.Graphics;  using WaveEngine.Framework.Resources;  using WaveEngine.Framework.Services;  #endregion    namespace ProgrammaticCamera  {      public class MyScene : Scene      {          protected override void CreateScene()          {              this.Load(WaveContent.Scenes.MyScene);                     }      }  }  



//------------------------------------------------------------------------------  // <auto-generated>  //     This code was generated by a tool.  //     Runtime Version:4.0.30319.42000  //  //     Changes to this file may cause incorrect behavior and will be lost if  //     the code is regenerated.  // </auto-generated>  //------------------------------------------------------------------------------    // File generated on 2015-10-04 12:43:05 PM  namespace ProgrammaticCamera  {      using System;                  public sealed class WaveContent      {                    public sealed class Scenes          {                            /// <summary> Path to Content/Scenes/MyScene.wscene </summary>              public const string MyScene = "Content/Scenes/MyScene.wscene";          }      }  }  


Game.cs creates your scene, MyScene.cs is your scene and WaveContent.cs is a system generated file for mapping resources in the editor into code friendly variables.  MyScene.cs is where your logic will go.  Let’s do a simple example that creates a red spinning cube entirely procedurally.


#region Using Statements  using System;  using WaveEngine.Common;  using WaveEngine.Common.Graphics;  using WaveEngine.Common.Math;  using WaveEngine.Components.Cameras;  using WaveEngine.Components.Graphics2D;  using WaveEngine.Components.Graphics3D;  using WaveEngine.Framework;  using WaveEngine.Framework.Graphics;  using WaveEngine.Framework.Resources;  using WaveEngine.Framework.Services;  using WaveEngine.ImageEffects;  using WaveEngine.Materials;  #endregion    namespace ProgrammaticCamera  {      public class MyScene : Scene      {          protected override void CreateScene()          {              this.Load(WaveContent.Scenes.MyScene);                           //Create a new red material              WaveEngine.Materials.StandardMaterial material = new                                                                StandardMaterial(                                                               Color.Red,                                                               DefaultLayers.                                                               Opaque);                //Create our new entity with the name "cube"              Entity entity = new Entity("cube");                // AddComponent is chainable.  Add a Transform3D for position,               ModelRenderer so it renders              // and a MaterialMap containing our material              entity.AddComponent(Model.CreateCube())                  .AddComponent(new Transform3D())                  .AddComponent(new ModelRenderer())                  .AddComponent(new MaterialsMap(material));                // Accessing components is easy.  Let's position at 0,0,0, even               though this is actually the default              entity.FindComponent<Transform3D>().Position = new Vector3(0f, 0f,                                                 0f);                // We can also add behaviors to our entity.  Let's make it spin              entity.AddComponent(new Spinner());                // You can also get components by type, the true/false is wether the               type needs to be an exact match              var spinner = (Spinner)entity.FindComponent(typeof(Spinner), true);              // Spin on the Y axis              spinner.IncreaseY = 5f;                // Finally add our component to the active scene using EntityManager               global              EntityManager.Add(entity);          }      }  }  


And when run:



The code is pretty heavily commented, so I wont bother with much explanation.  Keep in mind that code could actually be a great deal shorter.  Things were done the way they are for demonstration purposes only.  The entire thing could have been defined in a single chain of AddComponent calls.


Next let’s take a look at a 2D example that shows how you can respond to input and more tightly integrate into the editor.  We are going to add a class that can be used to control a 2D player sprite, such as the players character in a 2D game.

using System;  using System.Collections.Generic;  using System.Linq;  using System.Runtime.Serialization;  using System.Text;  using WaveEngine.Common.Graphics;  using WaveEngine.Common.Input;  using WaveEngine.Components.Animation;  using WaveEngine.Components.Graphics2D;  using WaveEngine.Framework;  using WaveEngine.Framework.Graphics;  using WaveEngine.Framework.Services;    namespace SpriteTest  {      [DataContract]      class MyPlayer : Behavior      {          [RequiredComponent]          public Transform2D transform2D;            [RequiredComponent]          public SpriteAtlas spriteAtlas;            [RequiredComponent]          public Animation2D animation2D;            [RequiredComponent]          public SpriteAtlasRenderer spriteAtlasRender;            public MyPlayer()              : base("MyPlayer")          {              transform2D = null;              spriteAtlas = null;              animation2D = null;              spriteAtlasRender = new SpriteAtlasRenderer();          }            protected override void Initialize()          {              base.Initialize();          }            protected override void Update(TimeSpan gameTime)          {              if(WaveServices.Input.KeyboardState.Left == ButtonState.Pressed)                  transform2D.X -= (float)(100.0 * gameTime.TotalSeconds);              if (WaveServices.Input.KeyboardState.Right == ButtonState.Pressed)                  transform2D.X += (float)(100.0 * gameTime.TotalSeconds);          }        }  }  


Now in Wave Editor when you add a new Entity you should see your type as an option as a component that can be added to an entity.



As you can see, the types we added and marked as [RequiredComponent] are exposed to the editor.  I define a sprite sheet for our player (see video for the complete process), then when you run the game:


Pretty cool.


Engine Features


Of course, we can only go into a very small subset of the actual engine functionality in this tutorial, so let’s take a quick look at the marketing feature set:


Wave Engine is a C# component-based modern game engine which allows you to create cross-platform games and apps for many platforms: Windows, Linux, MacOS, iOS, Android, Windows Store and Windows Phone.

Wave Engine supports the same set of features in all its platforms to make it easy to port all your projects to other supported platforms.

You also have a great set of extensions with the complete code on github, to use WaveEngine with Kinect, OculusRift, Vuforia, Cardboard, LeapMotion and much more.


There is also a product roadmap available here for some direction on where Wave Engine development is headed.


Documentation and Community


At first glance Wave Engine has extremely good documentation.  After closer inspection this proves to be untrue, in fact, this is certainly an area that Wave Engine needs to improve.  For example I couldn’t find a single comprehensive link on the 3D export process ( supported formats, process involved, etc ) an area that most certainly should be well documented.


There is a wiki that serves as the getting started guide and tutorial in one.  Again at first glance it looks pretty complete, but when you start opening up entries and see that 75% of them are just stubs you know there is an issue.  The generated reference material also at first glance looks very good, but once you start diving in you realize that there is almost no descriptive text in any of the entries.  This is extremely disappointing… I can live without tutorials/manual when getting started, but a lack of reference is a painful pill to swallow.  There is also a technical blog that covers a mismatch of subjects.


There is a community forum that seems fairly active.  In researching the product Google led me to far too many questions without answers however.  Given the state of the documentation, this makes things even more frustrating.  If you aren’t the type to figure things out yourself, this will be a frustrating experience.  The design is straightforward enough that you can intuit most steps, but when you run into a wall, it hurts, a lot.


Fortunately there are several starter kits hosted on Github.  It is through this source code that you will mostly figure out how to work with Wave Engine.




There are currently no books covering Wave Engine development.  Will update here if that changes.




Like the Paradox Game Engine, WaveEngine provides a solid code focused cross platform C# based alternative to Unity.  The design is clean, the code is intuitive and the examples are quite good.  The new editor is a step in the right direction and should certainly help with productivity, but does need a layer of polish.  The documentation certainly needs more attention too, especially if this engine is going to be used by newer developers.  The kernel here though shows a great deal of promise and the direction they are going is certainly the right one.  The api itself is quite large in scope, containing most of the functionality you will need.


One thing I don’t really understand, nor could I find a good source on, is the business model here.  Besides the splash screen, there are no real costs or requirements when using this engine.  There is currently no value add or upsell version, so I don’t understand where the company is making their money.  For non-open source projects, that is always a huge question mark in my head when evaluating an engine.  Companies ultimately need to make money to continue development, so this is certainly a huge question mark.  So they either use this engine for their own development and release it to others for altruistic reasons, or something is going to change.


If you like what you saw today though, I certainly recommend you check out Wave Engine.  With no cost and a minimal download, you have very little to lose!


The Video


Scroll to Top