Compare commits

...

25 commits
v0.4.0 ... main

Author SHA1 Message Date
Jarosław Konik
fa70abac23
Add annotations about Ruby only being supported on Linux (#64)
Some checks failed
Book / test (push) Has been cancelled
Deploy book / deploy (push) Has been cancelled
Rust / build (push) Has been cancelled
2025-06-01 18:28:22 +02:00
41d0fd57f3 Bump version
Some checks failed
Book / test (push) Has been cancelled
Deploy book / deploy (push) Has been cancelled
Rust / build (push) Has been cancelled
2025-06-01 14:21:40 +02:00
Curt Reyes
e430795dce
Compile on windows (#62)
* Don't check for rdynamic linking on Windows for now, fixes Windows builds

---------

Co-authored-by: Jaroslaw Konik <konikjar@gmail.com>
2025-06-01 14:19:43 +02:00
Jarosław Konik
c6bdfb1400
Fix rb-sys version (#60) 2025-05-27 19:55:13 +02:00
Jarosław Konik
450962b1d0
Bump version to 0.9.0 (#59)
Some checks failed
Book / test (push) Has been cancelled
Deploy book / deploy (push) Has been cancelled
Rust / build (push) Has been cancelled
2025-05-27 19:35:32 +02:00
Jarosław Konik
53479f94b5
Ruby support (#19)
Some checks are pending
Book / test (push) Waiting to run
Deploy book / deploy (push) Waiting to run
Rust / build (push) Waiting to run
Add support for Ruby language
2025-05-27 19:19:52 +02:00
Jarosław Konik
f2bb079c60
Update README.md (#58) 2025-05-23 08:53:07 +02:00
56fd44062c Bump version
Some checks failed
Deploy book / deploy (push) Has been cancelled
Rust / build (push) Has been cancelled
2025-05-07 14:37:51 +02:00
Jarosław Konik
297bffd060
Make value struct fields public, add examples (#44) 2025-05-07 14:23:26 +02:00
Peter David Faria
2c82a2fa0e
Added initial support for bevy 0.16.0 (#39)
* Added initial support for bevy 0.16.0

* Removed unnecessary bevy feature

* update version references

---------

Co-authored-by: Jaroslaw Konik <konikjar@gmail.com>
2025-05-01 11:18:52 +02:00
Jarosław Konik
ec84d9e740
move demo up (#37) 2025-04-18 08:54:33 +00:00
GolDNenex
f9e872e111
Update bevy 0.15 (#36)
* Update bevy 0.15

* Removed unused import "AsyncReadExt"

* Update README.md

* Update lib.rs

* Update README.md

* Fix cargo test by not running examples that never end in lib.rs

* get rid of warnings

* update version references

* dont run examples

* deny warnings

* remove obsolete runners

---------

Co-authored-by: Jarosław Konik <konikjar@gmail.com>
2025-04-15 21:27:08 +02:00
gak
a718aa7ce6
smallest typo fix ever: life -> live (#25) 2024-07-28 07:09:33 +02:00
Dennis
be8a80519d
Added add_scripting_api function to AppBuilder (#23)
* Added `add_scripting_api` function to builder
2024-07-17 10:36:00 +02:00
Jarosław Konik
f85dbcffe2
update readme (#22) 2024-07-05 17:26:25 +02:00
Jarosław Konik
182f26e273
update book bevy support matrix (#21) 2024-07-05 17:21:00 +02:00
Jarosław Konik
7488de076b
support bevy 0.14 (#20)
* support bevy 0.14
2024-07-05 17:16:06 +02:00
Jarosław Konik
eaffce5c6d
add demo (#17) 2024-06-16 07:54:48 +02:00
0766aef930 update version 2024-06-16 07:26:25 +02:00
7a8721f78f readme 2024-06-16 07:25:40 +02:00
a2ddb9b5c1 link to book 2024-06-16 07:25:11 +02:00
94b64f37a8 fix book build 2024-06-16 07:20:19 +02:00
3887e544b1 fix book build 2024-06-16 07:14:41 +02:00
6a30384aef change book action 2024-06-16 07:12:28 +02:00
Jarosław Konik
6726e40768
Lua support (#16)
* adds Lua language support
* makes the library generic, allowing for easy extension for more languages
* small improvements and fixes
2024-06-16 07:06:09 +02:00
185 changed files with 8753 additions and 789 deletions

54
.github/workflows/book.yml vendored Normal file
View file

@ -0,0 +1,54 @@
name: Book
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Cache Ruby
id: cache-ruby
uses: actions/cache@v4
with:
path: rubies
key: ${{ runner.os }}-ruby
- name: Install Ruby
if: steps.cache-ruby.outputs.cache-hit != 'true'
env:
CC: clang
run: |
url="https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.4.tar.gz"
prefix=`pwd`/rubies/ruby-3.4
mkdir rubies
mkdir ruby_src
curl -sSL $url | tar -xz
cd ruby-3.4.4
mkdir build
cd build
../configure --without-shared --prefix=$prefix
make install
echo $prefix/bin >> $GITHUB_PATH
- name: Add Ruby to PATH
run: |
prefix=`pwd`/rubies/ruby-3.4
echo $prefix/bin >> $GITHUB_PATH
- name: Install latest mdbook
run: |
tag=$(curl 'https://api.github.com/repos/rust-lang/mdbook/releases/latest' | jq -r '.tag_name')
url="https://github.com/rust-lang/mdbook/releases/download/${tag}/mdbook-${tag}-x86_64-unknown-linux-gnu.tar.gz"
mkdir mdbook
curl -sSL $url | tar -xz --directory=./mdbook
echo `pwd`/mdbook >> $GITHUB_PATH
- name: Test Book
run: |
cd book
export CARGO_MANIFEST_DIR=$(pwd)
cargo build
mdbook test -L target/debug/deps/

38
.github/workflows/deploy_book.yml vendored Normal file
View file

@ -0,0 +1,38 @@
name: Deploy book
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: write # To push a branch
pages: write # To push to a GitHub Pages site
id-token: write # To update the deployment status
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install latest mdbook
run: |
tag=$(curl 'https://api.github.com/repos/rust-lang/mdbook/releases/latest' | jq -r '.tag_name')
url="https://github.com/rust-lang/mdbook/releases/download/${tag}/mdbook-${tag}-x86_64-unknown-linux-gnu.tar.gz"
mkdir mdbook
curl -sSL $url | tar -xz --directory=./mdbook
echo `pwd`/mdbook >> $GITHUB_PATH
- name: Build Book
run: |
cd book
mdbook build
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
# Upload entire repository
path: 'book/book'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

View file

@ -2,27 +2,48 @@ name: Rust
on:
push:
branches: [ "main" ]
branches: ["main"]
pull_request:
branches: [ "main" ]
branches: ["main"]
env:
CARGO_TERM_COLOR: always
jobs:
build:
runs-on: ubuntu-latest
env:
RUSTFLAGS: -D warnings
steps:
- uses: actions/checkout@v3
- name: Clippy
run: cargo clippy --verbose -- -D warnings
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
- name: Install cargo-examples
run: cargo install cargo-examples
- name: Run all examples
run: cargo examples
- uses: actions/checkout@v3
- name: Cache Ruby
id: cache-ruby
uses: actions/cache@v4
with:
path: rubies
key: ${{ runner.os }}-ruby
- name: Install Ruby
if: steps.cache-ruby.outputs.cache-hit != 'true'
env:
CC: clang
run: |
url="https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.4.tar.gz"
prefix=`pwd`/rubies/ruby-3.4
mkdir rubies
mkdir ruby_src
curl -sSL $url | tar -xz
cd ruby-3.4.4
mkdir build
cd build
../configure --without-shared --prefix=$prefix
make install
- name: Add Ruby to PATH
run: |
prefix=`pwd`/rubies/ruby-3.4
echo $prefix/bin >> $GITHUB_PATH
- name: Clippy
run: cargo clippy --all-features --verbose -- -D warnings
- name: Build
run: cargo build --all-features --verbose
- name: Run tests
run: cargo test --all-features --verbose

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
/target
/Cargo.lock
.vscode
.nvim.lua

View file

@ -1,22 +1,217 @@
[package]
name = "bevy_scriptum"
authors = ["Jaroslaw Konik <konikjar@gmail.com>"]
version = "0.4.0"
edition = "2021"
version = "0.9.1"
edition = "2024"
license = "MIT OR Apache-2.0"
readme = "README.md"
categories = ["game-development"]
description = "Plugin for Bevy engine that allows you to write some of your game logic in a scripting language"
description = "Plugin for Bevy engine that allows you to write some of your game or application logic in a scripting language"
repository = "https://github.com/jarkonik/bevy_scriptum"
keywords = ["bevy", "rhai", "scripting", "game", "gamedev"]
keywords = ["bevy", "lua", "scripting", "game", "script"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
lua = ["dep:mlua", "mlua/luajit"]
rhai = ["dep:rhai"]
ruby = ["dep:magnus", "dep:rb-sys"]
[dependencies]
bevy = { default-features = false, version = "0.13.0", features = [
"bevy_asset",
] }
bevy = { default-features = false, version = "0.16", features = ["bevy_asset", "bevy_log"] }
serde = "1.0.162"
rhai = { version = "1.14.0", features = ["sync", "internals", "unchecked"] }
rhai = { version = "1.14.0", features = [
"sync",
"internals",
"unchecked",
], optional = true }
thiserror = "1.0.40"
anyhow = "1.0.82"
tracing = "0.1.40"
mlua = { version = "0.9.8", features = [
"luajit",
"vendored",
"send",
], optional = true }
magnus = { version = "0.7.1", optional = true }
rb-sys = { version = "0.9", default-features = false, features = ["link-ruby", "ruby-static"], optional = true }
crossbeam-channel = "0.5.15"
libc = "0.2.172"
[[example]]
name = "call_function_from_rust_rhai"
path = "examples/rhai/call_function_from_rust.rs"
required-features = ["rhai"]
[[example]]
name = "current_entity_rhai"
path = "examples/rhai/current_entity.rs"
required-features = ["rhai"]
[[example]]
name = "custom_type_rhai"
path = "examples/rhai/custom_type.rs"
required-features = ["rhai"]
[[example]]
name = "ecs_rhai"
path = "examples/rhai/ecs.rs"
required-features = ["rhai"]
[[example]]
name = "entity_variable_rhai"
path = "examples/rhai/entity_variable.rs"
required-features = ["rhai"]
[[example]]
name = "function_params_rhai"
path = "examples/rhai/function_params.rs"
required-features = ["rhai"]
[[example]]
name = "hello_world_rhai"
path = "examples/rhai/hello_world.rs"
required-features = ["rhai"]
[[example]]
name = "multiple_plugins_rhai"
path = "examples/rhai/multiple_plugins.rs"
required-features = ["rhai"]
[[example]]
name = "non_closure_system_rhai"
path = "examples/rhai/non_closure_system.rs"
required-features = ["rhai"]
[[example]]
name = "promises_rhai"
path = "examples/rhai/promises.rs"
required-features = ["rhai"]
[[example]]
name = "side_effects_rhai"
path = "examples/rhai/side_effects.rs"
required-features = ["rhai"]
[[example]]
name = "function_return_value_rhai"
path = "examples/rhai/function_return_value.rs"
required-features = ["rhai"]
[[example]]
name = "call_function_from_rust_lua"
path = "examples/lua/call_function_from_rust.rs"
required-features = ["lua"]
[[example]]
name = "current_entity_lua"
path = "examples/lua/current_entity.rs"
required-features = ["lua"]
[[example]]
name = "custom_type_lua"
path = "examples/lua/custom_type.rs"
required-features = ["lua"]
[[example]]
name = "ecs_lua"
path = "examples/lua/ecs.rs"
required-features = ["lua"]
[[example]]
name = "entity_variable_lua"
path = "examples/lua/entity_variable.rs"
required-features = ["lua"]
[[example]]
name = "function_params_lua"
path = "examples/lua/function_params.rs"
required-features = ["lua"]
[[example]]
name = "hello_world_lua"
path = "examples/lua/hello_world.rs"
required-features = ["lua"]
[[example]]
name = "multiple_plugins_lua"
path = "examples/lua/multiple_plugins.rs"
required-features = ["lua"]
[[example]]
name = "non_closure_system_lua"
path = "examples/lua/non_closure_system.rs"
required-features = ["lua"]
[[example]]
name = "promises_lua"
path = "examples/lua/promises.rs"
required-features = ["lua"]
[[example]]
name = "side_effects_lua"
path = "examples/lua/side_effects.rs"
required-features = ["lua"]
[[example]]
name = "function_return_value_lua"
path = "examples/lua/function_return_value.rs"
required-features = ["lua"]
[[example]]
name = "call_function_from_rust_ruby"
path = "examples/ruby/call_function_from_rust.rs"
required-features = ["ruby"]
[[example]]
name = "current_entity_ruby"
path = "examples/ruby/current_entity.rs"
required-features = ["ruby"]
[[example]]
name = "custom_type_ruby"
path = "examples/ruby/custom_type.rs"
required-features = ["ruby"]
[[example]]
name = "ecs_ruby"
path = "examples/ruby/ecs.rs"
required-features = ["ruby"]
[[example]]
name = "entity_variable_ruby"
path = "examples/ruby/entity_variable.rs"
required-features = ["ruby"]
[[example]]
name = "function_params_ruby"
path = "examples/ruby/function_params.rs"
required-features = ["ruby"]
[[example]]
name = "function_return_value_ruby"
path = "examples/ruby/function_return_value.rs"
required-features = ["ruby"]
[[example]]
name = "hello_world_ruby"
path = "examples/ruby/hello_world.rs"
required-features = ["ruby"]
[[example]]
name = "multiple_plugins_ruby"
path = "examples/ruby/multiple_plugins.rs"
required-features = ["ruby"]
[[example]]
name = "promises_ruby"
path = "examples/ruby/promises.rs"
required-features = ["ruby"]
[[example]]
name = "side_effects_ruby"
path = "examples/ruby/side_effects.rs"
required-features = ["ruby"]
[dev-dependencies]
tracing-subscriber = "0.3.18"
mlua = { version = "0.9.8", features = ["luajit", "vendored", "send"] }
rhai = { version = "1.14.0", features = ["sync", "internals", "unchecked"] }

189
README.md
View file

@ -1,32 +1,47 @@
# bevy_scriptum 📜
bevy_scriptum is a a plugin for [Bevy](https://bevyengine.org/) that allows you to write some of your game logic in a scripting language.
Currently, only [Rhai](https://rhai.rs/) is supported, but more languages may be added in the future.
![demo](demo.gif)
It's main advantages include:
bevy_scriptum is a a plugin for [Bevy](https://bevyengine.org/) that allows you to write some of your game or application logic in a scripting language.
### Supported scripting languages/runtimes
| language/runtime | cargo feature | documentation chapter |
| ------------------------------------------ | ------------- | --------------------------------------------------------------- |
| 🌙 LuaJIT | `lua` | [link](https://jarkonik.github.io/bevy_scriptum/lua/lua.html) |
| 🌾 Rhai | `rhai` | [link](https://jarkonik.github.io/bevy_scriptum/rhai/rhai.html) |
| 💎 Ruby(currently only supported on Linux) | `ruby` | [link](https://jarkonik.github.io/bevy_scriptum/ruby/ruby.html) |
Documentation book is available [here](https://jarkonik.github.io/bevy_scriptum/) 📖
Full API docs are available at [docs.rs](https://docs.rs/bevy_scriptum/latest/bevy_scriptum/) 🧑‍💻
bevy_scriptum's main advantages include:
- low-boilerplate
- easy to use
- asynchronicity with a promise-based API
- flexibility
- hot-reloading
Scripts are separate files that can be hot-reloaded at runtime. This allows you to quickly iterate on your game logic without having to recompile your game.
Scripts are separate files that can be hot-reloaded at runtime. This allows you to quickly iterate on your game or application logic without having to recompile it.
All you need to do is register callbacks on your Bevy app like this:
```rust
use bevy::prelude::*;
use bevy_scriptum::prelude::*;
use bevy_scriptum::runtimes::lua::prelude::*;
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(ScriptingPlugin::default())
.add_script_function(String::from("hello_bevy"), || {
println!("hello bevy, called from script");
});
.add_scripting::<LuaRuntime>(|runtime| {
runtime.add_function(String::from("hello_bevy"), || {
println!("hello bevy, called from script");
});
})
.run();
```
And you can call them in your scripts like this:
```rhai
hello_bevy();
```lua
hello_bevy()
```
Every callback function that you expose to the scripting language is also a Bevy system, so you can easily query and mutate ECS components and resources just like you would in a regular Bevy system:
@ -34,42 +49,47 @@ Every callback function that you expose to the scripting language is also a Bevy
```rust
use bevy::prelude::*;
use bevy_scriptum::prelude::*;
use bevy_scriptum::runtimes::lua::prelude::*;
#[derive(Component)]
struct Player;
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(ScriptingPlugin::default())
.add_script_function(
String::from("print_player_names"),
|players: Query<&Name, With<Player>>| {
for player in &players {
println!("player name: {}", player);
}
},
);
.add_scripting::<LuaRuntime>(|runtime| {
runtime.add_function(
String::from("print_player_names"),
|players: Query<&Name, With<Player>>| {
for player in &players {
println!("player name: {}", player);
}
},
);
})
.run();
```
You can also pass arguments to your callback functions, just like you would in a regular Bevy system - using `In` structs with tuples:
```rust
use bevy::prelude::*;
use bevy_scriptum::prelude::*;
use rhai::ImmutableString;
use bevy_scriptum::runtimes::lua::prelude::*;
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(ScriptingPlugin::default())
.add_script_function(
String::from("fun_with_string_param"),
|In((x,)): In<(ImmutableString,)>| {
println!("called with string: '{}'", x);
},
);
.add_scripting::<LuaRuntime>(|runtime| {
runtime.add_function(
String::from("fun_with_string_param"),
|In((x,)): In<(String,)>| {
println!("called with string: '{}'", x);
},
);
})
.run();
```
which you can then call in your script like this:
```rhai
fun_with_string_param("Hello world!");
```lua
fun_with_string_param("Hello world!")
```
### Usage
@ -78,97 +98,118 @@ Add the following to your `Cargo.toml`:
```toml
[dependencies]
bevy_scriptum = "0.2"
bevy_scriptum = { version = "0.9", features = ["lua"] }
```
or execute `cargo add bevy_scriptum` from your project directory.
Add the following to your `main.rs`:
```rust
use bevy::prelude::*;
use bevy_scriptum::prelude::*;
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(ScriptingPlugin::default())
.run();
```
or execute `cargo add bevy_scriptum --features lua` from your project directory.
You can now start exposing functions to the scripting language. For example, you can expose a function that prints a message to the console:
```rust
use rhai::ImmutableString;
use bevy::prelude::*;
use bevy_scriptum::prelude::*;
use bevy_scriptum::runtimes::lua::prelude::*;
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(ScriptingPlugin::default())
.add_script_function(
String::from("my_print"),
|In((x,)): In<(ImmutableString,)>| {
println!("my_print: '{}'", x);
},
);
.add_scripting::<LuaRuntime>(|runtime| {
runtime.add_function(
String::from("my_print"),
|In((x,)): In<(String,)>| {
println!("my_print: '{}'", x);
},
);
})
.run();
```
Then you can create a script file in `assets` directory called `script.rhai` that calls this function:
Then you can create a script file in `assets` directory called `script.lua` that calls this function:
```rhai
my_print("Hello world!");
```lua
my_print("Hello world!")
```
And spawn a `Script` component with a handle to a script source file`:
And spawn an entity with attached `Script` component with a handle to a script source file:
```rust
use bevy::prelude::*;
use bevy_scriptum::Script;
use bevy_scriptum::prelude::*;
use bevy_scriptum::runtimes::lua::prelude::*;
App::new()
.add_plugins(DefaultPlugins)
.add_scripting::<LuaRuntime>(|runtime| {
runtime.add_function(
String::from("my_print"),
|In((x,)): In<(String,)>| {
println!("my_print: '{}'", x);
},
);
})
.add_systems(Startup,|mut commands: Commands, asset_server: Res<AssetServer>| {
commands.spawn(Script::new(asset_server.load("script.rhai")));
});
commands.spawn(Script::<LuaScript>::new(asset_server.load("script.lua")));
})
.run();
```
You should then see `my_print: 'Hello world!'` printed in your console.
### Provided examples
You can also try running provided examples by cloning this repository and running `cargo run --example <example_name>`. For example:
You can also try running provided examples by cloning this repository and running `cargo run --example <example_name>_<language_name>`. For example:
```bash
cargo run --example hello_world
cargo run --example hello_world_lua
```
The examples live in `examples` directory and their corresponding scripts live in `assets/examples` directory within the repository.
### Bevy compatibility
| bevy version | bevy_scriptum version |
|--------------|----------------------|
| 0.13 | 0.4 |
| 0.12 | 0.3 |
| 0.11 | 0.2 |
| 0.10 | 0.1 |
|--------------|-----------------------|
| 0.16 | 0.8-0.9 |
| 0.15 | 0.7 |
| 0.14 | 0.6 |
| 0.13 | 0.4-0.5 |
| 0.12 | 0.3 |
| 0.11 | 0.2 |
| 0.10 | 0.1 |
### Promises - getting return values from scripts
Every function called from script returns a promise that you can call `.then` with a callback function on. This callback function will be called when the promise is resolved, and will be passed the return value of the function called from script. For example:
Every function called from script returns a promise that you can call `:and_then` with a callback function on. This callback function will be called when the promise is resolved, and will be passed the return value of the function called from script. For example:
```rhai
get_player_name().then(|name| {
print(name);
});
```lua
get_player_name():and_then(function(name)
print(name)
end)
```
which will print out `John` when used with following exposed function:
### Access entity from script
```rust
use bevy::prelude::*;
use bevy_scriptum::prelude::*;
use bevy_scriptum::runtimes::lua::prelude::*;
App::new()
.add_plugins(DefaultPlugins)
.add_scripting::<LuaRuntime>(|runtime| {
runtime.add_function(String::from("get_player_name"), || String::from("John"));
});
````
## Access entity from script
A variable called `entity` is automatically available to all scripts - it represents bevy entity that the `Script` component is attached to.
It exposes `.index()` method that returns bevy entity index.
It exposes `index` property that returns bevy entity index.
It is useful for accessing entity's components from scripts.
It can be used in the following way:
```rhai
print("Current entity index: " + entity.index());
```lua
print("Current entity index: " .. entity.index)
```
`entity` variable is currently not available within promise callbacks.
### Contributing
Contributions are welcome! Feel free to open an issue or submit a pull request.

View file

@ -7,8 +7,7 @@ currently being supported with security updates.
| Version | Supported |
| ------- | ------------------ |
| 0.1 | :x: |
| 0.2 | :white_check_mark: |
| 0.9 | :white_check_mark: |
## Reporting a Vulnerability

View file

@ -0,0 +1,13 @@
local my_state = {
iterations = 0,
}
function on_update()
my_state.iterations = my_state.iterations + 1;
print("on_update called " .. my_state.iterations .. " times")
if my_state.iterations >= 10 then
print("calling quit");
quit();
end
end

View file

@ -0,0 +1,7 @@
-- entity is a global variable that is set to the entity that is currently being processed,
-- it is automatically available in all scripts
-- get name of the entity
get_name(entity):and_then(function(name)
print(name)
end)

View file

@ -0,0 +1,4 @@
-- Create a new instance of MyType
my_type = MyType();
-- Call registered method
print(my_type:my_method())

View file

@ -0,0 +1 @@
print_player_names()

View file

@ -0,0 +1,3 @@
-- entity is a global variable that is set to the entity that is currently being processed,
-- it is automatically available in all scripts
print("Current entity index: " .. entity.index)

View file

@ -0,0 +1,4 @@
fun_with_string_param("hello")
fun_with_i64_param(5)
fun_with_multiple_params(5, "hello")
fun_with_i64_and_array_param(5, { 1, 2, "third element" })

View file

@ -0,0 +1,3 @@
function get_value()
return 42
end

View file

@ -0,0 +1 @@
hello_from_plugin_a()

View file

@ -0,0 +1 @@
hello_from_plugin_b_with_parameters("hello", 42)

View file

@ -0,0 +1,3 @@
get_player_name():and_then(function(name)
print(name)
end);

View file

@ -1,3 +1,3 @@
// entity is a global variable that is set to the entity that is currently being processed,
// it is automatically available in all scripts
print("Current entity index: " + entity.index());
print("Current entity index: " + entity.index);

View file

@ -0,0 +1,3 @@
fn get_value() {
42
}

View file

@ -0,0 +1 @@
hello_bevy();

View file

@ -0,0 +1 @@
hello_from_plugin_a();

View file

@ -0,0 +1 @@
hello_from_plugin_b_with_parameters("hello", 42);

View file

@ -0,0 +1 @@
spawn_entity();

View file

@ -0,0 +1,13 @@
$my_state = {
iterations: 0,
}
def on_update
$my_state[:iterations] += 1
puts("on_update called #{$my_state[:iterations]} times")
if $my_state[:iterations] >= 10
print("calling quit");
quit()
end
end

View file

@ -0,0 +1,3 @@
get_name(Bevy::Entity.current).and_then do |name|
puts(name)
end

View file

@ -0,0 +1,4 @@
# Create a new instance of MyType
my_type = MyType.new()
# Call registered method
puts(my_type.my_method)

View file

@ -0,0 +1 @@
print_player_names

View file

@ -0,0 +1,2 @@
# Bevy::Entity.current can be used to access the entity that is currently being processed
puts("Current entity index: #{Bevy::Entity.current.index}")

View file

@ -0,0 +1,4 @@
fun_with_string_param("hello")
fun_with_i64_param(5)
fun_with_multiple_params(5, "hello")
fun_with_i64_and_array_param(5, [1, 2, "third element"])

View file

@ -0,0 +1,3 @@
def get_value
42
end

View file

@ -0,0 +1 @@
hello_bevy()

View file

@ -0,0 +1 @@
hello_from_plugin_a

View file

@ -0,0 +1 @@
hello_from_plugin_b_with_parameters("hello", 42)

View file

@ -0,0 +1,3 @@
get_player_name.and_then do |name|
puts name
end

View file

@ -0,0 +1 @@
spawn_entity()

View file

@ -0,0 +1,3 @@
function test_func()
print("abc" + 5)
end

View file

@ -0,0 +1,7 @@
State = {
called_with = nil
}
function test_func(x)
called_with = x
end

View file

@ -0,0 +1,3 @@
function test_func()
rust_func(entity.index)
end

View file

@ -0,0 +1,5 @@
index = entity.index
function test_func()
rust_func(index)
end

View file

@ -0,0 +1,2 @@
mark_called()
error()

View file

@ -0,0 +1,3 @@
function test_func()
rust_func(entity)
end

View file

@ -0,0 +1,3 @@
function test_func()
rust_func(Vec3(1.5, 2.5, -3.5))
end

View file

@ -0,0 +1,6 @@
function test_func(vec3)
assert(vec3.x == 1.5)
assert(vec3.y == 2.5)
assert(vec3.z == -3.5)
mark_success()
end

View file

@ -0,0 +1,5 @@
function test_func()
rust_func():and_then(function(x)
print("abc" + 5)
end)
end

View file

@ -0,0 +1,9 @@
State = {
x = nil
}
function test_func()
rust_func():and_then(function(x)
State.x = x
end)
end

View file

@ -0,0 +1,3 @@
function test_func()
rust_func()
end

View file

@ -0,0 +1,3 @@
function test_func()
rust_func(5, "test")
end

View file

@ -0,0 +1,3 @@
function test_func()
rust_func(5)
end

View file

@ -0,0 +1,7 @@
State = {
times_called = 0
}
function test_func()
State.times_called = State.times_called + 1;
end

View file

@ -0,0 +1,9 @@
State = {
a_value = nil,
b_value = nil
}
function test_func(a, b)
State.a_value = a
State.b_value = b
end

View file

@ -0,0 +1,7 @@
State = {
a_value = nil
}
function test_func(a)
State.a_value = a
end

View file

@ -0,0 +1,3 @@
function test_func()
spawn_entity()
end

View file

@ -0,0 +1,3 @@
fn test_func() {
print("abc" * 5)
}

View file

@ -0,0 +1,2 @@
fn test_func(x) {
}

View file

@ -0,0 +1,3 @@
fn test_func() {
rust_func(entity.index);
}

View file

@ -0,0 +1,5 @@
let index = entity.index;
fn test_func() {
rust_func(index);
}

View file

@ -0,0 +1,2 @@
mark_called();
throw();

View file

@ -0,0 +1,3 @@
fn test_func() {
rust_func(entity);
}

View file

@ -0,0 +1,3 @@
fn test_func() {
rust_func(new_vec3(1.5, 2.5, -3.5));
}

View file

@ -0,0 +1,7 @@
fn test_func(vec3) {
if type_of(vec3) != "Vec3" { throw() }
if vec3.x != 1.5 { throw() }
if vec3.y != 2.5 { throw() }
if vec3.z != -3.5 { throw() }
mark_success();
}

View file

@ -0,0 +1,5 @@
fn test_func() {
rust_func().then(|x| {
print("abc" * 5)
})
}

View file

@ -0,0 +1,9 @@
let state = #{
x: 0
};
fn test_func() {
rust_func().then(|x| {
state.x = x;
})
}

View file

@ -0,0 +1,3 @@
fn test_func() {
rust_func();
}

View file

@ -0,0 +1,3 @@
fn test_func() {
rust_func(5, "test");
}

View file

@ -0,0 +1,3 @@
fn test_func() {
rust_func(5);
}

View file

@ -0,0 +1,7 @@
let state = #{
times_called: 0
};
fn test_func() {
state.times_called += 1;
}

View file

@ -0,0 +1,9 @@
let state = #{
a_value: (),
b_value: ()
};
fn test_func(a, b) {
state.a_value = a;
state.b_value = b;
}

View file

@ -0,0 +1,7 @@
let state = #{
a_value: ()
};
fn test_func(a) {
state.a_value = a
}

View file

@ -0,0 +1,3 @@
fn test_func() {
spawn_entity()
}

View file

@ -0,0 +1,3 @@
def test_func
raise
end

View file

@ -0,0 +1,7 @@
$state = {
'called_with' => nil
}
def test_func(val)
$state['called_with'] = val
end

View file

@ -0,0 +1,3 @@
def test_func
rust_func(Bevy::Entity.current.index)
end

View file

@ -0,0 +1,5 @@
$index = Bevy::Entity.current.index
def test_func
rust_func($index)
end

View file

@ -0,0 +1,2 @@
mark_called
raise

View file

@ -0,0 +1,3 @@
def test_func
rust_func(Bevy::Entity.current)
end

View file

@ -0,0 +1,3 @@
def test_func
rust_func(Bevy::Vec3.new(1.5, 2.5, -3.5))
end

View file

@ -0,0 +1,7 @@
def test_func(vec3)
raise unless vec3.is_a?(Bevy::Vec3)
raise unless vec3.x == 1.5
raise unless vec3.y == 2.5
raise unless vec3.z == -3.5
mark_success
end

View file

@ -0,0 +1,5 @@
def test_func
rust_func.and_then do |x|
raise
end
end

View file

@ -0,0 +1,9 @@
$state = {
'x' => nil
}
def test_func
rust_func.and_then do |x|
$state['x'] = x
end
end

View file

@ -0,0 +1,3 @@
def test_func
rust_func
end

View file

@ -0,0 +1,3 @@
def test_func
rust_func(5, 'test')
end

View file

@ -0,0 +1,3 @@
def test_func
rust_func(5)
end

View file

@ -0,0 +1,7 @@
$state = {
'times_called' => 0
}
def test_func
$state['times_called'] += 1
end

View file

@ -0,0 +1,9 @@
$state = {
'a_value' => nil,
'b_value' => nil
}
def test_func(a, b)
$state['a_value'] = a
$state['b_value'] = b
end

View file

@ -0,0 +1,7 @@
$state = {
'a_value' => nil
}
def test_func(a)
$state['a_value'] = a
end

View file

@ -0,0 +1,3 @@
def test_func
spawn_entity
end

3
book/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
book
doctest_cache
target

2498
book/Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

7
book/Cargo.toml Normal file
View file

@ -0,0 +1,7 @@
[package]
name = "bevy_scriptum_book"
publish = false
edition = "2024"
[dependencies]
bevy_scriptum = { path = "../", features = ["ruby", "lua", "rhai"] }

6
book/book.toml Normal file
View file

@ -0,0 +1,6 @@
[book]
authors = ["Jaroslaw Konik"]
language = "en"
multilingual = false
src = "src"
title = "bevy_scriptum"

15
book/justfile Normal file
View file

@ -0,0 +1,15 @@
export CARGO_MANIFEST_DIR := `pwd`
build-deps:
cargo clean && cargo build
_test:
mdbook test -L target/debug/deps/
test: build-deps _test
test-watch: build-deps
watchexec --exts md -r just _test
serve:
mdbook serve

30
book/src/SUMMARY.md Normal file
View file

@ -0,0 +1,30 @@
# Summary
- [Introduction](./introduction.md)
- [Runtimes](./runtimes.md)
- [Lua](./lua/lua.md)
- [Installation](./lua/installation.md)
- [Hello World](./lua/hello_world.md)
- [Spawning scripts](./lua/spawning_scripts.md)
- [Calling Rust from Lua](./lua/calling_rust_from_script.md)
- [Calling Lua from Rust](./lua/calling_script_from_rust.md)
- [Interacting with bevy in callbacks](./lua/interacting_with_bevy.md)
- [Builtin types](./lua/builtin_types.md)
- [Builtin variables](./lua/builtin_variables.md)
- [Ruby](./ruby/ruby.md)
- [Installation](./ruby/installation.md)
- [Hello World](./ruby/hello_world.md)
- [Spawning scripts](./ruby/spawning_scripts.md)
- [Calling Rust from Ruby](./ruby/calling_rust_from_script.md)
- [Calling Ruby from Rust](./ruby/calling_script_from_rust.md)
- [Interacting with bevy in callbacks](./ruby/interacting_with_bevy.md)
- [Builtin types](./ruby/builtin_types.md)
- [Rhai](./rhai/rhai.md)
- [Installation](./rhai/installation.md)
- [Hello World(TBD)]()
- [Multiple plugins](./multiple_plugins.md)
- [Multiple runtimes(TBD)]()
- [Implementing custom runtimes(TBD)]()
- [Workflow](./workflow/workflow.md)
- [Live-reload](./workflow/live_reload.md)
- [Bevy support matrix](./bevy_support_matrix.md)

Some files were not shown because too many files have changed in this diff Show more