Sand Simulator / 2D Fun

The Partridge Family were neither partridges nor a family. Discuss.
FirepathAgain
Posts: 30
Joined: March 20th, 2021, 3:01 am

Re: Sand Simulator / 2D Fun

Post by FirepathAgain » January 29th, 2022, 11:15 pm

Man that's rough, I feel for you. I don't know how people deal with divorce and all that complicated life stuff. I had a girlfriend once when I was 18 to 20 (about 1.5 years really). She and it was amazing but ended badly and I've never been in a position to meet anyone else since. I don't know I could ever trust anyone enough to get into a relationship with them anyway. Maybe that's just having had a bad experience with the wrong person who only cared about themselves regardless of what they said. I'm half trying to just steer clear of all that life stuff as I need life to be simple. I don't need stress like that.

I've got an environment, which is like the world, but mainly only for the particle simulation, so not quite the same. I'll consider having that collection on a single world as it makes sense. At the moment I could power up the weapon by changing its projectile to a different concrete class and the existing projectiles stay as they are. But I can definitely see them tied to the weapon as limited. If the weapon is somehow destroyed the existing projectiles would also cease to exist. Good suggestion, thanks! It will go on the TODO list lol. Probably sooner than the rest of it though as I can see its benefits for other things that will be in the world.

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Sand Simulator / 2D Fun

Post by albinopapa » January 30th, 2022, 6:30 pm

Yeah, I was hesitant in the beginning as it didn't feel right, especially since I'd have to pass this World instance into any function that needed to callback into it. I guess I could have also just used the Observer pattern, but I really haven't implemented it for any of my projects yet. There's a lot of programming patterns I haven't really used. I guess I'm too stubborn and like trying to figure things out on my own. Trying being the key word here lol.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

FirepathAgain
Posts: 30
Joined: March 20th, 2021, 3:01 am

Re: Sand Simulator / 2D Fun

Post by FirepathAgain » February 2nd, 2022, 4:51 am

I'm thinking I'll probably give the world to each asset. That way they can plonk new assets on the list as they need to create them.

I also need a media repository so I can reference the canvases instead of loading the file each time I create an asset (mainly projectiles this is a problem with).

I think I would also need a Z depth on each asset, either unique at time of creation based on a default for that type or also with a unique id on each asset when created, for sorting the world asset list for drawing. Don't want Z flicker garbage going on.

There is a static singleton pattern that I have used a bit where if I need access to something I don't need to pass it into the object, it can just access it directly.

Observer sounds (and quickly reads) like event handlers. Hook up a handler, something happens on that thing you're looking at, handler is called.

It also seems much like having a list of assets in world, looping through them and calling their update(dt) each frame.

Just quickly looking at those things as I need to shut down. Storm coming.

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Sand Simulator / 2D Fun

Post by albinopapa » February 3rd, 2022, 5:15 am

If you are assigning a float to a Z value then you'll get flicking if the values are relatively close to each other and fluctuate enough to crisscross.

If everything is done in 2D, you could just use the painters method, draw back to front. Of course, without a way of sorting, you'd have to manually list all objects in the order you want them drawn.

Another way of dealing with this is layers. Give each object an ID and that is the layer index to which it is drawn. So you wouldn't sort the objects by ID, it would just be used to tell which layer to draw. Then, you just composite the layers in order from 0-n. Not sure about other 2D drawing APIs, but Direct2D has a push/pop layer. For drawing direct to the buffer, you draw as normal. To draw on top, you push a layer, draw, then pop the layer. You can use this technique for effects like pushing a transparent layer with a design, fill a rectangle with a specific color then pop the transparent layer.

As for the Observer pattern, yes, I've only ever seen it used for event handling.
auto key_event = kbd.ReadKey();
key_listener.observe( key_event ); // <- tells all observers attached about the key event.

You could have World inherit from Subject, it would have a std::vector<Observer*> that each frame you'd call: world.observe( EventType::Update, dt ); However, something more straight forward for that in particular is just having a World::Update( float dt ). I say this because because all the assets are already known to World and each would have their own Update() function.

