feat: 50 игр на Lua + импорт Roblox для всех + поддержка Lua в плеере #39

Merged
min merged 215 commits from feat/lua-50-games-bundle into main 2026-06-09 21:59:25 +00:00
2 changed files with 30 additions and 0 deletions
Showing only changes of commit 8295d6f0fe - Show all commits

View File

@ -972,11 +972,31 @@ export class GameRuntime {
} else if (state?.player) { } else if (state?.player) {
realPos = { x: state.player.x, y: state.player.y, z: state.player.z }; realPos = { x: state.player.x, y: state.player.y, z: state.player.z };
} }
// Собираем актуальные позиции спавненных динамических примитивов
// (id >= 800000) — нужно для AABB-touched-check в Lua-shim, чтобы
// ловить попадание игрока в падающий куб.
let spawnedPositions = null;
try {
const pm = this.scene3d?.primitiveManager;
if (pm && pm.instances) {
for (const [id, data] of pm.instances.entries()) {
if (id < 800000 || data.anchored !== false) continue;
if (!spawnedPositions) spawnedPositions = [];
spawnedPositions.push([id, data.x, data.y, data.z]);
}
}
} catch (_) {}
for (const sb of this.sandboxes) { for (const sb of this.sandboxes) {
// Обновляем реальную позицию игрока для Lua-shim // Обновляем реальную позицию игрока для Lua-shim
if (realPos && sb.api?.updatePlayerPos) { if (realPos && sb.api?.updatePlayerPos) {
try { sb.api.updatePlayerPos(realPos.x, realPos.y, realPos.z); } catch (_) {} try { sb.api.updatePlayerPos(realPos.x, realPos.y, realPos.z); } catch (_) {}
} }
// Синк спавненных динамических примитивов
if (spawnedPositions && sb.api?.updateSpawnedPos) {
for (const [id, x, y, z] of spawnedPositions) {
try { sb.api.updateSpawnedPos(id, x, y, z); } catch (_) {}
}
}
// Для скриптов с target — добавляем актуальную позицию self // Для скриптов с target — добавляем актуальную позицию self
const stateForSb = sb.target const stateForSb = sb.target
? { ...state, selfPosition: this._collectSelfPosition(sb.target) } ? { ...state, selfPosition: this._collectSelfPosition(sb.target) }

View File

@ -2185,6 +2185,16 @@ export function registerRobloxShim(lua, opts) {
updatePlayerPos(x, y, z) { updatePlayerPos(x, y, z) {
api._realPlayerPos = { x: +x, y: +y, z: +z }; api._realPlayerPos = { x: +x, y: +y, z: +z };
}, },
// Синхронизация позиций спавненных физических частей (падающие кубы).
// GameRuntime каждый кадр зовёт это с актуальными координатами от
// pm.instances — иначе наш AABB-touched-check считает позиции
// устаревшими (на момент создания) и не ловит касание.
updateSpawnedPos(id, x, y, z) {
const part = partById.get(Number(id));
if (part && part._state && part._state.Position) {
part._state.Position = new RbxVector3(x, y, z);
}
},
// Доступ к ключевым объектам (для тестов и отладки) // Доступ к ключевым объектам (для тестов и отладки)
partById, localPlayer, humanoid, character, workspace, players, game, partById, localPlayer, humanoid, character, workspace, players, game,
}; };