mspraggs / potentia

Southampton Game Jam 2015
0 stars 0 forks source link

Fire. More complicated than we thought... #102

Closed DivFord closed 8 years ago

DivFord commented 8 years ago

So… currently fires don't burn things, and look like particularly animate tulips. We should probably do something about that.

I'm going to stay out of the mechanical side of things, but my take on the graphics is that a particle system should be used.

By way of example, here is a screenshot from my pet project. It's 3D, and using an additive shader, but hopefully you get the point.

screenshot_035

Fyll commented 8 years ago

"Looks like particularly animated tulip" D:

Feel free to try to write something. The problem is that I suck at graphics. As for fire not burning things, that's a bit more awkward. I'll look into it at some point, but bullets come first.

DivFord commented 8 years ago

I see you commented the particle system nicely, so I should be able to work something out.

DivFord commented 8 years ago

Right, I've added looping as an option the particle system, so step one is complete. I think I may need to optimize it though…

loopparticles

DivFord commented 8 years ago

I need Fire to have access to its particle system, so that it can turn looping off to douse it. I'm doing that by having Room::genParticles return the shared pointer to the new particle effect, but it seems hacky. Is there a way I'm supposed to do this?

Fyll commented 8 years ago

There's a Room::getLastObj() function (you may need to pull) that would give you the ParticleSystem.

DivFord commented 8 years ago

Ah. That sounds better. Now I just need to handle the merge conflict :(

Fyll commented 8 years ago

I don't think it'd be that bad. I didn't touch Fire or the Firey bits of Object (I don't think).

DivFord commented 8 years ago

Yeah, but this is basically my approach to using git: http://xkcd.com/1597/

Hmm… Somehow, I screwed this up. Either that, or your changes don't actually work...

Fyll commented 8 years ago

In what way don't they work? Do frozen crates still move?

EDIT: Nevermind, yeah, they don't seem to work. I'll get back on it then. :(

DivFord commented 8 years ago

Yes. I made a horrible mess of the merge though, so it could be that. Object::affectMobility is certainly present. Where is is meant to be called from?

Fyll commented 8 years ago

It's called in kill() and changeInto(). It gives either minus, or plus one to everything you're touching's staticness, respectively.

DivFord commented 8 years ago

I have all that… Does this work properly for you?

Fyll commented 8 years ago

Nah. Something's going wrong. I'll look into it.

EDIT: I've figured it out. It's because after the first bit of ice, the rest get added to the first one's BlockGroup, so don't get found by Room::getLastObj(), hence they don't affect the staticness of things.

EDITx2: Okay. Fixed and pushed (I hope). Bullet's flicker a little every now and then, but that's a problem for the bullet update.

mspraggs commented 8 years ago

@DivFord You could use a merge tool. Try git mergetool when you get a merge conflict.

DivFord commented 8 years ago

Thanks. I'll try that next time.

DivFord commented 8 years ago

Ok, I have the basics in. It doesn't quite look right, the particles aren't animated, and the particle system doesn't follow the prop or disappear with it, but the beginning is there.

Incidentally, my brother and I both looked at the early version (from the screenshot above) and thought it looked like it was vibrating. Is a sonic gun something we should do?

Fyll commented 8 years ago

Hmm. Are you sure using ParticleEffect is a good idea? I'd rather you didn't put too many odd things into it, just to accommodate fire, as, while it's similar, it has a lot of small differences (remember, they used to be the same system).

Anyway, as to fire not following/travelling with the prop, you could probably put a ParticleEffect object into Fire (as opposed to adding it to the room). Then, the Fire class could move, update, and draw it.

Also, as a quick mention, you've apparently changed all of the files to be executable.

With regards to a sonic gun, the question is, what would it do?

DivFord commented 8 years ago

Which files? They all look like cpp or hpp to me.

Surely one particle system that does everything we want it to do is better than two systems with very similar functionality? I'd be perfectly happy to roll fire back into particle system. I assumed they were separate to support the mechanics.

That was my sticking point as well. I thought it might shatter glass or crystal, but I imagine a cannon can do that anyway...

Fyll commented 8 years ago

I mean that you'd marked the executable bit, so whenever I tried to open them, it kept asking me if I wanted to run it instead. It's not a hard fix (just run one command in the shell), so it's not really a problem.

But how much code does it reuse, and how much is unused? It'd also make it easier to make the fire do particular things.

I imagine it'd be a pain to animate as well. Bear in mind, that we'd need to be able to think of at least 2 things for it to do. Googling for sonic weapons in popular culture doesn't seem to suggest anything useful (although it does talk about using one to vibrate eyeballs >.<).

DivFord commented 8 years ago

Currently all I've added is a fire pattern function and support for looping particle effects (which is about a dozen lines of code). Animated particles would require more, if that's your objection.

Essentially, it's the normal particle code, but if looping is set to true, when a particle reaches the end of its lifespan, it spawns a new one using the original pattern function. That meant adding a loop variable and a function to access it, and storing the pattern used in the constructor. Other than that it's all the same code.

(I have no idea how that happened. Maybe the merge tool set them to executables?)

mspraggs commented 8 years ago

At the risk of over-complicating the code base, couldn't ParticleSystem be sub-classed to give it the extra properties that the fire needs, without duplicating the code too much?

Also, my girlfriend thinks the fire looks good :-)

