# VoxelCore swaps Unreal's default containers for faster ones, in C++

> VoxelCore is an open source Unreal Engine plugin that replaces the engine's default containers, such as TMap, TArray and TBitArray, with faster equivalents built for voxel workloads, and it is written for C++ projects rather than blueprint-only ones. It suits Unreal developers with hot data structures, and the trade is a plugin that must track engine versions and containers that do not preserve insertion order in the same way the engine ones do.

**VoxelPlugin/VoxelCore** — Open-source plugin with the Core module of Voxel Plugin

- Repository: https://github.com/VoxelPlugin/VoxelCore
- Stars: 522 · Forks: 54
- Language: C++
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/voxelplugin-voxelcore

## A drop-in container replacement for Unreal C++ projects

VoxelCore is an open-source plugin carrying the Core module of Voxel Plugin. The README describes it as containing a bunch of high performance containers to replace the default Unreal ones, and a few helper macros and tools.

The scope is narrow and clear. It is not a rendering plugin or a voxel generation system. It is a set of container types, with names that make the substitution obvious: TVoxelMap, TVoxelSet, TVoxelArray, TVoxelSparseArray, FVoxelBitArray and TVoxelUniqueFunction, each standing in for an engine type such as TMap, TSet, TArray, TSparseArray, TBitArray and TUniqueFunction.

The audience restriction is stated just as plainly. This plugin is intented to be used in C++, and if your project is blueprint-only it will be of no use to you. That makes sense given what the containers are, since a blueprint project never names a container type.

The repository layout reflects a standard Unreal plugin. There is VoxelCore.uplugin at the root, the descriptor that makes the directory loadable as a plugin, alongside Source/ for the code, Resources/ and Shaders/ for assets, and a LICENSE. The Shaders directory is a reminder that this is part of a larger voxel toolset, even though the core module itself is about data structures.

The project is written in C++, licensed MIT, and the author invites questions about the code on a Discord server.

## What the benchmark numbers actually compare, and on what machine

The README publishes the full output of VoxelCoreBenchmark.cpp, comparing the voxel containers against the engine ones in shipping with checks disabled, and it states the capture was done on a 7945HX.

The output is a side-by-side table of timings, and each line pairs an engine call with a voxel call and ends in a ratio:

```
TMap::Remove                                       took 34.93ns   +- 3.1     and TVoxelMap::Remove                                  took 24.1ns    +- 2.3     ====>  1.4x faster
  Note: TVoxelMap::Remove does a RemoveAtSwap and doesn't keep order. TMap::Remove keeps order as long as no new element is added afterwards
TMap::FindOrAdd                                    took 0.95ns    +- 0.1     and TVoxelMap::FindOrAdd                               took 0.81ns    +- 0.1     ====>  1.2x faster
TMap::Add                                          took 7.51ns    +- 0.1     and TVoxelMap::Add_CheckNew                            took 2.14ns    +- 0.1     ====>  3.5x faster
  Note: TVoxelMap::Add_CheckNew can only be used when the element is not already in the map
TMap::Reserve(1M)                                  took 1.16ms    +- 0       and TVoxelMap::Reserve(1M)                             took 66.8us    +- 5.3     ====> 17.4x faster
  Note: TMap::Reserve builds a linked list on reserve, TVoxelMap::Reserve is a memset
```

Two things about how these numbers were produced matter for reading them.

The first is that they come from the plugin's own benchmark file, linked in the README, so the methodology is inspectable rather than asserted. The second is the configuration: shipping with checks disabled. That is the configuration where the containers behave as they would in a shipped game, and it is also where the engine's debug assertions would otherwise be adding overhead to the baseline.

The hardware matters too. A 7945HX is a high-end desktop part, and the absolute numbers in nanoseconds are small enough that measurement noise shows up in the error columns. The ratios are the useful part, and the largest of them, the 17.4x on Reserve, comes with its own explanation in the note line: TMap::Reserve builds a linked list on reserve, while TVoxelMap::Reserve is a memset.

That pattern holds across the output. Where the voxel container wins by a large factor, the note explains the structural reason. Where the margin is small, the note usually explains a limitation instead. The notes are the most valuable part of the benchmark, because a speed figure without a reason is not actionable.

## The differences that matter are semantic, not just speed

The benchmark notes record several behavioural changes that a reader should not miss, because they are the cases where the voxel container is not a transparent substitute.

