Intent
The basic idea was an explosion caught one moment after detonation, that could then be moved around to see how it would look like if it had been somewhere else. It started out as an experiment for myself to make something simple but easily upscaled for dramatic effect, and culminated in making the exploding subject a planet. What stopped it from getting bigger was how I calculated the explosion. The math was really simple, just calculate a vector based on the explosions strength and position compared to the cubes own weight and starting position, and voila you have a movable explosion!
This worked fine with 100 or even 1000 cubes, however reaching 10 000 cubes became a problem, as the simple math was single threaded by being in a for loop.
Enter Data Oriented Programming
We had a short and fractured Data Oriented Programming course due to a scheduling conflict, but it seemed like the solution to the current scale ceiling I had. We had 2 weeks to hand in a small space invader clone done in DOP for this course. I spent around 2 days on it and instead spend the rest of the time days converting the old OOP project to DOP.
I converted as I learned. I began with just spawning and modifying some cubes to se how it worked. After that I started modifying the rotation. With these basics down I now had to create an entity I could actually work with, one that could remember its starting position and weight. With all of these components and systems, the actual running of the explosion was in DOP.
The difference was immense, I could now make planets with radii being a limit of 10 units to 100, jumping from thousands to over 100 000 cubes with about equal if not better performance. There was one bottleneck now. The spawning.
The current spawning system would find a position on the sphere, then spawn a cube on said position. When this system has to spawn close to 200 000 cubes, it takes several seconds.
After putting in some profilers, I discovered that finding the points on the sphere was fast enough, even when there was 200 000 of them. The problem was the spawning.
The system was still a monobehavior script, but it didn’t need to be. Spawning the cubes didn’t have to be done in an order, all they needed were a position and a weight. I separated the spawning from the sphere calculation and instanced all the cubes I would need after figuring out all the points in one big chunk. But how could I assign them all a unique point on the sphere? The DOTS job is a ForEach loop!
int entityInQueryIndex. This is how I can get some structure in an otherwise random ForEach loop. Every instance would get assigned a point on the sphere from their unique query index, so I never had to worry about cubes sharing positions. Now the spawning went from several seconds to around 1.
With this, the conversion was complete. Not a single monobehavior aspect was left and the planets where huge.
Info
Language: C#
Platform: PC
Engine: Unity
Dev time: 1.5 weeks
Self with some assistance from classmates