A Closer Look At S2Engine

 

Welcome to the next part in the ongoing Closer Look At game engine series.  The Closer Look series combines a review, overview and getting started tutorial in one and aims to give a developer a good idea ofs2closerlook a given game engine is a good fit for them or not.  Today we are looking at the S2Engine, which is a commercial game engine available for purchase on Steam.  Right off the hop the S2Engine is going to have two major strikes against it for many game developers.  First, it’s Windows only.  Figured I’d get the out of the way right up front as if you are looking to create cross platform games, this is not the engine for you.  Second, it’s commercial and closed source, although the price tag is quite low at around $20USD.

 

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

 

Without further ado, let’s jump in to the S2Engine.

 

The Tools

The entire development experience in the S2Engine takes place in the S2EngineHD Editor.  Here is the editor in action running the included sample scene:

s1

 

The S2Engine Editor is absolutely loaded with tools, lets take a guided tour.  First off we have the scene window where you can see a live rendering of your game in action:

sceneoptimized

 

Please keep in mind the fuzziness in the picture above comes from the animated gif process, the real-time viewport looks vastly superior to the image above.  The Scene view is where you place entities in your scene and preview the results.

 

You can switch between the various available tools using the following toolbar:

image

Or via menu:

image

 

The Project Window

image

 

This is where the various assets of your game are organized.  It’s an analog to the underlying file system of your project.  The buttons across the left enable you to filter the various different objects ( Animations, Models, FSMs, etc ).

 

The Class Window

image

 

This is where you can instance various game objects.  Select an object, click Create and then click within the scene to place the entity.  The newly created entity (or a selected entity) can then be configured using the lower Params window, which is context sensitive to the selected object.

 

Terrain Tools

image

 

S2Engine has a full terrain editing system in.  The Terrain tool enables you to interactively edit the scenes landscape (height map).  There are tools for raising/lowering, flattening, stepping and painting terrain as well as drawing roads and vegetation.  The actual editing is done in the scene window:

terrain

 

Model Window

image

 

S2Engine supports 3D animated models of FBX format, simply click the Import button in the Project view:

image

 

There are multiple different panels for configuring models, setting and handling animations, managing joints/bones and even vertex level manipulations.

image

 

There is also an animation panel.

image

This enables you to blend animations together, set and remove animation keys and of course, preview animations.

 

Material Window

imageimage

 

A detailed material system allowing multiple layers.  You can control diffuse and normal maps, UV tilting, lighting properties and more.  You also have control over detailed material attributes like alpha blending, animations, scattering, light emission and more.

 

Special FX

image

 

Fine tuned control over multiple special FX of types weather, post processing and environmental.  Fine tune control over all aspects, including water fx, sky, weather, lens effects, etc.  You also have fine tune control over day/night cycles using a keyframe system:

image

 

Cutscene Tool

image

 

S2Engine has a complete system in place for authoring cut scenes.  Includes a curve editor:

image

 

As well as a detailed timeline:

image

 

Hierarchy

image

This is essentially your scene graph.

 

Font Tool

image

Enables you to create png textures for fonts of varying dimensions with font preview.  Fonts are imported in fnt format created using the BMFont tool.

 

GUI Editor

image

Currently in Beta, there is a UI editor available.  You can create a hierarchy of UI widgets and configure them using the Params class panel.

 

imageimage

Currently supported widgets include button, slider, frame, input box, combobox, label, checkbutton, colorbox, image, listbox, groupbox, tabbox and rangeinputbox.

 

Publishing

When you are complete publishing is a pretty straight forward process.  This is one of the advantages of only supporting a single platform publishing is as simple as choosing a file name, starting scene, main script (entry point) and a few other settings and clicking the Publish button.

image

 

Coding

There are two ways to code in S2Engine.  You can use their own scripting language or the visual FSM (Finite State Machine) visual programming language.  The scripting language has the sc2 extension and has a C like syntax.  You can read the language reference here while the API documentation is available here.  Scripts are simply connected to (and thus control) game objects.  Here is an example script that controls a jeep found in the demo game.