The clearest is ordering. TVoxelMap::Remove does a RemoveAtSwap and does not keep order, while TMap::Remove keeps order as long as no new element is added afterwards. That is a real semantic difference, and for code that iterates a map and depends on insertion order it is a behavioural change rather than an optimisation.

There is a similar constraint on insertion. TVoxelMap::Add_CheckNew can only be used when the element is not already in the map, which makes it safe to use but requires the caller to know the key is absent.

The sparse array benchmark shows the same shape. TSparseArray::Add on an empty array took 2.77ns while TVoxelSparseArray::Add on an empty array took 1.64ns, giving 1.7x faster, but on a full array with all elements removed the two were effectively identical at 2.76ns and 2.75ns, so 1.0x faster. The container that wins when there is room to append is no faster when it has to reuse a freed slot.

There is also a benchmark note about TRobinHoodHashMap::Remove being able to shrink the table, which is why the benchmark adds the element back after removing it. That is a measurement artefact rather than a limitation of the voxel containers, but it tells you the comparison is not entirely like for like.

Two more engine-side notes explain where the voxel versions get their edge. FVoxelBitArray::CountSetBits makes use of the popcount intrinsics, and TArray::RemoveAtSwap of one element does a memcpy with a non-compile-time size, which is where the 2.9x on TVoxelArray::RemoveAtSwap comes from.

## Memory footprint, and the reserve behaviour behind it

The size comparison is separate from the speed comparison and is worth reading on its own.

For a uint16 to uint16 map with 1M elements, TVoxelMap uses 9.6MB against TMap at 13.6MB and TRobinHoodHashMap at 19.8MB. For uint32 to uint32 with 1M elements, TVoxelMap is 13.4MB against 17.4MB for TMap and 23.6MB for TRobinHoodHashMap. So the voxel map is both smaller than the engine map and substantially smaller than the engine's own alternative hash map implementation.

The README attributes the Reserve speed difference to implementation strategy rather than to a cleverer hash function. TMap::Reserve builds a linked list on reserve, while TVoxelMap::Reserve is a memset.

That single detail explains a lot of the results. A memset over the whole allocated region is close to the theoretical floor for allocating and clearing memory, and it scales with the size of the allocation rather than with the number of elements. A linked list construction touches each element. For a map with a million entries that is the difference between 66.8us and 1.16ms.

It also explains the memory numbers, at least in direction. If the reserve path is a memset rather than a per-element operation, the container is likely laying down a flat array of buckets rather than maintaining a separate free list, and a flat layout is what makes the per-element structures smaller.

The note that TVoxelSet performs similarly is short but relevant, since a set is the other container most likely to appear in the same code paths as a map, and it means the sizing argument extends to both.

## Adding it to a project: the plugin folder, the dependency and the include

The getting started section is four sentences long, and there is no install command, because a Unreal plugin is not installed the way a library is.

You download the repository and put it in the Plugins folder of your project. Then you add the VoxelCore dependency, or VoxelCoreEditor for editor features, to your module. For runtime features you include VoxelMinimal.h, and for editor features you include VoxelEditorMinimal.h. If you have a custom PCH, the README says you should add these includes to it.

The minimal header naming is a convention worth understanding rather than copying. VoxelMinimal.h is the runtime surface, and it is what you include in shipped code. VoxelEditorMinimal.h is the editor-only surface. Splitting them means a runtime module does not accidentally pull in editor dependencies, which is a common cause of packaged builds failing to cook.

The custom PCH note is the other practical point. Projects with a shared prefix header have to add the include there, otherwise the include order and the module's own declarations end up inconsistent between translation units.

On compatibility, the README says Voxel Core usually compiles on the last few Unreal releases and to check branches for older engine versions. That is the honest framing for a plugin that reaches into engine container internals: it tracks recent engine versions, and if you are on an older one you are looking at a branch rather than the default. The repository has no GitHub releases, so the branches and the master branch are how versions are distinguished.

There is also a separate question of how the plugin is debugged. VoxelCore uses its own assertion macros, checkVoxelSlow and similar, and by default they follow DO_CHECK. You can manually disable them by defining VOXEL_DEBUG to 0 before including VoxelMinimal.h. That is a small but important detail, because the assertions are on by default and behave differently from the engine's own check macros in terms of what they guarantee.

## Where VoxelCore is the wrong choice

There are clear cases where this plugin is the wrong answer, and the first two are stated by the project itself.