DivFord commented 8 years ago

Please thank her for me :)

I see no problem with subclassing fire, though this is more Iain's area. Currently, particle effect inherits from object, but fire doesn't. Was there a particular reason for that?

Fyll commented 8 years ago

The reason for not having Fire be an Object (and by extension, a sub-class of ParticleEffect) were three-fold:

Fair enough about not changing the Particle system too much. I was mainly thinking back to when they used to be together, because that was a complete mess (then again, it did do animations...).

DivFord commented 8 years ago

That makes sense.

If we carry on down the route we're on, fire is essentially just going to link a burning object to a particle system. Your suggestion about putting the particle system in fire, rather than in room, would work, except that I don't think I can access all the dimensions of the owner object. I may be wrong about that. In any case, if that's all it does, the fire variable in object could maybe simply be a particle system, with no need for a separate fire class.

I think what it comes down to is how you want to approach fire mechanically. Does the fire itself need to collide and deal damage, or is it just that burning objects deal contact damage?

Fyll commented 8 years ago

Well, ParticleEffects can't actually collide with anything at the moment anyway (far too many hitboxes to worry about), and I really don't want to try implementing that due how much it'd slow everything down.

As to fire spreading, this should now be a thing.

I'm not sure I understand what you're saying. Is the ParticleEffect in Object? I thought it was in Room.

DivFord commented 8 years ago

At the moment, object has a fire variable storing an instance of the Fire class. When the object gets set on fire, it tells its fire to ignite, and the fire tells the object to add a particle system to room.

This seems needlessly complicated. Either we do what you said, and the fire has a particle system that it manages itself, or we cut out fire altogether, and just have object add a particle system to the room when it gets ignited.

It looks like you haven't used the fire class for the fire spreading and dealing damage. Is that correct?

Fyll commented 8 years ago

If the Fire will just be using ParticleEffect, then yeah, you could just remove the Fire class, as that was only there to manage the fire.

I'd think a pointer to a ParticleEffect in Object would be better, as then the fire would follow the Object. Adding it to Room means the Object would leave the fire behind, which is obviously a bad thing.

Yeah, I just made it so that when you get ignited, you gain the effect that triggers burning, then when you're doused, you lose it.

DivFord commented 8 years ago

I've been trying to sort this out. I've removed the _fire variable from Object, and commented out all references to it, with the aim of replacing it with a particle system, as discussed above.

