The high level architecture illustrated above, shows the involvement of modules and assemblies in the CE# Framework. Project CryMonoBridge, like any other CRYENGINE module is a plug-in which is loaded by CRYENGINE on startup. Hence, CryMonoBridge makes use of CRYENGINE’s C++ API, CryCommon. As far as this module is contained in the application’s binary folder it will be run automatically.
It is CryMonoBridge, which boots the Mono run-time and calls into CE#’s primary assemblies. Assemblies CryEngine.Core and CryEngine.MonoLauncher hold a reference to CryEngine.Common, in order to be able to connect with CRYENGINE.
CryEngine.MonoLauncher provides entry and exit points for CryMonoBridge. This assembly is the very starting point for a Mono based CRYENGINE application to be developed. It is not obligatory for this assembly to reference CryEngine.Core if one chooses to go without the CE# Framework libraries entirely.
CryEngine.Common is the actual C# sided API for CRYENGINE, which is compiled on a basis of CryCommon, making use of SWIG for interface generation. For information about how this interface is compiled, see chapter Compiling CRYENGINE for Mono.
The CE# Framework lives inside CryEngine.Core where all CryEngine.Common based wrappers, handlers and sub-systems are implemented. Through CryEngine.MonoLauncher the framework offers the ability to dynamically load and hot-reload assemblies which implement interface CryEngine.Resources.ICryEngineAddIn.
This approach is used in all CE# Programming, where each project has one class deriving from ICryEngineAddIn. These projects then are being compiled into sub-folder /mono/AddIns of the CRYENGINE run-time folder. Whenever an assembly in this folder is recompiled, MonoLauncher will shutdown and re-instantiate all assemblies in this folder.
Getting Started (Running C# in MonoDevelop)CRYENGINE project templates are delivered with the CE# Framework source, which can be found in folder <root>/Code/CESharp. This folder contains a solution as well as projects for CryEngine.Core, CryEngine.MonoLauncher and CryEngine.SampleApp.
By default, the two first assemblies are compiled and ready to use by launching GameMono.exe or Editor.exe. In case CryEngine.SampleApp is compiled, CryEngine.MonoLauncher instantiates a simple sample application in form of an add-in, which displays CRYENGINE’s output frame-rate. The frame-rate can be modified, using CVar mono_targetfps.
The Mono run-time and development tool MonoDevelop are provided with all builds of CRYENGINE. However, running MonoDevelop requires two installations of software ahead which are:
- GTK# for .NET: http://www.mono-project.com/download/#download-win
- Mono Libraries: https://files.xamarin.com/~jeremie/MonoLibraries.msi
Compiling the solution will produce assemblies in the applications binary folder (e.g. <root>/bin/win_x64) and inside CE# Framework's add-in folder (e.g. <root>/bin/win_x64/mono/AddIns). To compile from within MonoDevelop, press <F8>. To run from inside MonoDevelop, press <F5>. Running the application from within MonoDevelop allows for setting break points and debugging the CE# Framework.
Getting Started (Running C# in Visual Studio)
To install the extension run the *.VSIX file, this can be found in <root>\Tools\CESharpVSExtension\CESharpProjectType.vsix.
Once the extension has been installed CE# projects will load properly in Visual Studio. In accordance with the new project system, right clicking on the projects .cryproject file and selecting "Generate solution" will create a user file for our CE# project. The user file contains paths to the selected engine version, as well as command and command arguments, for Visual Studio to run the project properly.
If we want to change the application that is being executed when we press Run in Visual Studio (e.g. from GameSDK.exe to Sandbox.exe), we have to edit the project properties of the CE# project. To do so, we go to "Configuration Properties > Debugging", select "Run CryENGINE" as Debugger to launch and setup the "Command" parameter accordingly.
CE# Framework Overview
The assembly CryEngine.Core, in its namespace root, mostly consists of functionality enhancing wrappers for CRYENGINE objects (green) and listener implementations for CRYENGINE dispatchers (orange). The listeners do some preprocessing, in order to generate easy to use events for further processing inside the CE# Framework.
Many objects in the CE# Framework make use of the listener instances which are all globally accessible. Env is the primary global access point, which creates all listener and wrapper instances, as well as provides static access to CRYENGINE’s module instances.
All other objects (cyan) are new implementations, giving higher level functionality to the CE# Framework. Class SceneManager is used to prioritize updating of CE# Framework objects. Class SceneObject is used for hierarchical handling of any logical or physical object in a scene, including the elements of CE#’s UI System.
Sub namespaces comprise FlowSystem – which allows for the creation of CRYENGINE’s FlowNode object, Resources – which allows for the handling of textures and dynamic C# scripting and Components – which are view-controllers for CE#’s SceneObjects.
Namespace UI contains the full implementation of CE#’s UI System, which works closely with CRYENGINE to allow for the development of high performance, dynamic 2D and 3D user interfaces. This system is explained in further detail in chapter CE#’s UI System. For further information about individual objects of the CE# Framework, please refer to the CE# API Reference.
Compiling CRYENGINE for Mono
Since the triggering of interface generation is part of the WAF Build System, this chapter requires a basic understanding of the latter. By default, the Mono interface compilation is only enabled for one of the WAF solutions which contain project GameMono. If interface compilation is enabled, WAF will invoke SWIG for interface generation. As a consequence, a C-interface as well as a wrapping C# implementation will be generated and compiled into CryMonoBridge.dll and CryEngine.Common.dll respectively.
To enable interface compilation, a CryModuleExtension must be added according to the WAF Spec. For reference, check out <root>/_WAF_/specs/monogame.json. The file contains following line, which has the keyword mono in it, to trigger the compilation:
If the trigger for interface generation is set, WAF will invoke swig.exe, which is expected to be globally available. Latest binaries of SWIG can be found here: http://www.swig.org/download.html
Enhancing C++ game code and common interface
If a CRYENGINE Mono application requires the implementation of C++ code, there most likely is the need for exposing some of the controlling functionality to C#. This chapter describes how to expose C++ functions of a new project. Like any existing CRYENGINE module, also new modules can be exposed through SWIG. Project CryMonoBridge, is a straight forward example of how to do this.
For a code base to get stated, it is recommended to use or copy project SampleApp, which is the most basic application implementation to run alongside the CE# Framework. For information about how to expose a new C++ project to the WAF build system, please read up the initial tutorials of the WAF Build System documentation:
In the first place, any class which is supposed to be accessible from C# must be derived from interface classes in project CryCommon. E.g. for CryMonoBridge, all relevant classes are exposed via file <root>/Code/CryEngine/CryCommon/IMonoRuntime.h.
Secondly, one of the class instances which live in the new project need to be accessible, to get started on the C# side. This may be realized by adding the instance to global variable gEnv, which is defined by struct SSystemGlobalEnvironment in file ISystem.h. CryMonoBridge uses this approach, by writing its instance of IMonoRuntime to gEnv->pMonoRuntime, during initialization.
Last but not least, SWIG needs to know about the new interfaces, which is realized by adding an interface generation source file (<root>/Code/CrySharp/CryMonoBridge/SWIG/*.i). In case of CryMonoBridge, this is done in file CryMonoBridge.i.
Creating a new MonoDevelop project
On CE#’s side, projects should be created, using the frameworks Add-In mechanism. Projects in the CE# Programming Tutorials show step by step, how an application should be developed from scratch, using this mechanism. Hence the easiest way to create a new project is to copy and rename one of the sample applications, as they already have all necessary project settings. To read up more about individual sample projects, refer to CE# Programming.