reckfellENGINE

C# scripts

Your first script, builds, lifecycle, paths and checking references after deletion.

On this page

Requires the Cube (MeshInstance3D) from project setup.

1. Create and attach a script

  1. Stop with F8 and select the Cube of type MeshInstance3D in the local hierarchy.
  2. Use the attach-script button. Choose C#, base class Entity3D and path asset://Scripts/Rotator.cs. Create the Scripts folder if necessary.
  3. If asked to create a C# solution, confirm. It provides the project used to build your code.
  4. Open Rotator.cs in a code editor, replace its contents with the complete example below and save.

The file and class names must match: Rotator.cs and Rotator. Attach the script to the cube; placing the file in the Assets alone is not enough. MeshInstance3D inherits Entity3D, so this base class is suitable.

If it does not open automatically, find Scripts/Rotator.cs in the project folder and open it in an installed text editor. Any editor that saves plain text with a .cs extension, without appending .txt, is enough for this example. Reckfell still performs the build.

2. The complete script

C#
using Reckfell;

public partial class Rotator : Entity3D
{
    [Export] public float DegreesPerSecond { get; set; } = 45.0f;

    public override void _Ready()
    {
        ReckfellApi.Print("Rotator ready");
    }

    public override void _Process(double delta)
    {
        float angle = Mathf.DegToRad(DegreesPerSecond) * (float)delta;
        RotateY(angle);
    }
}

3. Build and run

Choose Build Project in the editor's C# tools; its default shortcut is Alt + B. Wait for a successful build. Save the document and press F6.

The cube should rotate around its vertical axis, and Output should contain Rotator ready. If it stays still, check that the latest build succeeded and the script is attached to the visible cube.

Reading the code

ExpressionMeaning
using Reckfell;Lets you use engine types without their full namespace each time
class Rotator : Entity3DDefines object behaviour based on Entity3D
partialLets the engine's generator add required supporting code
floatA fractional number; the f in 45.0f specifies this type
[Export]Exposes a property in the inspector after building
_Ready()Runs when the object and its children are ready
_Process(double delta)Runs each rendered frame
RotateY(angle)Rotates around Y by an angle in radians

Braces { } group instructions. A semicolon ; ends a statement. public makes a class member accessible from outside, void means a method returns no value, and override replaces a handler provided by the base class.

Why delta matters

DegreesPerSecond is a speed per second. delta is the elapsed time since the previous frame, in seconds. Multiplying them gives the change for this frame. At a speed of 45, the object rotates about 90 degrees in two seconds despite normal changes in frame rate.

The inspector displays degrees, but RotateY() expects radians. Mathf.DegToRad() converts between them. Without multiplication by delta, the object would turn by a fixed amount every frame and its speed would depend on FPS.

Change speed without editing code

Stop, select the cube and find the script's Degrees Per Second property in the inspector. Set it to 90, save and run: rotation becomes twice as fast. -45 reverses direction and 0 stops it.

Inspector values are saved separately from C# defaults. Once a property has been overridden, editing 45.0f in the script may not replace the value saved on the object.

When the code runs

MethodUse it for
_EnterTree()Every entry into the running hierarchy; connect subscriptions that are active only while in the level
_Ready()Once children are ready; obtain references and set the initial state
_Process(double delta)Each displayed frame; UI animation and visual changes
_PhysicsProcess(double delta)Physics steps; moving physics bodies and working with collisions
_ExitTree()Leaving the hierarchy; disconnect subscriptions to objects that remain alive

The parent enters the tree before its children, while each child's _Ready() runs before the parent's. This makes _Ready() a useful place to connect already initialized child components. A C# constructor does not mean the object is in a level yet: do not obtain GetTree() or gameplay children there.

_Ready() normally runs once per instance lifetime. Removing the same object with RemoveChild() and adding it back with AddChild() repeats _EnterTree() and _ExitTree(), but not _Ready(). If initialization really must repeat, call RequestReady() before the next addition. The request applies to that object, not automatically to its children.

Use _PhysicsProcess() for the character in the movement tutorial. Do not move every operation there just for a fixed frequency: rotating a decorative cube does not require a physics step.

Object references and paths

GetEntity<T>("Child") searches relative to the object running the script. The name and case must match the hierarchy. This is not a file path: load asset://Props/Crate.rprefab with ResourceLoader and instantiate it separately. See runtime objects.

When a missing child is valid, use GetEntityOrNull<T>() and check the result. When the child is required, fix the level's structure: silently skipping the error leaves the component nonfunctional.

After QueueFree(), the native object is deleted at the end of the frame. The C# variable does not automatically become null. Check ReckfellObject.IsInstanceValid(reference) for a retained reference, and also reference.IsQueuedForDeletion() to avoid using an object already scheduled for deletion. This matters particularly after await or a level change.

If the result differs from the example

SymptomCheck first
Code changes do not appearSave the file and wait for a successful Build Project; an old working assembly does not prove the new one built
Rotator ready never appearsThe script is attached to the cube, the class is named Rotator, includes partial, and builds without errors
The speed changed in code, but rotation stayed the sameCheck the saved Degrees Per Second value in the Inspector
_Ready() does not repeat when an object returnsIt is the same instance; use _EnterTree() for each entry
NullReferenceException / child lookup failureCheck the name, case, type and relative path; find the first line of your script in the stack trace
Access fails after deletionCheck whether the native object is valid, not just reference != null

SDK and command-line builds

The distribution includes .NET 10 and Reckfell.NET.Sdk/1.0.0.

The generated .csproj uses this foundation:

XML
<Project Sdk="Reckfell.NET.Sdk/1.0.0">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <EnableDynamicLoading>true</EnableDynamicLoading>
  </PropertyGroup>
</Project>

Run dotnet build from the project folder using the supplied dotnet.exe and configured local Reckfell packages. Rebuild after updating the project's SDK.

Build and script attachment errors: troubleshooting.

Code tools

See the built-in IDE for Roslyn completion, reference search and debugging. You can also create logic in SharpGraph and convert it to separate editable C# files.

Reckfell Engine documentationBack to top ↑
QUICK LINKSGetting startedEntity hierarchyC# & .NET 10Scenes and prefabs
Reckfell guides and full API K
reckfellENGINE
RECKFELL ACCOUNT

Sign in

Sign in to your Reckfell account.

One account for the entire Reckfell platform.