Need a place to put objects from game.Workspace where the scripts can still execute

Problem

As a Roblox developer, it is currently too hard to deal with objects that have scripts that need to be removed from the workspace but the scripts still need to execute.

Use Case

The one use case that I can think of is when dealing with weapons that have projectiles which have their own scripts that execute for the duration of the existence of the projectile. Usually, I just reparent the script to something else that is in the workspace and destroy the projectile. However, when the projectile root container is an Actor, this cannot be done because moving to a place that is outside the actor will cause the script to execute again from the start and possibly cause an error since the relational references aren’t present.

The parent of the actor cannot be changed to nil because then the script will stop working completely and events will be disconnected. Currently, the only viable solution is to parent the projectile to game.ServerScriptService which will remove the projectile from game.Workspace but allow the projectile’s script to keep executing. This issue with this is that it will pollute the tree with temporary objects which is not a good thing.

Suggested Solution

Although any solution would be up to Roblox and the engineers to devise, one possible solution is to implement a new service. The name of the service could be called TemporaryObjects which is designed specifically to house those objects. Objects placed in such a service would be removed from consideration by the physics engine but still allow the scripts attached to those objects to execute.

Conclusion

If Roblox is able to address this issue, it would improve my development experience because we will have a designated location to place game objects that need to be removed from the workspace but the associated scripts can still execute.

2 Likes

Could you use a folder in ServerScriptService for organization?

The reason this is so difficult is because putting scripts within reusable objects is pretty bad practice

Every script adds some overhead that adds up behind the scenes

To fix this you can add a module or something to replicated first or serverstorage then call that module when you need to spawn a projectile

You handle the entire projectile via a coroutine inside of the module

1 Like

You can use the RunContext property of scripts to ensure they work all the time, inside any container. Change it from legacy to Server or Client, depending on whether you want it to be like a local script, or like a server script

I don’t quite understand why you need to move your objects somewhere else before deleting them?

2 Likes

@VitalWinter That’s what I’m currently doing.

@LucidPolygon The way that this is set up is not really possible to do that because everything is in actors. So scripts are potentially isolated from each other due to being in different VMs. If everything was one thread, doing it that way wouldn’t be an issue. But it’s not. Believe me, I have done my research on this and that is the only viable way to do it.

@Tomi1231 I don’t see how the run context has any bearing on this since the script is already a server script. As for the reason, because there are effects being played when the projectile hits something, the projectile needs to be removed from the game environment but the associated script needs to keep running to process damage and cleanup of effects.

Scripts with RunContext set to Legacy will only run in certain containers such under Workspace or ServerScriptService; setting this to Server allows the script to run on the server while parented to anything (except nil), you could use this behaviour to parent your object to a different container (such as ReplicatedStorage) while retaining the script execution, achieving your desired use-case.

2 Likes

@Abcreator Interesting. It would be nice to have a dedicated place to put temporary objects though where the server script will still execute. In looking at RunContext, the link provided defines the Enum. But, in looking at the documentation, it shows this:

So that tells me that if I change it from Legacy to Enum.RunContext.LocalScript for a local script, it will run anywhere. Am I reading that correctly?

Besides, for client anti-cheat, I have been able to get things to run with a nil parent to hide scripts. So parenting to nil doesn’t stop scripts from executing in certain contexts, and that’s with Legacy set.

RunContext legacy acts like a normal server script. Only runs in certain places. RunContext server is a normal server script that can run anywhere. RunContext client is a localscript but can run anywhere. For a localscript that can only run in certain places, use the default localscript class.