makspll / bevy_mod_scripting

Bevy Scripting Plugin
Apache License 2.0
397 stars 31 forks source link

Serializing script variables #12

Open Semihazah opened 2 years ago

Semihazah commented 2 years ago

Two questions:

  1. Can you serialize scripts alongside the entities in scenes?
  2. Can you set variables in the script and serialize those as well?

When I work with scripts in Godot, I attach a script to a node, then export a variable from that script so that that particular script instance has a unique value. While there is no editor, is it possible to encode this data in a scene?

makspll commented 2 years ago

So out of the box, scripts state is not serialised at all, since state is stored inside the ScriptContexts resource and afaik resources are not touched by the scene system in bevy.

Now I am quite new to the whole ECS thing, and I am also used to mixing data and logic like Godot or Unity do.

However, I think it helps to think of the scripts as just another system in bevy, since that's essentially what they are as seen in this core system: https://github.com/makspll/bevy_mod_scripting/blob/f776e1501b79e931bea38c4476d1ac0d486c92b4/bevy_mod_scripting/src/hosts/mod.rs#L493

And having said that, I personally think serialising any script state/variables would be an anti-pattern. A more ECS-friendly approach would be to use your script to modify components (data) which then in turn get serialised, and can be modified by the upcoming editor.

But if you really want to use some sort of dedicated per-script state, you could probably create a blackboard or dedicated state component. But also worth noting is the fact that all your script variables (state variable in Rhai, and any globals in Lua) persist for the lifetime of the script (but they do not survive serialization).

When writing this library I am taking a lot of inspiration from the way Noita handled its script API as seen here: https://noita.fandom.com/wiki/Modding:_Lua_API. AFAIK they use ECS and scripts are pure control layers.

Hope that helps!

EDIT:

For point 1. I am not sure what is required for serialization/deserialization into the scene but in a recent commit I added reflection derives to ScriptCollection so that may work

makspll commented 2 years ago

I've done some more work in the area and I am confident currently the script components will persist a save/load cycle but none-of contexts will so I need to improve this

makspll commented 2 years ago

I am going to split this into two issues.

Serializing script variables can be handled by external plugins, you'd just need an on_serialize hook which would tell the script to serialize, or to populate some component with data, and then you could serialize that data.

coderedart commented 2 years ago

what exactly does serializing script variables mean?

like using https://github.com/MrGVSV/bevy_proto to load/unload/save scenes with entity data (like godot's .TSCN format) and attach scripts to those entities (like godot's .gd files) together? then easily load / save those scenes + script functionality for quick development / editing of levels?

or only pure scripts which save / load some serializable state like data / cache (remember previous player xp / story checkpoint / active equipped weapon etc..)?

makspll commented 2 years ago

@coderedart the latter, the former is supported in that script components are persisted across bevy scenes