docs: add Phase 8-3 Lua scripting status, spec, and deferred items
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -62,6 +62,14 @@
|
||||
- **raycast_all (다중 hit)** — 가장 가까운 hit만 반환.
|
||||
- **BVH 조기 종료 최적화** — 모든 리프 검사 후 최소 t 선택. front-to-back 순회 미구현.
|
||||
|
||||
## Phase 8-3
|
||||
|
||||
- **핫 리로드** — 파일 변경 감지 + Lua state 재로드 미구현.
|
||||
- **엔진 API 노출** — ECS, 물리, 오디오 등 Lua에서 접근 불가.
|
||||
- **Lua 테이블 ↔ Rust 구조체** — 복잡한 데이터 변환 미구현.
|
||||
- **코루틴** — Lua 코루틴 래핑 미구현.
|
||||
- **샌드박싱** — Lua 보안 제한 미구현.
|
||||
|
||||
## Phase 8-2
|
||||
|
||||
- **상태 동기화 (스냅샷)** — 미구현. 서버→클라이언트 월드 상태 전송.
|
||||
|
||||
@@ -125,6 +125,12 @@
|
||||
- voltex_ai: A* pathfinding on triangle graph (center-point path)
|
||||
- voltex_ai: Steering behaviors (seek, flee, arrive, wander, follow_path)
|
||||
|
||||
### Phase 8-3: Lua Scripting
|
||||
- voltex_script: Lua 5.4 내장 빌드 (cc crate)
|
||||
- voltex_script: Lua C API FFI 바인딩
|
||||
- voltex_script: LuaState 안전 래퍼 (exec, exec_file, register_fn, globals)
|
||||
- voltex_script: 기본 바인딩 (voltex_print)
|
||||
|
||||
### Phase 8-2: Networking Foundation
|
||||
- voltex_net: Packet protocol (Connect, Accept, Disconnect, Ping, Pong, UserData)
|
||||
- voltex_net: Binary serialization/deserialization
|
||||
@@ -144,10 +150,11 @@ crates/
|
||||
├── voltex_physics — Collider, ContactPoint, BvhTree, RigidBody, detect_collisions, physics_step, raycast
|
||||
├── voltex_audio — AudioClip, WAV parser, mixing, WASAPI backend, AudioSystem, MixGroup, spatial
|
||||
├── voltex_ai — NavMesh, A* pathfinding, steering behaviors
|
||||
└── voltex_net — UDP packets, NetServer, NetClient
|
||||
├── voltex_net — UDP packets, NetServer, NetClient
|
||||
└── voltex_script — Lua 5.4 FFI, LuaState, scripting bindings
|
||||
```
|
||||
|
||||
## 테스트: 236개 전부 통과
|
||||
## 테스트: 245개 전부 통과
|
||||
|
||||
- voltex_asset: 14
|
||||
- voltex_audio: 35 (audio_clip 2 + wav 5 + mixing 11 + audio_system 2 + spatial 8 + mix_group 7)
|
||||
@@ -157,6 +164,7 @@ crates/
|
||||
- voltex_platform: 3
|
||||
- voltex_ai: 15 (navmesh 4 + pathfinding 5 + steering 6)
|
||||
- voltex_net: 8 (packet 7 + integration 1)
|
||||
- voltex_script: 9 (state 8 + bindings 1)
|
||||
- voltex_renderer: 33 (20 + SSGI 3 + RT 3 + bloom 3 + tonemap 4)
|
||||
|
||||
## Examples (11개)
|
||||
@@ -173,7 +181,7 @@ crates/
|
||||
- audio_demo — 사인파 오디오 재생
|
||||
- deferred_demo — 디퍼드 렌더링 + 다중 포인트 라이트
|
||||
|
||||
## 다음: Phase 8-3 (스크립팅) / 8-4 (에디터) — Stretch Goal
|
||||
## 다음: Phase 8-4 (에디터) — Stretch Goal
|
||||
|
||||
스펙 참조: `docs/superpowers/specs/2026-03-24-voltex-engine-design.md`
|
||||
|
||||
|
||||
133
docs/superpowers/specs/2026-03-25-phase8-3-scripting.md
Normal file
133
docs/superpowers/specs/2026-03-25-phase8-3-scripting.md
Normal file
@@ -0,0 +1,133 @@
|
||||
# Phase 8-3: Lua Scripting — Design Spec
|
||||
|
||||
## Overview
|
||||
|
||||
`voltex_script` crate를 신규 생성한다. Lua 5.4 소스를 내장 빌드하고, FFI로 Lua C API를 호출하는 안전한 래퍼를 구현한다.
|
||||
|
||||
## Scope
|
||||
|
||||
- Lua 5.4 소스 내장 (cc crate로 빌드)
|
||||
- Lua C API FFI 선언
|
||||
- LuaState 안전한 래퍼 (exec, exec_file, 글로벌 변수 읽기/쓰기)
|
||||
- Rust 함수를 Lua에 등록 (register_fn)
|
||||
- 기본 바인딩 (voltex_print)
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- 핫 리로드 (파일 변경 감지)
|
||||
- 엔진 API 노출 (ECS, 물리 등)
|
||||
- Lua 테이블 ↔ Rust 구조체 변환
|
||||
- 코루틴 지원
|
||||
- 에러 핸들링 고도화
|
||||
|
||||
## Module Structure
|
||||
|
||||
```
|
||||
crates/voltex_script/
|
||||
├── Cargo.toml
|
||||
├── build.rs — cc::Build로 Lua 5.4 컴파일
|
||||
├── lua/ — Lua 5.4 소스코드 (.c, .h)
|
||||
└── src/
|
||||
├── lib.rs
|
||||
├── ffi.rs — Lua C API extern 선언
|
||||
├── state.rs — LuaState 래퍼
|
||||
└── bindings.rs — 기본 Rust→Lua 바인딩
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
- `cc` (build dependency) — C 소스 컴파일
|
||||
|
||||
## Lua 5.4 소스 내장
|
||||
|
||||
lua/ 디렉토리에 Lua 5.4.7 소스코드를 배치. build.rs에서 cc::Build로 컴파일.
|
||||
|
||||
제외 파일: lua.c (standalone interpreter), luac.c (standalone compiler) — main() 충돌 방지.
|
||||
|
||||
Windows: `LUA_USE_WINDOWS` 또는 기본값 사용.
|
||||
|
||||
## Types
|
||||
|
||||
### ffi.rs
|
||||
|
||||
```rust
|
||||
pub enum lua_State {}
|
||||
pub type lua_CFunction = unsafe extern "C" fn(*mut lua_State) -> c_int;
|
||||
pub type lua_Number = f64;
|
||||
pub type lua_Integer = i64;
|
||||
```
|
||||
|
||||
핵심 함수들:
|
||||
- luaL_newstate, luaL_openlibs, lua_close
|
||||
- luaL_dostring, luaL_loadfilex
|
||||
- lua_pcallk (lua_pcall 매크로 대체)
|
||||
- lua_pushnumber, lua_pushstring, lua_pushcclosure
|
||||
- lua_tonumberx, lua_tolstring
|
||||
- lua_setglobal, lua_getglobal
|
||||
- lua_gettop, lua_settop
|
||||
- lua_type, lua_typename
|
||||
|
||||
### LuaState
|
||||
|
||||
```rust
|
||||
pub struct LuaState {
|
||||
state: *mut ffi::lua_State,
|
||||
}
|
||||
```
|
||||
|
||||
- `new() -> Self` — luaL_newstate + luaL_openlibs
|
||||
- `exec(code: &str) -> Result<(), String>` — luaL_dostring, 에러 시 스택 메시지 반환
|
||||
- `exec_file(path: &str) -> Result<(), String>` — luaL_loadfilex + lua_pcall
|
||||
- `register_fn(name: &str, f: ffi::lua_CFunction)` — lua_pushcclosure + lua_setglobal
|
||||
- `get_global_number(name: &str) -> Option<f64>` — lua_getglobal + lua_tonumberx
|
||||
- `get_global_string(name: &str) -> Option<String>` — lua_getglobal + lua_tolstring
|
||||
- `set_global_number(name: &str, value: f64)` — lua_pushnumber + lua_setglobal
|
||||
- `set_global_string(name: &str, value: &str)` — lua_pushstring + lua_setglobal
|
||||
- `Drop` — lua_close
|
||||
|
||||
unsafe impl Send for LuaState {} (Lua state는 단일 스레드에서만 사용)
|
||||
|
||||
### bindings.rs
|
||||
|
||||
```rust
|
||||
pub fn register_default_bindings(lua: &LuaState)
|
||||
```
|
||||
|
||||
기본 바인딩:
|
||||
- `voltex_print(msg)` — Rust println!으로 출력
|
||||
- `voltex_log(msg)` — 로그
|
||||
|
||||
## build.rs
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let mut build = cc::Build::new();
|
||||
build.include("lua");
|
||||
|
||||
for entry in std::fs::read_dir("lua").unwrap() {
|
||||
let path = entry.unwrap().path();
|
||||
if path.extension().map_or(false, |e| e == "c") {
|
||||
let name = path.file_name().unwrap().to_str().unwrap();
|
||||
if name != "lua.c" && name != "luac.c" {
|
||||
build.file(&path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
build.compile("lua54");
|
||||
}
|
||||
```
|
||||
|
||||
## Test Plan
|
||||
|
||||
### state.rs
|
||||
- LuaState 생성/삭제 (new + drop)
|
||||
- exec 간단한 코드 ("x = 1 + 2")
|
||||
- exec 에러 코드 → Err
|
||||
- get_global_number: Lua에서 설정한 변수 읽기
|
||||
- set_global_number + get: 라운드트립
|
||||
- get_global_string: 문자열 변수
|
||||
- register_fn: Rust 함수 등록 후 Lua에서 호출
|
||||
|
||||
### bindings.rs
|
||||
- voltex_print 호출 (크래시 없이 실행)
|
||||
Reference in New Issue
Block a user