arcadia-unity / Arcadia

Clojure in Unity
http://arcadia-unity.github.io/
Apache License 2.0
1.68k stars 108 forks source link

Status of this project #388

Open SylvianHemus opened 2 years ago

SylvianHemus commented 2 years ago

Just curious -- what's the status of Arcadia? It hasn't been updated for a few years. Is it complete at this point?

TheWitheredStriker commented 1 year ago

It seems to have been abandoned by the developers, although it still works as it should on Unity 2021.3 LTS (not on 2022.1 though). Some people in the community have considered forking it for continued maintenance, but nothing has come of it so far. I do not have the experience to do that at the moment and others seem not to have the time.

For now, Arcadia is largely abandonware, but I hope that this will change in the future. If I ever get to a point where I have both the skill and the time to fork/maintain it, I will, but for now I can't do much.

darthdeus commented 1 year ago

Any idea how difficult it would be to make it work on 2022.1, or what are the reasons for it not working there? I'm relatively new to Clojure but know a bit about Unity, so I'm curious what change Unity introduced that caused Arcadia to break.

TheWitheredStriker commented 1 year ago

I don't know the details. All I can tell you is that Arcadia is now prevented from running play mode. I wish I could help you more.

TheWitheredStriker commented 1 year ago

@darthdeus I have asked around in the Arcadia chatroom over at Gitter for you. I highly recommend joining it if you are interested in Arcadia, even if the group isn't super active. It'll make coordination a bit easier :) https://gitter.im/arcadia-unity/Arcadia

kamisori commented 1 year ago

i mean, have you seen what tims is working on now? https://www.youtube.com/watch?v=Mc2r2qmC0y4 live edit games as they run

https://www.youtube.com/watch?v=Y3qadZY8inY

Folcon commented 1 year ago

@darthdeus so I had a project working with unity 2021.2.1f1, not seen any issues.

Just tried it with 2022.1.20f1 with the instructions here.

It seems to load and work fine?

image

What problems are you seeing?

I'm not an arcadia core dev, but I have been keeping an eye on the project =)...

TheWitheredStriker commented 1 year ago

That's strange. I've heard from @ekhart that Arcadia no longer works for him. Perhaps he can give us some more info.

darthdeus commented 1 year ago

Okay so I tried it, I ran into one error after adding Arcadia in Unity 2022.1.17f1 (just downloaded the latest release zip and copy pasted into assets). The error was

PrecompiledAssemblyException: Multiple precompiled assemblies with the same name Ionic.Zip.dll included on the current platform. Only one assembly with the same name is allowed per platform.

I clicked on the Ionic.Zip.dll in the arcadia folder, disabled it, and the error went away and it seems to start nREPL that I can connect to from emacs? I'm not entirely sure if it's working because I kinda ran out of time and needed to do different things for a few days, but I wonder if this is the error others ran into, or if there are other problems?

Folcon commented 1 year ago

Hi @darthdeus, possible? I think I've seen that error before.

The reason I pointed specifically to the instructions I used previously is that I know they produce a working output on my side. It would be good to shake out any issues with the process and fix them.

darthdeus commented 1 year ago

A little update, after a little bit of fiddling I got it to somewhat work, basically just ran this

