Game Development Community

T3D 1.2 meshRoad causing assert during pack function

by Dave Wagner · in Torque 3D Professional · 03/16/2012 (8:34 am) · 13 replies

I tracked the bug down to the fact that the splines for the roads, and for that matter rivers and paths should have the same problem, are stored in the mission. The BitStream has 1500 bytes and is checked after every object is packed to see if it goes over 1024 bytes. If it does it is transmitted. The problem is objects with splines are fairly large. I had it fail with a 16 segment road after two larger roads brought it up to but not over the 1024 byte limit to transmit. This caused it to assert with "Out of range write" in the BitStream writeBits function.

I don't think there is a good long term work around that isn't going to fail in some case. The only solution I see is to store the spline data in a file and pass the file name in the pack function. The only other way I see to fix this problem is to rewrite the network communications to use a packet layer separate from the message layer and that would be a whole lot more work!

Any suggestions?

#1
03/26/2012 (10:57 am)
My other thought was to convert the meshRoad into a .dts or Collada file and save that instead of the spline as sort of a back process. Not as nice because you can't edit it as a spline any more.
#2
04/26/2012 (1:33 pm)
No one is concerned that a mesh road with enough point will crash T3D?
#3
07/05/2013 (10:25 am)
@Dave,

It concerned me for a year now. The mesh road is a really great feature in T3D but still much too many flaws. I know the mesh road has been built to use for creating test objects and later replace it with a dts or collada file; but exporting the mesh road to collada comes without uvw mapping and if you dealing with road of 1km long for example... 'that' becomes simply undoable. The rendering of the shape gets messed up in large levels. It also causing main issues running the build in debug mode; something with the NetConnection, probably what you described some time ago. You can imagine all all kinds of things you can do with a mesh road; and if it's flawless, it would be a powerful design tool. At this point this bug is sometimes making me think of all of all my choices about T3D in the past 2 years. It still remains to be a pain in the )*( as I can't even run a debug build!

#4
07/05/2013 (9:48 pm)
If a meshroad could be exported to Collada with correct texturing /UV mapping, then it could be easily replaced. Keeping the original meshroad (hidden) until the release would give you the option to change it.

I'm even willing to transfer $66 for that solution!
#5
07/06/2013 (8:55 am)
It'd be easier to fix whatever issues exist in MeshRoad because they likely also exist in DecalRoad and River. To do that we'll need a test mission that can reliably replicate the crash/rendering bugs and then get as many eyes on the code as possible.

A while back I tried to create such a mission by creating a blank level with nothing but MeshRoads, one of which had ~70 nodes. Unfortunately my test level didn't have any of the issues you or Dave have shown. I suspect the crash/rendering bugs only happen on very 'dense' missions with lots of other objects.
#6
07/09/2013 (2:40 am)
@Chris; yes indeed, replicating the issue on command is tricky. It can be any random meshroad (often none) that's not rendering correctly. I never encountered any issues of such with the decalroad or river.

This description can be found with the MeshRoad Class:

"MeshRoad is not capable of handling intersections, branches, curbs, or other "
"desirable features in a final 'road' asset and is therefore intended for "
"prototyping and experimentation. \n\n"

The option of having the MeshRoad as an imported mesh would be good enough for me.
#7
07/09/2013 (3:14 am)
Unfortunately, there isn't really any way to replace a MeshRoad once you've designed a level around it. Even if you could export it to a 3D application for manual replacement, who wants to hand-make a 70-segment road mesh? That's the point of having procedural content generators like MeshRoad!

I'd vote for us fixing and enhancing MeshRoad instead of providing better ways to replace it, but I'm not sure whether I'll be able to put much time towards it personally.

One thing I was intending to do in TGE was add a bunch of classes similar to MeshRoad that all had to be children of a regular Path. They would add different effects to the Path - for example, replicating a mesh along its length, or creating a road (I nearly had that one working). The cool thing would be you could add multiple of these to a single Path, so you could have a mesh road, shape replicators for left and right fence posts, another mesh road for a central divider, etc., all following the same path, so if you edited that one path, all those decorations would update.

