Current Version: Release 8
Release Date: Feb 3, 2026
Roblox has unflagged the library, I hope it will not happen again for future releases.
Shatterbox Client-Server Voxel Destruction
External Resources
is used for client-server communication.
VoxBreaker inspired many features as well as the current syntax of the module.
Hello, I am here presenting a library designed for use in games that require voxel destruction on static maps. It is made to be scalable with performance and maintenance. It is also designed to be very easy to use. If you're looking for a fast destruction library that won't make your buildings flash (with StreamingEnabled), you found it!
In terms of performance, I would say that my system rivals JJS. It might even out-perform it. I am still working on the module.

Here is the test place file if you just want to jump into Studio and see it in action:
ShatterboxTestPlace.rbxl (213.1 KB)
There are 7 different tools that showcase various parts of the library. Feel free to explore and use the code from there if you need to.
Example GIFs
Secure (sanity checks are up to you), seamless client initiated destructions so you can have hitboxes that perfectly predict your Players.

The optional Puppeteer system creates interpolated debris, for when you just really want to squeeze out as much client side FPS as possible with loads of debris, at the expense of the server speed.

True greedy meshing is used (sorry VoxelDestruct 2.1) to minimize the number of static parts resulting from destruction

Texture instances maintain their proper offset on voxels and static parts

Encapsulation checks are used to make larger operations insanely fast. (SkipEncapsulatedVoxels)

Any Part shape is supported when using the destruction functions. MeshParts are not supported due to me using math under the hood to minimize calls to spatial query functions.
Encapsulation checks are used even when SkipEncapsulatedVoxels = false, which is a key difference in my subdivision algorithm compared to others. When a part is fully encapsulated, I either voxelize it entirely or just destroy it rather than doing expensive subdivisions and intersection checks.
(notice the player is 1 pixel large in this gif, SkipEncapsulatedVoxels = true):

The Reset function will reset all modified objects to the state they were in before subdividing. Use this before you change maps, to properly reset your map to the state it was in before Shatterbox touched it.

There is configurable smooth cleanup for destructions (you can turn it off with a setting or by setting CleanupDelay = 0)

There are 3 built-in destruction effects, one which is the first gif shown in this thread, the second is a re-creation of JJS M1 destructions (with interpolated voxels). It’s called “BumpyFloorBreakWalls”:

The final built in effect is called “MappingVoxelSpace” which is an example on how to use voxel space coordinates to perform voxel destruction effects regardless of the voxel size. All of these effects are found in the Shatterbox/effects modules

How does it work?
The voxel destruction algorithm
Part divisions use a modified form of octree subdividing, where parts can either divide into 8, 4, or just 2 pieces. Shatterbox decides when it is best to use KD subdivisioning instead (CutPartInHalf like VoxBreaker).
To explain my ImaginaryVoxels algorithm, which is one of the key differences between my library and others, I will first explain the standard algorithm for voxel destruction:
The first step is to use GetPartsInPart on your “CuttingPart” to find all of the parts you need to subdivide. Then you subdivide all of them, and immediately put them in the workspace. If a part cannot be subdivided, it’s returned as a voxel. Repeat this process over and over until you have no more parts to subdivide. This is how VoxelDestruct 2.1, VoxBreaker, and presumably everyone else handles their voxel destruction.
My algorithm is different in the sense that it may only use one singular call to GetPartsInPart to find the destructible parts, and then I use pure subdivision/intersection/encapsulation math to generate the final product with no intermediate parts (unless you have the frame limit enabled).
That is why it’s called ImaginaryVoxels, because in a sense, the computer is doing it all “in its head” before displaying to you what it already knew. This algorithm is insanely efficient, where most of the performance loss comes from creating new necessary parts and destroying old ones, rather than the voxel destruction calculation itself.
Both of the destruction functions use ImaginaryVoxels under the hood. Currently, GreedyMeshing happens after these final static parts are created, which is room for potential improvement
If an overlapping Block is fully inside of the intersecting part, it either gets deleted or voxelized using ImaginaryVoxelize (according to SkipEncapsulatedVoxels). Otherwise, it gets divided. If a division is attempted but the part is at the minimum voxel size, it is considered a voxel.
Client-Server
The Client-Server algorithm just tells clients to copy the map before the server breaks it. When the client is done copying, it instantly starts its own destruction. The server-owned parts are not replicated to clients unless a new player joins, that new player gets fresh parts. This helps network usage massively since only the original parts get replicated, and reduces the part flashing caused by having StreamingEnabled = true.
When a client performs voxel destruction with Client-Server enabled, they are given permission to create dirty groups for the server and other clients. Visually this does nothing. This is how Shatterbox allows secure client sided destructions. If you want a client sided destruction to replicate, you have to do it yourself by performing the same destruction on the server side, making sure to put your own sanity checks in there so you don’t get hacked.
The Puppeteer system was gracefully explained below by @Impermanently, it also utilizes buffers. Unlike JJS, I handle interpolation through CFrame:Lerp() which has less memory churn compared to having to manage Tweens.
https://devforum.roblox.com/t/shatterbox-client-server-voxel-destruction-simple-and-optimized-release-6/3674163/91?u=azavier123
Optimization tips
-
The key to efficient destructions is to use GridSize according to part sizes. Large parts should have a larger GridSize. This keeps the number of divisions required for the average operation consistent
-
Consider “chunking” up large parts like the ground. This saves operation steps, allows encapsulation checks to work their magic faster, and makes greedy meshing appear faster (since greedy meshing only goes as far as the original part did).
Changelog
Changelog has been moved to GitHub. You can scroll through the commit history to see the changes each commit brought, as I provide a changelog for each of them. I know it’s not perfect, but there are simply too many changes to list at this point.
Known issues
- None currently. Let me know if you find any bugs in this release, and tell me how I can reproduce it.
Planned features
-
Optionally, a more smooth “Smooth cleanup” algorithm which will dynamically remove operations, while preserving present ones.
-
Optional usage of the “ObjectCache” module.
-
Optional dynamic welding, for anyone who wants falling buildings instead of levitating ones.
-
Removal of the “static map” restriction. In the future, I plan to make Shatterbox a system akin to the “Clone Drone in the Danger Zone” so that resetting of moved divisions is possible.
-
Union “slice” style destructions, which are not voxel destruction, but I think are cool.
-
Some sort of EditableMesh destructions, perhaps with Marching Cubes?
Current development sneak peeks
Falling buildings / unanchored parts (people have been asking for this for so long)

I know it’s not perfect, and I am all ears for any possible optimizations. I am actively developing this and will update the thread if any information changes accordingly. I hope you guys like it!
Join the discord server if you need assistance: https://discord.gg/WRfz79uRTy

(I am thinking of ways to mitigate the part flashing even further. This gif shows that Client-Server currently isn’t foolproof, and if your server is extremely laggy part flashing can still happen)