If your project is blueprint-only, the plugin is useless, and the README says so without hedging. If your containers are not hot, the trade is not worth it, because you are taking on a dependency that has to track engine versions in exchange for speed on code paths that were never your bottleneck. The benchmark is a microbenchmark of container primitives, which is exactly where you would expect a data structure to matter, and exactly where in a real project it often does not.

The third case is order dependence. If your code relies on TMap preserving insertion order after a removal, TVoxelMap will change the behaviour, because it does a RemoveAtSwap. The README records the difference in the benchmark notes rather than as a warning section, so it is easy to miss, and a subtle ordering bug is the kind of thing that shows up as a rendering artefact rather than a crash.

The fourth is engine version churn. A plugin that replaces engine containers depends on engine internals, and the README's guidance to check branches for older engine versions tells you that the supported set is a moving window. Pinning your engine version and pinning the plugin branch together is the only way to keep a build reproducible, and that is a real ongoing cost that a self-contained library does not have.

For comparison, the alternatives differ in approach. Staying with the engine containers costs nothing and stays compatible, at the price of the Reserve behaviour and the memory overhead the README documents. Using an engine-supported alternative such as TRobinHoodHashMap keeps you inside the engine's own compatibility guarantees and still gives a memory improvement over TMap, at the price of the Remove-and-Add pattern the benchmark had to work around. Writing your own container for your specific key type is the third option, and it is what VoxelCore itself has done, so the argument for using theirs rather than your own is that theirs is already written and benchmarked.

For a team that has already profiled their voxel data structures and found the engine containers in the way, this plugin removes the work. For anyone else, the honest first step is a profile.

## Conclusion

Adopt VoxelCore if your Unreal C++ project keeps large voxel maps or arrays and the container operations show up in your profile, since the plugin replaces the engine types directly and the benchmark output is published with the reasoning behind each difference. Do not adopt it in a blueprint-only project, because the README states plainly that it is intended to be used in C++ and will be of no use otherwise, and do not adopt it if you depend on TMap's ordering guarantees, since TVoxelMap::Remove does a RemoveAtSwap and does not keep order. Before you build, check that a branch exists for your engine version, since Voxel Core usually compiles on the last few Unreal releases and older engine versions live on their own branches, and add the dependency VoxelCore or VoxelCoreEditor to your module. The licence is MIT, the repository publishes no GitHub releases, and the last push was on 2026-08-23.

## FAQ

### What does the VoxelCore plugin provide?

It provides high performance containers to replace the default Unreal Engine ones, such as TVoxelMap, TVoxelSet, TVoxelArray, TVoxelSparseArray, FVoxelBitArray and TVoxelUniqueFunction, plus a few helper macros and tools. It is written for C++ projects, and the README says it is of no use in a blueprint-only project.

### How do I add VoxelCore to an Unreal Engine project?

Download the repository and put it in the Plugins folder of your project, then add the VoxelCore dependency, or VoxelCoreEditor for editor features, to your module. Include VoxelMinimal.h for runtime features and VoxelEditorMinimal.h for editor features, and add those includes to your custom PCH if you have one.

### Does TVoxelMap preserve insertion order like TMap?

Not after a removal. The benchmark notes state that TVoxelMap::Remove does a RemoveAtSwap and does not keep order, while TMap::Remove keeps order as long as no new element is added afterwards.

### Why is TVoxelMap::Reserve so much faster than TMap::Reserve?

The benchmark note gives the reason directly: TMap::Reserve builds a linked list on reserve, while TVoxelMap::Reserve is a memset. The measured figures are 66.8us against 1.16ms for one million elements, which the README reports as 17.4x faster.

### Which Unreal Engine versions does VoxelCore support?

The README says Voxel Core usually compiles on the last few Unreal releases, and to check branches for older engine versions. The repository publishes no GitHub releases, so the branches are how older engine versions are supported.

### How do the VoxelCore assertions behave?

VoxelCore uses its own assertion macros, checkVoxelSlow and similar, which by default follow DO_CHECK. You can disable them manually by defining VOXEL_DEBUG to 0 before including VoxelMinimal.h.

## Sources

- [Issues](https://github.com/VoxelPlugin/VoxelCore/issues)
- [License: MIT](https://github.com/VoxelPlugin/VoxelCore/blob/master/LICENSE)
- [README](https://github.com/VoxelPlugin/VoxelCore/blob/master/README.md)
- [VoxelPlugin/VoxelCore on GitHub](https://github.com/VoxelPlugin/VoxelCore)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/voxelplugin-voxelcore
