Problems with CDCooley's teleport scripts

Post » Sun May 29, 2011 2:23 am

I've implemented a version of CDCooley's companion teleportation scripts for teleporting my companions in my mod. Now, I've had a handful of players tell me these scripts are causing the game to crash. I'm using the standard scripts used in most current companion mods, most of them completely unaltered. I finally tracked down the script to the FollowScrTrans, which checks to see if the player is using Mournhold transport or the propylons. It's when the players are moved to these cells, that the script executes to move the companion to the player's position. This is when the game decides to CTD. In fact, in some cases, the game CTDs as soon as the player enters any of these cells that the script is set to check for, even if it doesn't continue to execute because the player hasn't teleported.

Has anyone come across a crash when traveling with similar companions?

This is the script in question:
Begin gp_sara_FollowScrTransS;slightly modified from Kateri's Julan;simple comparison of cells to see if player has used standard scripted transportShort stateShort StoredCellShort NewCellFloat timerIf ( MenuMode == 1 )	ReturnEndIfIf ( state == 0 )	If ( gp_npc_Sara->GetCurrentAiPackage != 3 );check if she's still following		StopScript gp_sara_FollowScrTransS	Return	ElseIf ( GetPCCell "Andasreth, Propylon Chamber" == 1 )		Set StoredCell To 1	ElseIf ( GetPCCell "Berandas, Propylon Chamber" == 1 )		Set StoredCell To 2	ElseIf ( GetPCCell "Falasmaryon, Propylon Chamber" == 1 )		Set StoredCell To 3	ElseIf ( GetPCCell "Falensarano, Propylon Chamber" == 1 )		Set StoredCell To 4	ElseIf ( GetPCCell "Hlormaren, Propylon Chamber" == 1 )		Set StoredCell To 5	ElseIf ( GetPCCell "Indoranyon, Propylon Chamber" == 1 )		Set StoredCell To 6	ElseIf ( GetPCCell "Marandus, Propylon Chamber" == 1 )		Set StoredCell To 7	ElseIf ( GetPCCell "Rotheran, Propylon Chamber" == 1 )		Set StoredCell To 8	ElseIf ( GetPCCell "Telasero, Propylon Chamber" == 1 )		Set StoredCell To 9	ElseIf ( GetPCCell "Valenvaryon, Propylon Chamber" == 1 )		Set StoredCell To 10	ElseIf ( GetPCCell "Caldera, Guild of Mages" == 1 )		Set StoredCell To 11	ElseIf ( GetPCCell "Ebonheart, Grand Council Chambers" == 1 )		Set StoredCell To 12	ElseIf ( GetPCCell "Mournhold, Royal Palace: Reception Area" == 1 )		Set StoredCell To 13	EndIf	If ( StoredCell > 0 )		Set state To 10	Else		StopScript gp_sara_FollowScrTransS		Return	EndIfElseIf ( state == 10 )	If ( GetPCCell "Andasreth, Propylon Chamber" == 1 )		Set NewCell To 1	ElseIf ( GetPCCell "Berandas, Propylon Chamber" == 1 )		Set NewCell To 2	ElseIf ( GetPCCell "Falasmaryon, Propylon Chamber" == 1 )		Set NewCell To 3	ElseIf ( GetPCCell "Falensarano, Propylon Chamber" == 1 )		Set NewCell To 4	ElseIf ( GetPCCell "Hlormaren, Propylon Chamber" == 1 )		Set NewCell To 5	ElseIf ( GetPCCell "Indoranyon, Propylon Chamber" == 1 )		Set NewCell To 6	ElseIf ( GetPCCell "Marandus, Propylon Chamber" == 1 )		Set NewCell To 7	ElseIf ( GetPCCell "Rotheran, Propylon Chamber" == 1 )		Set NewCell To 8	ElseIf ( GetPCCell "Telasero, Propylon Chamber" == 1 )		Set NewCell To 9	ElseIf ( GetPCCell "Valenvaryon, Propylon Chamber" == 1 )		Set NewCell To 10	ElseIf ( GetPCCell "Caldera, Guild of Mages" == 1 )		Set NewCell To 11	ElseIf ( GetPCCell "Ebonheart, Grand Council Chambers" == 1 )		Set NewCell To 12	ElseIf ( GetPCCell "Mournhold, Royal Palace: Reception Area" == 1 )		Set NewCell To 13	Else		Set state To 0		StopScript gp_sara_FollowScrTransS		Return	EndIf	If ( NewCell == StoredCell )		Return	Else		Set state To 20	EndIfElseIf ( state == 20 )	If ( GetPCCell "Andasreth, Propylon Chamber" == 1 )		gp_npc_sara->PositionCell 540 730 -430 270 "Andasreth, Propylon Chamber"	ElseIf ( GetPCCell "Berandas, Propylon Chamber" == 1 )		gp_npc_sara->PositionCell 540 1124 -686 270 "Berandas, Propylon Chamber"	ElseIf ( GetPCCell "Falasmaryon, Propylon Chamber" == 1 )		gp_npc_sara->PositionCell 227 579 -430 270 "Falasmaryon, Propylon Chamber"	ElseIf ( GetPCCell "Falensarano, Propylon Chamber" == 1 )		gp_npc_sara->PositionCell 410 998 -558 270 "Falensarano, Propylon Chamber"	ElseIf ( GetPCCell "Hlormaren, Propylon Chamber" == 1 )		gp_npc_sara->PositionCell 4022 3823 12690 180 "Hlormaren, Propylon Chamber"	ElseIf ( GetPCCell "Indoranyon, Propylon Chamber" == 1 )		gp_npc_sara->PositionCell 489 866 -430 270 "Indoranyon, Propylon Chamber"	ElseIf ( GetPCCell "Marandus, Propylon Chamber" == 1 )		gp_npc_sara->PositionCell 244 988 -430 270 "Marandus, Propylon Chamber"	ElseIf ( GetPCCell "Rotheran, Propylon Chamber" == 1 )		gp_npc_sara->PositionCell 427 737 -430 270 "Rotheran, Propylon Chamber"	ElseIf ( GetPCCell "Telasero, Propylon Chamber" == 1 )		gp_npc_sara->PositionCell 333 842 -558 270 "Telasero, Propylon Chamber"	ElseIf ( GetPCCell "Valenvaryon, Propylon Chamber" == 1 )		gp_npc_sara->PositionCell 215 853 -558 720 "Valenvaryon, Propylon Chamber"	ElseIf ( GetPCCell "Caldera, Guild of Mages" == 1 )		gp_npc_sara->PositionCell 763 802 412 180 "Caldera, Guild of Mages"	ElseIf ( GetPCCell "Ebonheart, Grand Council Chambers" == 1 )		gp_npc_sara->PositionCell 1173.285 613.156 -120.847 0 "Ebonheart, Grand Council Chambers"	ElseIf ( GetPCCell "Mournhold, Royal Palace: Reception Area" == 1 )		gp_npc_sara->PositionCell 2.730 959.274 -105.817 180 "Mournhold, Royal Palace: Reception Area"	EndIf	Set state To 30	ReturnElseIf ( state == 30 )	Set timer To 0	Set state To 0	StopScript gp_sara_FollowScrTransSEndIfEnd


