This module was made by @Bartokens with the help of several developers from this thread. It is free to use and you don’t have to credit me. It is largely performant, but not perfect, so expect some issues with performance, especially with much larger scale destruction.
VoxBreaker is an open source voxel destruction module that gives developers several tools to work with voxel destruction. With such options as:
Optimized Voxelization
Custom Voxel Sizes
OOP structured hitboxes
Voxels resetting after a duration.
Code Rundown
So firstly, the module has several functions available to use, but generally they all do the same thing, which is divide a part into more parts. Only parts with a specified attribute name (“Destroyable” by default) can be divided.
The module will first check if the part is rectangular. This is to avoid rectangular voxels.
If the part is rectangular, the module cuts it in half, resulting in squares.
Then, let’s say your using the :CreateHitbox() function, the module will check for all parts touching the hitbox, and then repeatedly divide them until they reach a specified minimum voxel size. It divides them using quadtree partitioning, and results in something looking like this:
Voxels will not always be perfect cubes. This is to accommodate every possible part size, so if you’re dividing a part that’s incredibly thin on one axis, then the resulting voxels will be thin on one axis as well. But will still be square-shaped on the other two axes.
I heavily recommend changing the minimum voxel size to be bigger if your hitbox is large. This is because larger hitboxes will result in a ridiculous amount of parts if your voxel size is small, killing your performance.
When tagging your destroyable parts, make sure they don’t have any children. The module clones your parts, so anything parented to them will be cloned as well.
You can specify a minimum voxel size, but in many cases the voxels will not quite be accurate. The module will try to get as close to your specified size as possible.
Use this to create a hitbox that can be moved manually or attached to a part, and divides any part it touches continuously until :Stop() is called.
Functions:
:Start() - Starts moveable hitbox. Can be used to resume after :Stop() is called.
:Stop() - Completely stops moveable hitbox
:Destroy() - Destroys moveable hitbox.
GetTouchingParts() - Returns a table of parts touching the hitbox
WeldTo(part) - Welds the hitbox to a specified part.
UnWeld() - Unwelds the hitbox
:CutInHalf()
* :CutInHalf(Part : Part)
Use this to divide a part in half. Returns table containing halves.
This is mainly here to show how the module cuts parts in halves if they're rectangular. I don't actually know if there's a use case for this, so I suggest just using this to understand how the cutting works. It changes relative to how big the part is on different axes using pretty simple math.
Examples
Known Bugs:
In some rare cases, voxels larger than they should be will be returned. I’ve only found this to happen when PartCache is enabled, and will only occur on the client for some reason.
Voxels that are thin on the Y axis have been fixed. Before they would divide much thinner than necessary, resulting in a ton of thin parts stacking on top of one another, looking like this:
Now, they no longer do that, with much less stacked parts, so expect a drastic increase in performance. -The test place has also been updated to fit the new version
Specifics
Before, all parts were being divided using octrees. This would result in a cube divided into eight parts, 4 on top and 4 on the bottom. When you apply this to thin parts, you get even thinner parts, which isn’t the intended result. To fix this, I instead opted to go for quadtrees only for thin parts on the y axis, resulting in 4 parts evenly sized parts that aren’t thin. Meaning less stacking and a major increase in performance.
* Fixed parts not resetting back to normal after duration edit: they still aren’t resetting properly
2nd edit: voxels reset properly now!
Why not add a minimum size? Wouldn’t that be easier to implement and less edge cases? Minimum size could be like a ratio of the base part’s size to some value
Minimum Size is already a variable you can use in the module. As I’ve explained, the module will try to match the voxels to the minimum size on two axes. Since it has to accommodate every possible part size, one of those axes has to be left free, which results in parts like in the image I sent in my update post. But, I’ve already fixed it, so it’s fine.
For performance reasons I assume this is clientsided, yet it reminded me of a game where you eat stuff to get bigger, and it is slightly competitive as the map is limited so players fight for it, so I was wondering what were your thoughts on replicating the effects to the server.
Size
For example, the bigger the hitbox is, the more it will destroy, so the more points it would give, that’s just an example so I was wondering if there was any way to see that.
-
Sorry if I did a poor job at explaining myself I’m tired.
If you want to use it on the server, you can. I have only tested it on the client, so I’m not sure about the performance, but its pretty likely that it wouldn’t do well on the server.
And for the size question, yeah, you can always get whatever voxels are touching the hitboxes with built-in functions. So if you have a big ball-shaped hitbox, you can get all points (I’m assuming you mean voxels/parts), that are inside of the hitbox. All the hitboxes do is divide the voxels down, what you do with them is entirely up to you. You could unanchor them, delete them, send them flying, store them somewhere else, etc.
Also I just tested it on the server and it wasn’t working because I was using the MoveableHitbox and appearently RenderStepped can’t be used on the server.
Yet… I must be doing something wrong, I’m running into 2 issues here
It takes me multiple “hitboxes” for the destruction to show, as in I need to create a hitbox many times before the part is actually affected
Having a reset time less than zero makes the part just instantly disappear as soon as it is touched
I’ve just updated the module again. There were a few bugs with resetting the parts, but they should all be fixed now. Reinstall the module and you should be good
(and also I forgot runservice doesn’t work on the server, you could change renderstepped to a while loop and it should work)
So I should mention, the module does not automatically destroy everything. I don’t know if this is the mistake you made, as I can’t see your script, but when you create a normal hitbox (not moveable) you can create it as a variable, and it will return all voxels in a table. If you want to destroy them, then you would loop through the table and then destroy them.
Example Included in the module:
local VoxBreaker = require(game.ReplicatedStorage.VoxBreaker)
local Size = Vector3.new(10,10,10)
local Cframe = CFrame.new(5,5,5)
local Shape = Enum.PartType.Ball
local MinimumSize = 8
local Seconds = 20
local Voxels = VoxBreaker:CreateHitbox(Size,Cframe,Shape,MinimumSize,Seconds)
for i, v in pairs(Voxels) do
v:Destroy()
end
And as for the rest time issue, I’ll look more into it. I haven’t tested that much so I’ll see if that’s a bug.
the TouchEvent is just the bindable event used to fire the .Touched() event. You can just ignore it.
And for most questions concerning functions and the like, all of the documentation is listed in the module with examples, so you can look through that if you’re still confused. Or ask me if you’d like. There’s likely still bugs I haven’t seen yet.