Seemingly Random CTD from Started Script

Post » Wed Mar 11, 2015 7:52 am

Some 10 years ago I spiced up BILL_MarksDaedraScript so it would spawn a little more than only the one daedra lord once. This has worked well ever since then, but became a bit too predictable lately.

Last saturday morning I thought of a way more subtle approach which was easily programmed in only a couple of minutes. The original script now fires background script (CIB) if it isn't already running, CIB checks your level and luck and responds accordingly with a wide variation of Daedra, up to the most horrendous ones at player's highest levels.

BUT IT CRASHES QUITE OFTEN, at any point, and after four days of tweaking and testing I still have no clue what causes that. Maybe I do something utterly stupid that shouldn't be done in a Started Script, something I don't recognize as such.

I have run out of ideas how to discover whatever the error is. I've stripped the script to its bare essentials and still it's CTD at the randomest of moments.

If ANYONE out there has any idea how to successfully squash this bug, I would be very very grateful.

Azurolf

The Code :

=============================My changes to the Bill Script=============================begin BILL_MarksDaedraSummon; Summon an Daedra when an item is removed from altar;; script location: should be placed upon an object on a Daedric Altar ;; variables	short done;; # 15303 - if this fixes it, i'll be very disappointed; # Just for Debugging CTD in started Script - maybe this makes a diffif ( menuMode == 1 )	returnendif; # Of course, now one can avoid the Curse simply by having INV open, take the item and drop it there; # Alas Ancestral Tomb - this doesn't fix it either;if ( onActivate == 1 )	if ( scriptRunning rtk_cursed_item_bg == 1 )		messageBox "CIB adding one more Foe"		set rtkg_cib_1_more to rtkg_cib_1_more + 1	else		messageBox "CIB starting"		startScript rtk_cursed_item_bg	endif	Activate endif;return;End=======================================The Randomly Crashing Background Script=======================================begin rtk_cursed_item_bg;; # 15228 My update from 2005 in Bill_marks_Daedra etc completely svcks due to old age; # Time to start from scratch with a script that ; # A # Runs in the background so you can exit but not escape; # B # Adds a lot more variation in the Spawnees (been doing that quite a lot lately); # C # Other Things;; # Unfortunately, this scriptlet CTDs at seemingly random moments:; # # Often when picking up a Cursed Item straight after Game Load; # # # Leaving and returning to the Cell sometimes prevents this - or is that part of the Random deception ??? ; # # When first pickup worx OK, then second may fail between the Gong (initial Bell) and the first Spawn; # # First pickup may work well for a while and then CTD anywhere; # # Opening a Container / Corpse while script runs sometimes leads to immediate CTD ;; # 15228-15303 Originally this scriptlet did the spawning as well, but I put that in a second BG script; # # - which isn't performed - yet; # # - in an attempt to locate the error; # # - this baby still crashes;short swInit;short PL ; # player Levelshort PS ; # player 'stage';short spawnCount ; # Number of Spawnsshort spawnMax ; # Total to Spawn; float timer ; # float tSpawn ; # Time between Spawns;; # 'registers' :short ranshort s1short s2;SHORT RN ; # Frames Delay after leaving Menu Mode - doesnt fix it;;;;messageBox "CIB Poll";if ( menuMode == 1 )	SET RN TO 5	returnendif;if ( RN > 0 )	MESSAGEBOX "CIB Menu Mode Delay %G - Init:%G" RN swInit	SET RN TO RN - 1	returnendif;if ( swInit == 0 )	set swInit to 1	playSound "bell6";	messageBox "CIB Initializing";	set PL to ( player->getLevel ) 	set spawnMax to 1 + ( PL + 1 ) / 10 ; # 9 -> 1 , 10 -> 2 etc	set s1 to ( player->getLuck ) 	;;;if ( Random100 < s1 ) ; # Luck = More Fun ! 	set ran to ( random 100 ) 	if ( ran < s1 ) ; # Luck = More Fun ! 		set spawnMax to spawnMax + 1	endif	set spawnCount to 0	set tSpawn to ( 100.0 - PL ) / 5	;set timer to 0	;set timer to tSpawn	set timer to tSpawn - 1.0;	set PS to 1 + ( PL + 5 ) / 10	set rtkg_cib_ps to PS;	; # messageBox "The Daedric Curse is upon You"	messagebox "CIB Time %.2f , Total %G" tSpawn spawnMax "OK"	messageBox "More : %G" rtkg_cib_1_more	returnendif;if ( rtkg_cib_1_more > 0 )	set spawnMax to spawnMax + rtkg_cib_1_more	set rtkg_cib_1_more to 0	returnendif;set timer to timer + getSecondsPassed;;;messageBox "CIB Running...( %.2f / %.2f )" timer tSpawn;if ( timer < tSpawn )	returnendif;set timer to 0 ;set spawnCount to spawnCount + 1;messageBox "Here comes number %G/%G" spawnCount spawnMax ;;; "OK";if ( spawnCount < spawnMax );	set ran to ( random 100 )	set s1 to ran / 25 	messageBox "Thunder %G" s1;	if ( s1 == 0 )	;	playSound "Thunder0"	elseif ( s1 == 1 )	;	playSound "Thunder1"	elseif ( s1 == 2 )	;	playSound "Thunder2"	elseif ( s1 == 3 )	;	playSound "ThunderClap"	else ; # NOT - too weak , that's why / 25 , not / 20	;	playSound "Thunder3"	endif;else;	playSound "bell1";endif;;;;startScript rtk_cursed_item_bg_sel;if ( spawnCount < spawnMax ) 	messageBox "CIB More will follow"	returnendif;messageBox "CIB Stopping" ;;; "OK"set swInit to 0;stopScript rtk_cursed_item_bg;;;;return;end;
User avatar
Anthony Diaz
 
