Raven Engine v0.1
A modern 3D Game Engine
Loading...
Searching...
No Matches
Introduction to Scripting

Gameplay logic is written using native C++ scripts. Scripts are compiled int the project's script module DLL and executed by the engine during play mode

Ignite API conventions

To access all API functions, include:

All public scripting functions live under Raven::Script. Sub-namespaces map to engine subsystems:

Namespace Subsystem
Raven::Script::Log Logging
Raven::Script::Scene Entity/scene queries
Raven::Script::Physics Physics bodies
Raven::Script::Renderer Rendering hints
Raven::Script::Random RNG utilities

Functions suffixed with _Internal are implementation details and are not part of the supported scripting API. Their behaviour and signatures may change between engine versions without notice.

It is recommended to add

using namespace Raven::Script;
Definition LogAPI.cpp:6

at the top of each .cpp file.

Attaching a Script

Scripts can be attached through the Scriptcomponent in the editor.

Once attached, the engine automatically creates and manages script instances while the scene is running.

Creating a Script

From within the scriptcomponent, use the Script Creation Wizard to create a new script.

The wizard generates a class derived from ScriptBase and performas all required registration automatically.

class MyScript : public Raven::ScriptBase
{
public:
void OnCreate() override;
void OnUpdate(float dt) override;
void OnDestroy() override;
};
Abstract base class for all user-authored native scripts.
Definition ScriptBase.h:20
virtual void OnDestroy()
Called once just before the script instance is destroyed.
Definition ScriptBase.h:43
virtual void OnUpdate(float dt)
Called every frame while the scene is running.
Definition ScriptBase.h:36
virtual void OnCreate()
Called once after the script instance is created and fields are applied.
Definition ScriptBase.h:30

Script Lifecycle

Scripts receive lifecycle callbacks from the engine.

  • OnCreate() is called when the script instance is created
  • OnUpdate() is called every frame
  • OnDestroy() is called before the script instance is destroyed

Exposing Properties

Public fields can be exposed to the editor. Adding a field such as:

float Speed = 5.0f

to your class and then adding the Reflection Macro to ScriptEntry.cpp

RV_REFLECT_MEMBER(MyScript, Speed);
#define RV_REFLECT_MEMBER(Type, Member)
Exposes a member variable of a reflected script class to the inspector and serialisation system.
Definition ScriptEntry.h:277

Once registered, the field becomes editable in the editor and its value is applied when the script instance is created. The initial class reflection gets handled by the Script Creation Wizard.

Accessing the Owning Entity

Each script instance automatically receives the identifier of the entity it is attached to. u64 EntityID

Most scripting API functions operate on this identifier.

For example, to retrieve the entity's tranform component:

auto* transform = Scene->GetComponent<TransformComponent>(Raven::UUID(EntityID));
A class representing a Universally Unique Identifier (UUID).
Definition UUID.h:65
Definition SceneAPI.cpp:8
Represents position, rotation, and scale of an entity.
Definition TransformComponent.h:13

Both EntityID and Scene are only valid during Play mode. While there is nothing stopping you from overriding them, it is not recommended to do so and could have unforseen consequences.

Working With the Scene

Scripts can create entities, search for existing entities, and access + modify their components.

Creating Entities

Entity cube = Scene::CreateEntity("Magic Cube");
Lightweight wrapper for manipulating a single entity within the ECS.
Definition Entity.h:29
Entity CreateEntity(const std::string &name)
Creates a new entity in the active scene.
Definition SceneAPI.cpp:14

This will create and Entity named "Magic Cube" at (0, 0, 0).

Attaching Models

If you now wish to add a Mesh to that object, you may now call CreateMesh with that entity, as follows:

Renderer::CreateMesh(cube, "engine://Models/Cube.obj");
void CreateMesh(Entity &entity, const std::string &path)
Loads a static mesh asset and attaches it to an entity.
Definition RendererAPI.cpp:10

This will load the object based on the provided URI. The engine:// prefix will look for that file in the engine's Resources directory.

If you wish to instead load from your project structure, use project://Assets/path/to/model.

Searching for Entities

Entities can also be found by name. Use:

Entity cube = Scene::FindEntityByName("Magic Cube");
Entity FindEntityByName(const std::string &name)
Searches the active scene for an entity whose TagComponent matches name.
Definition SceneAPI.cpp:24

Input Handling

Keyboard and mouse input can be queried directly through Raven's input system.

{
// your code here
}
Declares the core input query interface for polling keyboard and mouse state.
static bool IsKeyPressed(KeyCode key)
Checks if a specific key is currently pressed.
Definition Input.cpp:104
@ F
Definition KeyCodes.h:61

NOTE: This assumes you defined using namespace Raven; somewhere. It is recommended to do so in every .cpp file

Logging

The scripting API provides a logging system through Raven::Script::Log.

Logs are displayed in the editor's Log panel and are useful for debugging gameplay code, tracking state, and reporting runtime issues.

Logging a message

Log::Info("Hello {} my format {} and ptrs too {}!", "World", 124, &ptr);
void Info(std::format_string< Args... > fmt, Args &&... args)
Logs an info-level message from a script. Supports std::format syntax.
Definition LogAPI.h:45

The logging system supports formatted strings using {fmt} style formatting

Log levels

  • Log::Debug -> debug information
  • Log::Info -> general information
  • Log::Warn -> warnings that may indicate incorrect behaviour
  • Log::Error -> recoverable runtime errors
  • Log::Critical -> severe errors that may lead to script termination

Whether the Log Messages gets displayed/forwarded depends on the log level set in the Raven.ini

Useful headers

#include <Ignite/API/IgniteAPI.h> // Ignite API functions
#include "Components/Components.h" // All components
#include "Raven/Input/Input.h" // Input handling
#include "Raven/Memory/Scope.h" // Scope bound pointer type
#include "Raven/Memory/Ref.h" // Intrusive Reference counted pointer
Defines atomic reference-counted smart pointers for Raven.
Defines scoped and allocator-aware smart pointers for Raven.

Important note

As it stands right now, the scripting API is fairly minimal and the entire system might have some quirks here and there. If something stands out, do not fear to ask us directly. This helps improve the API surface and general user friendliness.

The scripting API intentionally exposes native C++ functionality with very few restrictions. Scripts have the same ability to allocate memory, access engine systems, and crash as any other C++ code. If you want to allocate 10 GiB of memory, Raven won't stop you. In fact, we even provide GiB(10) to make it easier to calculate the number of bytes needed. Whether your operating system agrees with that decision is a separate matter.

If you crash your script through whatever means, that individual script is excluded from executing until you stop play mode. The script will be flagged as "faulted" in the Properties panel.

Happy Developing!