Getting Started with WitEngine: Your First 15 Minutes
So you've heard about WitEngine—a distributed computing platform that can turn everything from smart TVs to high-end servers into a unified compute mesh. Sounds cool, but where do you actually start?
This post gets you from zero to running code in about 15 minutes. No theory lectures. No architecture deep-dives. Just clone, build, run, and see something work.
What We're Working With
WitEngine.Public—a repository containing example controllers (plugins) for WitEngine. This is your playground for:
- Understanding how WitEngine plugins work
- Running and modifying working examples
- Building your own controllers
- Testing everything locally before thinking about distributed execution
The repo includes four complete controllers: Variables (basic types), Special (utilities), Grid (distributed operations), and Matrices (linear algebra). Each one is a real, working plugin you can learn from.
Prerequisites
You'll need:
- .NET 10 SDK — Download here
- An IDE — Visual Studio 2022+, JetBrains Rider, or VS Code with C# extensions
That's it. No special tools, no complex setup.
Step 1: Clone and Open (2 minutes)
git clone https://github.com/dmitrat/WitEngine.Public.git
cd WitEngine.PublicOpen OutWit.slnx in your IDE. You'll see a solution with multiple projects organized by controller:
WitEngine.Public/
├── Variables/
│ ├── OutWit.Controller.Variables/ # The actual plugin
│ ├── OutWit.Controller.Variables.Model/ # Shared data models
│ └── OutWit.Controller.Variables.Tests/ # Test suite
├── Special/
│ ├── OutWit.Controller.Special/
│ └── OutWit.Controller.Special.Tests/
├── Grid/
│ ├── OutWit.Controller.Grid/
│ ├── OutWit.Controller.Grid.Model/
│ └── OutWit.Controller.Grid.Tests/
├── Matrices/
│ ├── OutWit.Controller.Matrices/
│ ├── OutWit.Controller.Matrices.Model/
│ └── OutWit.Controller.Matrices.Tests/
└── OutWit.slnxEach controller follows the same pattern: implementation, models (if needed), and tests. Once you understand one, you understand them all.
Step 2: Run the Tests (3 minutes)
Let's make sure everything works:
dotnet testYou should see all tests pass. If something fails, check your .NET version (dotnet --version should show 10.x).
What just happened? The test projects use WitEngineSdk—a development version of the WitEngine runtime that lets you compile and execute WitEngine scripts locally. No cluster required.
Step 3: Understand What You're Looking At (5 minutes)
Let's peek inside the simplest controller: Variables.
The Script Language
WitEngine has its own scripting language. Here's a tiny example:
Job:Test()
{
Int:a = 5;
Int:b = 10;
Int:result = Int.Add(a, b);
Trace("Result:", result);
}This declares two integers, adds them, and logs the result. Simple, right?
What Controllers Provide
Controllers define:
- Variables — Data types you can use in scripts (
Int,String,DoubleCollection, etc.) - Activities — Operations you can perform (
Int.Add,String.Concat,Trace, etc.)
The Variables controller provides basic types. The Special controller provides utilities like Trace and Return. The Grid controller provides Grid.ForEach for distributed processing.
A Real Test
Open Variables/OutWit.Controller.Variables.Tests/ and find any test file. Here's what a typical test looks like:
[Test]
public async Task IntAddReturnsCorrectSum()
{
// Compile a WitEngine script
var job = WitEngineSdk.Instance.Compile(@"
Job:Test()
{
Int:a = 5;
Int:b = 3;
Int:result = Int.Add(a, b);
Return(result);
}
");
// Execute it
var status = await WitEngineSdk.Instance.ScheduleAndWaitAsync(job);
// Check the result
Assert.That(status.Result, Is.EqualTo(WitProcessingResult.Completed));
Assert.That(status.ReturnedValues.First(), Is.EqualTo(8));
}That's the pattern:
- Write a script as a string
- Compile it with
WitEngineSdk.Instance.Compile() - Run it with
WitEngineSdk.Instance.ScheduleAndWaitAsync() - Check the results
Step 4: Modify Something (5 minutes)
Learning by reading is fine. Learning by breaking things is better.
Experiment 1: Change a Test
Find a simple test in the Variables controller. Change the expected result to something wrong:
Assert.That(status.ReturnedValues.First(), Is.EqualTo(999)); // Wrong!Run the tests. Watch it fail. Now you know the test is actually checking something.
Experiment 2: Add a Trace
Modify a test to add Trace statements:
var job = WitEngineSdk.Instance.Compile(@"
Job:Test()
{
Int:a = 5;
Int:b = 3;
Trace(""Adding"", a, ""and"", b);
Int:result = Int.Add(a, b);
Trace(""Result is"", result);
Return(result);
}
");Run the test with your debugger. The trace output shows up in the test output—useful for understanding execution flow.
Experiment 3: Try Something Invalid
What happens with a syntax error?
var job = WitEngineSdk.Instance.Compile(@"
Job:Test()
{
Int:a = ; // Syntax error!
}
");The compiler throws an exception with a helpful message. This is how you'll debug your own scripts.
What's Inside Each Controller
Now that you've got things running, here's a quick map of what each controller provides:
Variables Controller
The foundation. Provides:
- Primitives:
Int,Double,Bool,String,Long - Collections:
IntCollection,DoubleCollection,StringCollection,ObjectCollection - Operations: Arithmetic (
Int.Add,Double.Multiply), string manipulation (String.Concat,String.Length), collection utilities (Collection.Add,Collection.Count)
Special Controller
Utilities that every script needs:
Trace(...)— Log messages during executionReturn(...)— Return values from a job- Conditional execution support
Grid Controller
The distributed computing magic:
Grid.ForEach(item in collection) => Transformer(item)— Process items in parallel across nodes
This is where WitEngine becomes interesting. A single line distributes work across your entire cluster.
Matrices Controller
Linear algebra operations:
- Sparse matrix multiplication (Gustavson algorithm)
- Row-by-matrix operations designed for distribution
- Benchmarking for load balancing
This controller demonstrates a real computational workload with proper benchmarking.
SDK Limitations (Important!)
The SDK you're using has intentional limits:
| Limit | Value |
|---|---|
| Max activities per job | 50 |
| Max variables per job | 100 |
| Max execution time | 5 minutes |
| Max nodes | 1 (local only) |
| Max variable size | 100 MB |
These limits exist because the SDK is for development, not production. When you deploy to WitCloud, these limits disappear.
But for learning and testing? The SDK is perfect.
Your Next 15 Minutes
You've got the environment running. Here's what to explore next:
If you want to understand the code structure:
- Read through
WitControllerVariables.cs— see how a controller registers its activities - Look at any Activity class — see the pattern of properties and attributes
- Check the corresponding Adapter class — see where the actual logic lives
If you want to build something:
- Follow the pattern in Variables to create a new activity
- Start simple: an activity that takes one input and produces one output
- Write a test first, then make it pass
If you want to understand distributed execution:
- Look at the Grid controller
- Study how
Grid.ForEachtransforms a collection operation into distributable work - Check the Matrices controller for benchmarking patterns
Quick Reference
Clone and run:
git clone https://github.com/dmitrat/WitEngine.Public.git
cd WitEngine.Public
dotnet testNuGet packages for your own projects:
dotnet add package OutWit.Engine.Sdk
dotnet add package OutWit.Engine.Data
dotnet add package OutWit.Engine.InterfacesKey classes:
WitEngineSdk.Instance.Compile()— Parse a scriptWitEngineSdk.Instance.ScheduleAndWaitAsync()— Execute a jobIWitControllerHost/IWitControllerNode— Interfaces your controller implements
Wrap Up
You now have:
- A working WitEngine development environment
- Four example controllers to learn from
- The ability to write, compile, and test WitEngine scripts locally
The SDK is your sandbox. Break things. Experiment.