VoxBreaker | An OOP Voxel Destruction module

–Server Script
local VoxBreaker = require(game.ReplicatedStorage.VoxBreaker)
local remote = game.ReplicatedStorage.RemoteEvent

remote.OnServerEvent:Connect(function(player,cframe)
local voxels = VoxBreaker:CreateHitbox(Vector3.new(5, 6, 6),cframe,Enum.PartType.Ball,1,20)
for _,voxel in voxels do
voxel.Parent = game.ReplicatedStorage --Parent voxels to replicated storage so that the client can see them
end
remote:FireAllClients(voxels,cframe) --Fire the table back to the client before destroying them on the server
for _,voxel in voxels do
voxel:Destroy()
end
end)

for _, part in workspace.Map[“Biome Sprites”]:GetDescendants() do
if (part:IsA(“BasePart”) or part:IsA(“MeshPart”) or part:IsA(“UnionOperation”)) and (part.Name ~= “Snowflakes”) then
part:SetAttribute(“Destroyable”, true)
end
end

for _, part in workspace.Map.Biomes:GetDescendants() do
if (part:IsA(“BasePart”) or part:IsA(“MeshPart”) or part:IsA(“UnionOperation”)) and (part.Name ~= “Snowflakes”) then
part:SetAttribute(“Destroyable”, true)
end
end

–Local Script
local crumbleSound = script:WaitForChild(“crumble”)

local VoxBreaker = require(game.ReplicatedStorage.VoxBreaker)

local Random = Random.new()

game.ReplicatedStorage.RemoteEvent.OnClientEvent:Connect(function(voxels,cframe)
local sound = crumbleSound:Clone()
sound.Parent = voxels[1]
sound.PlaybackSpeed = Random:NextInteger(0.85,1.15)
sound.Volume = sound.Volume
sound:Play()
game.Debris:AddItem(sound, 3)
for _,voxel in voxels do
local clone = voxel:Clone()
clone.Parent = workspace.Destruction
clone.Anchored = false
local velocity = CFrame.lookAt(clone.Position,cframe.Position).LookVector * (-85 * (clone.Mass))
clone:ApplyImpulse(velocity)
clone.Velocity = velocity / 8
clone:ApplyAngularImpulse(velocity)
clone:SetAttribute(“Destroyable”, true)
end
task.wait(30)
for _,v in workspace.Destruction:GetChildren() do
v:Destroy()
end
end)

Sorry I’m new to the devforum and don’t know how to format

I dont believe this script should make it lag though

I’m noticing a few issues here. For one you shouldn’t be setting BaseParts or unions to destroyable. The module only divides normal parts.

Your also setting your minimum voxel size to 1. I don’t really recommend setting that so low as it will result in a ton of parts and could kill performance.

In addition, your also using apply impulse twice in a row. Not sure if that’s the issue here but it’s a possibility.

And if none of that fixes your issues, then you could have children nested under your parts. If you have any scripts within your destroyable parts, then they could be getting cloned and adding onto the lag.

okay i will fix those and see if the frame rate improves

what do you reckon would be a reasonable minimum size?
(also the lag greatly reduced, thanks)

1 Like

I usually do 3-4 for player sized hitboxes. But it depends on how big your hitbox is. The larger your hitbox is, the bigger your minimum size should be. And you can also set the minimum size to “Relative” for hitboxes that expand or shrink.

Okay, and lastly could you explain what the use of the partCache is :sweat_smile:, please.

PartCache is a seperate module that allows you to create a massive amount of parts without much lag. With it, you can make a ton of parts at the start of a script and store them within a cache, and then instead of instancing any new parts, you can retrieve them from the cache.

The reason I implemented it into VoxBreaker was because instancing new parts and destroying them can be pretty bad for performance. So with PartCache, the issue of lag when creating or destroying parts is alleviated, as you dont have to create or destroy parts with it.

So I recommend having PartCache on for performance purposes, but there are currently a few bugs that occur when you have it activated mentioned in previous posts, which will get fixed soon.

1 Like

Okay, thank you for answering my questions!

1 Like

Oh , it seems that enabling streaming enabled in the workspace COMPLETELY eliminates the lag

1 Like

haven’t had any trouble with this update, good work!

1 Like

How to make the size of voxels consistent? MinimumSize works fine with even number but if I use an odd number the size will be inconsistant. MinimumSize 2 is too small and MinimumSize 4 is too big, how can I get something in between? Btw thanks for open sourcing this awesome module.

1 Like

maybe try 2.98, as it ends with an even number?

Why do the voxels end up being not cube-shaped?
When I create the hitbox, the voxels end up being more rectangular instead of perfect 2-by-2 voxels.
Does anyone know how to fix this?

I haven’t touched the VoxBreaker module, and am using pretty normal code.

local VoxBreaker = require(script:WaitForChild("VoxBreaker"))

local Hitbox:BasePart = script.Parent

task.wait(4)

print("Voxelizing...")

local Parts = VoxBreaker:CreateHitbox(Hitbox.Size, Hitbox.CFrame, Hitbox.Shape, 2, 6)

for _, Part in pairs(Parts) do
	Part:Destroy()
end

I’ve clarified this before, in many instances, creating perfectly cube shaped voxels is impossible. If the voxels have to fit in every possible sized part, then in many cases they’d have to be rectangular if the part is rectangular. Otherwise you’d have gaps between voxels. If you do want perfectly cube shaped voxels, then you’d have to build your map with only cubes.

Why not create as many perfect cubes as you can, but then leave the excess (portion too small to be cubed) at the end?
Like this:
image

I did consider this, but just for consistency, I’d rather have several evenly sized rectangles than some cubes with outliers.

I’ve had a few issues with this module recently, mainly these 3 though:
The map flashing for a second then returning to normal whilst creating voxels
Part lag even with PartCache enabled
Parts sometimes just being deleted and not returning back to normal

It may just be my scripting, as other attacks I have in my game cause part flashing less frequently, but all of them do the other 2 issues.

What I do in my script is intended use, so I don’t think it is my scripting. I have tried turning PartCache off, but nothing changed.

Heres what I do:

local HitboxV = VoxBreaker:CreateHitbox(Vector3.new(16,16,16),NewSlash.CFrame,Enum.PartType.Ball,3,60)
for i,v in pairs(HitboxV) do
	v.Anchored = false
end

I use RaycastHitbox to see if the projectile attack has hit a part or player, and if it is a part, it does the destruction physics, aka the code above. Is there a better way of going about this, or any solutions to my problems?

1 Like

To anyone concerned about bugs and the like, I will be updating the module soon. The previously mentioned game I’ve been working on will be releasing soon, so I’ve had to devote 100% of my time into that. But I am aware that there are bugs, and I will be fixing them. So expect bug fixes, along with some new features, as well as the new division algorithm, to be coming in the next update.

I’ve made my voxel destruction similar to yours (before ive seen this i might add) and I’m wondering if we can put our heads together and create somethingh m9ch better like this

fyi here’s my voxel destruction system in action, it isnt COMPLETELY done but its in the works for sure https://gyazo.com/8eba0d686c56c9667a588851e513239d

1 Like