unavi-xyz/unavi

Scripting

kayhhh opened this issue · 5 comments

kayhhh commented

I laid out some ideas in the wired repo, but we need something concrete to start with and work off of.
We need a way to let users write scripts, save them to the scene, then load + run them in a sandbox at runtime.

What language?

  • Original plan was isolated WASM modules (with a Rust API)
  • I did see a few bevy scripting libraries for using scripting languages like Rhai or Lua (https://github.com/makspll/bevy_mod_scripting)
    • Might work better for hot-reloading
    • Scripting languages would be easier for users to write than Rust
    • Unsure about the sandboxxing capabilities

But I think I'll still go with WASM. Rust is what I enjoy writing, and WASM works better for the vision I put in the wired repo. I eventually want some sort of node system built on this lower level Rust API, so people can use that instead of writing code for simpler behaviors.

How will you write scripts?

  • create a project folder they can open and edit with their IDE and work out of.
    • there is a web api for linking to the file system so web support is not out of the question, just not super supported by browsers right now (and I have no idea whether wasm-bindgen supports it)
  • can we support hot reloading scripts with WASM?
kayhhh commented

Making some progress on this using the wasm component model. This is still very new tech, but it seems to be working well enough for us to use it? Still need to see if I can get it working on native, then will need to see if I can get it working in the browser (I did see some shim libraries for running component model wasm in the browser, since it is not yet supported and likely wont for a while).

The process of writing these scripts would be by creating a .wit interface file, then implementing it in your language of choice via generated bindings - right now wit-bindgen supports Rust, Go, and C, but aims to support more languages in the future like JavaScript and Python.

.wit file creation isn't the best experience right now, I don't even have syntax highlighting for it, but as I said this is new tech and should improve over time. There are also dependency management solutions being worked on to allow the publishing of WASM packages. Overall WASM components seems like a perfect fit for The Wired.

kayhhh commented

Awesome. Got a setup working in bevy for loading + running any arbitrary WASM file that implement the "script" component interface from the wired protocol. Scripts export functions like init and update, and can make use of host system imports.

I think this is basically it for the base scripting framework. Only thing left is web support, then we're good to start building out the API.

kayhhh commented

Been researching what do to about web support. I think what we want is a generalized wrapper API that internally uses either wasmtime for native, or js-sys browser APIs for web. There doesn't seem to be a up to date solution for this that supports the component model, but I did see a promising project working on it. For now I think I'll delay web support and keep an eye on that repo.

OK, thanks to some awesome wasm libraries I think everything is ready. Its now mostly just a matter of writing out WASM APIs for scripts to use.

On main we have a solid pipeline for writing WASI 0.2.0 components in WIT + Rust, then loading and running them in the app on both native and web. The end result isnt too dissimilar from what I had originally prototyped out, but the whole process is more complete now with better handling of component dependencies, the usage of WASI for system APIs (ie we can write to stdout from within scripts), and the ability to run in the web.