So after various games of smooth play I crashed 3 times on the same map, all different stuff.
I'm using a BAT file to rotate logs on my client, just like any decent server.
============================================================================
Oh ho! I found something interesting in this log... thanks to one of my mods.
Code: Select all
Critical: ULevel::CheckEncroachment
Critical: ULevel::FarMoveActor
Critical: UGameEngine::Draw
Critical: UWindowsViewport::Repaint
Critical: UWindowsClient::Tick
Critical: ClientTick
Critical: UGameEngine::Tick
Critical: UXC_GameEngine::Tick
Critical: ACE8421
Critical: EnforceTickRate
Critical: MainLoop
One of those nasty CheckEncroachment checks happeing in the rendering process, then I realized that the only thing moving actors in that stage is LCWeapons (position advancer).
LCWeapons removes actors from the hash/octree using a
SetCollision(false) call, so I checked CheckEncroachment and found something interesting...
Code: Select all
guard(ULevel::CheckEncroachment);
check(Actor);
// If this actor doesn't need encroachment checking, allow the move.
if( !Actor->bCollideActors && !Actor->bBlockActors && !Actor->bBlockPlayers && !Actor->IsMovingBrush() )
return 0;
This doesn't care if the actor isn't supposed to collide anymore!!
Looks like a bug to me but I'll happily test a branch where all encroachment checks return NULL if the actor doesn't have bCollideActors=True.
============================================================================
Same old stuff, I have to figure out what's up here.
One interesting thing is that this part of the code only does stuff if there's movers in the way.
If there are no movers then this does nothing (almost).
BTW, the game mode uses brushless movers as platforms, I'll have to start there...
Code: Select all
Critical: CheckWithActors
Critical: ULevel::MultiLineCheck
Critical: ULevel::MoveActor
Critical: AActor::moveSmooth
Critical: AActor::Tick
Critical: TickAllActors
Critical: ULevel::Tick
Critical: (NetMode=3)
Critical: TickLevel
Critical: UGameEngine::Tick
Critical: UXC_GameEngine::Tick
Critical: ACE8421
Critical: EnforceTickRate
Critical: MainLoop
============================================================================
Ouch, this code is inside XC_Engine.
Code: Select all
Critical: ActorLoop
Critical: FCollisionOctree::FastLineQuery
Critical: FCollisionCacus::ActorLineCheck
Critical: CheckWithActors
Critical: ULevel::MultiLineCheck
Critical: ULevel::Trace
Critical: AActor::Tick
Critical: TickAllActors
Critical: ULevel::Tick
Critical: (NetMode=3)
Critical: TickLevel
Critical: UGameEngine::Tick
Critical: UXC_GameEngine::Tick
Critical: ACE8421
Critical: EnforceTickRate
Critical: MainLoop
Alright, let's take a look.
Code: Select all
FVector4 HitLocation; //TODO: use FVector4!!!
FVector4 HitNormal;
guard(ActorLoop);
for ( INT i=0 ; i<ActorCount ; i++ )
{
AActor* Actor = CacusNodes[CurRef]->Actors(i).Actor;
if ( !ValidCollidingActor(Actor) )
continue;
if ( !Ray.HitsGCylActor( Actor, &HitLocation, &HitNormal, Primitive) )
continue;
/* ... crash doesn't occur here ... */
}
unguard;
I see these options:
- Invalid pointer (Actor)
- Unstable math in HitsGCylActor (3 different trace methods, I should add exception handlers here)
============================================================================