Add optional Lua scripting module, examples, and validation
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
# Lua playground
|
||||
|
||||
A Lua-only project: there is no project `Gameplay.cpp`. The native engine and Player
|
||||
are built normally; the two gameplay behaviors are loaded from Lua source.
|
||||
|
||||
Open this folder as a project in the Editor, refresh Lua schemas, open
|
||||
`Scenes/main.scene.json`, then Play. **A/D** or arrows move, **Space** jumps from
|
||||
ground, and **E** resets the player. The gold beacon shows non-physical animation
|
||||
and a shared `require("util.motion")` module.
|
||||
|
||||
Change `Scripts/player.lua` in an external editor and save. Development Play watches
|
||||
Lua sources; a successful reload restarts the scene and resets script state. Invalid
|
||||
source leaves the previous generation running and reports the error. Export copies
|
||||
the captured Lua files into the game; a Lua executable or separately installed Lua
|
||||
library is not needed.
|
||||
|
||||
Run `faset_lua_setup` through the Editor command palette to install the Faset LuaLS
|
||||
declarations and, if absent, `.luarc.json`. See the
|
||||
[Lua manual](../../docs/manual/scripting/lua.md) for the API and sandbox boundaries.
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"format": "faset.scene",
|
||||
"version": 1,
|
||||
"id": "example-lua-scene",
|
||||
"name": "Lua playground — A/D / Space / E",
|
||||
"dimension": 2,
|
||||
"simulation": {
|
||||
"fixed_delta": 0.016666666666666666,
|
||||
"max_catch_up_ticks": 4,
|
||||
"physics_substeps": 4,
|
||||
"gravity": [0, -9.81, 0]
|
||||
},
|
||||
"entities": [
|
||||
{
|
||||
"id": "floor", "name": "Ground", "parent": null,
|
||||
"components": [
|
||||
{
|
||||
"id": "floor-transform", "type": "faset.transform", "version": 1,
|
||||
"fields": {"position": [0, -0.5, 0]}
|
||||
},
|
||||
{
|
||||
"id": "floor-sprite", "type": "faset.sprite", "version": 1,
|
||||
"fields": {"size": [16, 1], "color": [0.2, 0.3, 0.4, 1]}
|
||||
},
|
||||
{
|
||||
"id": "floor-body", "type": "faset.rigid_body_2d", "version": 1,
|
||||
"fields": {"body_type": "static", "half_extents": [8, 0.5]}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "player", "name": "Player", "parent": null,
|
||||
"components": [
|
||||
{
|
||||
"id": "player-transform", "type": "faset.transform", "version": 1,
|
||||
"fields": {"position": [-2, 1.5, 0]}
|
||||
},
|
||||
{
|
||||
"id": "player-sprite", "type": "faset.sprite", "version": 1,
|
||||
"fields": {"size": [0.8, 1], "color": [0.2, 0.75, 0.9, 1]}
|
||||
},
|
||||
{
|
||||
"id": "player-body", "type": "faset.rigid_body_2d", "version": 1,
|
||||
"fields": {"body_type": "dynamic", "half_extents": [0.4, 0.5], "friction": 0.3}
|
||||
},
|
||||
{
|
||||
"id": "player-controller", "type": "example.lua_player", "version": 1,
|
||||
"fields": {"move_speed": 5, "jump_speed": 7}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "beacon", "name": "Beacon", "parent": null,
|
||||
"components": [
|
||||
{
|
||||
"id": "beacon-transform", "type": "faset.transform", "version": 1,
|
||||
"fields": {"position": [3, 2, 0]}
|
||||
},
|
||||
{
|
||||
"id": "beacon-sprite", "type": "faset.sprite", "version": 1,
|
||||
"fields": {"size": [0.5, 0.5], "color": [1, 0.7, 0.2, 1]}
|
||||
},
|
||||
{
|
||||
"id": "beacon-behavior", "type": "example.lua_beacon", "version": 1,
|
||||
"fields": {"amplitude": 0.3, "frequency": 0.7}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"instances": []
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
local motion = require("util.motion")
|
||||
|
||||
local Beacon = faset.behavior {
|
||||
id = "example.lua_beacon",
|
||||
version = 1,
|
||||
name = "Lua Beacon",
|
||||
fields = {
|
||||
amplitude = { name = "Height", type = "number", default = 0.3, min = 0, max = 2 },
|
||||
frequency = { name = "Frequency", type = "number", default = 0.7, min = 0, max = 5 }
|
||||
}
|
||||
}
|
||||
|
||||
function Beacon:on_start()
|
||||
self.state.origin_y = self.entity:transform().position.y
|
||||
self.state.elapsed = 0
|
||||
end
|
||||
|
||||
function Beacon:update(delta)
|
||||
self.state.elapsed = self.state.elapsed + delta
|
||||
local pose = self.entity:transform()
|
||||
pose.position.y = self.state.origin_y
|
||||
+ motion.bob(self.state.elapsed, self.fields.frequency, self.fields.amplitude)
|
||||
pose.rotation.z = self.state.elapsed
|
||||
self.entity:set_transform(pose)
|
||||
end
|
||||
|
||||
return Beacon
|
||||
@@ -0,0 +1,47 @@
|
||||
local Player = faset.behavior {
|
||||
id = "example.lua_player",
|
||||
version = 1,
|
||||
name = "Lua Player",
|
||||
fields = {
|
||||
move_speed = {
|
||||
name = "Move speed", type = "number", default = 5,
|
||||
min = 0, max = 30, units = "m/s"
|
||||
},
|
||||
jump_speed = {
|
||||
name = "Jump speed", type = "number", default = 7,
|
||||
min = 0, max = 20, units = "m/s"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Player:on_start()
|
||||
self.state.origin = self.entity:transform()
|
||||
self.state.jumps = 0
|
||||
faset.log("Lua player ready: A/D move, Space jump, E reset")
|
||||
end
|
||||
|
||||
function Player:fixed_update(delta)
|
||||
local input = faset.input()
|
||||
if input.interact_pressed then
|
||||
self.entity:teleport(self.state.origin)
|
||||
self.entity:set_velocity { x = 0, y = 0, z = 0 }
|
||||
self.state.jumps = 0
|
||||
return
|
||||
end
|
||||
|
||||
local velocity = self.entity:velocity()
|
||||
velocity.x = input.horizontal * self.fields.move_speed
|
||||
if input.jump_pressed and self.entity:is_grounded() then
|
||||
velocity.y = self.fields.jump_speed
|
||||
self.state.jumps = self.state.jumps + 1
|
||||
faset.log("Jump", self.state.jumps)
|
||||
end
|
||||
self.entity:set_velocity(velocity)
|
||||
|
||||
if self.entity:transform().position.y < -10 then
|
||||
self.entity:teleport(self.state.origin)
|
||||
self.entity:set_velocity { x = 0, y = 0, z = 0 }
|
||||
end
|
||||
end
|
||||
|
||||
return Player
|
||||
@@ -0,0 +1,7 @@
|
||||
local motion = {}
|
||||
|
||||
function motion.bob(time, frequency, amplitude)
|
||||
return math.sin(time * frequency * 2 * math.pi) * amplitude
|
||||
end
|
||||
|
||||
return motion
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"format": "faset.project",
|
||||
"version": 1,
|
||||
"id": "example-lua-project",
|
||||
"name": "Lua playground",
|
||||
"dimension": 2,
|
||||
"start_scene": "Scenes/main.scene.json",
|
||||
"scripting": {
|
||||
"lua": {
|
||||
"scripts": ["Scripts/player.lua", "Scripts/beacon.lua"]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user