#message TakeControl  #message LeftControl  #message LockWaypoints  #message UnlockWaypoints    #use "engine.wav"    var float acc;  var float steer;  var bool brake;  var bool control;  var float steerAng;  var string steerNode;  var string handsNode;  var float oldsteerAng;  var bool _on;    function void Init()  {  	_on=false;  	control=false;  	steerAng=0.0;  	steerNode="steer";  	handsNode="hands";  	AICreateObject(false,false,205.0,200.0);  	resetNodeFlags("camera","visible");  	resetNodeFlags("hands","visible");  	SetSource(10.0,15000.0);  }    function void PostInit()  {  	SetPerObjectMaterialData(3,0.0);  	resetNodeFlags("light01","visible");  	resetNodeFlags("light02","visible");  	_on=false;  }    function void update()  {  	if(control==true)  	{  		acc=0.0;  		steer=0.0;  		brake=false;  		RotateNode(steerNode,"rgt",-steerAng);  		RotateNode(handsNode,"rgt",-steerAng);  		  		SetSourcePitch((PhysicsGetVehicleRPM()*0.0025)+1.0);  		/*LOG( string(PhysicsGetVehicleRPM()) );*/  		  		if(IsKeyPressed("w"))  		{  			acc=1.0;  		}  		if(IsKeyPressed("s"))  		{  			acc=-0.5;  		}  		oldsteerAng=steerAng;  		if(IsKeyPressed("d"))  		{  			steerAng=steerAng+(frametime);  			steer=-1.0;  		}  		else  		{  			if(IsKeyPressed("a"))  			{  				steerAng=steerAng-(frametime);  				steer=1.0;  			}  			else  			{  				steerAng=0.0;  			}  		}  		if(IsKeyPressed(" "))  		{  			brake=true;  		}  		if(steerAng>=35.0)  		{  			steerAng=35.0;  		}  		if( steerAng<=(-35.0) )  		{  			steerAng=-35.0;  		}  		steerAng=ScalarInterpolate(oldsteerAng,steerAng,(frametime/200.0));	  		RotateNode(steerNode,"rgt",steerAng);  		RotateNode(handsNode,"rgt",steerAng);  		PhysicsVehicleControl(steer,acc,brake);  		  		if(acc!=0.0)  		{  			var vec3 fwdaxis;  			fwdaxis=GetWorldAxis("fwd");  			SendMessageMulti("pushOut",string(fwdaxis),400.0,"null");  		}  	}  	else  	{  		PhysicsVehicleControl(0.0,0.0,true);  		if(ObjectIsInRange("player01",300.0))  		{  			SendMessageSingle("player01","DriveVehicle","");  		}  	}  }    function void message()  {  	if( ReceivedMessage("TakeControl") )  	{  		/* lights control */  		var float tod;  		tod=float(GetLevelParam("TimeOfDay"));  		LOG("tod"+string(tod));  		if( (tod>=18.0) && (tod<=24.0) )  		{  			SetPerObjectMaterialData(3,1.0);  			if(!_on)  			{  				SetNodeFlags("light01","visible");  				SetNodeFlags("light02","visible");  				_on=true;  			}  		}  		if( (tod>0.0) && (tod<6.0) )  		{  			SetPerObjectMaterialData(3,1.0);  			if(!_on)  			{  				SetNodeFlags("light01","visible");  				SetNodeFlags("light02","visible");  				_on=true;  			}  		}  		if( (tod>6.0) && (tod<18.0) )  		{  			SetPerObjectMaterialData(3,0.0);  			ResetNodeFlags("light01","visible");  			ResetNodeFlags("light02","visible");  			_on=false;  		}  	  		/*=======================================0*/  		control=true;  		SetNodeFlags("hands","visible");  		PlaySound("engine.wav",true);  	}  	  	if( ReceivedMessage("LeftControl") )  	{  		control=false;  		ResetNodeFlags("hands","visible");  		StopSound();  		SetPerObjectMaterialData(3,0.0);  		ResetNodeFlags("light01","visible");  		ResetNodeFlags("light02","visible");  		_on=false;  	}  }  

 

