hi doggy
hi doggy
Because of day job stuff, not too much progress unfortunately. Mostly cleaning up spawning and movement functions.
Last demo is weird since it combines vector curve velocity and standard projectile movement forces. Neither task is aware of the other, allowing for this additive behavior.
Tfw you still have some edge cases to fix in your procedural locomotion system #gamedev
So far, this is the highest score that I've gotten out of all of the playtests. Good stuff.
Here's the super silly curves used for the above video.
Instead of continuing to port over UE's Projectile Movement code, I might actually keep this goofy implementation as an alternative option.
I'm guessing this is not how bullet hells are supposed to work, ha ha.
As a joke, I decided to make bullet movement reliant on a Vector Curve and it's surprisingly easier to make complex movement patterns, especially if you want it to execute in "stages".
Took a while to research the best method haha. It's a "solved problem" but since there's so many different solutions of varying difficulty, picking the most applicable was a bit tough.
Sparse 3D Grid made the most sense to me since it allocates cubes/cells only if there's stuff there.
Previous posts mentioned a sparse 3D grid but I never actually showed it off. Looks kinda similar to Minecraft. π
Essentially, bullets check if their current position corresponds with a cell. If so, then it has "collided". It's much cheaper than traces/sweeps and you hardly notice the difference!
I was able to update the bullet hell collision system to include dynamic objects! Each cell now contains an extra flag that determines if a dynamic object occupies that cell.
Realistically, no one will be able to navigate around 10k-15k active projectiles so keeping under 8.33ms will be super easy.
For now, I only have static world objects implemented but dynamic objects will be tested soon...
If this ever does become a "real gameπΉπ²", I do think that the actual active bullet count would be much lower (maybe limit to ~500). It is pretty to look at though. π
First pass at a spatial collision method.
While I could use a sphere sweep per bullet, the Game Thread starts to rise past 8.33ms rather quickly.
By implementing a sparse 3D grid, the collision accuracy is lowered but the Game Thread hovers around 6ms. Pretty reasonable win!
Okay, but there's still a chance that they are working on DMC6 based on ***random corporate head canon***.
Currently, no collision detection has been incorporated yet, as this has to run in standard For Loop. This would erase the performance gains that I've made so I'm currently studying how to properly implement this.
Recorded a quick unlisted demo of the ParallelFor optimization.
Previously, a For Loop could handle ~1200 bullets before Game Thread exceeds 8.33ms.
With ParallelFor, it takes about ~20k bullets before Game Thread exceeds 8.33ms.
youtu.be/L1s9Jky9I4s
I have work in the morning but I just learned about ParallelFor loops!
Before: ~1200 bullets would start affecting the game thread.
With hasty ParallelFor impl.: ~10k bullets (possibly more) while still maintaining 120fps. Very audible "holy shit" after hitting the compile button.
Rather busy in the past week so just a little progress.
+ Velocity now accounts for bullet's rotation
+ Visuals via writing to NDC on tick. New particles are constantly spawned, with a lifetime equal to delta time. Allows for illusion of "persistent" visuals but may lead to extra spawned particles.
These are very silly yet official macros within Unreal Engine. Thank you for the chuckle.
It's definitely challenging. My understanding is...
Instead of 500 individual bullets, with their own tick functions handling movement/collision/etc., what if we had a single tick that could handle all 500 bullets?
And if bullets can be represented by a struct, then we can avoid using objects...
No object pooling, just pure data (a struct array) π
If this were a learning path, it would be like...
Level 1: Spawn/destroy bullets.
Level 2: Pre-spawn n number of bullets in a pool
Level 3: Individual bullet objects don't exist. They are just pure data being manipulated by a single system.
Of course, I still have a long way to go.
I'm still studying the Projectile Movement Component and trying to figure out what parts I can steal from it. I'd really like for "bouncing" bullets to coexist in the same subsystem so lots of collision studying to do...
For this "Projectile Hell" system, one of the ideas I had was replicating Niagara's stack system for constructing projectiles in a modular fashion.
Here, I've created spawn tasks to set a lifespan and update tasks that run on tick that increment the projectile's age and handle its velocity.
I've been quietly tinkering at bullet hell system in UE5 for the past two weeks.
No actor spawning here! Completely data-driven, with a subsystem iterating over an array of variables in a single tick. Demo showcases 64 bullets, with minor dips once ~1280 bullets are active at once. π
Yes, this is definitely Jeremiah, a frog villager from the Animal Crossing series.
For me, the main concern is knowing when to tap the gas or tap the brake. Because damn, it's so incredibly tempting to smash that gas pedal.
If I'm feeling this only after having used it for 2ish weeks, oh my god, what about the people who have been using it for a year+ without restraint?
However, without it, I would not have been able to have made as much progress with UE5's RDG or my current WIP bullet hell system.
I created the prompt for how I generally wanted the framework for these systems to work, and it's providing me with code that I certainly wouldn't have known about it.
It feels like a very dangerous rabbit hole. I've been incredibly hesitant to use LLM tools for a while, and now, I think one of my fears has been confirmed.
It is so incredibly tempting to callously dump a problem in full into this magical black box, skipping parts of the brainstorming process.
After having only started using ChatGPT for the first time in the past month, I can see why people are clamoring about it being the futureβ’οΈ. I'm currently experimenting with a bullet hell system, and it's incredibly surprising how it can easily interpret my prompts and spit out usable code.
Based off of a recommendation in a server that I'm in, this was my first time using GPT5 and it's rather competent at providing a minimal module. Of course, hallucinations can occur but it's not too hard to nudge it into the right direction.
It's a bit scary how much it knows about UE5 source.
γRDG Paintingγ
And now, I'm back to Tricolor painting. It's been tricky but this is my current method...
Pass 1. Take an array of splat parameters, draw a "splat" for each element, add the current Paint Map, then draw to a 16-bit Render Target.
Pass 2. Copy contents of 16-bit RT to Paint Map.