The code compiles fine, but when I try to run it I get a bad access exception on launch, apparently related to block groups. Here is the relevant part of the crash report:

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 game 0x000000010ac7e474 Vector::operator=(Vector const&) + 20 (Vector.hpp:39) 1 game 0x000000010ad85dcb BlockGroup::rebuildHitbox() + 5499 (utility:293) 2 game 0x000000010ad6992f BlockGroup::addBlock(std::1::shared_ptr) + 495 (BlockGroup.hpp:32) 3 game 0x000000010ad5b893 Room::addBlock(std::__1::shared_ptr) + 6963 (Room.cpp:102) 4 game 0x000000010ad881b7 BlockGroup::rebuildHitbox() + 14695 (BlockGroup.hpp:279) 5 game 0x000000010ad6992f BlockGroup::addBlock(std::1::shared_ptr) + 495 (BlockGroup.hpp:32) 6 game 0x000000010ad5b893 Room::addBlock(std::1::shared_ptr) + 6963 (Room.cpp:102) 7 game 0x000000010ad881b7 BlockGroup::rebuildHitbox() + 14695 (BlockGroup.hpp:279) 8 game 0x000000010ad6992f BlockGroup::addBlock(std::__1::shared_ptr) + 495 (BlockGroup.hpp:32) 9 game 0x000000010ad5b893 Room::addBlock(std::1::shared_ptr) + 6963 (Room.cpp:102) 10 game 0x000000010ad881b7 BlockGroup::rebuildHitbox() + 14695 (BlockGroup.hpp:279) 11 game 0x000000010ad6992f BlockGroup::addBlock(std::1::shared_ptr) + 495 (BlockGroup.hpp:32) 12 game 0x000000010ad5b893 Room::addBlock(std::__1::shared_ptr) + 6963 (Room.cpp:102) 13 game 0x000000010ad881b7 BlockGroup::rebuildHitbox() + 14695 (BlockGroup.hpp:279) 14 game 0x000000010ad6992f BlockGroup::addBlock(std::1::shared_ptr) + 495 (BlockGroup.hpp:32) 15 game 0x000000010ad5b893 Room::addBlock(std::1::shared_ptr) + 6963 (Room.cpp:102) 16 game 0x000000010ad881b7 BlockGroup::rebuildHitbox() + 14695 (BlockGroup.hpp:279) 17 game 0x000000010ad69d87 BlockGroup::addBlockGroup(std::__1::shared_ptr) + 1015 (BlockGroup.hpp:41) 18 game 0x000000010ad5afbc Room::addBlock(std::1::shared_ptr) + 4700 (Room.cpp:97) 19 game 0x000000010ad881b7 BlockGroup::rebuildHitbox() + 14695 (BlockGroup.hpp:279) 20 game 0x000000010ad6992f BlockGroup::addBlock(std::1::shared_ptr) + 495 (BlockGroup.hpp:32) 21 game 0x000000010ad5b893 Room::addBlock(std::__1::shared_ptr) + 6963 (Room.cpp:102) 22 game 0x000000010ad881b7 BlockGroup::rebuildHitbox() + 14695 (BlockGroup.hpp:279) 23 game 0x000000010ad6992f BlockGroup::addBlock(std::1::shared_ptr) + 495 (BlockGroup.hpp:32) 24 game 0x000000010ad5b893 Room::addBlock(std::1::shared_ptr) + 6963 (Room.cpp:102) 25 game 0x000000010ad881b7 BlockGroup::rebuildHitbox() + 14695 (BlockGroup.hpp:279) 26 game 0x000000010ad69d87 BlockGroup::addBlockGroup(std::__1::shared_ptr) + 1015 (BlockGroup.hpp:41) 27 game 0x000000010ad5afbc Room::addBlock(std::1::shared_ptr) + 4700 (Room.cpp:97) 28 game 0x000000010ad881b7 BlockGroup::rebuildHitbox() + 14695 (BlockGroup.hpp:279) 29 game 0x000000010ad6992f BlockGroup::addBlock(std::__1::shared_ptr) + 495 (BlockGroup.hpp:32) 30 game 0x000000010ad5b893 Room::addBlock(std::__1::shared_ptr) + 6963 (Room.cpp:102) 31 game 0x000000010ad881b7 BlockGroup::rebuildHitbox() + 14695 (BlockGroup.hpp:279) 32 game 0x000000010ad6eecf BlockGroup::removeAllDead() + 2799 (BlockGroup.hpp:59) 33 game 0x000000010ad5d0bc Room::erase(int, bool) + 1596 (Room.cpp:268) 34 game 0x000000010ad5981d Room::checkDead() + 477 (Room.cpp:237) 35 game 0x000000010ad584bc Room::update(Vector const&) + 2476 (Room.cpp:41) 36 game 0x000000010adb77a0 World::update(Vector const&) + 64 (World.cpp:296) 37 game 0x000000010acd1112 Game::update() + 194 (Game.cpp:161) 38 game 0x000000010acd0d77 Game::run() + 1015 (Game.cpp:50) 39 game 0x000000010ad0ac0e main + 2926 (main.cpp:74) 40 game 0x000000010ac776f4 start + 52