I think that's a framework worth trying to replicate. For example, if you want a mesh road with a decal road on top of it to represent wear and tear, they should be coupled to a single path object so they stay together. Then if we optimise how Paths work in terms of editing and network transmission, these pathed PCGs should all benefit.
#8
07/09/2013 (7:03 am)
The meshroad can be exported with the editor to Collada perfectly; even the pivot is exactly in place where it should be. Importing back would be just with the same transform. The only thing is material mapping; doing that for 210 faces would be a hell of job. So without UV mapping it's of course also not an option for me. Collision would be better though; there are still several issues with meshroad and its collision. The downside of a mesh however is that friction (for vehicles) can't be used. I also meant it to replace it when publishing the game; at the very last end.

Once a meshroad doesn't display correctly it can be fixed with opening the meshroad editor and move a node of that road (and undo the action). Also does the collision stay in place where it should be (so you see a road going one direction off but still you can drive over the collision mesh) I tried to start with rendering disabled and enable it when the mission is starting... no effect. Another thing (if possible) I will try is to build the road with script when the mission is starting, leaving it out the mission file. When it hasn't been fixed of course.

Sorry, I'm not that good with words; hope it doesn't sound too jibberish
#9
07/09/2013 (8:21 am)
My work around was to increase the buffer size that can be transmitted in the BitStream from its original 1500 bytes. The problem is in the algorithm that that transmits the mission data. It packs the data in the mission to be transmitted to the client into a buffer and when it starts to get close to the limit it sends the message to the client. The spline data for roads and rivers can get quite large and it can overrun the buffer during serialization before the check. The only real fix is to move the spline data out of the mission and into a separate file and transmit those file to the client along with the mission or to add a mechanism to estimate the size an object before serializing it. This would mean change every object that gets serialized which would be a big change and a really long road still might not fit in a single message. Another approach would be to make it so an object data could be serialized and de-serialized over multiple messages which would be more of localized change.
#10
07/09/2013 (8:24 am)
One addition note. I'm running on a local network so I can use jumbo packets. This fix won't work over the internet.
#11
07/09/2013 (8:30 am)
One additional note. I've also added a mesh sidewalk editor were you can define the texture on the top, left, right, and bottom sides. I also add the ability to define the shape of the curb. This comes in really handy. I wish I could share it with the community but it was developed for the government, sorry. Maybe someone else will add this to the engine.
#12
07/09/2013 (9:38 am)
MeshRoad::packUpdate(), which determines how MeshRoads are networked, seems a little off somehow. It attempts to be smart about sending node data by:

1). Checking to see if all of the nodes will fit within the current packet (including a 100 byte 'buffer' for other stuff). If all of the nodes will fit within the current stream, they're sent, otherwise...

2). It sends the nodes via multiple guaranteed & ordered NetEvents (20 nodes per event).

I'm a little concerned because the MeshRoad class makes some assumptions about node data, namely: that each node = 32 bytes and 20 nodes can fit into a single NetEvent. I can see a couple of potential problems arising as a result of these assumptions.

Looking over the code, I'm really not sure why MeshRoad needs to exist as a ghostable object in the first place. It feels like it should be something similar to the old fxShapeReplicator which existed (almost) entirely on the clientside. It'd seem to make more sense just to have the server send a filename to the client which contains a list of all of the MeshRoads and their nodes.
#13
07/10/2013 (5:47 am)
@Dave; I'm developing a single player game so I could increase the bitstream for now, until there's a better solution. Is this the line where you do that (bitstream.h):
ResizeBitStream(U32 minSpace = 1500, U32 initialSize = 0);
or (prefs.cs)
$pref::Net::PacketSize = "1500";
or both?

And sorry for asking more questions, but what is a big number (jumbo packet)?