user> (use 'arcadia.core)
user> (import '[UnityEngine GameObject Time Mathf Transform Vector3])
user> (set! (.. (object-named "Player") transform position) (Vector3.))

and saw the player move. All it took was disabling the Ionic.Zip, which I configured like this for Arcadia to compile image

Seems there's a lot of errors from fiddling with the REPL though

image

Here's the two stacktraces for anyone who wants to look into things

TypeNotFoundException: Unable to find type: clojure.stacktrace
clojure.lang.RT.classForNameE (System.String p) (at <fb1204dbf0b848beaab1559f81f1b22c>:0)
clojure.lang.CljCompiler.Ast.HostExpr.MaybeType (System.Object form, System.Boolean stringOk) (at <fb1204dbf0b848beaab1559f81f1b22c>:0)
clojure.lang.Compiler.MacroexpandSeq1 (clojure.lang.ISeq form) (at <fb1204dbf0b848beaab1559f81f1b22c>:0)
clojure.lang.Compiler.macroexpand1 (System.Object form) (at <fb1204dbf0b848beaab1559f81f1b22c>:0)
clojure.lang.Compiler.Macroexpand (System.Object form) (at <fb1204dbf0b848beaab1559f81f1b22c>:0)
clojure.lang.Compiler.eval (System.Object form) (at <fb1204dbf0b848beaab1559f81f1b22c>:0)
clojure$core$eval__3112.invokeStatic (System.Object ) (at <f25e268922394fd0aa90bd66a9e9327d>:0)
clojure$core$eval__3112.invoke (System.Object ) (at <f25e268922394fd0aa90bd66a9e9327d>:0)
clojure.lang.Var.invoke (System.Object arg1) (at <fb1204dbf0b848beaab1559f81f1b22c>:0)
Arcadia.NRepl+EvalFn.invoke () (at Assets/Plugins/Arcadia/Editor/NRepl.cs:299)
arcadia$internal$callbacks$run_callbacks__28828.invokeStatic (System.Object , System.Object ) (at <f25e268922394fd0aa90bd66a9e9327d>:0)
arcadia$internal$callbacks$run_callbacks__28828.invoke (System.Object , System.Object ) (at <f25e268922394fd0aa90bd66a9e9327d>:0)
arcadia$internal$editor_callbacks$run_callbacks__28922.invokeStatic () (at <f25e268922394fd0aa90bd66a9e9327d>:0)
arcadia$internal$editor_callbacks$run_callbacks__28922.invoke () (at <f25e268922394fd0aa90bd66a9e9327d>:0)
clojure.lang.Var.invoke () (at <fb1204dbf0b848beaab1559f81f1b22c>:0)
Arcadia.EditorCallbacks.RunCallbacks () (at Assets/Plugins/Arcadia/Editor/EditorCallbacks.cs:24)

and second one

NullReferenceException: Object reference not set to an instance of an object
Arcadia.NRepl.HandleMessage (BencodeNET.Objects.BDictionary message, System.Net.Sockets.TcpClient client) (at Assets/Plugins/Arcadia/Editor/NRepl.cs:471)
Arcadia.NRepl+<>c__DisplayClass36_0.<StartServer>b__1 () (at Assets/Plugins/Arcadia/Editor/NRepl.cs:580)
UnityEngine.Debug:LogException(Exception)
Arcadia.<>c__DisplayClass36_0:<StartServer>b__1() (at Assets/Plugins/Arcadia/Editor/NRepl.cs:584)
System.Threading.ThreadHelper:ThreadStart()

In either case, I'm a little scared to proceed, so I'll just put my Arcadia exploration on hold until/if the situation stabilizes a bit :) I'm currently a little scared to play with it more since this is a non-trivially sized game that'll be released in a few months at most.

TheWitheredStriker commented 1 year ago

https://github.com/arcadia-unity/Arcadia/tree/ifrit

Interesting – this appears to be an active branch of Arcadia ahead of the main branch, and one of the main devs (@timsgardner) actually contributed to it as recent as last November. Does this branch have the same issues as the main one?

benjamin-asdf commented 1 year ago
Arcadia.NRepl.HandleMessage (BencodeNET.Objects.BDictionary message, System.Net.Sockets.TcpClient client) (at Assets/Arcadia/Editor/NRepl.cs:398)
Arcadia.NRepl+<>c__DisplayClass36_0.<StartServer>b__1 () (at Assets/Arcadia/Editor/NRepl.cs:580)
UnityEngine.Debug:LogException(Exception)
Arcadia.<>c__DisplayClass36_0:<StartServer>b__1() (at Assets/Arcadia/Editor/NRepl.cs:584)
System.Threading.ThreadHelper:ThreadStart()

This is when cider asks for eldoc or info. I have fixed and improved this #389

This is because cider tries to pretty print a stacktrace but resolving clojure.stacktrace/print-cause-trace throws an error at that point.

(defun cider-default-err-eval-handler ()
  "Display the last exception without middleware support."
  (cider--handle-err-eval-response
   (cider-nrepl-sync-request:eval
    "(clojure.stacktrace/print-cause-trace *e)")))

This should be somewhat fixed with a recent version of cider because it has a check:

 (defun cider-default-err-handler ()
  "This function determines how the error buffer is shown.
It delegates the actual error content to the eval or op handler."
  (cond ((cider-nrepl-op-supported-p "analyze-last-stacktrace")
         (cider-default-err-op-handler))
        ((cider-library-present-p "clojure.stacktrace")
         (cider-default-err-eval-handler))
        (t (cider-default-err-eval-print-handler)))) 
    With a recent cider, you will get error overlays by default because it detects no stacktrace support. 
    This currently brings another rought edge with Arcadia nrepl, because it outputs an empty string to stdout for eval. 

A current workaround would be to redefine cider-interactive-eval-handler like so:


(defun cider-interactive-eval-handler (&optional buffer place)
  "Make an interactive eval handler for BUFFER.
PLACE is used to display the evaluation result.
If non-nil, it can be the position where the evaluated sexp ends,
or it can be a list with (START END) of the evaluated region.
Update the cider-inspector buffer with the evaluation result
when `cider-auto-inspect-after-eval' is non-nil."

  (let* ((eval-buffer (current-buffer))
         (beg (car-safe place))
         (end (or (car-safe (cdr-safe place)) place))
         (beg (when beg (copy-marker beg)))
         (end (when end (copy-marker end)))
         (fringed nil)
         (res ""))
    (nrepl-make-response-handler (or buffer eval-buffer)
                                 (lambda (_buffer value)
                                   (setq res (concat res value))
                                   (cider--display-interactive-eval-result res end))
                                 (lambda (_buffer out)
                                   (cider-emit-interactive-eval-output out))
                                 (lambda (_buffer err)
                                   (cider-emit-interactive-eval-err-output err)

                                   (when (not (string-empty-p err))
                                     (when (or (not cider-show-error-buffer)
                                               (not (cider-connection-has-capability-p 'jvm-compilation-errors)))

                                       ;; Display errors as temporary overlays
                                       (let ((cider-result-use-clojure-font-lock nil))
                                         (cider--display-interactive-eval-result
                                          err end 'cider-error-overlay-face))))
                                   (cider-handle-compilation-errors err eval-buffer))
                                 (lambda (buffer)
                                   (if beg
                                       (unless fringed
                                         (cider--make-fringe-overlays-for-region beg end)
                                         (setq fringed t))
                                     (cider--make-fringe-overlay end))
                                   (when (and cider-auto-inspect-after-eval
                                              (boundp 'cider-inspector-buffer)
                                              (windowp (get-buffer-window cider-inspector-buffer 'visible)))
                                     (cider-inspect-last-result)
                                     (select-window (get-buffer-window buffer)))
                                   (when cider-eval-register
                                     (set-register cider-eval-register res))))))

https://github.com/clojure-emacs/cider/compare/master...benjamin-asdf:cider:do-not-display-empty-err-overlays

SylvianHemus commented 1 year ago

Just wanted to thank all contributors for posting updates

TheWitheredStriker commented 1 year ago

My pleasure! =)

TheWitheredStriker commented 1 year ago

https://github.com/arcadia-unity/Arcadia/tree/ifrit

Interesting – this appears to be an active branch of Arcadia ahead of the main branch, and one of the main devs (@timsgardner) actually contributed to it as recent as last November. Does this branch have the same issues as the main one?

Has anyone tried out this branch, out of curiosity?

TheWitheredStriker commented 1 year ago

I tried using Arcadia myself. It is currently completely unusable for me in every possible way.

I can't attach Arcadia scripts to components with Arcadia Behaviours (it just says "No functions"), and I can't use the REPL either, because anything I do nets me an error:

image

At this point, I am very close to giving up completely. Arcadia no longer works and no one seems to have both the time and the interest to maintain the repository. It's really just sad, since using Clojure in Unity is so much cooler than C#. :(

kamisori commented 1 year ago

as i also said on gitter: the REPL works fine, there is no function "log", but you can try println.

though more as a joke, admittedly. you get something out of that (use 'arcadia.core), and the REPL does what its supposed to... idk whats wrong on your machine but to be sure im not making a fool out of myself, (i was pretty certain arcadia would still work) so just downloaded their hubby app, installed unity, checked out arcadia, started sublimetext, updated my nrepl checkout, badda boom badda bam, im an idiot, log is there, something is wrong on your machine but arcadia aint it checked out from 9fbc2fd.

so, what exactly are talking about? i'll try out some of my old projects in the mean time

edit: the long startup times of this is not worth figuring out how i figured my toy projects should work... i dont know what is wrong with arcadia, but yeah unity version and arcadia commit. is neccessary to have a coherent discussion: up there i see now i had tried 9fbc2fd with 2020.1.11f1 which isnt as ancient as with the projects running in a 2019.3.5f1.. but still seem to compile and start up fine with 9fbc i will try current LTS 2021.3.24f1 next and try to come up with some sort of example project i could leave here. it's been a while.

TheWitheredStriker commented 1 year ago

as i also said on gitter: the REPL works fine, there is no function "log", but you can try println

Also as said on Gitter :P

Strange, I could've sworn I saw people use a function "log" before. Thanks for the reply! I'll give Arcadia another go soon.

TheWitheredStriker commented 1 year ago

Oh, wait. I just saw your edit.

Yeah, I figured that "log" is a real function, and that it doesn't work. I'm in my exam period right now, so my schedule is a bit crammed; but as soon as I find a bit of free time I'll take a look at my install of Arcadia to see what's wrong. What do you suggest I do?

kamisori commented 1 year ago

o hi

i would check your unity version, arcadia commit and repl client. most likely is the repl client though

cpackard commented 1 year ago

@TheWitheredStriker I was able to get a basic scene running with a REPL and the log function like below (click to toggle each step):

1. Installing Arcadia with Unity Follow the steps in [Getting Started doc](https://github.com/arcadia-unity/Arcadia/wiki/Getting-Started#start-unity-project): 1. Download latest stable version of Unity (`2022.3.9f1` as of 2023-09-09) 2. Create a new project from the default 3D template. 3. In the Unity editor click *Edit* from the menu bar and then *Project Settings*. In the *Player* tab toggle *Other Settings*. Then in the *Configuration* section change *Api Compatibility Level* to *.NET Framework*. 4. From a terminal, `cd` into the `Assets` folder of your project's directory, then clone the Arcadia repository: `cd my-proj/Assets && git clone https://github.com/arcadia-unity/Arcadia.git` After Unity loads the new code (i.e. modal disappears) open the Console in the Unity editor and you should see a log message saying "Arcadia Started!" ![image](https://github.com/arcadia-unity/Arcadia/assets/6462409/eae60f60-41fc-4b27-bd9e-35ed18630933) Finally, from the Unity menu bar select Arcadia → AOT Compile to compile all of Arcadia's source code into your project for faster load times. The logs should look like this: ![image](https://github.com/arcadia-unity/Arcadia/assets/6462409/c1c24655-1351-4c15-9c4c-dbba71fdc4e7)
2. Creating a Unity object and attaching an Update script To get a basic script working I followed the docs from the Using Arcadia section of the wiki, specifically [Hooks and State](https://github.com/arcadia-unity/Arcadia/wiki/Using-Arcadia#hooks-and-state) and [Storing a Start-hook in the scene](https://github.com/arcadia-unity/Arcadia/wiki/Using-Arcadia#storing-a-start-hook-in-the-scene). First, create a new file `my-proj/Assets/game/core.clj` with the following contents: ```clojure (ns game.core (:use arcadia.core) (:use arcadia.linear)) (defn log-name [obj role-key] (log (.name obj))) (defn spawn-cube "Spawns a cube `n` units in front of the `MainCamera`" [name & {:keys [n] :or {n 3}}] (let [cube (create-primitive :cube name) tr-cam (. Camera/main transform)] (set! (.. cube transform position) (v3+ (. tr-cam position) (v3* (. tr-cam forward) n))))) (comment (require 'game.core) (when-not (object-named "Nice Cube") (spawn-cube "Nice Cube")) (hook+ (object-named "Nice Cube") :update :log-name #'log-name)) ``` Then, eval each expression in the `comment` block to the REPL, switch to the Unity editor, and **save the updated scene**. * To connect to the REPL in emacs I ran the command `M-x cider-connect` with `localhost` for the host and `3722` as the port, upon which I can load a basic nREPL buffer.

After running those steps, you should have an Arcadia-generated cube in your scene with an Update script attached:

image

Playing the scene confirms that it is, indeed, a nice cube 😎

image

I hope this helps!

(note: this worked with both the default master branch as well as the ifrit branch)

TheWitheredStriker commented 1 year ago

Woah! That's incredible, and in deep detail! Thank you so much, Christian!

So the go-to-way to create and attach Clojure scripts is by using the REPL?

cpackard commented 1 year ago

Woah! That's incredible, and in deep detail! Thank you so much, Christian!

So the go-to-way to create and attach Clojure scripts is by using the REPL?

No problem! I’m not sure if it’s the go-to way as I just started looking into this project today. Either way I would love to use Clojure as the language to interface with Unity so if I find out more I’ll be sure to report back.