Creating and Building Scripts¶
Each Lucky Engine project compiles its C# scripts into one assembly. The editor creates the script project for you, builds it with the .NET SDK, and reloads the result while you work, so most of the time you write code, save, and see the change in the scene.
This page covers what you need installed, the ways to create and attach a script, the files the editor generates in your project, and how building and reloading work.
In short
Install the .NET 9 SDK. Create a script from the Content Browser with New → Script,
or right-click an entity in the viewport and choose Add Script. Saving a .cs file
in the built-in Text Editor builds the scripts; after editing in an external IDE, build
there or press Ctrl+B. The editor reloads the scripts after every successful build.
Customise the build in premake5.lua and leave the other generated files alone.
Requirements¶
Scripting needs the .NET 9 SDK or higher on the machine that runs the editor. The runtime alone isn't enough, because the editor compiles your scripts. The tool that generates the C# project files (premake) ships with the editor, so there is nothing else to install.
When the editor starts, it checks for an installed .NET SDK. If it finds none, it shows a dialog titled Lucky Engine - C# Scripting Engine Initialization Failure that says "Lucky Engine requires the .NET 9 SDK or higher!". Choose Yes to open the .NET download (on Linux, Microsoft's install instructions), install the SDK, and start the editor again. The editor cannot start without the SDK, so it closes after this dialog. Installers for every platform are at https://dotnet.microsoft.com/en-us/download/dotnet/9.0.
The editor finds the SDK through the dotnet command, so dotnet must be on your PATH
(the .NET installers normally set this up). To check, run this in a terminal and look for
a 9.x or later SDK:
Creating a script¶
From the Content Browser¶
- In the Content Browser, open the folder you want the script in. Any folder under
Assetsworks, because the project compiles every.csfile there (see What gets compiled). - Right-click an empty area and choose New → Script.
- In the New Script dialog, type a Class Name. Below the field the dialog shows the
file it will create (
Creates: <ClassName>.cs), or a warning if that file already exists. - Optionally fill in Namespace. Left empty, the script uses the project's Default Namespace, which the field shows as a hint.
- Click Create.
Double-click the new file to open it in the built-in Text Editor. The class is not available to entities until the scripts are built, so save the file (which builds) or press Ctrl+B before you attach it.
From the viewport¶
Right-click an entity in the Scene viewport and choose Add Script. The editor:
- creates
<EntityName>_Script.csin theSourcefolder of the project's script folder (characters that are not valid in a C# name become_, and a number is added if the file already exists), - opens the file in the Text Editor,
- builds the scripts, and
- attaches the new class to the entity.
If the build fails, a Build Log window shows the compiler output. When the entity already has a working script, the menu shows Edit Script instead, which opens that script's source file.
The viewport's Create menu (the + button) also has Script. It creates
NewScript.cs in the same Source folder, opens it and builds it, but does not attach it
to anything.
What a new script contains¶
A new script is a class that derives from Entity, in the namespace you chose, with empty
OnCreate and OnUpdate methods:
using System;
using Hazel;
namespace MyProject
{
public class MyScript : Entity
{
protected override void OnCreate()
{
}
protected override void OnUpdate(float deltaTime)
{
}
}
}
OnUpdate runs once per simulation step of its time runner (50 Hz by default), and its
argument is the step length in seconds. Entity lifecycle lists every
callback, and Time runners explains the fixed-step clocks behind them.
Attaching a script to an entity¶
- Select the entity. In the Inspector (the properties area of the Scene Hierarchy panel), click Add Component and choose Script.
- In the Script component, click the Script Class field and pick your class. The list shows each class with its namespace; type to narrow it.
The script's public fields then appear below Script Class, where you can edit them per entity. An entity runs one script: to swap it, choose a different class in Script Class.
To open an entity's script, right-click the entity in the viewport and choose Edit Script, or select it and press Ctrl+/. In Edit mode, when it is the only entity selected, the viewport's selection controls also show an Edit Script button.
Renaming a script class
Entities refer to a script by its full name, namespace included. After you rename a class or change its namespace, the Script Class field turns red on entities that used the old name. Pick the class again to reconnect them.
Project files¶
The editor generates the C# solution with premake. These files sit in your project:
| File | Location | Edit it? |
|---|---|---|
premake5.lua |
Project folder | Yes. The editor creates it the first time, and from then on it is yours. Put your own build settings here. Keep the engine-location option at the top and the line that includes ScriptProject.Generated.lua. |
ScriptProject.Generated.lua |
Project folder | No. The editor rewrites it from the project settings every time the project opens. |
<AssemblyName>.sln |
Project folder | No. Generated from premake5.lua. |
<AssemblyName>.csproj |
The project's script folder, under Assets/Scripts |
No. Generated from premake5.lua. |
Win-CreateScriptProjects.bat (Windows), CreateScriptProjects.sh (Linux, macOS) |
Project folder | No. Run it to regenerate the .sln and .csproj without opening the editor. The editor rewrites it on every project open. |
<AssemblyName> is the project's Script Assembly Name, usually the project name. The
.sln, .csproj and helper script point at the editor installation that last opened the
project; opening the project in a different installation updates them.
Version control
Commit premake5.lua and your .cs files. The .gitignore that the editor writes for
new projects already excludes the generated .sln, .csproj and helper scripts, and
the Binaries and Intermediates folders.
What gets compiled¶
- Every
.csfile underAssets, including scripts that come with installed packs. You never add files to the project by hand. - Except the compiled-output folders, and any folder whose name ends in
~(for exampleExperiments~). Put.csfiles there that you want to keep but not compile.
The project targets .NET 9 with nullable reference types enabled, which is why the
examples in these docs write RobotControllerComponent? for a component that may be
missing. The output is <AssemblyName>.dll in the project's Script Module Path
(Assets/Scripts/Binaries by default). The editor always builds the Debug configuration.
Working in an IDE¶
Build → Open Visual Studio Solution opens <AssemblyName>.sln in whichever application
your system associates with .sln files. Any IDE that opens .NET SDK-style solutions
works, and it gets code completion for the whole scripting API. The menu item is
unavailable until the solution exists.
Build → Regenerate Visual Studio Solution regenerates the .sln and .csproj from
premake5.lua. Run it after you change premake5.lua. The editor also regenerates them
before every build it starts, when the project opens, and when you add or delete a script in
the Content Browser.
When you build in your IDE, the assembly lands in the Script Module Path and the editor reloads it on its own. Saving a file in an external editor does not start a build: build in the IDE, or press Ctrl+B in the editor.
Inspector edits change your source
When you change a script field in the Inspector, the editor also writes the new value
into that field's initialiser in the .cs file, so it becomes the script's default.
Array fields and entity or asset reference fields are the exception. Your IDE will report
the file as changed on disk.
Building¶
Choose Build → Build C# Assembly, or press Ctrl+B. The result appears as a notification:
- Build Succeeded. The editor then reloads the scripts.
- Build Failed:
<File>.cs(click to open). Click the notification to open the first file with an error in the Text Editor.
The full compiler output, with every error and warning, goes to the Log panel.
The editor also builds on its own:
- when a project opens,
- when you save a
.csfile in the built-in Text Editor, - after Add Script and Create (+) → Script in the viewport.
Reloading scripts¶
In Edit mode, the editor reloads the scripts whenever the compiled assembly changes, after a build from the editor or from your IDE. Script field values on entities are kept across the reload.
During Play, the reload waits until you stop the scene. The editor also reloads the scripts every time Play stops, so a build made while playing takes effect then.
Build → Reload C# Assembly reloads the last compiled assembly without building.
Project scripting settings¶
Open Settings (the gear in the side bar, or Edit → Settings) and choose Project → Scripting:
| Setting | Description |
|---|---|
| Script Module Path | The folder the compiled assembly goes to, Assets/Scripts/Binaries by default. Read-only on this page. |
| Default Namespace | The namespace new scripts are created in. Must be a valid C# namespace; dots are allowed, for example MyProject.Robots. |
| Script Assembly Name | The name of the compiled .dll and of the generated .sln and .csproj. Must be a valid C# identifier: letters, digits and underscores, not starting with a digit. |
| Automatically Reload Assembly | Has no effect in this release. Scripts always reload after a build. |
After you change Script Assembly Name, the page shows "Scripts must be rebuilt for this change to take effect." next to a Build C# Assembly button. Click it to regenerate the project files under the new name and rebuild. If a namespace or assembly name is not valid, the page says why in red, and the value is not saved.
Upgrading projects from older releases¶
The first time a project from an older release opens in 2026.3, the editor brings its script project up to date:
- No
premake5.lua(projects from 2026.2): the editor creates one and regenerates the.slnand.csproj. Settings you added to the old.csprojby hand are not kept; add them topremake5.luainstead. - A
premake5.luawritten by an older engine release: the editor renames it topremake5.lua.legacy, writes a freshpremake5.lua, and the Log shows "Replaced the legacy premake5.lua of '' with the current one. The old file was kept as ' '." If you had customised the old file, copy your changes across from the .legacycopy. - A
premake5.luayou wrote yourself is left as it is.
Troubleshooting¶
| Symptom | What to do |
|---|---|
| "Lucky Engine requires the .NET 9 SDK or higher!" at startup | Install the .NET 9 SDK, then check that dotnet --list-sdks lists it in a new terminal. |
| Build C# Assembly is greyed out and Ctrl+B does nothing | The solution has not been generated yet. Choose Build → Regenerate Visual Studio Solution and read the errors in the Log. |
| Notification "Failed to regenerate the C# project. See the console for details." | The Log has the error from the project generator. A mistake in premake5.lua is the usual cause. |
| Build Failed | Click the notification to open the file, and read the full list of errors in the Log. |
| Script Class is red | The class was not found. Build the scripts, and check the class name and namespace. |
| A change does not show up | The scripts were not rebuilt (saving in an external editor does not build), or the scene is playing and the reload is waiting for you to stop. |
| A script stops working during Play | Exceptions thrown by scripts appear in the Log as C# Exception: …. Use Log.Info to print your own values there. |
A failed build does not remove scripts from entities. Their scripts and field values come back with the next successful build.
Where to go next¶
- Entity lifecycle: every callback a script can override.
- Editor attributes: shape how script fields look in the Inspector.
- Viewing Files: the built-in Text Editor and the other file tabs.
- Settings: the rest of the Settings panel.
- API reference: the scripting API, grouped by area.