I'd only use it to decouple rare events like when a collision happens or a user presses a key associated with some game event. This way you might keep the wnd.kbd and wnd.mouse stuff in the Game class, and you'd only be passing around the events to observers to which those events are relevant.

Hope you're safe, and are stocked up.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

FirepathAgain
Posts: 30
Joined: March 20th, 2021, 3:01 am

Re: Sand Simulator / 2D Fun

Post by FirepathAgain » February 5th, 2022, 1:13 am

Yeh that's what I meant for Z value - just a sort order to draw back to front. But that is kinda being done on a system of layers lol.

I'm already dealing with layers, but only in a simple way. Originally I had intended to make a side-scroller with different layers where the foreground moved faster than the main player stage area, and the background slower. It would do that automatically based on their size + how far you were across the map. I was going to have these main layers (foreground, stage, background) as the base and anything added to that layer gets added with an increment on its depth from that layer. The layers are two triangles being rendered at different Z depths.

Then I started doing particle simulation and dumped that all on the main layer and did away with the layers moving independently. So now I'm currently just painting the particles on one layer and the ship and weapon, projectiles on a layer in front, and in that order.

I started creating the world and it is going OK but I really need to change how I'm doing drawing as at the moment the particle simulation has a bunch of panels with layers for each block and I need those block locations to know where to find the panels I need to get from the view to draw to. Having the panels in each block allows me to multi-thread drawing the particles to them. I kinda would like the ship stuff (assets) to draw to a single screen panel but I can't be bothered working that out at the moment. It needs to slightly be oversize of the screen/view when the zoom level is not a good fit (1x / 2x, 4x etc).

I'm doing Update(dt) in world, moving the particle simulation environment in there too. One glaring problem with the weapons managing the projectiles is that when it is detached from the ship the projectiles stop moving, as the weapon isn't getting updated from the ship update, and the projectiles aren't getting updated from the weapon update. Moving them all to be in the world and world.Update(dt) updating them all individually is much better.

I made world.AddAsset(unique_ptr<asset>) return a pointer to the asset so you could create it in the world but get a pointer to it for accessing it if need be, like if it is the player ship.

Drawing the assets is also simplified by having them all in the world, based on how I was checking to see if they should be drawn, based on if they are in the view and if they are in a block (in the game environment). Having said that hmm I guess having to use the environment to find if and where assets should be drawn (to get the panel from the view) is fairly correct as the world is the world but the environment defines the playable area. So maybe my quick idea of still needing the environment to draw the assets is actually pretty correct for me. Good chat, helped me work that out.

The storm wasn't that big after all. I like to be safe when it comes to lightning and my valuable electrical equipment (pc, tv, fridge) and turn them off and unplug where I can.

FirepathAgain
Posts: 30
Joined: March 20th, 2021, 3:01 am

Re: Sand Simulator / 2D Fun

Post by FirepathAgain » February 5th, 2022, 1:42 am

Alright I did a vid (without world changes) on the weapon-ship separation and the polymorphic asset goodness, which I guess you don't get any of the polymorphism stuff in the video lol but w/evs.

I played with chili's framework a lot, in two different periods in the last few years. This thing I'm doing here is completely built from scratch, following chili's videos. I even started from creating a window from nothing - one of chili's series. So the window wasn't even baked-in stuff from Visual Studio.

Anyway, enjoy.

https://youtu.be/M0owIin4XY0

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Sand Simulator / 2D Fun

Post by albinopapa » February 8th, 2022, 8:41 am

Looks good so far. I'd like to see the projectiles have a lighting effect on the terrain, but that's just me lol.

Not sure what you're using for collision detection, like a quadtree or some other partitioning algorithm/structure, but doing something like that might help with drawing as well. I had made a quadtree a while back and used it to determine if objects were within a specified rectangle. The tree wasn't as optimized as some others have gotten theirs, but it worked out okay. Originally, I tried using heap allocations for each object, that was pretty slow. Then, nodes were heap allocated and a vector of objects in each not was pretty good. The last optimization I had made on it was instead of retrieving a collection of colliding objects, I made it so I could pass in a lambda that would handle "found" objects.

