Runaway loop with Suits

Discussions about Coding and Scripting
Post Reply
User avatar
Barbie
Godlike
Posts: 2807
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Runaway loop with Suits

Post by Barbie »

While testing my Invulnerability armor I get a critical error at certain circumstances:
UnrealTournament.log wrote:Critical: AsbestosSuit Autoplay.AsbestosSuit1 (Function Engine.Inventory.ArmorPriority:0001) Runaway loop detected (over 10000000 iterations)
This error raises if my inventory contains that SBInvulnerability and any of the UnrealTorunament Armors and I pick up a AsbestosSuit or ToxinSuit while having damage by shooting rockets at wall. If either SBInvulnerability or any of the UnrealTorunament Armors is NOT in the inventory, I was not able to reproduce that runaway loop.
FYI the full UnrealTournament.log:
Spoiler
Log: Log file open, 05/02/16 16:13:54
Init: Name subsystem initialized
Init: Detected: Microsoft Windows 98 4.10 (Build: 67766446)
Init: Version: 436
Init: Compiled: Oct 24 2000 23:40:18
Init: Command line: Autoplay.unr HWND=394912 -log
Init: Base directory: D:\Programme\UT\System\
Init: Character set: Unicode
Log: Bound to Engine.dll
Log: Bound to Core.dll
Log: Bound to Window.dll
Init: Object subsystem initialized
Init: Computer: (my computer name)
Init: User: (my user name)
Init: Memory total: Phys=261584K Pagef=1835564K Virt=2093056K
Init: Working set: 32000 / 159000
Init: CPU Speed=3392.198880 MHz
Init: CPU Page size=4096, Processors=4
Init: CPU Detected: PentiumPro-class processor (GenuineIntel)
Init: CPU Features: CMov FPU RDTSC PAE MMX KNI
Init: Unreal engine initialized
Log: Bound to WinDrv.dll
Init: Mouse info: 0 0 0
Init: Initializing DirectDraw
Log: DirectDraw drivers:
Log: display (Primärer Anzeigetreiber)
Init: DirectDraw initialized successfully
Init: DirectInput initialized successfully.
Init: Client initialized
Log: Bound to Render.dll
Init: Lighting subsystem initialized
Init: Rendering initialized
Log: LoadMap: Entry
Log: Bound to Fire.dll
Log: Bound to IpDrv.dll
Log: Game class is 'UTIntro'
Log: Level is Level Entry.MyLevel
Log: Bringing Level Entry.MyLevel up for play (0)...
ScriptLog: InitGame:
ScriptLog: Base Mutator is Entry.Mutator0
Log: Browse: Autoplay.unr?Name=Barbie?Class=BotPack.TFemale1?team=0?skin=FCommandoSkins.cmdo?Face=FCommandoSkins.ivana?Voice=BotPack.VoiceFemaleTwo?OverrideClass=
Log: LoadMap: Autoplay.unr?Name=Barbie?Class=BotPack.TFemale1?team=0?skin=FCommandoSkins.cmdo?Face=FCommandoSkins.ivana?Voice=BotPack.VoiceFemaleTwo?OverrideClass=
Log: Collecting garbage
Log: Purging garbage
Log: -0.0ms Unloading: Package Render
Log: Garbage: objects: 15520->15519; refs: 176577
Log: Game class is 'DeathMatchPlus'
Log: Level is Level Autoplay.MyLevel
Log: Bringing Level Autoplay.MyLevel up for play (0)...
ScriptLog: InitGame: ?Name=Barbie?Class=BotPack.TFemale1?team=0?skin=FCommandoSkins.cmdo?Face=FCommandoSkins.ivana?Voice=BotPack.VoiceFemaleTwo?OverrideClass=
ScriptLog: Base Mutator is Autoplay.DMMutator0
ScriptLog: Found Autoplay.SCUBAGear0 at 1568.000000,-880.000000,-2032.000000
ScriptLog: Found Autoplay.AsbestosSuit0 at 1981.227051,-820.629639,-2016.000000
ScriptLog: Found Autoplay.KevlarSuit0 at 1984.000000,-752.000000,-2016.000000
ScriptLog: Found Autoplay.ToxinSuit0 at 1984.000000,-688.000000,-2016.000000
ScriptLog: Initiating local logging...
Init: Initialized moving brush tracker for Level Autoplay.MyLevel
Log: Bound to UWeb.dll
ScriptLog: Team 0
ScriptLog: Login: Barbie
Log: Possessed PlayerPawn: TFemale1 Autoplay.TFemale0
Init: Input system initialized for WindowsViewport0
Log: Opened viewport
Log: Bound to OpenGLDrv.dll
Log: Initializing OpenGLDrv...
Log: Enter SetRes()
Init: Using pixel format 7
Init: GL_VENDOR : NVIDIA Corporation
Init: GL_RENDERER : GeForce GTX 750 Ti/PCIe/SSE2
Init: GL_VERSION : 4.5.0 NVIDIA 364.51
Init: Device supports: GL_EXT_bgra
Init: Device supports: GL_ARB_texture_compression
Init: Device supports: GL_EXT_texture_compression_s3tc
Init: Device supports: GL_EXT_texture_env_combine
Init: Device supports: GL_ARB_texture_env_combine
Init: Device supports: GL_EXT_texture_filter_anisotropic
Init: Device supports: GL_NV_texture_env_combine4
Init: Device supports: GL_EXT_texture_lod_bias
Init: Device supports: GL_EXT_compiled_vertex_array
Init: Device supports: GL_EXT_secondary_color
Init: Device supports: GL_ARB_multitexture
Init: Device supports: GL_SGIS_generate_mipmap
Init: Device supports: GL_EXT_multi_draw_arrays
Init: Device supports: GL_ARB_vertex_program
Init: Device supports: GL_ARB_fragment_program
Init: Depth bits: 24
Log: 4 Texture Mapping Units found
Log: Trying to use S3TC extension.
Log: MinLogTextureSize = 2
Log: MaxLogTextureSize = 14
Log: BufferActorTris = 1
Log: UseDetailAlpha = 1
Log: Bound to Galaxy.dll
Init: Galaxy is using DirectSound
Init: Galaxy initialized
DevAudio: Galaxy SetViewport: WindowsViewport0
Init: Game engine initialized
Log: Startup time: 1.477668 seconds
ScriptLog: Found Autoplay.ToxinSuit1 at 1984.000000,-688.000000,-2016.000000
ScriptLog: Found Autoplay.AsbestosSuit1 at 1981.227051,-820.629639,-2016.000000
Critical: appError called:
Critical: AsbestosSuit Autoplay.AsbestosSuit1 (Function Engine.Inventory.ArmorPriority:0001) Runaway loop detected (over 10000000 iterations)
Critical: Windows GetLastError: Der Vorgang wurde erfolgreich beendet. (0)
Exit: Executing UObject::StaticShutdownAfterError
Exit: Executing UWindowsClient::ShutdownAfterError
Exit: UGalaxyAudioSubsystem::ShutdownAfterError
Log: DirectDraw End Mode
Exit: UOpenGLRenderDevice::ShutdownAfterError
Critical: FFrame::Serialize
Critical: UObject::ProcessEvent
Critical: (RocketMk2 Autoplay.RocketMk1, Function Engine.Projectile.HitWall)
Critical: AActor::physProjectile
Critical: AActor::performPhysics
Critical: AActor::Tick
Critical: TickAllActors
Critical: ULevel::Tick
Critical: (NetMode=0)
Critical: TickLevel
Critical: UGameEngine::Tick
Critical: UpdateWorld
Critical: MainLoop
Exit: Exiting.
Uninitialized: Name subsystem shut down
Uninitialized: Log file closed, 05/02/16 16:14:21
One of my questions is: does "Runaway loop" mean that the function "ArmorPriority" was called over 10000000 times in a row or does it mean that a runaway loop was detected within that function? The function "ArmorPriority" in question is defined in Inventory.uc and can not produce any loop:

