Game Development Community

Ideas for moving a large number of objects simultaneously

by Jack Stone · in Game Design and Creative Issues · 10/22/2014 (7:24 am) · 11 replies

Hello,

I am currently working on a sandbox type game where players have the ability to create objects and combine them to make simple machines and moving vehicles.

I am doing this by adding all objects which are connected together to a group, and applying a movement vector to that group. In the objects process tick, I am then moving each object along that vector. This works perfectly for small groups of objects, but once I add more objects, I get a very noticeable "jitter" effect, where I can see each object in the structure moving out of sync with the others as it the objects are updated one at a time.

I am running a debug build and of course a release build would be faster, but even so think this may be a fatal flaw with my concept, particularly since I would like to add multiplayer support in future.

Does anyone know of a concept that would allow me to rapidly update the position of a large number of objects over a network in this way?

Thanks!

#1
10/22/2014 (10:25 am)
One idea of mine I've been wanting to try out, in Torque to solve moving platforms and players jittering and thrown off of them problem, is anchored objects.

The idea is to make one object be an anchor or local origin coordinate center for objects that are anchored to it. Pretty much similar to how Torque handles mounted objects, except with anchors the anchored objects are able to freely move around as an offset to the anchor object instead being in a fixed offset position.

As to how to apply it to your situation, since you're constructing a vehicle made up of objects, I would suggest that you create an anchor object class that doesn't render but does exist in the world that all other objects can reference as point of origin. So the objects that makeup the vehicle would be created after anchor object and reference the anchor object on creation and their positions will only be offsets to that anchor object. Then on move updates you only move and/or rotate the anchor object and on the clients all the objects will only update their position relative to anchor object.

So in theory once all that is said and done, provided that none of the anchored objects need to animate, all you would ever have to network update is the anchor object regularly and the entire vehicle, made up of multiple objects, would move around perfectly. Just make sure in your physics update procedure that anchor objects get update priority/first before any of their anchored objects (could be said their child objects).

That's one idea anyway. :)
#2
10/24/2014 (7:18 am)
That's a great idea, that would certainly solve the network issues.

The transforms of all of those objects would still need to be updated though, is there a fast way of doing this?
#3
10/26/2014 (11:12 am)
I know that Vince Gee ran into this issue when he was programming OneWorld. You may want to see if u can contact him.
#4
10/29/2014 (7:10 pm)
Ah, thanks Paul, that's helpful. OneWorld does look quite similiar to the type of thing I am trying to do.
#5
10/29/2014 (11:05 pm)
Quote:The transforms of all of those objects would still need to be updated though, is there a fast way of doing this?
What do you mean a 'fast' way? If they all just update their transforms when they process a tick or whatever, what's the problem?
#6
11/02/2014 (2:24 pm)
The problem is that with a large number of objects being updated in processtick, I get a jitter effect, ie, the objects "shake" noticeably as the positions of all of the objects are updated.

I could try to fix this by moving the objects at a slower rate of speed, but that would really only mask the issue.
#7
11/03/2014 (3:37 pm)
There are a couple things that might be causing the "jitter" effect you see:

1). No render interpolation. If you're updating the mounted object's transform directly in processTick() but not properly interpolating positions in interpolateTick(), then you'll see the mounted objects 'warp' from position to position every ~32ms. To fix this you'll need to update the position in processTick, and then update the render transform in interpolateTick. Lots of examples of how to do this in the engine.

2). Packet overflow. If your mounted objects are "net heavy" (meaning, they each send several bytes worth of data), it's possible that update data for all of your mounted objects are being split across several network packets.

Let's say you have 100 mounted objects, each which require 8 bytes of data to properly update across the network. That's 800 bytes of data to update all of your mounted objects. If your $pref::Net::packetSize is, say, 400 bytes, then you're looking at a minimum of 2 packets required to update all of your mounted objects (likely more because other things, like score, client movement, etc. will be sent across as well).

The result is every (1000 / $pref::Net::packetRateToClient) milliseconds, the game will process a packet and cause a noticeable, staggered 'warp' effect in mounted objects.

The fix for this is some combination of increasing the packet size ($pref::Net::packetSize), increasing the packet-to-client send rate ($pref::Net::packetRateToClient), and reducing the 'byte footprint' of your objects.
#8
11/03/2014 (4:02 pm)
Or modifying them so that, as Nathan suggested, they know who their parent is, and can calculate the correct transform on the client, rather than having to have it cent across the network constantly.
#9
11/04/2014 (3:08 am)
I had this problem with prefabs in oneworld. When you would move a prefab all the components would move seperately.

When your moving an individual item, turn off ghosting of that object to the client moving it.

I wrote a locking system, so that when a player started to move something, it would lock the object so that the server new not to send the updates to that client. When they let go of the mouse it released the lock and did any final snapping.

In regards to moving a collection of objects, the only option I really see is to set a transform for the group, and then all object's positions are offsets off the group location.

So for example, add a point3f to simgroup type of collection for simgroup location and then when they combine the objects you put them in the simgroup and change there location to a relative location. That way when they move the collection your just ghosting a single transform versus each objects transform.

The only thing that you would need to do is to make sure the collection object which you create is ghosted before the objects inside it. That can be tricky, I used a simevent which kept rechecking for the container every so many seconds.

Vince

Winterleaf Entertainment L.L.C.
#10
11/04/2014 (3:46 am)
I think there examples in ShapeBase of dealing with dependencies and ghosting. I think mounting, for example, has some logic to wait for the mount to ghost.
#11
11/05/2014 (12:45 pm)
Those are excellent suggestions, thanks!

@Chris Haigler, I think you got it right with the "No Render Interpolation" suggestion. I am doing all of my work in processtick, and not using interpolate tick at all. I am confident that there are optimisations to be made here.

@Vince Gee, I hadn't considered using ghosting like that, I'll definitely look into that as well.

Thanks again!