Posts: 3474
Joined: Thu Aug 09, 2007 11:24 pm

Post » Wed Mar 11, 2015 3:33 am

You can use MWSE functions to find the line that crashes the game. Add this line to your script

xFileWriteText "debug" "whatever" 

When it runs a file named debug will be created in "morrowind/data files/mwse" folder.

User avatar
J.P loves
 
Posts: 3487
Joined: Thu Jun 21, 2007 9:03 am

Post » Wed Mar 11, 2015 9:24 am

The structure of the script seems sound. I see that you are setting random values, but I do not see an instance that you are dividing by such a variable that might sometimes result in dividing by zero.

Some have reported crashes as a result of displaying more than one message during the same frame (cycle). I have not experienced that in the few instances where I have deliberately called three (empty) messages in a row, but that does not mean it is not an issue. You might try running it with all of the messageboxes commented-out. Most of them seem to be for the purpose of debugging anyway.

One thing I will agree can lead to strange behavior (although not necessarily crashes) is the 'complex mathematics' your script performs. It is more reliable to perform one operation in a line of code and string out a more complex formula over several lines.

You also do not make as much use of parentheses as you could (should?). The Morrowind engine is finicky, and I tend to err on the side of caution to make certain it interprets my code as I intended.

I assume 'rtkg_cib_ps' and 'rtkg_cib_1_more' are global variables.

Here is a revision of your script incorporating my suggestions:

begin rtk_cursed_item_bg short swInit short PL ; # player Levelshort PS ; # player 'stage' short spawnCount ; # Number of Spawnsshort spawnMax ; # Total to Spawn float timer ; #float tSpawn ; # Time between Spawns short ranshort s1short s2 SHORT RN ; # Frames Delay after leaving Menu Mode - doesnt fix it if ( menuMode == 1 )            SET RN TO 5            returnendif if ( RN > 0 )            SET RN TO ( RN - 1 ) ; ADDED PARENTHESES            returnendif if ( swInit == 0 )            set swInit to 1            playSound "bell6"            set PL to ( player->getLevel ) ;;          set spawnMax to 1 + ( PL + 1 ) / 10 ; SIMPLIFIED MATH            set spawnMax to ( PL + 1 )            set spawnMax to ( spawnMax / 10 )            set spawnMax to ( spawnMax + 1 )             set s1 to ( player->getLuck )            set ran to ( random 100 )            if ( ran < s1 )                        set spawnMax to ( spawnMax + 1 ) ; ADDED PARENTHESES            endif            set spawnCount to 0 ;;          set tSpawn to ( 100.0 - PL ) / 5 ; SIMPLIFIED MATH            set tSpawn to ( 100.0 - PL )            set tSpawn to ( tSpawn / 5 )             set timer to ( tSpawn - 1.0 ) ; ADDED PARENTHESES ;;          set PS to 1 + ( PL + 5 ) / 10 ; SIMPLIFIED MATH            set PS to ( PL + 5 )            set PS to ( PS / 10 )            set PS to ( PS + 1 )             set rtkg_cib_ps to PS             returnendif if ( rtkg_cib_1_more > 0 )            set spawnMax to ( spawnMax + rtkg_cib_1_more ) ; ADDED PARENTHESES            set rtkg_cib_1_more to 0            returnendif set timer to ( timer + getSecondsPassed ) ; ADDED PARENTHESESif ( timer < tSpawn )            returnendif set timer to 0 set spawnCount to ( spawnCount + 1 ) ; ADDED PARENTHESES if ( spawnCount < spawnMax )             set ran to ( random 100 )            set s1 to ( ran / 25 ) ; ADDED PARENTHESES             if ( s1 == 0 )            ;           playSound "Thunder0"            elseif ( s1 == 1 )            ;           playSound "Thunder1"            elseif ( s1 == 2 )            ;           playSound "Thunder2"            elseif ( s1 == 3 )            ;           playSound "ThunderClap"            else ; # NOT - too weak , that's why / 25 , not / 20            ;           playSound "Thunder3"            endif else             playSound "bell1" endif if ( spawnCount < spawnMax )            returnendif set swInit to 0 stopScript rtk_cursed_item_bg end