Code: Select all

function int ArmorPriority(name DamageType)
{
	if ( DamageType == 'Drowned' )
		return 0;
	if( (DamageType!='None') 
		&& ((ProtectionType1==DamageType) || (ProtectionType2==DamageType)) )
		return 1000000;

	return AbsorptionPriority;
}
"ProtectionType1", "ProtectionType2" and "AbsorptionPriority" are only variables, no functions.
The main question of course is how to avoid that runaway loop.

Background: I want to create a pickup that gives invulnerability for some time, and for some reasons I do not want to realize it with PlayerPawn(Owner).ReducedDamageType='All' but with an Armor. That sounds easy - make the armor be the first in the armor chain and absorb all damage:
Source code of SBInvulnerability

Code: Select all

class SBInvulnerability extends TournamentPickup;
// class SBInvulnerability extends Pickup; <- same result

function int ArmorAbsorbDamage(int Damage, name DamageType, vector HitLocation) {
	return 0;
}


function int ArmorPriority(name DamageType) {
	return 1000000 + 1; // parents class returns 1000000 if DamageType==ReducedDamage
}


function inventory PrioritizeArmor(int Damage, name DamageType, vector HitLocation) {
	return Self;
}


function int ReduceDamage(int Damage, name DamageType, vector HitLocation) {
	return 0;
}



