543 lines
10 KiB
Markdown
543 lines
10 KiB
Markdown
# Scripting
|
|
|
|
Project uses LuaJIT as a scripting language.
|
|
|
|
## Core functions
|
|
|
|
```lua
|
|
require "packid:module_name" -- load Lua module from pack-folder/modules/
|
|
-- no extension included, just name
|
|
|
|
-- deprecated functions
|
|
load_script("packid:scripts/script_name.lua") -- load Lua script if not loaded yet
|
|
load_script("packid:scripts/script_name.lua", true) -- load Lua script anyway
|
|
```
|
|
|
|
## *player* library
|
|
|
|
|
|
```python
|
|
player.get_pos(playerid: int) -> number, number, number
|
|
```
|
|
Returns x, y, z coordinates of the player
|
|
|
|
```python
|
|
player.set_pos(playerid: int, x: number, y: number, z: number)
|
|
```
|
|
|
|
Set player position
|
|
|
|
```python
|
|
player.get_rot(playerid: int) -> number, number
|
|
```
|
|
|
|
Returns x, y of camera rotation (radians)
|
|
|
|
```python
|
|
player.set_rot(playerid: int, x: number, y: number, z: number)
|
|
```
|
|
|
|
Set camera rotation (radians)
|
|
|
|
```python
|
|
player.get_inventory(playerid: int) -> int, int
|
|
```
|
|
|
|
Returns player inventory ID and selected slot index (0-9)
|
|
|
|
## *world* library
|
|
|
|
```python
|
|
world.get_day_time() -> number
|
|
```
|
|
|
|
Returns current day time in range \[0.0-1.0\] where 0.0 and 1.0 - midnight, 0.5 - noon.
|
|
|
|
```python
|
|
world.set_day_time(time: number)
|
|
```
|
|
|
|
Set day time value.
|
|
|
|
```python
|
|
world.get_total_time() -> number
|
|
```
|
|
|
|
Returns total time passed in the world
|
|
|
|
```python
|
|
world.get_seed() -> int
|
|
```
|
|
|
|
Returns world seed.
|
|
|
|
## *gui* library
|
|
|
|
Library contains ui elements access functions. Library should not be directly used, because script *layouts/layout_name.xml.lua* already has a generated variable **document** (instance of **Document**)
|
|
|
|
Example:
|
|
|
|
```lua
|
|
print(document.some_button.text) -- where 'some_button' is an element id
|
|
document.some_button.text = "new text"
|
|
```
|
|
|
|
## **inventory** library
|
|
|
|
Library for inventories interaction.
|
|
|
|
```python
|
|
inventory.get(invid: int, slot: int) -> int, int
|
|
```
|
|
|
|
Requires an inventory ID and slot index. Returns item ID and count. ID = 0 (core:empty) means that slot is empty.
|
|
|
|
```python
|
|
inventory.set(invid: int, slot: int, itemid: int, count: int)
|
|
```
|
|
|
|
Set slot content.
|
|
|
|
```python
|
|
inventory.size(invid: int) -> int
|
|
```
|
|
|
|
Returns inventory size (slots number). Throws an exception if there's no inventory having specified ID.
|
|
|
|
```python
|
|
inventory.add(invid: int, itemid: int, count: int) -> int
|
|
```
|
|
|
|
Add an item to the specified inventory. Returns remaining count if could not to add fully.
|
|
|
|
```python
|
|
inventory.get_block(x: int, y: int, z: int) -> int
|
|
```
|
|
|
|
Returns block inventory ID or 0.
|
|
|
|
```python
|
|
inventory.bind_block(invid: int, x: int, y: int, z: int)
|
|
```
|
|
|
|
Bind inventory to the specified block.
|
|
|
|
```python
|
|
inventory.unbind_block(x: int, y: int, z: int)
|
|
```
|
|
|
|
Unbind inventory from the specified block.
|
|
|
|
> [!WARNING]
|
|
> Unbound inventories will be deleted on world close.
|
|
|
|
```python
|
|
inventory.clone(invid: int) -> int
|
|
```
|
|
|
|
Create inventory copy. Returns the created copy ID.
|
|
|
|
## *block* library
|
|
|
|
```python
|
|
block.name(blockid: int) -> str
|
|
```
|
|
|
|
Returns block string ID (name) by index
|
|
|
|
```python
|
|
block.index(name: str) -> int
|
|
```
|
|
|
|
Returns block integer ID (index) by name
|
|
|
|
```python
|
|
block.get(x: int, y: int, z: int) -> int
|
|
```
|
|
|
|
Returns integer ID by block position
|
|
|
|
```python
|
|
block.get_states(x: int, y: int, z: int) -> int
|
|
```
|
|
|
|
Returns block state (rotation + additional information) as an integer.
|
|
|
|
```python
|
|
block.set(x: int, y: int, z: int, id: int, states: int)
|
|
```
|
|
|
|
Set block with specified integer ID and state (default - 0) at specified position.
|
|
|
|
> [!WARNING]
|
|
> `block.set` does not trigger on_placed.
|
|
|
|
```python
|
|
block.is_solid_at(x: int, y: int, z: int) -> bool
|
|
```
|
|
|
|
Check if block at the specified position is solid.
|
|
|
|
```python
|
|
block.is_replaceable_at(x: int, y: int, z: int) -> bool
|
|
```
|
|
Check if block may be placed at specified position. (Examples: air, water, grass, flower)
|
|
|
|
```python
|
|
block.defs_count() -> int
|
|
```
|
|
|
|
Returns count of available block IDs.
|
|
|
|
Following three functions return direction vectors based on block rotation.
|
|
|
|
|
|
```python
|
|
block.get_X(x: int, y: int, z: int) -> int, int, int
|
|
```
|
|
|
|
Returns X: integer direction vector of the block at specified coordinates.
|
|
Example: no rotation: 1, 0, 0
|
|
|
|
```python
|
|
block.get_Y(x: int, y: int, z: int) -> int, int, int
|
|
```
|
|
|
|
Returns Y: integer direction vector of the block at specified coordinates.
|
|
Example: no rotation: 0, 1, 0
|
|
|
|
```python
|
|
block.get_Z(x: int, y: int, z: int) -> int, int, int
|
|
```
|
|
|
|
Returns Z: integer direction vector of the block at specified coordinates.
|
|
Example: no rotation: 0, 0, 1
|
|
|
|
|
|
```python
|
|
block.get_rotation(x: int, y: int, z: int) -> int
|
|
```
|
|
|
|
Returns block rotation index based on used profile.
|
|
|
|
```python
|
|
block.set_rotation(x: int, y: int, z: int, rotation: int)
|
|
```
|
|
|
|
Set block rotation by index.
|
|
|
|
### User bits
|
|
|
|
Part of a voxel data used for scripting. Size: 8 bit.
|
|
|
|
```python
|
|
block.get_user_bits(x: int, y: int, z: int, offset: int, bits: int) -> int
|
|
```
|
|
|
|
Get specified bits as an unsigned integer.
|
|
|
|
```python
|
|
block.set_user_bits(x: int, y: int, z: int, offset: int, bits: int, value: int) -> int
|
|
```
|
|
Set specified bits.
|
|
|
|
## *item* library
|
|
|
|
|
|
```python
|
|
item.name(itemid: int) -> str
|
|
```
|
|
|
|
Returns item string ID (name) by index
|
|
|
|
```python
|
|
item.index(name: str) -> int
|
|
```
|
|
|
|
Returns item integer ID (index) by name
|
|
|
|
```python
|
|
item.stack_size(itemid: int) -> int
|
|
```
|
|
|
|
Returns max stack size for the item
|
|
|
|
```python
|
|
item.defs_count() -> int
|
|
```
|
|
|
|
Returns count of available item IDs.
|
|
|
|
## *hud* library
|
|
|
|
|
|
```python
|
|
hud.open_inventory()
|
|
```
|
|
|
|
Open player inventory
|
|
|
|
```python
|
|
hud.close_inventory()
|
|
```
|
|
|
|
Close inventory
|
|
|
|
```python
|
|
hud.open_block(x: int, y: int, z: int) -> int, str
|
|
```
|
|
|
|
Open block UI and inventory. Throws an exception if block has no UI layout.
|
|
|
|
Returns block inventory ID (if *"inventory-size"=0* a virtual inventory will be created), and UI layout ID.
|
|
|
|
```python
|
|
hud.show_overlay(layoutid: str, playerinv: bool)
|
|
```
|
|
|
|
Show overlay with layout specified. Shows player inventory also if playerinv is **true**
|
|
|
|
> [!NOTE]
|
|
> Only one block may be open at same time
|
|
|
|
```python
|
|
hud.open_permanent(layoutid: str)
|
|
```
|
|
|
|
Add element to the screen. The element will be removed on world close only.
|
|
**inventory** element will be bound to the player inventory.
|
|
|
|
```python
|
|
hud.close(layoutid: str)
|
|
```
|
|
|
|
Remove an element from the screen
|
|
|
|
## Block events
|
|
|
|
```lua
|
|
function on_placed(x, y, z, playerid)
|
|
```
|
|
|
|
Called on block placed by player
|
|
|
|
```lua
|
|
function on_broken(x, y, z, playerid)
|
|
```
|
|
|
|
Called on block broken by player
|
|
|
|
```lua
|
|
function on_interact(x, y, z, playerid) -> bool
|
|
```
|
|
|
|
Called on block RMB click interaction. Prevents block placing if **true** returned.
|
|
|
|
```lua
|
|
function on_update(x, y, z)
|
|
```
|
|
|
|
Called on block update (near block changed)
|
|
|
|
```lua
|
|
function on_random_update(x, y, z)
|
|
```
|
|
|
|
Called on random block update (grass growth)
|
|
|
|
```lua
|
|
function on_blocks_tick(tps: int)
|
|
```
|
|
|
|
Called tps (20) times per second.
|
|
|
|
## Item events
|
|
|
|
```lua
|
|
function on_use(playerid: int)
|
|
```
|
|
|
|
Called on RMB click out of a block.
|
|
|
|
```lua
|
|
function on_use_on_block(x: int, y: int, z: int, playerid: int)
|
|
```
|
|
|
|
Called on block RMB click. Prevents block **placing-block** placing if returns **true**
|
|
|
|
```lua
|
|
function on_block_break_by(x: int, y: int, z: int, playerid: int)
|
|
```
|
|
|
|
Called on block LMB click (unbreakable blocks included). Prevents block destruction if returns **true**.
|
|
|
|
## World events
|
|
|
|
Script *scripts/world.lua* events.
|
|
|
|
```lua
|
|
function on_world_open()
|
|
```
|
|
|
|
Called on world open.
|
|
|
|
```lua
|
|
function on_world_save()
|
|
```
|
|
|
|
Called before world save.
|
|
|
|
```lua
|
|
function on_world_tick()
|
|
```
|
|
|
|
Called 20 times per second
|
|
|
|
```lua
|
|
function on_world_quit()
|
|
```
|
|
|
|
Called on world close (after saving)
|
|
|
|
## Layout events
|
|
|
|
Script *layouts/layout_name.xml.lua* events.
|
|
|
|
```lua
|
|
function on_open(invid: int, x: int, y: int, z: int)
|
|
```
|
|
|
|
Called on element added to the screen.
|
|
invid=0 if no inventory bound
|
|
x,y,z=0 if no block bound
|
|
|
|
```lua
|
|
function on_close(invid: int)
|
|
```
|
|
|
|
Called on element removed from the screen.
|
|
|
|
## HUD events
|
|
|
|
Script *scripts/hud.lua* events.
|
|
|
|
|
|
```lua
|
|
function on_hud_open(playerid: int)
|
|
```
|
|
|
|
Called after world open.
|
|
|
|
```lua
|
|
function on_hud_close(playerid: int)
|
|
```
|
|
|
|
Called on world close (before saving)
|
|
|
|
## Engine libraries
|
|
|
|
### file
|
|
|
|
Filesystem interaction library.
|
|
|
|
```python
|
|
file.resolve(path: str) -> str
|
|
```
|
|
|
|
Function turns *entry_point:path* (example *user:worlds/house1*) to a regular path. (example *C://Users/user/.voxeng/worlds/house1*)
|
|
|
|
> [!NOTE]
|
|
> The function should be used for debug only. *entry_point:path* notation is required in all **file** functions.
|
|
|
|
Resulting path is not canonical and may be relative.
|
|
|
|
```python
|
|
file.read(path: str) -> str
|
|
```
|
|
|
|
Read whole text file.
|
|
|
|
```python
|
|
file.read_bytes(path: str) -> array of integers
|
|
```
|
|
|
|
Read file into bytes array.
|
|
|
|
```python
|
|
file.write(path: str, text: str) -> nil
|
|
```
|
|
|
|
Overwrite text file.
|
|
|
|
```python
|
|
file.write_bytes(path: str, data: array of integers)
|
|
```
|
|
|
|
Overwrite binary file with bytes array.
|
|
|
|
```python
|
|
file.length(path: str) -> int
|
|
```
|
|
|
|
Get file length (bytes) or 0.
|
|
|
|
```python
|
|
file.exists(path: str) -> bool
|
|
```
|
|
|
|
Check if file or directory exist.
|
|
|
|
```python
|
|
file.isfile(path: str) -> bool
|
|
```
|
|
|
|
Check if the path points to a file.
|
|
|
|
```python
|
|
file.isdir(path: str) -> bool
|
|
```
|
|
|
|
Check if the path points to a directory.
|
|
|
|
```python
|
|
file.mkdir(path: str) -> bool
|
|
```
|
|
|
|
Create directory. Returns true if new directory created
|
|
|
|
```python
|
|
file.mkdirs(path: str) -> bool
|
|
```
|
|
|
|
Create directories chain. Returns true if new directory created
|
|
|
|
### time
|
|
|
|
```python
|
|
time.uptime() -> float
|
|
```
|
|
|
|
Returns time elapsed since the engine started.
|
|
|
|
## Available modules
|
|
|
|
### TOML serialization/deserialization
|
|
|
|
```lua
|
|
local toml = require "core:toml"
|
|
|
|
local t = {a=53, b=42, s="test", sub={x=1, y=6}}
|
|
local s = toml.serialize(t)
|
|
print(s)
|
|
local t2 = toml.deserialize(s)
|
|
```
|
|
output:
|
|
```toml
|
|
b = 42
|
|
s = "test"
|
|
a = 53
|
|
[sub]
|
|
y = 6
|
|
x = 1
|
|
```
|