This code has not been tested.

User avatar
Marion Geneste
 
Posts: 3566
Joined: Fri Mar 30, 2007 9:21 pm

Post » Wed Mar 11, 2015 6:26 am

I'd try attaching the local script to e.g. an activator and see if it still crashes. If it crashes no more, it may be a problem related to attaching the global script to something moved to inventory
User avatar
Kahli St Dennis
 
Posts: 3517
Joined: Tue Jun 13, 2006 1:57 am

Post » Wed Mar 11, 2015 4:07 am

@cyran0 - Thank you for providing sound advice. I've used simplified maths before and the code looks very childish bu if it works... I'll give it a try. If the parentheses don't solve the problem.

@abot - The script is on a Daedric Container as well. You may have point.

@qqqbbb - MWSE? Mkay. I'll try that as well.

Guys, THANKS. Plenty of leads to follow, you're Great!

[ Edit - You're right where the messages are concerned : they were put in *after* the crashing - Thunder and Bells could have caused the crashes to, or Random100, or whatever. There's quite some DBG stuff in/out by now. And when it works, it's awesome, that's why i want that bug out - and the messages :-) ]

User avatar
*Chloe*
 
Posts: 3538
Joined: Fri Jul 07, 2006 4:34 am

Post » Wed Mar 11, 2015 7:46 am

Thank you, it works now! No more CTDs. It wasn't the Big Script. It was the Little One.

@cyran0 : I'll be using Parentheses more from now on, and it's still not my intention to simplify already quite straightforward mathematics, but I'll keep potential pitfalls in that area in mind. Thanks.

But it was Abot's remark that triggered the solution. Something's wrong with onActivate when pickuppable items are concerned. I've added a cooldown loop. A delay of only a couple of frames did the trick. But it immediately interfered with the previous version of the Script. I've commented all intricacies in the Source, which I'd like to share here:

begin BILL_MarksDaedraSummon;; # Special thanx to qqqbbb, cyran0 and ABOT for helping me fix the Horrible CTD here; # Special thanx as well to all those hundreds of scamps who voluntarily gave their lives to test the Fix :-);; Triggers the Daedric Curse ; - Hopi Daedra to have Fun with and Hopi Loot to turn Adrenaline into Endorphine afterwards;; script location: should be placed upon an object on a Daedric Altar ;; variables	short done ; # now acts as a Cool Down counter - maybe rename this one...;if ( done > 0 ) ;; # Abused it to capture ( random 100 ) in my prev version of this script . . .; # # This causes all previously touched Cursed Items in INV to Count Down; # # That's why in This Release, the Cool Down will Count Up...;	set done to 0;endif;if ( done == 0 )	if ( onActivate == 1 )		set done to -3		Activate 	endif	returnendif;messageBox "Countdown %G" done;if ( done == -3 ) 	;; set done to ( done + 1 )	;; set onActivate to 0 ; # it's a Function... 	if ( scriptRunning rtk_cursed_item_bg == 1 )		messageBox "CIB adding one more Foe"		set rtkg_cib_1_more to rtkg_cib_1_more + 1	else		messageBox "CIB starting"		startScript rtk_cursed_item_bg	endif	;;;;;;;;;;;;;;;;returnendif;set done to ( done + 1 );return;End

Now can you guess which return I forgot to comment somewhere in the process ? :-)

It works now. No more CTDs. Oh m-a-a-a-a-n, I will cherish this Synergetic Burst for a very long time, and I've decided to mention the three of you so I may never forget.

THANX!

User avatar
Killah Bee
 
Posts: 3484
Joined: Sat Oct 06, 2007 12:23 pm


Return to III - Morrowind