Any ideas what's going on here?

Fyll commented 8 years ago

Was this just a one off, or is it every time?

The code recurses there, which is what's causing the crash. It recurses when the process of adding or removing a Block from the BlockGroup causes one of the Blocks in the BlockGroup to be completely separated from the others, so I'm not sure how changing fire will have effected it.

Are you sure you've only commented out fire stuff? EDIT: Did you maybe somehow comment out the hitbox? That'd cause that error I think.

DivFord commented 8 years ago

It's every time.

All I've changed is:

Fyll commented 8 years ago

Try putting the initialisation of dead, layer, and name_ back in. Deleting them causes no problems for me, but it would be down to compiler initialisation, so is completely up in the air.

DivFord commented 8 years ago

Oops. I thought those where part of the constructor for fire. I'll give it a shot.

EDIT: It worked! Good call. However, I now get a bug where it places the invisible solid blocks in front of the exit instead of behind it. That is, I can walk backwards out the level, but I can't walk into the level. This happens about 50% of the time. I will investigate further tomorrow.

Fyll commented 8 years ago

Try drawing the hitboxes (-dh), and widening the screen (in Screen::update(), remove the ternary operations (i.e. change a ? b : c to b)). These should help you see the problem.

It doesn't happen for me, and I don't think fiddling with fire should affect this at all.... Are you sure you haven't removed any other bits of code? And that you initialised dead_, layer_, and name_ correctly?

DivFord commented 8 years ago

Here is the entrance working correctly: entrance_correct

Here it is messing up: entrance_bugged

Here is the correct exit: exit_correct

And here it is bugged: exit_bugged

I'm pretty sure this is the entrance/exit block messing up, but those shouldn't be able to move or rotate, should they? Are they blocks, props, or something else?

Originally I thought it was something to do with the lizard, but I think it's actually that the exit blocker is missing so the lizard walks out of the level.

Fyll commented 8 years ago

That's definitely wierd. You're correct that they're Blocks, but I don't see why they're moving, when Blocks and BlockGroups can't move, so....

I'll poke around and see what could be causing it. The giant yellow line in the last image implies that something has moved really fast off of the screen immediately before you took the screenshot. Given the position (roughly in the middle of the level), I'd think it was the edge BlockGroup (as the yellow line is measured from the middle of the Object).

EDIT: An idea - In canCollide() (a local function in Room.cpp, just above Room::collisionCheck()) , try changing the != 0's to > SMALL_FLOAT's. The randomness of the occurrences and the fact that it's not happening to me implies it's either a memory issue, a rounding error, an uninitialisation error, or something else along those lines.

DivFord commented 8 years ago

That doesn't seem to help… small_float

The diagonal collider (presumed to be the edge block group) definitely moves. I just about see it, but it moves fast enough that sometimes I end to the left of it, sometimes to the right.

I wasn't getting this bug before changing the fire stuff, and I'm certain I didn't change anything except what I mentioned above. I really don't see how one could cause the other though...

Fyll commented 8 years ago

Hmm....