It’s a straight forward enough language, but I generally prefer that engines use an off the shelf scripting engine instead of rolling their own.  This gives the community access to a much larger source of expertise, sample code and generally is much more time tested and stable.  As you can see from the script above, much of the logic and communication is implemented via message passing.

The majority of in game programming however is done using FSM (Finite State Machines ) via the FSM graph.

s2

If you’ve ever worked in Blueprints in Unreal Engine or Flowgraph in CryEngine you should have a pretty good idea how FSM programming works.  You’re code responds to various events and creates program flows using a series of connecting cables to other states.  Each node can have multiple actions, configured like so:

s3

There are dozens of states available, and new ones can easily be created.

image

Variables are easily created as well.

image

In addition to local variables, parameters and globals can also be defined.

image

 

 

The Documentation, Community and Content

The S2Engine has a decent amount of documentation, reference materials, getting started videos and beginner projects.  There are however a few issues, the first of which is English.  The developers primary language is not English and it shows on occasion in the documentation.  The actual UI is very well translated but some of the documentation  is certainly a tad “Engrish”.  Worse, some of the linked starting videos aren’t in English at all.  I have no issue with non-English videos, but I would recommend not linking them directly from an English localized application.

In terms of actual available documentation, there is a Wiki available here, a very solid reference manual available here, and a series of video tutorials available here.  S2Engine also comes with the beginner scene you’ve seen throughout this review.

The community for S2Engine isn’t huge but there is an active forum.  There is also a Trello bug tracking board available on Trello as well as a few other community options.  One impressive thing about the engine is the engine developer is very responsive to user requests and feedback.

One interesting aspect of the S2Engine is the existence of Content DLC.  These are themed content packs you can download and use in your game.  Currently the only content pack is the Medieval content pack shown in the video below. There is another content DLC pack in the works.

 

 

Conclusion

I pointed out the two biggest negatives to this game engine in the very first paragraph.  It’s Windows only, both for tooling and target platforms.  It’s closed source and commercial.  For many those are going to be big enough deal breakers that nothing else really matters.  For the rest though, is this a worthwhile engine?  For a small team effort, there is a massive amount of functionality included in this engine, it’s capable of some staggeringly pretty results and the workflow, once understood, is pretty accessible to people with limited programming experience.

My biggest recommendation to the developer behind this engine is to make a proper demo available.  What will get people to use this engine over the other options is that they prefer the workflow, the tools, the built in assets, etc.  The lack of a current demo is going to vastly limit the potential audience.  Even with a low price tag, few people will spend money to evaluate an engine and having a previous weaker version of your engine available as the trial is certainly a mistake.  When you go to the download section of the website, you are greeted by this text:

NOTE: The version to be downloaded here (1.4.5) is a previous, very old, FREE BETA version. It is useful just for letting you to view How S2ENGINE HD is organized and How it works. It doesn’t represent the final quality of the 1.4.6 Steam version.

This is quite simply a mistake.  A demo is about selling people on your engine, so having them experience a “very old” version is a bad idea.  Always put your best foot forward when showing an engine.  I would recommend creating a version of the current engine that is full featured but either time locked, save limited or publish limited.  You will have a great many more developers willing to give your engine a try. 

I have found the performance to be a bit inconsistent.  I was running consistently at 70+ FPS, then struggled to hit 15FPS for a while with a ton of UI glitches.  Upgrading to the newest nVidia drivers didn’t help.  Then oddly, switching Optimus to use the integrated GPU, then back to dedicated seemed to fix the problems.  Hopefully these problems are localized to me and not widespread.  I wish the developers used a standard UI toolkit like Qt, as their custom implementation can be a bit buggy or not perform as you’d expect.  I also unfortunately experienced a half a dozen crashes while evaluating the engine, including one while making the video version of this review.

 

The Video

Programming


Scroll to Top