Origo is a lightweight, platform-agnostic C# game framework. It uses the SND (Strategy-Node-Data) model and isolates engine code through adapters.
- Engine-free Core:
Origo.Corehas no engine dependency. - SND Entity Model: behavior (
Strategy), view (Node), and state (Data) are separated. - Stateless Strategy Pool: strategies are shared and validated at registration.
- Layered Runtime:
SystemRun -> ProgressRun -> SessionManager -> SessionRun. - Foreground/Background Session Parity: background sessions run the same strategy logic and lifecycle as foreground sessions.
- Built-in Save Flow: current workspace + snapshot slots.
- Official Godot 4 Adapter:
Origo.GodotAdapterfor bootstrap and runtime integration. - TCP Remote Console:
Origo.ConsoleBridgefor agent-driven development over a network connection. - Source Generation:
Origo.SourceGenerationgenerates strongly-typedTypedDataaccessors at compile time via Roslyn incremental generator. - Active Strategy: type-safe inter-entity service invocation via
InvokeStrategy<TInput, TOutput>. - Dynamic Strategy Management: add/remove strategies at runtime with full lifecycle hooks (
AfterAdd/BeforeRemove).
Full documentation: origo.manual
Note: Documentation is written entirely in Chinese due to its scale. If you need to use it, feed the repository as a knowledge base to an AI agent and query the agent for answers.
Origo supports creating background sessions that execute the same gameplay logic path as the foreground session. This means you can run AI simulation, procedural generation, or long-running world updates in memory while keeping exactly the same strategy behavior and data contracts.
Create one with ctx.SessionManager.CreateBackgroundSession(key, levelId) and process it through the same session pipeline.
Origo.ConsoleBridge provides a TCP-based remote console for agent-driven development. External tools (e.g., AI coding agents) can send console commands and receive command output over a TCP connection, enabling automated gameplay testing and runtime inspection.
# Connect via any TCP client
nc localhost 9876Note: The Console Bridge only carries console I/O — command input and command output. Runtime logs are handled by the engine/logger independently and do not travel through the bridge.
<PackageReference Include="Origo.Core" />
<PackageReference Include="Origo.GodotAdapter" />
<PackageReference Include="Origo.ConsoleBridge" />NuGet packages are published via GitHub Releases. Download the
.nupkgfiles from the latest release, place them in./packages/origo/, and configurenuget.configto add the local package source (a samplenuget.configis included in the release assets).<?xml version="1.0" encoding="utf-8"?> <!-- nuget.config (place in your Godot project root) --> <configuration> <packageSources> <add key="origo-local" value="./packages/origo/" /> </packageSources> </configuration>Commit
nuget.configto your repository so all contributors share the same package source. Addpackages/to your.gitignore—.nupkgbinaries should not be tracked by version control.
<ProjectReference Include="../Origo.Core/Origo.Core.csproj" />
<ProjectReference Include="../Origo.GodotAdapter/Origo.GodotAdapter.csproj" />Godot
[GlobalClass]resolution: Godot resolves[GlobalClass]by script resource path and may fail to locateOrigoDefaultEntryregardless of which option you chose above (NuGet or ProjectReference). Workaround: create a bridge class in your project:[GlobalClass] public partial class MyOrigoEntry : GodotAdapter.Bootstrap.OrigoDefaultEntry { }Then point your
.tscnnode script toMyOrigoEntryinstead.
res://origo/
entry/entry.json
maps/scene_aliases.map
maps/snd_templates.map
initial/
Attach OrigoDefaultEntry to your startup scene, then set:
ConfigPathSceneAliasMapPathSndTemplateMapPathSaveRootPathInitialSaveRootPath
using Origo.Core.Snd;
using Origo.Core.Snd.Strategy;
[StrategyIndex("game.player_move", Priority = 100)]
public sealed class PlayerMoveStrategy : EntityStrategyBase
{
public override void Process(ISndEntity entity, double delta, ISndContext ctx)
{
var (found, speed) = entity.TryGetData<float>("speed");
if (!found) return;
// movement logic...
}
}Priority: Strategy priority (default 6205). Process and all lifecycle hooks execute in ascending priority order; same priority uses insertion order (FIFO). Lower values execute first.
{
"name": "Player",
"node": { "pairs": { "sprite": "player_sprite" } },
"strategy": { "indices": ["game.player_move"] },
"data": { "pairs": { "speed": { "type": "Single", "data": 200.0 } } }
}OrigoDefaultEntryboots runtime.- Load entry save/config.
- Spawn entities from metadata.
- Execute strategy
Processeach frame. - Save to
current/, then snapshot tosave_xxx/.
Origo.Core/
Origo.SourceGeneration/
Origo.ConsoleBridge/
Origo.GodotAdapter/
Origo.Core.Tests/
Origo.ConsoleBridge.Tests/
Origo.GodotAdapter.Tests/
scripts/
Origo.sln
Run the same pipeline as CI from repository root:
bash scripts/ci.shQuick test-only run:
bash scripts/run-test.shMIT. See LICENSE.