Start
Install the SDK, open the Code Workspace, and create your first project.
Learning hub
Follow the path from setup to gameplay code, sprites, physics, tilemaps, audio, particles, debugging, and preview builds. No visual editor needed.
Install the SDK, open the Code Workspace, and create your first project.
Write C# entities, add components, move the player, and draw sprites.
Load a tilemap, set camera bounds, use collision, triggers, audio, and particles.
Use console logs, diagnostics, profiler output, and temp Preview Play safely.
Step 1
The installer gives users the Code Workspace, runtime, Engine.dll API, templates, and build tools.
Open the setup file. It installs the modern editor, runtime, SDK, templates, and helper scripts.
Open NoEditorEngine Code Workspace from Desktop or Start Menu.
%LOCALAPPDATA%\NoEditorEngine\NoEditorEngine-0.8\
editor/
runtime/
sdk/
templates/
Step 2
The workspace is not a scene editor. It is a code-focused place to edit scripts, build, preview, and read logs.
Open scripts, assets, maps, sounds, and project.json without leaving the workspace.
Edit .cs files with line numbers, tabs, save support, search, and Engine API completion.
Run dotnet build, read compiler output, and jump to diagnostics by file and line.
Build into a temp folder, run the C++ runtime, capture logs, then clean temp files.
Step 3
A NoEditorEngine game is just a folder with config, C# scripts, and assets.
MyGame/
project.json
scripts/
Game.csproj
Game.cs
Player.cs
assets/
maps/
level1.json
sprites/
sounds/
{
"name": "MyGame",
"version": "0.8",
"mainAssembly": "scripts/bin/Debug/net8.0/Game.dll",
"mainClass": "Game",
"startScene": "assets/maps/level1.json",
"window": {
"width": 1280,
"height": 720,
"title": "My Game"
},
"performance": {
"targetFps": 240,
"fixedPhysicsFps": 60,
"maxDeltaTime": 0.05,
"enableFrameLimiter": true
}
}
Step 4
Entities are the gameplay objects. Components add behavior like rendering, physics, audio, and particles.
using Engine;
public class Player : Entity
{
public override void Awake()
{
Name = "Player";
}
public override void Start()
{
Log.Info("Player started");
}
public override void Update(float deltaTime)
{
}
public override void OnDestroy()
{
Log.Info("Player destroyed");
}
}
Step 5
Use Rigidbody2D velocity instead of directly pushing through walls with Transform changes.
using Engine;
public class Player : Entity
{
Rigidbody2D rb;
public float Speed = 300f;
public override void Start()
{
rb = AddComponent<Rigidbody2D>();
rb.UseGravity = false;
}
public override void Update(float dt)
{
Vector2 move = Vector2.Zero;
if (Input.IsKeyDown(KeyCode.W)) move.Y += 1;
if (Input.IsKeyDown(KeyCode.S)) move.Y -= 1;
if (Input.IsKeyDown(KeyCode.A)) move.X -= 1;
if (Input.IsKeyDown(KeyCode.D)) move.X += 1;
if (move.Length() > 0)
move = move.Normalized();
rb.Velocity = move * Speed;
}
}
Tip: Normalized movement keeps diagonal movement from becoming faster.
Step 6
SpriteRenderer draws one texture. AnimatedSpriteRenderer switches named clips over time.
var sprite = AddComponent<SpriteRenderer>();
sprite.TexturePath = "assets/sprites/player.png";
sprite.Size = new Vector2(64, 64);
var anim = AddComponent<AnimatedSpriteRenderer>();
anim.AddAnimation("Idle", new[]
{
"assets/player_idle_1.png",
"assets/player_idle_2.png"
}, fps: 4, loop: true);
anim.AddAnimation("Walk", new[]
{
"assets/player_walk_1.png",
"assets/player_walk_2.png"
}, fps: 8, loop: true);
anim.Play("Idle");
if (move.Length() > 0)
{
anim.Play("Walk");
if (move.X < 0) anim.FlipX = true;
if (move.X > 0) anim.FlipX = false;
}
else
{
anim.Play("Idle");
}
Step 7
BoxCollider2D creates an AABB collider. Trigger colliders send trigger events without physically pushing entities.
var collider = AddComponent<BoxCollider2D>();
collider.Size = new Vector2(48, 48);
collider.Layer = CollisionLayer.Player;
public override void OnCollisionEnter(Entity other)
{
Log.Info("Hit " + other.Name);
}
public override void OnTriggerEnter(Entity other)
{
Log.Info("Trigger touched " + other.Name);
}
Use for walls, enemies, and physical blockers.
Use for coins, checkpoints, doors, and invisible sensors.
Set wall Rigidbody2D as static so the player resolves against it.
Step 8
Tilemaps define walls, empty space, coins, and player spawn points through JSON.
{
"tileSize": 64,
"width": 16,
"height": 10,
"layers": [
{
"name": "Walls",
"solid": true,
"tiles": [
"################",
"#..............#",
"#....P.....C...#",
"#..............#",
"################"
]
}
],
"legend": {
"#": { "type": "wall", "sprite": "assets/wall.png", "solid": true },
".": { "type": "empty" },
"P": { "type": "player_spawn" },
"C": { "type": "coin" }
}
}
public class Game : Entity
{
public override void Start()
{
Tilemap map = Scene.LoadTilemap("assets/maps/level1.json");
Player player = Scene.Spawn(new Player());
player.Transform.Position = map.PlayerSpawn;
Camera.Main.Follow(player, smooth: 8.0f);
Camera.Main.SetBounds(0, 0, map.WorldWidth, map.WorldHeight);
}
}
Step 9
The camera affects rendering only. Entity Transform.Position always stays in world coordinates.
Camera.Main.Follow(player, smooth: 8.0f);
Camera.Main.DeadZone = new Vector2(120, 80);
Camera.Main.Zoom = 1.0f;
Camera.Main.SetBounds(0, 0, map.WorldWidth, map.WorldHeight);
Rule: Camera movement should never change the player's Transform.Position.
Step 10
Use AudioSource for short WAV sounds and ParticleEmitter for lightweight effects.
var audio = AddComponent<AudioSource>();
audio.Clip = "assets/sounds/coin.wav";
audio.Volume = 0.8f;
audio.Play();
var dust = AddComponent<ParticleEmitter>();
dust.MaxParticles = 256;
dust.EmitRate = 20;
dust.Lifetime = 0.5f;
dust.Speed = 120;
dust.Size = 6;
dust.Play();
public class Coin : Entity
{
public override void OnTriggerEnter(Entity other)
{
Log.Info("Coin collected");
Scene.Destroy(this);
}
}
Step 11
Use keyboard debug tools during preview to inspect runtime behavior without adding editor features.
[Profiler]
FPS: 238
Frame Time: 4.16 ms
Update: 0.30 ms
Physics: 0.45 ms
Render: 1.10 ms
Draw Calls: 8
Collision Checks: 145
Troubleshooting
Most first-project issues are path, build, or class-name problems. These are the first things to check.
Press Build first and check that project.json mainAssembly points to the built DLL.
Make sure project.json mainClass matches the C# class name exactly, for example Game.
Check asset path spelling. Paths are relative to the project folder, not the editor folder.
Use Rigidbody2D velocity and BoxCollider2D. Walls should have solid static colliders.
Next steps
After these lessons, try making a small scene with a player, coins, walls, camera follow, sound, and particles.
Create a player that moves with WASD, cannot walk through walls, collects a coin trigger, plays a sound, and uses Camera.Main follow.