Teardown-Issue-Tracker-Maintainers / Teardown-Issue-Tracker

A public repo for the community to track issues/bugs/feature requests in Teardown.
12 stars 5 forks source link

[Bug] GetEntityParent does not work on scripts #591

Open FlorentP42 opened 2 months ago

FlorentP42 commented 2 months ago

Describe the bug

I tried to use GetEntityParent() to get the parent script of a body entity: it didn't work, it kept returning nothing.

Steps to reproduce the behavior

  1. Make the following script and prefab spawnable
    -- script.lua
    function init()
    local body = FindBody("body")
    local parent1 = GetEntityParent(body)
    local parent2 = GetEntityParent(body, "", "script")
    local parent3 = body-1
    DebugPrint("parent1="..parent1..", type="..GetEntityType(parent1))
    DebugPrint("parent2="..parent2..", type="..GetEntityType(parent2))
    DebugPrint("parent3="..parent3..", type="..GetEntityType(parent3))
    end
    <prefab version="1.5.4">
    <group>
        <script file="MOD/script.lua">
            <body tags="body">
                <voxbox size="10 10 10"/>
            </body>
        </script>
    </group>
    </prefab>
  2. Spawn the object in the world.
  3. Notice that none of the methods using GetEntityParent() works to get the script handle, only the old body-1 hack works.

Expected behavior

GetEntityParent() works as advertised, on any kind of entities.

Environment

Additional context

Not sure if the issue is specific to the parent being a script or if it's a larger issue, you might want to test with other prefab structures...

YuLun-bili commented 2 months ago

Undocumented function GetScriptId() returns the handle of script which called it, currently not restricted but not sure if would change.

Gregory-Gregory commented 2 months ago

@FlorentP42 hi!

Thank you for reporting this issue. I have forwarded it to the QA team for further investigation.

FlorentP42 commented 2 months ago

Undocumented function GetScriptId() returns the handle of script which called it, currently not restricted but not sure if would change.

This would work for the example I provided above but sadly not for my real use case: I have scriptA parent of bodyA and scriptB and unrelated script able to find bodyA through some tags, and I need from that handle of bodyA to find scriptA in order to delete it safely (without crash).

I guess I could workaround that by putting a tag on scriptA as well and finding it through FindEntity() (assuming it does not have the same limitation as GetEntityParent()), but that's quite annoying when I know the body-1 hack works perfectly :p

YuLun-bili commented 2 months ago

deleting scripts at run time would skip function calls in other scripts for 1 tick iirc

FlorentP42 commented 2 months ago

deleting scripts at run time would skip function calls in other scripts for 1 tick iirc

Well that's sad... But I noticed that not deleting scripts when you have a bunch of bodies with script attached being spawned and then "killed" (broken until they are unusable) also make the game lag quite a lot ; which is fixed by deleting the "idle" scripts attached to the dead bodies so... Now I delete whatever script I spawned that is no longer doing anything relevant :p

Of course this does not apply to all mods, but for mods that spawns endless waves of enemies for example, the performance impact is real ;)

YuLun-bili commented 2 months ago

if broken then return at start of tick() etc. should be enough to prevent such issue I think. Or try to reuse these scripts maybe?

Or maybe implement a way to tell the game a script no longer required and can be skipped on the engine side (feature request detected)

FlorentP42 commented 2 months ago

if broken then return at start of tick() etc. should be enough to prevent such issue I think. Or try to reuse these scripts maybe?

Sadly returning at the start of every function was not enough, I had that already and it was still causing huge lag on the long run having a lot of dead scripts returning immediately in every function :/ About reusing scripts that's a lot trickier as you cannot put the script in the prefab any more if you want to do that, which is very inconvenient when you are building spawnable scripted objects for the spawn menu ^^

Or maybe implement a way to tell the game a script no longer required and can be skipped on the engine side (feature request detected)

That would help and avoid a lot of extra work on modders side for sure ^^

Gregory-Gregory commented 2 months ago

@FlorentP42 hi!

There is a response from the team regarding this:

That is intended behavior. The entity tree is flattened for optimization purposes when the level loads.

FlorentP42 commented 2 months ago

@Gregory-Gregory What does "flatten" means in this context? Does GetEntityParent() not work at all then? Or does it find only specific types of entities? Ideally I would like "script" to be part of the list of entities that are retained. If not possible, at least the exhaustive list of entities should be in the documentation so that we know "script" is purposefully not one of them... Right now it's a partial list that suggests there is more: image Same goes with other *Entity*() related functions in the doc. Note that I consider "script" a valid entity type because GetEntityType() returns it.

YuLun-bili commented 2 months ago

Flatten basically is what the hierarchy tree appears in editor is not what it looks like when level is loaded, such as shapes not being children of another shape but still under the same parent body. But I honestly don't know if game would flatten a script node. If that's the case it indeed needs to be documented.