Anyone have any idea what could be going wrong here?
User avatar
Evaa
 
Posts: 3502
Joined: Mon Dec 18, 2006 9:11 am

Post » Sat May 28, 2011 2:53 pm

Could this be caused by the npc being dead? I've had some oddity using cdc's teleport mod after killing a companion.(she deserved it, stupid shoddy merchandise!)
User avatar
MARLON JOHNSON
 
Posts: 3377
Joined: Sun May 20, 2007 7:12 pm

Post » Sat May 28, 2011 5:20 pm

As far as I know, my tester's companions are alive and well. It only happens to certain people, but once it starts happening, the problem is persistent and happens to all the companions.

I've just got some new insight into the problem. It happens when the companion is asked to wait, not when the companion is following. So the problem is with the script not checking the CurrentAiPackage for follow mode and not stopping the script when it's supposed to.
User avatar
JESSE
 
Posts: 3404
Joined: Mon Jul 16, 2007 4:55 am

Post » Sat May 28, 2011 7:42 pm

A few corrections/clarifications based on my experience (others may have seen it differently):

The game doesn't CTD--it freezes. Whatever was on the screen remains there. Nothing moves, including the cursor when I move the mouse. No hotkey produces a response. I can get out of it only by using Ctl-Alt-Del to bring up Task Manager, and using that to close the Morrowind program.

