VoxBreaker | An OOP Voxel Destruction module

So with those returned parts, do i need to clone them and parent them to workspace?

You can do whatever you want with them. If you want to do some heavy physics calculations then yes id recommend cloning the parts on the client and destroying the original ones.

Is the VoxBreaker rework going well?

Its mostly done I’ve just had some complications with other projects which have been taking up my time. As well as one major bug which I’ve been struggling to work out.

4 Likes

how to fix that voxel size is relative to walls size…
изображение
You can see that voxels are longer in one direction and thinner in another…
I want them to be cubic.

Alright so bit of an update, I’m sharing the current state of this new version here:
VoxBreaker 2.0.rbxm (24.3 KB)

I’m not heavily announcing this massive new update yet, as the current version I just sent, is heavily bugged. Though a vast improvement from the previous version of the module. I revamped essentially everything, and It is much more readable and performant.

The main thing that changed was the logic, in that now parts are no longer cloned, but I am instead creating a table of part information that is divided. Essentially, before, the module was repeatedly dividing and cloning parts in a single instant. Now, the module is just repeatedly dividing a table of part information. Since there is no instancing in this process, the performance is heavily increased. This idea was suggested by @527366

Additionally, the module now uses object cache instead of part cache. I made the move due to numerous people suggesting it, as well as object cache generally having better results visually.

And of course, the thing that I’ve been teasing at for a long while, the new algorithm is also here. This new version has support for both the original algorithm, Octrees, and the new algorithm, which I couldn’t really find a name for, but it was sourced from Voxel Destruct
Performance wise, I’m not exactly sure how much more performant this new algorithm is, but it does have major differences visually. The biggest of which is that this algorithm produces perfectly cubic voxels, which is a concern I have received from several people now.

There is one new method, ReturnPart() which allows you to return parts to the cache outside of the module. Use this instead of destroying the voxels.

When you open the module, you may notice a greedy mesher in there, but the module does not currently have greedy meshing capabilities. I haven’t had the time to make a greedy meshing function that works, but I have found a way to implement greedy meshing without there being major loads on performance.

And something else I shared previously, was the improvements to part resetting. The logic for part resetting has been rewritten completely, and is now almost perfectly seemless.

Also, the module now uses tags instead of attributes.

Overall, performance wise, this is a massive improvement to the previous version. But like I said, there are 2 major bugs, and several features I have yet to add which are already in the previous version of the module. The first of these bugs is that chunks of parts are not getting created, leaving holes between voxels. The second is that moveable hitboxes are not detecting some voxels. Both of these are 100% logic errors, I’ve just been struggling to figure them out.
And then this new version is missing key features, such as textures being cloned onto voxels, and setting reset times below zero, which would normally prevent voxels from resetting entirely.

The reason why I’m releasing this entirely unfinished version is due to a lack of time for me to work on this module. I am currently balancing several projects with college, and I have had very little time to work on this module. I have also had a lot of trouble in figuring out the current bugs, and so instead of agonizing over fixing them, I’ve decided to just release it in it’s current state since I know some of you have been waiting quite a while for this.

The complete version of this may take a long while to be fully completed due to how little time I have, and given how unfinished it is, I am only sharing this here. The github, marketplace model, and test place have not been updated, and you can still get the previous version of the module in any of those places.

7 Likes

It looks like the test place has been updated, and is broken lol.

Might just be the place in studio. I never published the changes but I forgot you can see the changes in studio lol. Fixed it now.

1 Like

@Bartokens will you add a setting gridlock like in voxel destruct to avoid this happening
Edit:

module doesnt work at all…
изображение

Like i said, its majorly bugged. Please read through everything i said first. The only breaking change of the new version is that it uses tags instead of attributes now. You can also still use the previous version.

1 Like

OHHH I DIDNT SEE THAT Sorry, i am stupid and eepy
Edit:
Actually tags are more perfomant than attributes, i prefer to use them.
Edit 2:
Couldnt find any bugs, but new version is much more perfomant and better in voxelizing stuff, gonna implement some code from it into my api that i may release soon (it adds sounds, particles, neon screens breaking, etc…)
Edit 3:
theres one major bug, its deleting the walls and when
изображение
this setting set to false almost no debris appear, likely because its deleting all parts that are under size or over size of the minimum voxel size, i would like to see this setting work like in jujutsu shenanigans(because its making parts cubic and then resizes them somehow, couldnt figure it out, but if i find solution will make post about this!) or something like the gridlock in voxel destruct.
изображение


as you can see its just deleting everything.

1 Like

I still appreciate your work very much! looking forward to see the completed version of this module rework.

1 Like

We appreciate all of your hard work! I’m really happy about the move to tags. The module still needs some clean up, but this is something I’ll contribute on the repository once this version is released.

1 Like

