Instance method: ClearAllChildren + IsA

Super common problem in gui programming: You have a list that contains a mix of actual list contents (GuiObjects) and layout constraints. You need to clear the list to display new contents.

Current solution:

for _, obj in list:GetChildren() do
   if not obj:IsA('GuiObject') then continue end
   obj:Destroy()
end

What I want to do:

list:ClearAllChildrenWhichAreA('GuiObject')

Easier to read, easier to write, instantly cleans up any code that populates lists or grids.

9 Likes

Is there a particular motivation towards this being a native method instead of a utility function you have? We don’t love adding things like this (especially on Instance) without serious value.

2 Likes

I think it’s bad to require strong arguments for adding things to Instance. Roblox should make their core API as ergonomic as possible instead of relying on users to fill in the gaps. If you rely on users like this as a rule then you end up with friction across your entire developer ecosystem where people need to learn an entirely new API toolset to join a project. There’s obviously a desire for standards across the platform, which is why you see things like Fusion and Roact. New developers come into this and can’t figure out what they should be using or where they should be getting it from. Developers can’t be trusted to coalesce upon frameworks that are accessible, forward-looking, and rigorously tested (see: Rojo not working with packages for the fifth year in a row). The entire reasoning chain here needs to be reevaluated with the knowledge of what developers are actually currently doing and how it can be improved.

Pros of an instance method:

  • Easy to read
  • Easy to write
  • Don’t have to set up boilerplate imports
  • Onboarding likely not needed
  • Tested by Roblox

Cons of an instance method:

  • There’s lots of tools for people to use (?)

Pros of writing it yourself

  • You can give it special features unique to your project/style (but if you do this then it becomes a con because it increases friction)

Cons of writing it yourself:

  • Have to import it from a module
    • The module is in a different place in each project
  • Have to write it yourself
    • Or rely on someone else to write it
  • Have to test it yourself
  • Non-standard naming and accessing scheme creates project-specific knowledge

This stuff all applies to instance methods in general

1 Like

I often find myself writing out long-hand alternatives to functions like these which makes my code longer, takes more time, and overall slows my game development process. It’s annoying to type this out over and over again. I find a wide variety of use cases from gui to map systems of my game. By having built-in methods it will improve my development experience by making code more readable and understandable whilst avoiding unneccessary code lines.

There’s already the basic Instance:ClearAllChildren(), which I personally have never found a use case for because there’s always some kind of condition I need.

Personally, I feel that methods like Instance:ClearAllChildrenOfClass() and Instance:ClearAllChildrenWhichAreA() for clearing child objects of class and child objects of class with inheritance (respectively) would be really useful.

2 Likes

Useful for what actually concrete examples?

The bar for something being added on Instance is high, but if you can give a bunch of good examples you could get there.

1 Like
  • clearing items from a ScrollingFrame/Frame which also contains formatting and appearance instances like UIListLayout, UIStroke, UIGridLayout, etc. For things like leaderboards and player lists where a sample frame is cloned and modified.
  • Clear all of a certain avatar item type in games like Catalog Avatar Creator which let you try on avatar items as to easier allow different ones to be tried should the user want to remove them all.
  • in pvp games, scripts may be dynamically created to create different behaviour for a specific map. It would be much easier to clear these scripts when they are no longer needed.
  • when the character needs to be cloned, for example to be placed into a ViewportFrame, clearing all LocalScripts from the character so they aren’t being run again.
  • games including abilities could use many VFX instances like Beams and ParticleEmitters to create an effect for the ability. Clearing these would become much easier.
  • in games with customisable items, instances like Decals and SurfaceGuis may be used. Should a player want to reset their customisation, we can clear them with Instance:ClearAllChildrenOfClass().
  • in vehicle simulation games where the vehicles are customisable, you may need to clear all VehicleSeat instances or constraint instances depending on the player’s choice.

These are just a few examples of where Instance:ClearAllChildrenOfClass() and Instance:ClearAllChildrenWhichAreA() would come in really helpful. I tried to pick examples which would be more relavant to a wider variety of games and therefore useful in more games.

5 Likes

Agreed. This is is an API I have found myself wanting a few times per month, for 10+ years now.
Specifically for the main reason in quoted reply:

4 Likes

I feel this can be pretty useful for clearing specific items when there are other existing items at play; However, I feel like each example - while similar - has its own use case for a specific purpose, where :ClearAllChildren() is for when you need to remove everything, while a for loop allows you to customize what specific condition should occur when it finds a specific object.

One example (which is the main reason people want it in the first place) would be when you have a hirearchy of disposable items of the same class, but you have objects that are essential for all the said disposable items. What it could do is only remove the disposable items when you specify their class, and only the essentials remain for later use of more disposable items.

Though, the alternative I can think of is CollectionService to identify and dispose of the disposable items:

for _,v in CollectionService:GetTagged("DisposableFrames") do
    v:Destroy()
end

In my opinion, its cool, has its cases, and would be very convinient for said cases.
Maybe an argument can be incorporated into the already existing function for those cases, like:

  • No Argument = Clear all Instances
  • Argument with a unknown class = Errors (Class does not exist or something idk)
  • Argument with a class = clear all children under class

I feel like the same could be said about stuff like :FindFirstChildOfClass() or :FindFirstChildWhichIsA().

While there are a few cases you might use them here are there, is much better than doing:
for _,v in this:GetChildren() do
    if not v:IsA(that) then continue end
    return v
end

-- when you can just say this:
this:FindFirstChildOfClass(That)

Even :ClearAllChildren(),

where all thats needed for it is:
for _,v in this:GetChildren() do
    v:Destroy()
end

Another one being :WaitForChild(), where before 2013,

you had to create the whole function in order to get something you wanted to load in:
--// THEN
function waitForChild(parent, childName)
	local child = parent:findFirstChild(childName) 
	if child then return child end
	while true do
		child = parent.ChildAdded:wait()
		if child.Name==childName then return child end
	end
end

local object = waitForChild(This, "That")

--// NOW
local object = This:WaitForChild("That") -- takes up a single line
-- very convinient and people take that for granted now
1 Like

Very well-written; our studio personally uses a luau-defined version of such a method for clearing UI containers, without removing the aforementioned ‘appearance’ instances. ClearAllChildrenWhichAreA would be super helpful, however it is quite the word soup. Perhaps ClearChildrenOfType or ClearChildrenByClass could work, however Roblox makes a distinction between “IsA” and “Class”, where IsA matches sub-classes, while e.g. FindFirstChildOfClass matches the specific class. However, FindFirstAncestorWhichIsA does already exist, so perhaps this isn’t much of an issue in the first place.

1 Like

Maybe it’d be easier to get something like this added? Would at least stop the endless “if instance isn’t instance I want” boilerplate spam.

2 Likes