So in the case of drawing, I queried the tree for all items found in the rectangle, and instead of retrieving them, they would be passed to the lambda function. When I was retrieving objects I only got about 10,000 objects 60 fps. After making the change to allow a lambda it doubled to 20,000. Again, this is far lower than some of the other algorithms I've heard of where they get 100K or more. My issue was using objects themselves instead of integer indices or object IDs like you'd have from using ECS.

Nevertheless, just an idea.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

FirepathAgain
Posts: 30
Joined: March 20th, 2021, 3:01 am

Re: Sand Simulator / 2D Fun

Post by FirepathAgain » February 8th, 2022, 9:31 pm

Lighting from the projectiles is one of my next favourite TODOs. I need to clean up how I'm passing in lighting info. ATM it's a hack job with just one light to get it working / test and build the pixel shader.

No collision yet except the particle simulation. Which means the particles also don't interact with the assets (ships, guns, etc). I kinda want them to. I was thinking of having three layers of the particles drawing / interacting with the assets. The front and rear layers don't interact with the assets and the front draw over the assets and rear behind. The middle layer bounces off the assets. This way you'd get some depth and it would look integrated. I was thinking maybe 25% in front, 50% behind, and 25% middle / interacting with assets. That would be nice but the particle simulation is a bit heavy as it is with some quirky behaviour that I haven't worked out whether it is buggy or not.

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Sand Simulator / 2D Fun

Post by albinopapa » February 8th, 2022, 11:06 pm

I was more wondering about the algorithm and structure you use to find collisions. Surely you aren't testing each particle against every other particle, right?
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

FirepathAgain
Posts: 30
Joined: March 20th, 2021, 3:01 am

Re: Sand Simulator / 2D Fun

Post by FirepathAgain » February 11th, 2022, 11:08 pm

No I have fields of particles, say 50x50 particles. Those fields make up blocks in say 8x8 fields or something.

The fields encapsulate the logic and an array that makes up the 50x50. Originally I think this was an array of pointers to particles but I changed that to just be directly particles in the array as there isn't much information in them. They each have a pointer to the material that they are. The material contains the logic on how they interact.

There are also vector lists in the fields of the particles slots that actually have a particle in them. The list is for dynamic particles (still in motion / not yet settled). I use these lists when processing the simulation.

Firstly for every timestep I divvy up the fields amongst multiple threads spread by particle count to even it out. The threads do acceleration (update velocity) for each of the dynamic particles.

For every time step each particle has its travel distance calculated for how many individual particle spaces it will move. This distance is kept summed as decimal values (float vector I think) but movement is only done in whole distance increments. Any collisions and resulting energy transfer and deflection is calculated for each of those steps so particles don't just skip through each other moving more than one space at a time.

The way it checks what the particle could collide with is that the particle has its location inside itself and you can calculate where it will go in the next step, then you can get that particle from the array knowing its index by using its location. If empty, you can move, if not, do a collision (energy transfer and deflection).

So if a particular particle is going to move 4.2 particle distances in this frame timestep due to its velocity then each whole particle distance movement is checked for collision in the new location, do energy transfer with some loss, update velocity, adjust trajectory due to deflection.

This process of movement is further complicated by being multi-threaded. This means I need to make groups of fields I called sectors where I work on moving the particles in the middle sector and knowing it can move to the other sectors. The particle speed has a limit on only being able to move an entire field in one frame timestep. I have to make 4 iterations of sectors of left, right, up, down (4 passes of multi-threading) to ensure that complete potential movement of each particle from each field is covered.

There is still a little jankiness on some field edges depending on which edges (due to which fields are moved first) where particles can pile up on an invisible edge if there are too many at once. Well it isn't so much piling up as it is the ones underneath get moved after the ones on top, but since there are ones underneath them, they can't fall, but the ones underneath can, but they are done afterwards, so they pull away from the ones above.

I'm going from memory here so I might not get it 100% lol. I haven't looked at the particle simulation for a while. It's gotten more complicated and a little buggy and I'd like to change how it works by passing a pointer to pointer through it instead of what it does now when it needs to move a particle, which needs more steps each time it moves. Right now it moves the particle by filling details in one array position and clears the original, then back where you called it from you need to re-get the particle. Passing a pp through should allow me to do the move and update the particle currently being looked at / processed.

Post Reply