Basics: Plugins

C++ Plugins

Table of Contents


C++ plugins can be used on all engines except where explicitly stated in the documentation for the individual platform. Plugins work equally well with both Lua script based games as well as C++ native code applications.

Please note that you have to compile libraries for every platform you want to publish for, and possibly for every architecture too (arm, x86, x86_64).

Plugin Project

To get started with your plugin project, open the solution/project file in Make/Platform in your exported plugin project directory.

winrt plugin project
The cpp file you want to modify is named after your plugin. Please do not touch the Plugin.h/.cpp itself. Do not modify the file structure and comment blocks! Otherwise ShiVa will have trouble keeping the API package in sync with your source code. Constant value or description modification is allowed.

Constant value or descriptions modification is allowed.

You will see that plugin function callbacks follow basically the same principle as hooks and callbacks via system.callClientFunction(). Please select the item "CallClientFunction" from the "C++" chapter in the navigation to learn more about how these functions are structured and registered.

You can use your own plugin functions (and constants) directly in other plugin functions:

// API package "tools", function "tools.add" defined elsewhere in the plugin
tools.add ( 2, 3 );
// tools.kConstantNumber defined elsewhere in the plugin
tools.add ( 2, tools.kConstantNumber );

... and of course the entire S3DX API.


The Runtime Lua API is the one that you will be dealing with most of the time when creating plugins, hooks and callbacks, and bridge functions between your own C++ code and the translated code ShiVa gives you upon export. The corresponding C++ API is called S3DX and can be used like the Lua API with "S3DX::" in front, as shown in the following snippet:

S3DX::AIVariable tStrings = S3DX::table.newInstance ( ) ;
S3DX::table.add ( tStrings, "foo" ) ;

The C++ runtime API is virtually identical in structure to the Lua runtime API. The entire reference can be found in S3DX/S3DXAIEngineAPI.h in any ShiVa C++ "Project" export.


Functions can have only 13 parameters, less is always better.

Please note that *_pOut points to an array of S3DVariables that are returned to ShiVa, which is not the same as the return value of the function in C++. You can return more than one value per function can be done using ShiVa's table API:

S3DX::AIVariable tStrings = S3DX::table.newInstance ( ) ;

S3DX::table.add ( tStrings, "foo" ) ;
S3DX::table.add ( tStrings, "bar" ) ;
S3DX::table.add ( tStrings, "gee" ) ;

_pOut[iReturnCount++] = tStrings ;
// no need to release/destroy the created table, will be done automatically

From within ShiVa, you can then retrieve the values using the Lua table API.

Alternatively, you can avoid tables and fill the _pOut array with multiple AIVariables. In ShiVa Lua, you can retrieve these values by using the following syntax:

local return1, return2, return3 = plugin.function ( someParameter )

S3DX::AIVariable Types

Our C++ API comes with its own variable type S3DX::AIVariable which is not compatible with the standard C++ types (char, string, int, etc.) - before you can exchange data between ShiVa and your C++ code, you must transform the types using the following methods:

// getters
(bool) .GetBooleanValue()
(void) .GetHandleValue()
(float32) .GetNumberValue()
(const char*) .GetStringValue()

.SetBooleanValue(bool _bValue)
.SetBooleanValue(const void* _bValue)
.SetStringValue(const char* _pValue)

If you are unsure about the type of an AIVaribale, GetType and SetType are also available.


For performance reasons, the memory pool for strings is only 1MB by default. If you have a lot of strings or want to import big text files, you need to increase it by adding this line of Lua code to your main AI:

application.setOption ( application.kOptionNativeStringPoolSize, nSizeInBytes )

This is a C++ export only setting, it has no effect for regular script exports.


All numbers in ShiVa are floats. If you are calculating with ints, doubles, quads etc. inside your C++ code, you have to typecast back to float before you return a value back to ShiVa:

S3DClient_SendEventToCurrentUser ( "MainAI", "onExternalEvent", 1, &variables );

Extended Plugin Documentation

Please note that we have a special section for plugins further down the Nav Tree, where we go into much greater detail on creating, using and building plugins.