An issue I came across were subdivided parts not disappearing when further destructed upon. I managed to find a fix by adding the following lines of code into the :ConstructVoxels() method (under the for loop):

if partInfo.OriginalPart then
	partInfo.OriginalPart:RemoveTag('Voxel')
end

Edit: Also thank you very much for making this module! I really appreciate what you’ve given us to use for our own works.

1 Like

The Raycast keep detecting the hitbox and exclude doesn’t work, how to fix this?

Hows it going with the module?

do you have any idea how i could fix making player get flung or something when using the createhitbox on a floor? so far it hasnt been going great and its really annoying… this is the script i used

local PhysicsService = game:GetService("PhysicsService")

local collisions = "Voxel"

-- Function to set up collision groups
local function setupCollisionGroups()
	-- Create the collision group if it doesn't exist
	if not pcall(function() PhysicsService:CreateCollisionGroup(collisions) end) then
		print("Collision group already exists.")
	end
	PhysicsService:CollisionGroupSetCollidable(collisions, collisions, false)
end

local function setCollisionGroup(parts)
	for _, part in ipairs(parts:GetDescendants()) do
		if part:IsA("BasePart") then
			PhysicsService:SetPartCollisionGroup(part, collisions)
		end
	end
end

-- Call setup function at the start of the script
setupCollisionGroups()

local function handlevoxelbreaker(CF)

	local TweenService = game:GetService("TweenService")
	local deb = game:GetService("Debris")







	local VoxBreaker = require(game.ReplicatedStorage.VoxBreaker)
	local Size = Vector3.new(10, 10, 10)

	-- Set the Cframe to be in front of the HumanoidRootPart
	local Cframe = CF
	local Shape = Enum.PartType.Ball
	local MinimumSize = math.random(2.5, 4)
	local Seconds = 5

	-- Assign player parts to PlayerGroup collision group
	task.spawn(function()
		local Voxels = VoxBreaker:CreateHitbox(Size, Cframe, Shape, MinimumSize, Seconds)
	local playedSounds = {}

		for _, v in pairs(Voxels) do
			setCollisionGroup(v)
		if math.random(1, 2) == 1 then
			v.CastShadow = false
			v.Anchored = false
			v.Massless = true
			v.Size = v.Size - Vector3.new(0.05, 0.05, 0.05)

			-- Set voxel to VoxelGroup collision group
			PhysicsService:SetPartCollisionGroup(v, "VoxelGroup")

			local initialVelocity = v.Velocity.Magnitude
			local soundsFolder = game.ReplicatedStorage.Rockimpacts
			local soundNames = {}

			for _, sound in pairs(soundsFolder:GetChildren()) do
				if sound:IsA("Sound") then
					table.insert(soundNames, sound.Name)
				end
			end

			local function playImpactSound()
				local currentVelocity = v.Velocity.Magnitude
				if not playedSounds[v] or math.abs(currentVelocity - initialVelocity) > 5 then
					playedSounds[v] = true
					initialVelocity = currentVelocity
					if math.random(1, 3) == 1 then
						local particle = game.ReplicatedStorage.Rockimpactpar["skin" .. math.random(0, 2)]:Clone()
						particle.Parent = v
						particle.Enabled = true
						deb:AddItem(particle, 0.5)
					end
					if #soundNames > 0 then
						local randomSoundName = soundNames[math.random(1, #soundNames)]
						local randomSound = soundsFolder[randomSoundName]:Clone()
						randomSound.Parent = v
						randomSound:Play()
						game:GetService("Debris"):AddItem(randomSound, randomSound.TimeLength)
					else
						warn("No sounds found in ReplicatedStorage.Rockimpacts.")
					end
				end
			end

			local touchedsounddeb = false
			v.Touched:Connect(function()
				local touchingParts = v:GetTouchingParts()
				if #touchingParts > 0 and not touchedsounddeb then
					touchedsounddeb = true
					playImpactSound()
					task.spawn(function()
						wait(0.5)
						touchedsounddeb = false
					end)
				end
			end)

			-- Despawn the voxel by tweening its size to 0
			local tweenInfo = TweenInfo.new(Seconds, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
			local goal = { Size = Vector3.new(0, 0, 0) }
			local tween = TweenService:Create(v, tweenInfo, goal)
			task.spawn(function()
				task.wait(1)
				tween:Play()
			end)
		elseif math.random(1,2) == 2 then
			v:Destroy()
		end

	end
	end)
	
end
1 Like

Is it just me or does the test place cause an immense lag spike when spawning the voxels? Does the module consistently cause lag spikes like this?

I have not looked at how it’s scripted, but perhaps it’s because it’s spawning too many parts in one frame. It may be better to spread it out over a couple frames, but I don’t know, just speculating based on my couple minutes of testing it.

Mine did that too, until I turned on StreamingEnabled (I have no idea why it affects it)