Exploding Atoms

Aug 27, 2009 at 2:25 AM

I've creates a game using farseer in which many circular atoms are spawned and the user can collide with these to chain them together. Howeverr there seems to be an issue with this I am using WeldJoints everytime one atom collides with another they weld together. When the mass of the object is getting up around 10 it starts to do very strange behaviours like blow up and expand outwards then pulls back into itself sometimes it rotates really quickly then explodes and crashes the program. I have no idea whats going on with it or if there is something I can do to avoid it. Any help is greatly appreciated

Coordinator
Aug 27, 2009 at 2:50 PM

Could you send me a sample of this problem?

Aug 28, 2009 at 9:04 AM
Edited Aug 28, 2009 at 9:08 AM

I've uploaded the release version of the program I'm currently running simply collide with the other circles and they will stick to you. This uses weld joints to stick them together. After many stick together the whole lot of them become very unstable. There is not an endless supply of balls to collide with however they do respawn if they get too far away from you. Simply use the arrow keys to move in any direction. You may only absorb objects smaller or equal to the current mass of your combined components so hit the balls which are similar sizes and close by first. This problem happens in varying degrees approximately 70% of the time it ends in an unplayable situation. It can also happen randomly depending on the combination of atoms. You may need to give it a couple tries depending.

You can download the zipped solution here: http://www.easy-share.com/1907521732/Release.zip

If you cannot figure out whats wrong without the source code I will email you a version of it personally rather than posting it here.

Aug 28, 2009 at 10:03 AM

I had a go and couldnt get the game to crash but they did explode in and out alot once i got over 20 atoms.
Maybe you could try 2 weld joints per link in may be more stable...
Or you could try another form of linking them.

Aug 29, 2009 at 2:54 PM
Edited Aug 29, 2009 at 2:58 PM

I've tried other forms but I never throught to put in a second weld joint per connection. I'll let you know if that helps.

Update:

Interestingly enough the problem happens more often if you put two weld joints per connection

Aug 29, 2009 at 2:59 PM
Edited Aug 30, 2009 at 1:38 AM

make sure that the 2 weld joints are not at the exact same position thou.

offset them so they are 5-10 pixels away from each other.
That should help to ensure that it is a nice stable simulation.

Aug 31, 2009 at 4:32 PM

I have done them offset by as much as 10 in both the x and y and it still does not help the problem only enhances it.

Sep 1, 2009 at 4:53 PM

Once the atoms have welded together, will they ever be disconnected? If that's not the case and you run out of ideas, you could set all collided atom geoms to reference the same body instead of using joints to keep them together.

Sep 7, 2009 at 5:38 AM

Yes I initially attempted it that way, however there were significant problems with putting them in the same body also.

Sep 14, 2009 at 7:18 PM

Anyone else got ideas on how to make this work? Doesn't work with welds or with moving all the geoms into one body. Don't know enough about farseer to know if its possible any other way.

Sep 14, 2009 at 8:50 PM

im trying to understand the problem. im assuming your making a snakes type game? where the objects you get are chained behind you at the end of a chain?

Coordinator
Sep 14, 2009 at 9:12 PM
Edited Sep 14, 2009 at 9:17 PM

I've just had a look at it and it seems to be the classic problem of controlling force.

What I mean by this is that once you get a good amount of atoms welded together, any atom you add to the system will add a small overlap between all the atoms and the physics reaction will push them back. This will create a bouncing effect and that effect will reach a point where it can't be recovered and the simulation atoms will try to escape, but can't because they are hold together by weld joints (and thus you are trying to control an uncontrollable (self-amplifying) force)

Unfortunately this is inherited in this kind of physics engine. A thing you could try is to lower the mass of the atoms to something smaller and increase the amount of iterations on the physics simulator (PhysicsSimulator.Iterations).

Tweak those values until you get something that behaves stable with the amount of atoms you need. (it is a accuracy versus performance trade-off)

Update: Adding more joints to the mix should make the reaction worse. It makes sense that the simulation should become more stable (and it will in a external force-free world) but in this case the reaction should intensify with each added joint.

Also, this is just speculations. It would indeed be easier with the source since I could determine exactly what the problem is - by just observing the reaction I can only make an educated guess :)

Sep 15, 2009 at 1:42 AM

Might I ask what sort of problems there were, putting the geometries onto the same body? Were they just difficulties with updating the center of mass, moment of inertia, and velocities?

Sep 16, 2009 at 8:52 PM
Edited Sep 16, 2009 at 8:58 PM

This is a how I create a random atom in my simulation, it has been modified to come up with a lower Mass.

Also I'm running the simulation at 2000 iterations. The problem seems to have not slowed down at all. Therefore I'm wondering if maybe one of these two parts of my code are causing the problem.

Body ballBody;
Geom ballGeom;
float Mass;

Mass = RandomBetween(1f, 50f);

//The Mass has been divided by 100 in order to give a smaller number than previously used. As an attempt to stabilize the collisions. ballBody = BodyFactory.Instance.CreateCircleBody((Mass * .96f), (Mass * .96f)/100); ballBody.Position = new Vector2(250, 100); ballGeom = GeomFactory.Instance.CreateCircleGeom(phySim, ballBody, (Mass * .96f), 32); ballBody.Position = ObjGen.AddObject(player.Position); ballGeom.RestitutionCoefficient = .8f; ballGeom.OnCollision += OnCollision; ballGeom.Tag = "circle"; ballGeom.CollisionGroup = collisionGroups; collisionGroups++; ballBody.ApplyImpulse(new Vector2(RandomBetween(10,-10),RandomBetween(10,-10))); BallGeoms.Add(ballGeom); phySim.Add(ballBody); phySim.Add(ballGeom); Atoms.Add(new Atom(ballBody, ballGeom, BallTex, Color.Purple, (Mass*2/100), (int)RandomBetween(0, 45), ID)); ID++;

This is the Welding code that is called when a collision is detected

WeldJoint Connector = new WeldJoint(geom1.Body, geom2.Body, contactList[0].Position);
phySim.Add(Connector);

Cowdozer - There were problems detecting collisions in the new bodys I had issues getting collisions to be detected as well as problems with the velocities.

The weld joints work in every regards to other problems I've had using other methods. Except for the occasional game-fatal explosion.

Thanks everyone for your help.

I'm cleaning up the full source code to make availiable if necessary