packages/app/modulus
m

modulus

c56b5d8app

A modular and data driven engine written in Odin

0 stars0 forksUnknownupdated 4 months ago
Open repo

modulus

A high-performance, ultra-modular engine runtime written in Odin. The runtime is a pure loader — everything runs as a dynamically loaded module.

Philosophy

  • The runtime loads one app module at startup. That module owns everything: game, editor, server, tools.
  • Modules are shared libraries (.so / .dll) with a defined ABI
  • no engine coupling.
  • Hot-reload is a first-class dev feature, stripped entirely in release builds.
  • All performance-sensitive paths are compile-time gated. Release builds are uncompromising.

Requirements

  • Odin compiler in PATH
  • Linux (Windows cross-compilation supported, native Windows in progress)
  • inotify-tools for make watch (hot-reload source watching): sudo apt install inotify-tools

Build

make build          # debug build (hot-reload, logging enabled)
make release        # release build (all dev features stripped, -o:aggressive)
make rebuild        # clean + debug build
make build-module   # rebuild only the module .so (use while engine is running)

Run

make run                    # run default module from build.conf
make run MODULE=my_app      # run a specific module
make run-release            # release build then run

Hot-reload dev workflow

make run          # terminal 1 — engine running, watching .so for changes
make watch        # terminal 2 — watches modules/**/*.odin, rebuilds .so on save

Edit any module source file, save, and the engine reloads it automatically. Requires inotify-tools. No-op if MODULUS_HOT_RELOAD=false in build.conf.

Project structure

engine/
  core/         ABI types, feature flags, logging interface
  host/         Module loader, runtime loop
  platform/     OS abstractions (dynamic libraries, file watcher)
modules/
  test_module/  Reference module implementation
scripts/        build.sh, run.sh, clean.sh
build.conf      Default build flags and module name
main.odin       Entry point — calls host.run()

Writing a module

A module is any shared library that exports modulus_get_module_api:

package my_module

import core "mod:engine/core"

module_api := core.Module_API{
    name    = "my_module",
    version = 1,
    init     = proc(ctx: ^core.Engine_Context) -> bool { return true },
    update   = proc(ctx: ^core.Engine_Context, dt: f64) {},
    shutdown = proc(ctx: ^core.Engine_Context) {},
}

@(export)
modulus_get_module_api :: proc() -> ^core.Module_API {
    return &module_api
}

Build it as a DLL and pass the path to the runtime:

odin build modules/my_module -build-mode:dll -collection:mod=. -out:build/linux_amd64/modules/my_module.so
./build/linux_amd64/bin/modulus ./build/linux_amd64/modules/my_module.so

Build flags (build.conf)

Flag Default Effect
MODULUS_DEBUG true Enables verbose logging. Stripped in release.
MODULUS_HOT_RELOAD true Enables file watcher and live module reload. Stripped in release.
MODULE test_module Default module name for make run.

Override per-invocation without editing the file:

MODULUS_HOT_RELOAD=false make build
make run MODULE=editor

Release mode forces all feature flags off regardless of build.conf.

Package Info
Version
c56b5d8
License
Unknown
Author
@p-victor
Type
app
Forks
0
Created
4 months ago
Updated
4 months ago
Health
maintained
has releases
has readme
has license
Activity
last 56 weeks