Skip to content

ScriptAsset loading is script evaluation, and why Script IDs? #426

Open
@shanecelis

Description

@shanecelis

Firstly, I love bevy_mod_scripting. It's a huge part of why I thought the prospect of Nano-9 seemed feasible. As an avid user I've developed some opinions. Let me relate them as issues.

Problem: ScriptAsset loading is script evaluation

I've got two problem instances for this general problem.

Problem Instance 1: Multiple scripts

In Nano-9 I'm trying to support someone providing multiple scripts in a shared context environment like this:

scripts = [
"vector.p8", // p8 is just the Pico-8 dialect of Lua, which I translate into vanilla Lua.
"actor.p8",
"platformer.p8",
"dolly.p8",
"main.lua",
]

This happens through an AssetLoader, which is restricted environment; it's an async function where I don't have access to the world or resources, etc. Some of the scripts do depend on the preceding scripts. Although I load these ScriptAssets sequentially using an immediate loader, they are evaluated in an indeterminate order, which often means the wrong order.

Problem Instance 2: Can't setup the environment fast enough

I'd really like to be able to support having a hello world script that looked like this:

print("hello world")

However, because of this issue, it must currently look like this:

function _init()
   print("hello world")
end

The reason is that in my config file where I load the code, I also load the sprite sheets and color palette. I need to set up the color palette before I can call print().

Solution A: Don't do that.

I could punt the loading of scripts outside of the AssetLoader but images, sounds, fonts, etc. load this way, why not scripts?

Solution B: Separate script evaluation and script loading.

Let's evaluate scripts at another time, perhaps when they're added to a ScriptComponent.

Solution C: Evaluate scripts in order of load.

If we can't change the evaluation after loading can we ensure the order they're evaluated is the order they were loaded?

Problem: ScriptIds complicate everything

The script IDs have been a hassle for me to get right. I’ve added and removed and changed my asset path to script id mapper many times. And when it stops working, it’s hard for me to figure out why.

As an aside, I added Reflect to everything once so I could see what was going on in the inspector. (This was before it was part of BMS proper. Love seeing a changes that mimic my own homebrew!)

When I take a step back I mostly don’t understand why script IDs exist.

I thought maybe you’d want it like that so you could add ScriptComponent(["hello.lua"]) and then it would use the path to load the script, but we have to load the Handle for "hello.lua" ourselves anyway and store it, so we’re not saved from dealing with Handles by using Script IDs.

Solution A: Use the handles.

What if we used the prevalent Bevy pattern and used handles directly?

ScriptComponent([asset_server.load("foo.lua")])

You could even specify the language on load:

asset_server.load_with_settings("hello.p8", |settings: &mut ScriptSettings| {
   settings.language = Language::Lua;
});

Maybe ScriptAsset could look like this?

pub struct ScriptAsset {
    /// The body of the script
    pub content: Box<[u8]>,
    /// The language of the script
    pub language: Language,
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions