How to use MAGIC in a Unity project: compile your Clojure to .clj.dll with the nos CLI outside Unity, then load it at play time through the magic-unity UPM package. The package also rewrites MAGIC's IL during IL2CPP builds (iOS, Android, consoles).
This is the consumer-side guide. For what the package contains and how its internals work, see magic-unity. For the deps.edn / magic.edn compile workflow in depth, see Porting a Clojure library to MAGIC.
-
Install
nos(build-time only; needs themonoruntime, no .NET SDK). See Install in the root README for the one-line installer. -
Add the package to
Packages/manifest.json, pinned to a tag from the releases page. Pick one variant (see Choosing a variant):{ "dependencies": { "sg.flybot.magic.unity": "https://github.com/flybot-sg/magic.git?path=magic-unity#<tag>" } } -
Add
deps.ednandmagic.ednat your project root.deps.edndeclares your source:pathsand any:deps;magic.ednpoints the build at Unity's plugins folder:;; magic.edn {:build {:namespaces [my.game.core] :out "Assets/Plugins/Magic"}}
A project with custom build/test steps can still hand-write a
dotnet.cljinstead (see the porting guide);unity-examples/magic-unity-smokedoes, because its test runner is notclojure.test. -
Compile before opening Unity:
nos build
This drops your
.clj.dllintoAssets/Plugins/Magic/, where Unity loads them. -
Open Unity and hit Play. For CI,
nos testruns the Mono-sideclojure.testsuites without Unity. IL2CPP-only regressions need a real Unity build.
The package ships in two variants, identical except for whether the runtime .clj.dll plugins are visible to the Editor:
sg.flybot.magic.unity (default) |
sg.flybot.magic.unity.dual |
|
|---|---|---|
| Runtime in the Editor | loadable | excluded (!UNITY_EDITOR) |
| MAGIC in Editor Play mode | works | not available (Editor uses stock ClojureCLR) |
| Alongside stock ClojureCLR | benign console noise, handled by the guard | silent (runtime absent from the Editor) |
| Player builds (Mono / IL2CPP) | identical | identical |
- Default if MAGIC runs in your Editor (Play mode, edit-mode tooling) and there is no stock ClojureCLR.
.dualif your Editor runs stock ClojureCLR (REPL / hot-reload) and MAGIC ships only in player builds. Pin?path=magic-unity-dual#<tag>.
Full comparison and rationale: magic-unity, Package variants.
A project that keeps stock ClojureCLR in the Editor and ships MAGIC in players runs both runtimes. With the default variant the Editor prints one benign Assembly is incompatible with the editor line per runtime .clj.dll on each domain reload (Unity narrating the intended exclusion; player builds are unaffected). The .dual variant excludes the runtime from the Editor by construction, so those lines never appear. Either way the stock probe for clojure.core.clj is kept away from the fork assemblies (#25).
The in-repo reproduction is unity-examples/magic-unity-coexist: bb coexist-noise checks that the dual variant is silent, bb coexist-noise magic-only reproduces the noise on the default variant.
unity-examples/magic-unity-smoke: standalone IL2CPP regression suite. The reference pattern fordeps.ednand a customdotnet.clj, with aMAGIC -> Smoke -> Build & Run IL2CPPmenu. Run by hand on Unity 2022.3.62f3.unity-examples/magic-unity-coexist: coexistence repro that vendors stock ClojureCLR, driven bybb coexist-noise.