Skip to main content
12 years of engine work, now open

Extend the game
without touching
the engine.

UniversalCore turns hardcoded, recompile-required C++ systems into declarative, scriptable, observable platforms — so you ship features in Lua, Python and YAML, not engine patches.

20+
subsystems
Lua
+ Python + YAML
0
engine edits
›_features/rejoin_dungeon.luaLUA · copy
-- register a feature, no C++ required
local d = core.feature {
  id       = "rejoin_dungeon",
  rejoin   = true,
  on_enter = function(player, ctx)
    if ctx:has_flag("cleared") then
      return player:teleport(ctx.checkpoint)
    end
    ctx:spawn_wave("stage_1")
  end,
}
hot-reloaded in the running client · no recompile
One platform, four layers
FoundationsSubsystemsDeveloper ExperienceOperations
// The platform

Everything the engine never gave you.

Scripting foundation

A first-class bridge that exposes engine primitives, event hooks and messaging to Lua and Python — write features, not patches.

foundations

Declarative content

Drops, affects, skills and UI move from hardcoded C++ to YAML + Lua declarations you can read, diff and hot-reload.

config

Composable subsystems

Avatars, dungeons, skill graphs and more — each built on the same foundation, each extendable without forking the engine.

subsystems

Real developer UX

Source maps, a quest/forge compiler and a remote debugger for Lua and Python — set a breakpoint in the running client.

developer-experience

Built-in observability

Structured logs, faucet/sink profiling and a server-wide backoffice — see what your economy and players are actually doing.

operations

Clean dev APIs

Precise, documented, versioned interfaces with fixed extension points — so integrating a custom feature is a pleasure, not a hunt.

architecture
// Declarative by default

Describe it. Don't hardcode it.

Systems that used to mean editing the engine and recompiling become plain declarations. Tune a drop table or an affect in YAML, wire the behaviour in Lua, and reload — the running client picks it up.

Tip

Every declaration is validated on load, so a typo fails fast with a source-mapped error — not a silent crash mid-raid.

›_drops/boss_wing.yamlYAML · copy
boss_wing:
  from: "metin_of_rage"
  rolls:
    - item: "wing_of_dawn"   chance: 0.5
    - item: "soul_shard"     chance: 12.0
›_affects/warmup.luaLUA · copy
core.affect("warmup", {
  duration = 30,
  apply = function(p) p:mod("atk_spd", 0.15) end,
})

Read the story behind the platform.

Start with the docs, or follow the build journal on the blog.