(Solved) Probable cause for parts either staying rendered or not rendering at all?

We know that this happens sometimes but so far I’ve never seen a repro. I had @VolcanoINC show me this bug in his game once, but I could never replicate it in his game on my computer IIRC…

If there’s a way to see this happen with reasonable chance on an online or offline level we can investigate it. It’s really hard to find this otherwise.

P.S. It does not matter too much if the level has other parts - like, if you have a level with cars and I can get the car to disappear from the physics world but keep rendering even if there are thousands other parts in the level - that’s good enough as long as the repro is consistent (e.g. can get it by playing a few minutes).

This can be solved by using the Scriptable camera type instead of Custom

Go to Phantom Forces with a friend, hope you’re on the same team, and then meet up somewhere in the map. Get your friend to spam switch their weapons (switch to secondary, primary, secondary, primary, etc) and you’ll see it happen pretty quickly – the times I’ve tested it it happens no later than ~10 seconds (complete guess but by quickly I don’t mean in a couple of minutes) every time. Not sure if it happens in a server with 2 or 3 people because every time I’ve tested it in a full server.

Edit: here are my hardware specs if they’re relevant http://pastebin.com/ncXDgsbM
Edit2: Resource usage screenshot:

Shouldn’t be too hard to reproduce in my kart game at all online. On an active server this happens very frequently, just don’t reset and drive around looking for characters/karts that have no collisions/sound emitting.

Haven’t actually started scripting the camera yet, I’ll work on getting a basic scriptable camera out and see if that solves the problem.

Ok, so in your case (and I bet Phantom Forces is the same) the problem is relatively straightforward.

Parts are grouped for rendering purposes into clusters, and a cluster has to be invalidated if parts inside it change other than CFrames being updated. I know that Phantom Forces does that all the time for the humanoids by animating the welds (which is bad for performance and I still don’t really understand why it does not use Motor6Ds but that’s a separate conversation); I’m not sure yet why your game has the same behavior - will look into it tomorrow.

Anyway, so what happens is that these clusters are put in a queue whenever they have to be updated, and we only process a few clusters from that queue to try to keep the game realtime. Unfortunately, this queue does not have a well defined ordering so if some clusters are constantly invalidated they can get “in front” of other clusters every time something changes so we end up constantly updating some clusters and never updating other. Which is why you’re seeing what you’re seeing.

It should not be hard to maintain a proper update order. I’ll look into doing this (not sure about next week, probably the week after that).

7 Likes

Sounds great, at least I know what the issue is now! Please do let me know when you look into this so that I know when I can get back to work. In the meantime I’ll work on some other projects. :happy1:

We do use Motor6Ds.

1 Like

Hmm. Right, sorry. I think there’s something else that you guys do that is not ideal for rendering perf… I’ll need to look into this again. I looked very briefly before the winter break but then forgot all the details.

1 Like

So I believe the root cause in your case is - similar to PF - the manual “animation” of Motor6Ds by changing C0/C1.

Motor6D has another CFrame “in between” C0/C1 that’s designed for being free to change (this is what the built-in animation system is driving); changing C0/C1 requires rebuilding some rendering data currently.

I have a tentative fix to make C0/C1 of Motor6D animatable (ideally we’d expose the third cframe in Lua API instead of just one angle but that’s a bigger change and would require changing the scripts). I think I want to make that fix first and not do anything about the queueing mechanism for now - the fix can ship next week (of course it can also break something I’m not thinking of right now…)

P.S. In your case I also sometimes see joints being removed/readded but it could just be people dying/resetting; I hope you aren’t destroying joints every frame on render stepped!

7 Likes

Definitely not re-making joints every frame haha, that’d be insane. It’s likely just players resetting, as all the joints have to be reinitialized on spawn for the new kart.

We are constantly setting the C0s of the Motor6Ds, though, and are not actually using the angle stuff. I don’t know if this is as bad as constantly setting the C0 of Welds. But I mean, how else am I going to do all the foot planting and gun holding and what not?

(Sorry this is late, my Internet connection has been down for hours.)

No no no! I think there was some weird or unwanted behavior happening when we used the joints the player spawned with, or maybe they replicate or something, I don’t remember. But when a new character is loaded, on each client, we remove the joints on the client and replace them with our own joints. Remember on PF, none of your body animations are processed on your own client, Every other client processes your body’s animations.

https://i.gyazo.com/d7dbacf1ead12317ca630bafa0414e70.gif

https://i.gyazo.com/2621a18a5d0081e54209796c91790197.gif

Yeah, Motors are much better than welds. If you change C0/1 on welds we have a reason to regenerate render data. If you change C0/1 on motors we also do that but at least that’s accidental and we can fix that :slight_smile:

You do not have a better way right now. I’m just saying it would be good to have Motor6D fully exposed to Lua - the design intention is that C0/C1 define the points on the respective parts that are joined together, and the other cframe controls the relative position - so ideally you specify C0/C1 once and then animate the cframe. Which is what our animation system is doing, you just can’t do the same thing in Lua right now.

6 Likes

I do the exact same thing in my game, except with boats.

Yes! Please yes! Please expose this API. I’d actually be willing to pay money for this feature. This saves me from:

  1. Replicating default C0/C1 values over to animating clients (an extra network request / handshake)
  2. Having part clusters recalculated (as noted before).

Right now I’m using ManualWelds for my animations.

We had this discussion before, and although I found the issue (JointService wasn’t GCing removed joints, for some reason, leading to errors somehow, resulting in boats going to -inf), I’m still experiencing performance issues with animating welds.

1 Like

Not sure if this has been mentioned before but - I use anchored parts for animation and do the math for C1/C0 in welds with a module. It lets me do some crazy stuff (90 humanoids with one hat and one union weapon) without slowdown.

1 Like

I’ve done this before. In my situation, this doesn’t work because I’m relying on ROBLOX’s physics (remember: boat simulation). The other issue with this is you have to maintain a render-frame update rate, where as I am scaling my updating rate based upon camera distance.

Local rendering lets you do that second part.

Changing CFrame on an anchored part is fine, we don’t really use the Anchored flag for any rendering optimizations.

Just don’t animate C0/C1 on welds.

Welds have rendering optimization but anchored parts don’t? So, from a rendering perspective, a welded brick wall is more efficient than an anchored brick wall?