Tables or Inheritance

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Knaimhe
Prole
Posts: 34
Joined: Mon Jan 23, 2012 7:23 pm

Re: Tables or Inheritance

Post by Knaimhe »

Knaimhe wrote:Hey! I figured it out!
I was wrong.
Very, very, wrong.
That system apparently finds any random shot and destroys it. Not the shot that actually hit.
Big problem when there are multiple shots on screen.

So I changed to this:
It gets a bit rough. I've heavily ramped up the heatMax and firerate of the main weapon, for testing purposes. Shoot about two or three overheats worth and you should get an error message.

I believe you can directly access the code just by renaming the .love to a .zip. It's in a N++ file.
Attachments
Slag.love
11/24/12
(18.09 KiB) Downloaded 121 times
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Tables or Inheritance

Post by ivan »

Hi again. I looked at the code but it was quite a bit of a challenge because everything is packed in a single 1000-line file. Things are made considerably more complicated by the fact that you have a large number of globals that are accessed from everywhere. You may want to consider breaking your code in separate files (one for drawing, another for physics, etc) and cut down on the globals.
Ok, anyways, there are several things that could be wrong:
1. You are destroying shapes/bodies during a collision callback
Note: Using Shape:destroy when there is an active remove callback can lead to a crash. It is possible to work around this issue by only destroying object that are not in active contact with anything.
2. Destroying a body automatically destroys all relevant shapes, fixtures and joints. You are destroying a body then destroying one of its fixtures. Not sure how this is handled by Love2D but I would recommend destroying the fixture first.

Code: Select all

 		hitF:getBody():destroy()
		hitF:destroy()
3. You don't need to search the table if you already know the index:

Code: Select all

		shotT[searchTable(shotT, hitF)] = nil
Could become:

Code: Select all

		shotT[hitF] = nil
Knaimhe
Prole
Posts: 34
Joined: Mon Jan 23, 2012 7:23 pm

Re: Tables or Inheritance

Post by Knaimhe »

*shrug*
I never learned to split code into separate files.
In terms of performance, does it make a big difference?

1. I'm actually destroying those bodies/fixtures in a function separate from the collision callback. And there is no remove callback.

Code: Select all

world:setCallbacks(beginContact, nil, nil, nil)
2. I checked with the changed order just to be safe, but I don't think it makes a difference.

3. That actually makes more sense, but for some reason doesn't really remove the target fixture from the table. It ends up creating an error in the draw().

Code: Select all

for k,v in pairs(shotT) do
	love.graphics.polygon("fill", v:getBody():getWorldPoints(v:getShape():getPoints()))
end
Apparently it still leaves the fixture's reference in the table, but the fixture has been destroyed and therefore can provide no data to draw with.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Tables or Inheritance

Post by Robin »

Knaimhe wrote:*shrug*
I never learned to split code into separate files.
In terms of performance, does it make a big difference?
In terms of maintainability, it makes a big difference.

If the maintainability is poor, other people will have trouble helping you, because they will have trouble understanding what you already have.
If the maintainability is poor, future you will have trouble fixing bugs and adding features, because you will have trouble understanding what you already have.
Help us help you: attach a .love.
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Tables or Inheritance

Post by ivan »

Knaimhe wrote:1. I'm actually destroying those bodies/fixtures in a function separate from the collision callback. And there is no remove callback.
There is a collision callback during the time you are destroying shapes, it doesn't matter if you put the code in an outside function. Earlier versions of Box2D did not allow destroying/creating shapes and bodies at all during any callback, you may want to look into this. Let's hope this limitation has been relegated to "remove" callbacks.

Like Robit said, sloppy code shows that you don't care about it. So yeah, that's a good starting point if you plan on finding those bugs.
Knaimhe
Prole
Posts: 34
Joined: Mon Jan 23, 2012 7:23 pm

Re: Tables or Inheritance

Post by Knaimhe »

Iirc, as far as Love 0.7 was concerned, all that mattered was whether or not the creation/destruction was in an outside function.

How complicated would splitting my code be? I've never done it before, so there's a bit of apprehension.
Would it be as simple as just creating another .lua file and cutting some of the functions into that?
I expect I'd also have to do some importing in the main.
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Tables or Inheritance

Post by ivan »

Just want to point out how callbacks are executed:

Code: Select all

function outside ( )
 -- destroy shape
end

function callback ( )
 -- callback begins
  outside()
  -- callback ends
end
It doesn't matter where the code is located, callbacks aren't "finished" until the callback function has returned.
Knaimhe
Prole
Posts: 34
Joined: Mon Jan 23, 2012 7:23 pm

Re: Tables or Inheritance

Post by Knaimhe »

No, I know how it works, it's just...
I had code that destroyed shapes within the collisions callback. It crashed.
I moved the code to an outside function and called that with the collisions callback. It did not crash.

(For Love 0.7.)
Knaimhe
Prole
Posts: 34
Joined: Mon Jan 23, 2012 7:23 pm

Re: Tables or Inheritance

Post by Knaimhe »

Whoops! Sorry guys.
I figured out that this bug occurs when a shot strikes a corner, thereby creating two collisions.
I solved it by adding a return nil statement at the end of searchTable() and adding another check for nil within hitShot().
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Tables or Inheritance

Post by Robin »

Knaimhe wrote:I solved it by adding a return nil statement at the end of searchTable() and adding another check for nil within hitShot().
Fun fact! If you don't return anything, you automatically return nil, so you technically could have made only the second change and it would still have worked.
Help us help you: attach a .love.
Post Reply

Who is online

Users browsing this forum: No registered users and 6 guests