The problem doesn't happen if I enter one of the problem locations by any means other than teleporting, assuming I have the companion following me. If I teleport to the location with the companion following me, the game freezes.

If the companion is active but not following (he's been told to "wait here"), it depends on which companion is active. With Ash-Kosh, the game freezes if I'm in any of the problem locations and he's in wait mode, whether he's in the same cell with me or in another one. If he follows me into the cell and I tell him to wait, the game freezes as soon as I click "goodbye" in the dialog. With Gavyn, the game does not freeze if he's waiting, no matter where I go. Also, if I teleport while Gavyn is waiting, he teleports with me, continues to wait in the new location, and there's no freeze. I don't know what would happen with Sara; I haven't met her yet.
User avatar
Laura Ellaby
 
Posts: 3355
Joined: Sun Jul 02, 2006 9:59 am

Post » Sat May 28, 2011 12:00 pm

Ok. I sent you an email about testing this from a different angle. I'm not sure if it will help with the freezing while the companion is following, but it should stop anything from happening while the companion is in wait mode and eliminate one of the problems.

As for the freeze while following, I'm going to have to keep looking at this script itself, because that's where the main problem seems to lie.
User avatar
Kayleigh Williams
 
Posts: 3397
Joined: Wed Aug 23, 2006 10:41 am

Post » Sun May 29, 2011 1:37 am

I have never examined cdCooley's scripts before, but I think I follow the logic of this script. I notice that the local float variable timer is declared but not used (except to set to zero - a value from which it never deviates). As I was reading the script I wondered if a short delay would be necessary after assigning a value to storedCell and then assigning a value to newCell. If the player is currently teleporting between two cells perhaps it could create confusion for the engine. Perhaps that is what the timer was for - to create a short delay before making this check. It this part of his code that you omitted from your version of his scripts? I do not know under what circumstances this script is started so I cannot say how effective such a delay would be or even if that is the purpose of the timer.
User avatar
ImmaTakeYour
 
Posts: 3383
Joined: Mon Sep 03, 2007 12:45 pm

Post » Sat May 28, 2011 1:52 pm

I don't remember omitting the timer part, but that just might be a solution. I grabbed the scripts from Julan's scripting I believe, so it's not the original CDCooley script. If the script is constantly checking those conditions every frame, I can see where it might cause a freeze for some players but not others.

Do you think a timer or frame counter at the beginning of the script might be a good idea as well?
User avatar
Baby K(:
 
Posts: 3395
Joined: Thu Nov 09, 2006 9:07 pm

Post » Sat May 28, 2011 11:50 pm

I do not know the context of the timer's use, but if it a matter of creating a delay for new cells to load completely, then a timer will be a more reliable choice. The player's framerate will determine how 'long' a 10 frame delay represents. On faster systems it may not be long enough, whereas 100 frames on a slower system might be too long a delay. If you want to allow two seconds for a cell to load, then using a timer will allow you pointpoint that for any system.

However before you decide to do this you should examine on of cdCooley's original teleport scripts to see for what the timer is actually used - I am just speculating.
User avatar
Stephanie I
 
Posts: 3357
Joined: Thu Apr 05, 2007 3:28 pm

Post » Sat May 28, 2011 3:25 pm

Well, that script may be vaguely inspired to CDC code, but maybe it is not as efficient :)
this is how I'd try to change it, umtested and probably even more broken, but I think there are some possibly useful optimization hints
Begin gp_sara_FollowScrTransS;slightly modified from Kateri's Julan;simple comparison of cells to see if player has used standard scripted transport; script should be called  from the NPC reference, I.E.; gp_npc_Sara->startscript "gp_sara_FollowScrTransS"; instead of; startscript "gp_sara_FollowScrTransS"; so to avoid scanning for referencesShort stateShort StoredCellShort NewCellFloat timerif ( GetInterior == 0 )	returnendifIf ( MenuMode )	ReturnEndIfIf ( state == 10 )	if ( timer < 3 )		set timer to ( timer + GetSecondsPassed )		return	endif	set timer to Random 1001	set timer to ( timer * 0.001 )	If ( GetPCCell "Andasreth, Propylon Chamber" )		Set NewCell To 1	ElseIf ( GetPCCell "Berandas, Propylon Chamber" )		Set NewCell To 2	ElseIf ( GetPCCell "Falasmaryon, Propylon Chamber" )		Set NewCell To 3	ElseIf ( GetPCCell "Falensarano, Propylon Chamber" )		Set NewCell To 4	ElseIf ( GetPCCell "Hlormaren, Propylon Chamber" )		Set NewCell To 5	ElseIf ( GetPCCell "Indoranyon, Propylon Chamber" )		Set NewCell To 6	ElseIf ( GetPCCell "Marandus, Propylon Chamber" )		Set NewCell To 7	ElseIf ( GetPCCell "Rotheran, Propylon Chamber" )		Set NewCell To 8	ElseIf ( GetPCCell "Telasero, Propylon Chamber" )		Set NewCell To 9	ElseIf ( GetPCCell "Valenvaryon, Propylon Chamber" )		Set NewCell To 10	ElseIf ( GetPCCell "Caldera, Guild of Mages" )		Set NewCell To 11	ElseIf ( GetPCCell "Ebonheart, Grand Council Chambers" )		Set NewCell To 12	ElseIf ( GetPCCell "Mournhold, Royal Palace: Reception Area" )		Set NewCell To 13	Else		Set state To 0		StopScript gp_sara_FollowScrTransS		Return	EndIf	If ( NewCell != StoredCell )		Set state To 20	EndIf	returnelseIf ( state == 0 )	If ( GetCurrentAiPackage != 3 ) ;check if she's still following		StopScript gp_sara_FollowScrTransS		Return	ElseIf ( GetPCCell "Andasreth, Propylon Chamber" )		Set StoredCell To 1	ElseIf ( GetPCCell "Berandas, Propylon Chamber" )		Set StoredCell To 2	ElseIf ( GetPCCell "Falasmaryon, Propylon Chamber" )		Set StoredCell To 3	ElseIf ( GetPCCell "Falensarano, Propylon Chamber" )		Set StoredCell To 4	ElseIf ( GetPCCell "Hlormaren, Propylon Chamber" )		Set StoredCell To 5	ElseIf ( GetPCCell "Indoranyon, Propylon Chamber" )		Set StoredCell To 6	ElseIf ( GetPCCell "Marandus, Propylon Chamber" )		Set StoredCell To 7	ElseIf ( GetPCCell "Rotheran, Propylon Chamber" )		Set StoredCell To 8	ElseIf ( GetPCCell "Telasero, Propylon Chamber" )		Set StoredCell To 9	ElseIf ( GetPCCell "Valenvaryon, Propylon Chamber" )		Set StoredCell To 10	ElseIf ( GetPCCell "Caldera, Guild of Mages" )		Set StoredCell To 11	ElseIf ( GetPCCell "Ebonheart, Grand Council Chambers" )		Set StoredCell To 12	ElseIf ( GetPCCell "Mournhold, Royal Palace: Reception Area" )		Set StoredCell To 13	EndIf	If ( StoredCell > 0 )		Set state To 10	Else		StopScript gp_sara_FollowScrTransS	EndIf	returnElseIf ( state == 20 )	If ( NewCell == 1 ); keep it simpler & faster		PositionCell 540 730 -430 270 "Andasreth, Propylon Chamber"	ElseIf ( NewCell == 2 )		PositionCell 540 1124 -686 270 "Berandas, Propylon Chamber"	ElseIf ( NewCell == 3 )		PositionCell 227 579 -430 270 "Falasmaryon, Propylon Chamber"	ElseIf ( NewCell == 4 )		PositionCell 410 998 -558 270 "Falensarano, Propylon Chamber"	ElseIf ( NewCell == 5 )		PositionCell 4022 3823 12690 180 "Hlormaren, Propylon Chamber"	ElseIf ( NewCell == 6 )		PositionCell 489 866 -430 270 "Indoranyon, Propylon Chamber"	ElseIf ( NewCell == 7 )		PositionCell 244 988 -430 270 "Marandus, Propylon Chamber"	ElseIf ( NewCell == 8 )		PositionCell 427 737 -430 270 "Rotheran, Propylon Chamber"	ElseIf ( NewCell == 9 )		PositionCell 333 842 -558 270 "Telasero, Propylon Chamber"	ElseIf ( NewCell == 10 )		PositionCell 215 853 -558 720 "Valenvaryon, Propylon Chamber"	ElseIf ( NewCell == 11 )		PositionCell 763 802 412 180 "Caldera, Guild of Mages"	ElseIf ( NewCell == 12)		PositionCell 1173.285 613.156 -120.847 0 "Ebonheart, Grand Council Chambers"	ElseIf ( NewCell == 13 )		PositionCell 2.730 959.274 -105.817 180 "Mournhold, Royal Palace: Reception Area"	EndIf	Set timer To 0	Set state To 0	StopScript gp_sara_FollowScrTransSEndIfEnd

User avatar
Cesar Gomez
 
Posts: 3344
Joined: Thu Aug 02, 2007 11:06 am

Post » Sun May 29, 2011 1:53 am

Ok, we've had a good test with that optimized script abot, and Rex Little is still getting game freezes every time he enters those areas. So the optimized script really didn't make the problem better or worse. It works pretty much the same. He's going to stick some messageboxes in the script and report his findings. I'm relying on him to help with the debugging, because I can't replicate the problem.
User avatar
~Amy~
 
Posts: 3478
Joined: Sat Aug 12, 2006 5:38 am

Post » Sat May 28, 2011 7:05 pm

I have a new guess about what might be happening. The FollowScrTransS script is started by another script which, as far as I can tell, runs whenever the companion is active (either following or waiting, but not back in his/her lair). This script starts FollowScrTransS whenever it is not already running and the PC is in one of the tested locations (Council Chamber, Mournhold reception area or propylon chamber). So, if FollowScrTransS stops itself while the PC is in one of these locations, the other script will immediately start it again.

I'm thinking that maybe starting a script too quickly after stopping it might have the potential to confuse the scripting engine and send it into an infinite loop. I won't have the chance to look further into this until tonight, but meanwhile, if anyone sees this post who is familiar with the inner workings of the scripting engine (a Bethesda developer perhaps?), maybe you can tell us if my idea makes sense.

If this is indeed the problem, we can do one of two things (just off the top of my head; there may be other workarounds):
1. Define a global timer which starts whenever FollowScrTransS is stopped. The calling script is not allowed to start it again until the timer expires.
2. Don't stop FollowScrTransS if the PC is in one of the tested locations. Just use Return.
User avatar
Ysabelle
 
Posts: 3413
Joined: Sat Jul 08, 2006 5:58 pm

Post » Sat May 28, 2011 5:46 pm

Looks like I was right--putting in a timer which forces a one-second wait before restarting the FollowScrTransS script fixed the freeze.

Actually, the original script writer had such a timer implemented, so he must have been aware of the potential problem. Trouble is, he didn't initialize it correctly in some situations, which means it doesn't generate any delay. All I had to do was fix the initialization.
User avatar
adame
 
Posts: 3454
Joined: Wed Aug 29, 2007 2:57 am

Post » Sun May 29, 2011 12:40 am

Thanks for all your detective work Rex. My tests have gone well using the fixed scripts you sent me. So it was a timing problem, but not with the script itself, but the calling script.
User avatar
Jodie Bardgett
 
Posts: 3491
Joined: Sat Jul 29, 2006 9:38 pm


Return to III - Morrowind