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
Showing only changes of commit 59d0d86811 - Show all commits

View File

@ -241,9 +241,27 @@ function makeInstanceMethods() {
return _instanceMethods;
}
// Создаёт stub-signal который ничего не делает — для unknown свойств Instance
// которые скрипты пытаются использовать как сигнал (script.Parent.Selected:Connect).
function makeStubSignal() {
const sig = makeSignal();
// Помечаем чтобы знать что это stub (для возможной отладки)
sig.__stub = true;
return sig;
}
// Эвристика: какие имена свойств вероятно сигналы?
// В Roblox сигналы заканчиваются на: Changed, Added, Removed, Began, Ended,
// Clicked, Activated, Touched, Selected, Deselected, Equipped, Unequipped, и т.д.
function isProbablySignalName(prop) {
if (typeof prop !== 'string') return false;
return /^(Mouse|Touch|Input|Render|Step|Heart|Render|On|Char|Player|Selected|Deselect|Equipped|Unequipped|Activated|Click|Changed|Added|Removed|Began|Ended|Died|Spawned|Reached|Loaded|Hover)/.test(prop)
|| /(Changed|Added|Removed|Began|Ended|Clicked|Activated|Touched|Died|Loaded|Hover|Connect|Event|Signal|Reached)$/.test(prop);
}
function newInstance(className, name) {
const m = makeInstanceMethods();
return {
const target = {
ClassName: className || 'Instance',
Name: name || className || 'Instance',
Parent: undefined,
@ -269,6 +287,35 @@ function newInstance(className, name) {
SetAttribute: m.SetAttribute,
GetPropertyChangedSignal: m.GetPropertyChangedSignal,
};
// Proxy: для unknown свойств возвращаем stub чтобы скрипты не падали.
return new Proxy(target, {
get(t, prop) {
if (prop in t) return t[prop];
if (typeof prop !== 'string') return undefined;
// Системные/wasmoon-внутренние ключи — undefined чтобы wasmoon не путался
if (prop === 'then' || prop === 'catch' || prop === 'toJSON' ||
prop === Symbol.toPrimitive || prop.startsWith('__')) {
return undefined;
}
if (isProbablySignalName(prop)) {
const stub = makeStubSignal();
t[prop] = stub;
return stub;
}
// Иначе — child stub (Folder) который тоже выживет на чтении свойств
// и может иметь свои дочерние stub'ы. Cache в target чтобы тот же ссылочно.
const childStub = newInstance('Folder', prop);
t[prop] = childStub;
return childStub;
},
set(t, prop, value) {
t[prop] = value;
return true;
},
has(t, prop) {
return prop in t || (typeof prop === 'string' && !prop.startsWith('__'));
},
});
}
/**