fix(lua): inst.Parent = X авто-добавляет в parent.Children

Корень бага: g1_main делал:
  ev = Instance.new('BindableEvent')
  ev.Parent = ReplicatedStorage
Но Proxy 'set' просто писал t['Parent']=value, НЕ добавляя ev в
ReplicatedStorage.Children. Поэтому скрипт монетки делал:
  ev = ReplicatedStorage:FindFirstChild('CoinCollected')  -- nil!
  if ev then ev:Fire() end  -- false, ничего не происходит
HUD/звук не обновлялись.

Фикс: Proxy.set теперь:
1) удаляет себя из старого parent.Children
2) пушит в новый parent.Children
3) фейерит ChildRemoved/ChildAdded/AncestryChanged

Это паритет с Roblox Instance.Parent setter.
This commit is contained in:
min 2026-06-09 10:41:49 +03:00
parent 701125d17b
commit 598b91bd9e

View File

@ -394,7 +394,8 @@ function newInstance(className, name) {
GetPropertyChangedSignal: m.GetPropertyChangedSignal,
};
// Proxy: для unknown свойств возвращаем stub чтобы скрипты не падали.
return new Proxy(target, {
let proxyRef;
proxyRef = new Proxy(target, {
get(t, prop) {
// Существующее свойство всегда возвращаем как есть (включая методы)
if (Object.prototype.hasOwnProperty.call(t, prop) || prop in t) {
@ -417,6 +418,27 @@ function newInstance(className, name) {
return stub;
},
set(t, prop, value) {
// Авто-управление иерархией при `inst.Parent = X`:
// 1) удаляем себя из Children старого Parent
// 2) пушим в Children нового Parent
// 3) фейерим ChildAdded/ChildRemoved
if (prop === 'Parent') {
const oldP = t.Parent;
if (oldP && oldP.Children) {
const i = oldP.Children.indexOf(proxyRef);
if (i >= 0) {
oldP.Children.splice(i, 1);
try { oldP.ChildRemoved && oldP.ChildRemoved.Fire(proxyRef); } catch (_) {}
}
}
t[prop] = value;
if (value && value.Children && value.Children.indexOf(proxyRef) < 0) {
value.Children.push(proxyRef);
try { value.ChildAdded && value.ChildAdded.Fire(proxyRef); } catch (_) {}
}
try { t.AncestryChanged && t.AncestryChanged.Fire(proxyRef, value); } catch (_) {}
return true;
}
t[prop] = value;
return true;
},
@ -426,6 +448,7 @@ function newInstance(className, name) {
return true;
},
});
return proxyRef;
}
/**