singular function UsedUp() {
	if ((Pawn(Owner) != None) && (M_Deactivated != ""))
		Pawn(Owner).ClientMessage(ItemName $ M_Deactivated);
	if (PlayerPawn(Owner) != None)
		PlayerPawn(Owner).ReceiveLocalizedMessage(class'ProtectionMessageEnd', , PlayerPawn(Owner).PlayerReplicationInfo);
	Destroy();
}


state Activated {

	function Timer() {
		Charge -= 10;
		if (Charge <= 0)
		{
			UsedUp();
			return;
		}
	}


	function BeginState() {
		SetTimer(1, True);
	}

}


defaultproperties {
	AbsorptionPriority=999
	ArmorAbsorption=100
	bActivatable=True
	bAutoActivate=True
	bCanHaveMultipleCopies=false
	bIsAnArmor=true
	bMeshEnviroMap=True
	bRotatingPickup=true
	Charge=300 // in 1/10 sec
	ItemName="Invulnerability"
	M_Activated=""
	M_DeActivated=""
	M_Selected=""
	MaxDesireability=2.5
	Mesh=LodMesh'botpack.UDamage'
	PickupMessage="You got the Invulnerability!"
	PickupViewMesh=LodMesh'botpack.UDamage'
	// not needed: ProtectionType1='All'
	RemoteRole=ROLE_DumbProxy
	RespawnTime=120 // in sec
	Texture=Texture'Botpack.Skins.Jearth21'
}
(In fact the "real" version is more complex - I reduced the source to the core.)

If you want to try it: I've added a test map (including source code) where you can pick up the 10 seconds lasting Invulnerability, one ore more UT armors, shoot rockets at the wall and pick up one of the suits. Good luck.
Attachments
TestSBInvulnerabilityV0.zip
(10.27 KiB) Downloaded 74 times
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
Higor
Godlike
Posts: 1866
Joined: Sun Mar 04, 2012 6:47 pm

Re: Runaway loop with Suits

Post by Higor »

Any IF check increases the runaway counter by 1.
And the loop can be anywhere inside our outside of the function, keep searching.

EDIT:
If you need to make multiple exclusive checks with same result in a loop, try and use the && || operators more often, as packing as many together helps prevent the iterator count from increasing.
Post Reply