There's honestly only so much I can suggest without seeing the code. One last suggestion (before I get back to work on the assignment due in tomorrow :P): Make the edge Blocks visible (give them the same tileset as the water or something), then slow the framerate down (with the -fps flag) and just try to see exactly what's happening. Possibly also make the Window larger (with the -g flag), so that the edge tiles are visible from the get go.

DivFord commented 8 years ago

My plan was more exciting. I replaced the block below the entrance with water, so that I could freeze myself in it and thus trigger the antigravity bug (I think the affectMobility code may be bugged, by the way)… I then used the recoil on the cannon to fly around the outside of the map. I can confirm that the UFO is indeed the edge block. It looks like an upside down U-shape which fits the dimensions of the level.

Also, freezing the water pushed the edge block-group out the way, so it is reactive to collisions, if nothing else.

Anyway, I'll try to stop distracting you now...

Fyll commented 8 years ago

Yeah, affectMobility() is borked. It's the reason there're crates gluing themselves in place. It's on my to-do list, but unsurprisingly, isn't my highest priority at the moment.

If it's reacting to collisions, it's returning positively from canCollide(). Maybe try just printing out the various quantities, to see which bit of it's causing the problem.

DivFord commented 8 years ago

Hang on, your "SMALL_FLOAT" idea fixed it, I just misread it previously. My screenshot of awfulness was "!= SMALL_FLOAT", whereas of course it was meant to be "> SMALL_FLOAT". Crisis averted. You may now focus on that assignment.

Fyll commented 8 years ago

What assignment? :P

Anyway, good to hear. I was surprised that that made everything mess up so badly, but that does explain it.

DivFord commented 8 years ago

It's stable again now, so I've committed, but I won't push until I actually get fires working properly. Probably later this week.

DivFord commented 8 years ago

"I'd think a pointer to a ParticleEffect in Object would be better, as then the fire would follow the Object. " Iain, in the past.

I'm trying to set this up, but I can't work out how I'm actually supposed to move the particle effect around. I assume I'm meant to do something with Skeleton, but I can't see any way to change position without using forces. Is there a way to do this?

Fyll commented 8 years ago

Skeleton::start(Vector); moves the hitbox by the given Vector (also supplying a momentum/velocity to it, but it does actually move it to). Skeleton::stop(); then removes its velocity. That's how the Objects are initially moved to the position given in the constructor.

Looking at it now, start may not be the best name for that function, but I like it for the symmetry. :P

DivFord commented 8 years ago

…and the last piece of the puzzle slots into place. We now have fire graphics! I have pushed, and will close this issue.

Fyll commented 8 years ago

Actually, do you mind if I remove the Fire class? It looks quite empty at the moment, so it's probably safe to just put the ParticleEffect pointer straight into Object (and that way, the ParticleEffect doesn't have to sit in Room's Object vector, marginally slowing down the physics :P).

EDIT: Nevermind, just read the code again. I hadn't noticed that Fire is a child of ParticleEffect. Is it safe to cut out addLoopingParticles() now?

DivFord commented 8 years ago

Ah. Just saw the edit. The original post confused me.

Add looping particles can go. I left it in case we wanted looping particles for something else later, but to be honest, if we do, it's probably better to add "looping" in to particle data and just have one particle creation function.

Fyll commented 8 years ago

Lovely.

Do you think it'd be possible to move the looping stuff from ParticleEffect into Fire? I just want something else in Fire. It feels too empty! >.<

Also, what's deadParticles_ for? Is it for if you ignite, douse, then ignite again very quickly?

EDIT: Okay, I figured it out. I've also moved the looping stuff into Fire (sorry).

DivFord commented 8 years ago

Really? What if I want to use it for waterfalls, or spice geysers, or smoke?

If you want to put more stuff in, it might be possible to move the fire pattern into Fire. I'm not sure how simple that would be.

Fyll commented 8 years ago

Oops! I hadn't thought of those (although I'd be against waterfalls. Drawing attention to our dodgy Water doesn't seem like a good thing).

If we're going to do that, then fair enough. Alternatively, could that be a type of Fire?