Best Practices (Papyrus)

Post » Mon Nov 19, 2012 6:27 am

Yeah, I hear you. Best practices will do no good unless they're made accessible, though, you're absolutely right there. At the moment the order of the points made in the OP is just based on the order in which they were thought of/brought up.

I guess the most important things to do when it comes to making this accessible are to...
  • ...make the information available in the appropriate places (e.g. the http://www.creationkit.com/GetPlayer_-_Game documentation should have a note linking to the best practice on only getting this value once per script).
  • ...provide solutions. So, for example, the best practices documentation should not only note that Game.GetPlayer() shouldn't be used repeatedly but it should also show how a script can be changed to use the standard best practice instead.
Listing the best practices in approximate order of important also comes to mind, since some are obviously more important than others (e.g. avoiding Game.GetPlayer() will have a much bigger impact than remembering to use literals of the correct type).

I think it's probably best to keep them all on the same page on the wiki, but I can also see how putting each standard on its own page and creating a "Best Practices" category might also be a useful approach - does anyone else have any thoughts on this?

I feel like this is getting pretty close to the point where it'll be useful to have on the wiki, so it might go up soon. Is there anything else I've forgotten about that'll be important for making these standards accessible? I admit that I sometimes find it difficult to imagine things from the perspective of an inexperienced scripter.

Cipscis
That's my thought. How do you stick this advice in front of the people who could use it most, at the point they need it most?

If you look at the Bendo tutorial, even it - in its later stages - goes back and corrects methods it has previously taught. So some way of writing/publish such a Best Practice Guide needs to be (carefully) inserted into the existing info/help that newer modders are (probably) working their way through.

Maybe an inclusion in the Wiki "Tutorial Menu" will be enough? Will it get read if it is part of the framework already in place to teach people how to get started (and how many do Bendo, anyway?)? Also, would some form of Video-Tutorial (linked from the Sticky) be worthwhile (a bit like AVs "Voice Acting Social" demo that he posted a few days ago?). People love their visual-demonstrations ...


Anyway, this is a great initiative, so hopefully it can be worked out in the most beneficial way for all the community.
User avatar
Brian LeHury
 
Posts: 3416
Joined: Tue May 22, 2007 6:54 am

Post » Mon Nov 19, 2012 4:38 am

hopefully it can be worked out in the most beneficial way for all the community.
Yeah, that's exactly why I didn't want this to be something that I wrote up in private. I want this to be owned by the community, and I think that's the best way to get both the best standards and the best adoption of those standards.

I'd planned on linking to a page detailing these best practices from the index of the http://www.creationkit.com/Category:Papyrus page (which is available from the main navigation as "Scripting Reference"), probably somewhere under "Papyrus Concepts" as well as adding a link in the actual text of the page somewhere.

Going through the existing Papyrus tutorials on the wiki to make sure they follow these standards is a great idea. The same should be done for the examples on the http://www.creationkit.com/Complete_Example_Scripts and other pages.

A tutorial for converting existing scripts to comply with best practices would probably be helpful too. I wonder if there are any vanilla scripts that would be good candidates for this (as everyone with the Creation Kit already has access to those), or perhaps a few vanilla scripts that each fail to follow one standard or another.

I've never really had anything to do with video tutorials myself, and I'll admit I find written tutorials more helpful (which is part of why that's generally what I produce) but, having said that, I won't deny the use of video tutorials to others. I wonder if anyone with experience (or just enthusiasm for) producing video tutorials would be interested in putting something together?

Cipscis
User avatar
Jonathan Montero
 
Posts: 3487
Joined: Tue Aug 14, 2007 3:22 am

Post » Mon Nov 19, 2012 12:21 am


...

Going through the existing Papyrus tutorials on the wiki to make sure they follow these standards is a great idea. The same should be done for the examples on the http://www.creationkit.com/Complete_Example_Scripts and other pages.
...

Now this is work ... but ...

You know some of the tutorials have the small and bordered/shaded "info box" where a little more detail is given about a particular thing already mentioned - Like this: http://www.creationkit.com/Bethesda_Tutorial_Basic_Quest_Scripting#Scripting_the_Amulet (read down to the example script and right at the bottom for an example "box")

An Info-Box, under that script, detailing the Best-Practice Change might do more good than anything? (I should note: Actually rewriting the example script to USE best practice might be an even better idea?)

But this ^^^^^^ is really going to mean getting the buy-in of all of the wiki authors who can amend their "stuff" on the wiki where it conflicts with agreed Best Practice (and agreement, I think, is probably the point of this topic?)
User avatar
Bigze Stacks
 
Posts: 3309
Joined: Sun May 20, 2007 5:07 pm

Post » Sun Nov 18, 2012 6:42 pm

Some general optimization tips - some are just general programming techniques that work for any language, but a couple are Papyrus-specific.
  • Always measure. Don't spend an hour optimizing a function that's only called once. Find and optimize the slow function that's called 100 times. The Papyrus profiling functions can help you here.
  • A good algorithm will speed things up more than a million little optimizations. In other words, don't hurt yourself trying to optimize each line of a bubble sort when you could just use a quicksort and end up with something much faster.
  • The fastest code is code that doesn't run. Which can be extended to coding your if statements well so they short-circuit in the common case, or making sure the common case is at the top of an if/elseif/else chain.
  • If you can, calculate everything before doing something visible to the user. This can make things appear smoother to the user then, say, calculate - enable - calculate - move - calculate - activate.
  • (Papyrus specific) Native functions, in general, have to sync up to the framerate. So in some rare cases, doing things purely in script may be faster (this is partially why array access is faster then formlist access). Native functions that are the exception to this general rule are on the http://www.creationkit.com/Category:Non-delayed_Native_Function - but again, always test and measure.
  • (Papyrus specific) Take advantage of threading, if you can. An easy way to do this would be to set up an activate parent on several hidden objects, and script each of those hidden objects to do a task in OnActivate. Then your controller script activates the activate parent and Papyrus will run each of those child object's OnActivate blocks in parallel, resulting in a faster/smoother result. Of course, if all of them fight over the same object (like a single quest) you might cause bottle-necking, eliminating the advantage, so test and measure :)
User avatar
Curveballs On Phoenix
 
Posts: 3365
Joined: Sun Jul 01, 2007 4:43 am

Post » Sun Nov 18, 2012 8:59 pm

Some general optimization tips - some are just general programming techniques that work for any language, but a couple are Papyrus-specific.
Many thanks :). Any other pearls of wisdom are gratefully received :D!
User avatar
scorpion972
 
Posts: 3515
Joined: Fri Mar 16, 2007 11:20 am

Post » Mon Nov 19, 2012 5:04 am

So anyway ... I was thinking last night.

Really, what "we" should do, is rewrite the Bendo quest (as in actually recreate the ESP) using "Best Practice" rather than "easiest way to get it done".

Once it is all rewritten and perfick, change the Bendo Tutorial (wiki articles) to reflect Bendo v2 code/techniques

But "we" are all pretty busy, so I won't be insisting "we" do this next week :wink:




(and more much-thanks to the GoldName for his/her input to this topic :smile:)
User avatar
Lil'.KiiDD
 
Posts: 3566
Joined: Mon Nov 26, 2007 11:41 am

Post » Mon Nov 19, 2012 4:09 am

All functions that could be global* should be global, and all others should not.

Just out of curiosity, is it possible to make global variables or properties? I keep thinking there must be, but I can't find any examples in the beth scripts and it's an awkward term to search for on the wiki.

It just seems odd to have global functions and not allow similarly scoped variables.
User avatar
Skivs
 
Posts: 3550
Joined: Sat Dec 01, 2007 10:06 pm

Post » Mon Nov 19, 2012 3:24 am

@SmkViper:
Thanks for joining us, those are some great tips :)

In particular, the comment about using activate parents to essentially split a single thread into many could be just the solution Verteiron needs to get his mod working the way he intends.

@h4vent:
I agree, although hopefully not too much will need to be changed to bring the tutorial in line with what's considered best practice. The biggest task sounds like it'll be updating the files. I think the permissions on the wiki might restrict that task to a "sheriff" like myself.

@DocClox:
Global functions essentially belong to a type instead of a particular object. Because regular properties and variables belong to a specific object (an instance of a type as opposed to the type itself), global functions don't have access to them. Instead, global functions only have access to local variables, which are subject to function scope and therefore can't be used to create global properties in the same scope as global functions.

What we do have, though, is GlobalVariable objects. They don't belong to a particular type like global functions (which, by the way, are called "Static" functions in Papyrus assembly, the language read by the game itself - only the compiler calls them "global") but, being non-reference objects, they essentially do belong to a global namespace. Of course an important distinction to make here is that, unlike global functions and other purely scripting things, GlobalVariable objects exist within data files, and therefore must be accessed through a property interface.

Cipscis
User avatar
Anna Krzyzanowska
 
Posts: 3330
Joined: Thu Aug 03, 2006 3:08 am

Post » Mon Nov 19, 2012 3:59 am

Global functions essentially belong to a type instead of a particular object. Because regular properties and variables belong to a specific object (an instance of a type as opposed to the type itself), global functions don't have access to them. Instead, global functions only have access to local variables, which are subject to function scope and therefore can't be used to create global properties in the same scope as global functions.

Yeah yeah, I understand that. The global keyword is anologous to declaring a member function as "static" in C++. No associated object, and no way to access the object-scoped members for that reason.

The point I'm making is that C++ (and most other OO languages) allow you to declare class variables and properties as static also. Variables so defined are accessible from static functions which means you can have data shared through all instances of a class while still restricting the scope to the class in question.

I can accept that there are no global properties in papyrus. It just seems like an odd sort of omission in an OO language.

What we do have, though, is GlobalVariable objects.

They don't really help though. For one thing, you can only store numerics. That means if I want to store, say, a discriminator for a dialogue tree I need to remember that 1 maps on to SSG02a Stage 40, 2 -> SSG02 stage 70, 3 -> SSG03/10 and so forth. What I really want to do is store a string or a quest reference.

There's also the problem of how to set a global variable from a global function. Generally you'd use a property, but of course we can't access those from global functions. So we either have to load the reference by form id or else pass it in as a parameter, neither of which seems particularly satisfactory.

global functions (which, by the way, are called "Static" functions in Papyrus assembly, the language read by the game itself - only the compiler calls them "global")

Yeah, that struck me too. I guess someone thought that "global" was more intuitive than "static".

Anyway, this is sidetracking the thread away from Best Practice and into Language Design. That wasn't my intention, so I should probably shut up now.
User avatar
Ashley Clifft
 
Posts: 3468
Joined: Thu Jul 26, 2007 5:56 am

Post » Mon Nov 19, 2012 3:49 am

I guess the closest thing you could do is use a singleton. With only a single instantiation of a class you could effectively treat that instance as the class itself. I often find myself doing this with "controller" quests.

Cipscis
User avatar
Alexis Estrada
 
Posts: 3507
Joined: Tue Aug 29, 2006 6:22 pm

Post » Sun Nov 18, 2012 9:55 pm

These are sort of nonsense examples but, I have a couple questions.

Memory/speed wise, is it better to have a bunch of light functions:
Spoiler
Quest Function GetQuestThis()	Return zzThisQuest as QuestEndFunctionQuest Function GetQuestThat()	Return zzThatQuest as QuestEndFunctionQuest Function GetQuestThose()	Return zzThoseQuest as QuestEndFunction

Or just a few heavier functions:
Spoiler
int iQuestThis = 1int iQuestThat = 2int iQuestThose = 3Quest Function GetQuest(int iQuestEnum)	If (iQuestEnum == iQuestThis)		Return zzThisQuest as Quest	ElseIf (iQuestEnum == iQuestThat)		Return zzThatQuest as Quest	ElseIf (iQuestEnum == iQuestThose)		Return zzThoseQuest as Quest	EndIf		Return NoneEndFunction

--

And if you need to access another script, is it better to do it in the scope of the function:
Spoiler
Event OnCellAttach()	zzSomethingScript Something = SomethingObj as zzSomethingScript		Something.DoStuff()EndEventEvent OnTriggerEnter(ObjectReference akActionRef)	zzSomethingScript Something = SomethingObj as zzSomethingScript			Something.DoMoreStuff(akActionRef)EndEvent

Or is there some downside to making it "global" to all functions:
Spoiler
zzSomethingScript Somethingbool bInit = FalseEvent OnCellAttach()	If (!bInit)		Something = SomethingObj as zzSomethingScript		bInit = True	EndIf		Something.DoStuff()EndEventEvent OnTriggerEnter(ObjectReference akActionRef)	Something.DoMoreStuff(akActionRef)EndEvent

Would the first basically be "lighter" because the include is gone when it exits scope or is it basically the same?
User avatar
I’m my own
 
Posts: 3344
Joined: Tue Oct 10, 2006 2:55 am

Post » Sun Nov 18, 2012 6:31 pm

These are sort of nonsense examples but, I have a couple questions.

Memory/speed wise, is it better to have a bunch of light functions:
Spoiler
Quest Function GetQuestThis()	Return zzThisQuest as QuestEndFunctionQuest Function GetQuestThat()	Return zzThatQuest as QuestEndFunctionQuest Function GetQuestThose()	Return zzThoseQuest as QuestEndFunction

Or just a few heavier functions:
Spoiler
int iQuestThis = 1int iQuestThat = 2int iQuestThose = 3Quest Function GetQuest(int iQuestEnum)	If (iQuestEnum == iQuestThis)		Return zzThisQuest as Quest	ElseIf (iQuestEnum == iQuestThat)		Return zzThatQuest as Quest	ElseIf (iQuestEnum == iQuestThose)		Return zzThoseQuest as Quest	EndIf		Return NoneEndFunction
The first one will be much more readable, and as you'll have exactly the same number of function calls (call 3 different functions instead of 1 function 3 times) will run as near the same speed as makes no difference. If you're always going to do all three calls then returning the three values in an array from 1 call would be faster, but the loss of readability means that would only make sense if you're doing this very frequently - if you're doing it a few times a second or less often then I'd say go for the three functions.

As for memory - how many bytes of pseudocode do you think that'll compile to? Compared to how many Megabytes of memory Skyrim uses just for data? You're not coding for a Raspberry Pi here :D!
And if you need to access another script, is it better to do it in the scope of the function:
Spoiler
Event OnCellAttach()	zzSomethingScript Something = SomethingObj as zzSomethingScript		Something.DoStuff()EndEventEvent OnTriggerEnter(ObjectReference akActionRef)	zzSomethingScript Something = SomethingObj as zzSomethingScript			Something.DoMoreStuff(akActionRef)EndEvent

Or is there some downside to making it "global" to all functions:
Spoiler
zzSomethingScript Somethingbool bInit = FalseEvent OnCellAttach()	If (!bInit)		Something = SomethingObj as zzSomethingScript		bInit = True	EndIf		Something.DoStuff()EndEventEvent OnTriggerEnter(ObjectReference akActionRef)	Something.DoMoreStuff(akActionRef)EndEvent

Would the first basically be "lighter" because the include is gone when it exits scope or is it basically the same?
Global to all functions will definitely be faster, and if the initialised value is something you'll use a lot then it's a very good idea. But if at all possible pull the initialisation into an InitialiseSomething function, and lose the binit variable - in your particular example it just slows up the OnCellAttach to no purpose, clutters things up, and will cause a script error (or worse) if somewhere in your code you try to use Something before the OnCellAttach.

True, that was a quick fake example, but good coding practice is good coding practice, and uninitialised variables still haunt my dreams at times :(. The big advantage of doing things the slow way is you reduce the risk of having Something being uninitialised. Whether that matters depends a lot on how big your scripting project will be and how long you'll be maintaining and altering it. Bigger and older means messier and more chance of mistakes that will be a nightmare to anolyse and fix.
User avatar
JUan Martinez
 
Posts: 3552
Joined: Tue Oct 16, 2007 7:12 am

Post » Mon Nov 19, 2012 5:14 am

I don't really have much to add to what andyw has said, but just wanted to chime in with my agreement.

In general, fewer function calls means more efficient code. However, efficiency isn't everything, and sometimes readability has to take priority. Generally the question to ask is "would making this an inline function harm the readability of my code?". If it would, don't do it, otherwise go for it.

If you want to minimise function calls, then you'll want to avoid shorthand functions such as http://www.creationkit.com/GetActorBase_-_Actor, which is shorthand for http://www.creationkit.com/GetBaseObject_-_ObjectReference with an added cast to http://www.creationkit.com/ActorBase_Script. You'll likely only call functions like that a few times though, so the difference will be tiny.

If multiple functions in your script need to access a value, then make it available to all of them. Memory really shouldn't be a worry here. If it helps convince you, know that the compiler creates a bunch of extra "temp" local variables for each function that are used to store the results of each operation. For example:
foo = (2*bar) + 1
In this example, a temporary variable (usually named something like ::temp0 will first store the result of (2*bar)), then another will be used to store the result of what is now ::temp0 + 1, then finally the value in ::temp1 will be assigned to foo.

Interestingly enough, assignments like this can usually be slightly optimising by cutting out the middleman, so to speak, by editing the assembly directly. In the above example, that would mean assigning the result of ::temp0 + 1 directly to foo instead of using ::temp1 as unnecessary temporary storage. There are a few systematic ways in which assembly can be slightly optimised like this.

The compiler has an "-op" command line argument that does some slight optimisation, but as far as I've been able to tell that only affects things like this:
foo = 3 * 12 ; Is optimised to...foo = 36

Cipscis
User avatar
Suzie Dalziel
 
Posts: 3443
Joined: Thu Jun 15, 2006 8:19 pm

Post » Mon Nov 19, 2012 12:31 am

Thanks for the input.

Global to all functions will definitely be faster, and if the initialised value is something you'll use a lot then it's a very good idea. But if at all possible pull the initialisation into an InitialiseSomething function, and lose the binit variable - in your particular example it just slows up the OnCellAttach to no purpose, clutters things up, and will cause a script error (or worse) if somewhere in your code you try to use Something before the OnCellAttach.

I'm not sure how else to init it. Wouldn't there have to be a bool somewhere at least to ensure that bit of code doesn't run again. I get what your saying, but I'm not sure how to implement it.

Spoiler
zzSomethingScript Somethingbool bInit = FalseEvent OnInit()		If (!bInit)				Something = SomethingObj as zzSomethingScript				bInit = True		EndIfEndEventEvent OnCellAttach()		Something.DoStuff()EndEventEvent OnTriggerEnter(ObjectReference akActionRef)		Something.DoMoreStuff(akActionRef)EndEvent
Or do you mean try to init it from another script?

In general, fewer function calls means more efficient code. However, efficiency isn't everything, and sometimes readability has to take priority. Generally the question to ask is "would making this an inline function harm the readability of my code?". If it would, don't do it, otherwise go for it.

If you want to minimise function calls, then you'll want to avoid shorthand functions such as GetActorBase, which is shorthand for GetBaseObject with an added cast to ActorBase. You'll likely only call functions like that a few times though, so the difference will be tiny.

If multiple functions in your script need to access a value, then make it available to all of them. Memory really shouldn't be a worry here. If it helps convince you, know that the compiler creates a bunch of extra "temp" local variables for each function that are used to store the results of each operation. For example:
foo = (2*bar) + 1
In this example, a temporary variable (usually named something like ::temp0 will first store the result of (2*bar)), then another will be used to store the result of what is now ::temp0 + 1, then finally the value in ::temp1 will be assigned to foo.
I think I get it, speed and readability have a much higher priority than memory consumption. Speed taking priority until it becomes difficult to read. Assembly is still over my head, but maybe one day :smile:. I didn't know about the "-op" switch, thanks for that.

Thanks again.
User avatar
Andrea P
 
Posts: 3400
Joined: Mon Feb 12, 2007 7:45 am

Post » Mon Nov 19, 2012 9:33 am

I'm not sure how else to init it. Wouldn't there have to be a bool somewhere at least to ensure that bit of code doesn't run again. I get what your saying, but I'm not sure how to implement it.

Spoiler
zzSomethingScript Somethingbool bInit = FalseEvent OnInit()		If (!bInit)				Something = SomethingObj as zzSomethingScript				bInit = True		EndIfEndEventEvent OnCellAttach()		Something.DoStuff()EndEventEvent OnTriggerEnter(ObjectReference akActionRef)		Something.DoMoreStuff(akActionRef)EndEvent
Or do you mean try to init it from another script?
Ok, I think I may have misunderstood where you were coming from (or going to). It might clarify if you spelt out what SomethingObj is and how it's initialised, and what is the context for this script fragment - just so I don't go off chasing imaginary wild geese while barking up the wrong virtual tree (if you see what I mean :)).
User avatar
Portions
 
Posts: 3499
Joined: Thu Jun 14, 2007 1:47 am

Post » Mon Nov 19, 2012 8:19 am

Np :smile:

I guess I'm thinking something like this (not set in stone, still tossing it around):

Spoiler
Scriptname ConfigQuestScript extends Questbool Property bBirdsEnabled = True Auto

Scriptname GlobalQuestScript extends QuestQuest Property ConfigQuest AutoObjectReference Property PlayerRef AutoGlobalVariable Property ModVersion Auto

Scriptname BirdTriggerScript extends ObjectReferenceQuest Property GlobalQuest AutoSound Property FXAMBBirdTreeLP Autobool bInit = Falsebool bReady = Falseint iBirdSound = 0GlobalQuestScript GlobConfigQuestScript ConfigEvent OnInit()    If (!bInit)        Glob = GlobalQuest as GlobalQuestScript        Config = Glob.ConfigQuest as ConfigQuestScript        bInit = True    EndIfEndEventEvent OnCellAttach()    iBirdSound = FXAMBBirdTreeLP.Play(Self)    bReady = TrueEndEventEvent OnCellDetach()    Sound.StopInstance(iBirdSound)    bReady = FalseEndEventEvent OnTriggerEnter(ObjectReference akActionRef)    If (bReady)        If (akActionRef == Glob.PlayerRef)            If (Config.bBirdsEnabled && Glob.ModVersion.GetValue() > 1.0)                Self.PlayAnimation("PlayAnim01")                Utility.Wait (0.5)                Sound.StopInstance(iBirdSound)                bReady = False            Endif        Endif    EndifEndEvent
Where there are common vars in "GlobalQuest" that many scripts need (IE: so I don't have to add a "ObjectReference Property PlayerRef Auto" to every script) and a "ConfigQuest" which hold vars based on preference (used here and there).

There is already a bird script like this, I'm just using it as an example. I'm thinking of adding something like that so that it can be triggered again after a delay rather than once per cell attach like default. But that basically covers how I was thinking of doing it. I don't really need to check the "ModVersion", just showing how I would if I did have to.

I thought it might be best to initialize them "OnCellAttach" so that if there are quite a few of these (and/or other scripts) so they wouldn't all hammer at once during the "OnInit". But that might not matter as much as I thought. The only other way I can think of in order to scrap the init bool and ensure the vars are initialized would be like this:

Spoiler
Scriptname BirdTriggerScript extends ObjectReferenceQuest Property GlobalQuest AutoSound Property FXAMBBirdTreeLP Autoint iBirdSound = 0Event OnCellAttach()    iBirdSound = FXAMBBirdTreeLP.Play(Self)EndEventEvent OnCellDetach()    Sound.StopInstance(iBirdSound)EndEventEvent OnTriggerEnter(ObjectReference akActionRef)    If (bReady)        GlobalQuestScript Glob = GlobalQuest as GlobalQuestScript        ConfigQuestScript Config = Glob.ConfigQuest as ConfigQuestScript                If (akActionRef == Glob.PlayerRef)            If (Config.bBirdsEnabled && Glob.ModVersion.GetValue() > 1.0)                Self.PlayAnimation("PlayAnim01")                Utility.Wait (0.5)                Sound.StopInstance(iBirdSound)                bReady = False            Endif        Endif    EndIfEndEvent
But there may end up being quite a few functions in one script that need the same vars.

Edit: Corrected a missing endif
User avatar
Brandon Bernardi
 
Posts: 3481
Joined: Tue Sep 25, 2007 9:06 am

Post » Mon Nov 19, 2012 7:12 am

The http://www.creationkit.com/OnInit event is called on your objects right after all of their properties and variables are assigned their initial values, which happens in these cases:
  • When the script is attached to an existing object
  • When an object with the script attached is created
  • After an object is reset
One semi-exception is quests that are both "Start game enabled" and not set to "Run once", as they will have the script attached and then be instantly reset, as quests that can run multiple times are reset whenever they are started, so the OnInit block will run twice consecutively for them at first.

Storing a value like PlayerRef in a remote script isn't as good as having a local PlayerRef property in each script, as accessing a local Auto property is optimised to be as fast as accessing a variable whereas accessing a remote property involves calling a remote script. It seems to me that you're essentially sacrificing speed and readability (e.g. Glob.PlayerRef vs. PlayerRef alone) for no gain.

Global settings, that should be able to be changed once in one place and have that change reflected everywhere, are different. Using a GlobalVariable or a property in a particular Quest are pretty good things to use for such values.

Also note that you can create properties of your own custom types. Remember, each time you define a script, you're defining a new type, and every time you attach a script to an object you are adding the type defined by that script to that object. So, for example, if you were to create an auto Property of type GlobalQuestScript, then the Creation Kit would let you select all objects with that script attached (presumably only the 1 object you're looking for). That way you wouldn't need an extra Quest property and you would be able to initialise it in the Creation Kit itself.

Cipscis
User avatar
Austin England
 
Posts: 3528
Joined: Thu Oct 11, 2007 7:16 pm

Post » Mon Nov 19, 2012 9:55 am

Good to know about the OnInit :smile:

Storing a value like PlayerRef in a remote script isn't as good as having a local PlayerRef property in each script, as accessing a local Auto property is optimised to be as fast as accessing a variable whereas accessing a remote property involves calling a remote script. It seems to me that you're essentially sacrificing speed and readability (e.g. Glob.PlayerRef vs. PlayerRef alone) for no gain.

Ya, it would definitely just be a convenience thing:
* Access to PlayerRef and the rest of the common vars without needing the CK open
* Fewer "oops, I added the property but forgot to fill it in the CK" :dry:
* Ability to change the var in one file rather than finding and replacing in many

Doing it on a trigger might not be the best idea since it can be activated just by walking into it, but like on a switch with a message box, I don't think it would be really noticeable. Calling the "PlayerRef" remotely might not be as fast as locally, but I'm pretty sure it's still a lot faster than "Game.GetPlayer()". For me, "Glob.PlayerRef" is as good/bad readability wise as "Game.GetPlayer()". For others, it may be more difficult, but they're not the ones that are going to have to spend weeks hammering away at them. I guess I'm not to worried about the people who would open it, say "that's easily readable", close it and move on with their lives. :smile:

I'm curious as to how much of a difference it would actually be between calling the "PlayerRef" locally or remotely. If it comes down to like "0.00001" vs "0.00003" for something that isn't constantly running (not doing any OnUpdate's), I think the convenience might outweigh the minor speed loss. If it's a decent speed loss, then it wouldn't be worth it.

Also note that you can create properties of your own custom types. Remember, each time you define a script, you're defining a new type, and every time you attach a script to an object you are adding the type defined by that script to that object. So, for example, if you were to create an auto Property of type GlobalQuestScript, then the Creation Kit would let you select all objects with that script attached (presumably only the 1 object you're looking for). That way you wouldn't need an extra Quest property and you would be able to initialise it in the Creation Kit itself.

I'm not sure I follow that (is there a page on that like http://www.creationkit.com/Variables_and_Properties?). Do you mean attach the the GlobalQuestScript and the ConfigQuestScript to the "BirdTrigger" activator form in that example? And by doing that, I can remove "Quest Property ConfigQuest Auto" from the GlobalQuestScript and just do something like this when it inits?:

Event OnInit()	If (!bInit)		Glob = GlobalQuest as GlobalQuestScript		Config = ConfigQuest as ConfigQuestScript		bInit = True	EndIfEndEvent
IE: No need to reference "Glob" when initializing "Config"?
User avatar
Mélida Brunet
 
Posts: 3440
Joined: Thu Mar 29, 2007 2:45 am

Post » Mon Nov 19, 2012 5:55 am

I'm curious as to how much of a difference it would actually be between calling the "PlayerRef" locally or remotely. If it comes down to like "0.00001" vs "0.00003" for something that isn't constantly running (not doing any OnUpdate's), I think the convenience might outweigh the minor speed loss.
Remote vs. Local property (both Actor properties filled with the player)

Spoiler
  • Raw output
    Spoiler
    [09/19/2012 - 05:19:52AM] Code Comparer log opened (PC)[09/19/2012 - 05:19:52AM] Code Comparer Version: 1.010000[09/19/2012 - 05:19:52AM] Skyrim Version: 1.7.7.0[09/19/2012 - 05:19:53AM] SKSE Version: 1.051100[09/19/2012 - 05:19:58AM] === 'Remote Property' ===[09/19/2012 - 05:19:58AM] Time elapsed (calibration offset) for an empty test: 0.013000[09/19/2012 - 05:19:58AM] Started 'Remote Property' at: 25.091999 | Iterations to complete: 1000[09/19/2012 - 05:19:58AM] Finished 'Remote Property' at: 25.113001 | Iterations completed: 1000[09/19/2012 - 05:19:58AM] Time elapsed (Raw) for 'Remote Property': 0.021002[09/19/2012 - 05:19:58AM] Time elapsed (Calibrated) for 'Remote Property': 0.008001[09/19/2012 - 05:19:58AM] Approximate time for each iteration (Raw): 0.000021[09/19/2012 - 05:19:58AM] Approximate time for each iteration (Calibrated): 0.000008[09/19/2012 - 05:19:59AM] === 'Local Property' ===[09/19/2012 - 05:19:59AM] Time elapsed (calibration offset) for an empty test: 1.198999[09/19/2012 - 05:19:59AM] Started 'Local Property' at: 26.525000 | Iterations to complete: 1000[09/19/2012 - 05:19:59AM] Finished 'Local Property' at: 26.534000 | Iterations completed: 1000[09/19/2012 - 05:19:59AM] Time elapsed (Raw) for 'Local Property': 0.009001[09/19/2012 - 05:19:59AM] Time elapsed (Calibrated) for 'Local Property': 0.000000[09/19/2012 - 05:19:59AM] Approximate time for each iteration (Raw): 0.000009[09/19/2012 - 05:19:59AM] Approximate time for each iteration (Calibrated): 0.000000[09/19/2012 - 05:20:08AM] Log closed
  • Remote Property
    Spoiler
    • Log
      [09/19/2012 - 05:19:58AM] === 'Remote Property' ===[09/19/2012 - 05:19:58AM] Time elapsed (calibration offset) for an empty test: 0.013000[09/19/2012 - 05:19:58AM] Started 'Remote Property' at: 25.091999 | Iterations to complete: 1000[09/19/2012 - 05:19:58AM] Finished 'Remote Property' at: 25.113001 | Iterations completed: 1000[09/19/2012 - 05:19:58AM] Time elapsed (Raw) for 'Remote Property': 0.021002[09/19/2012 - 05:19:58AM] Time elapsed (Calibrated) for 'Remote Property': 0.008001[09/19/2012 - 05:19:58AM] Approximate time for each iteration (Raw): 0.000021[09/19/2012 - 05:19:58AM] Approximate time for each iteration (Calibrated): 0.000008
    • Profiling
      Stack_1148 log opened (PC)12456:START:114812456:POP:1148:4:None:Debug..StartStackProfiling12456:PUSH:1148:4:CodeComparerQUST (02000800):Form..StartObjectProfiling12457:POP:1148:4:CodeComparerQUST (02000800):Form..StartObjectProfiling12457:POP:1148:3:CodeComparerQUST (02000800):codecomparerquestscript..Track12457:PUSH:1148:3:CodeComparerQUST (02000800):Form..GotoState12457:PUSH:1148:4:CodeComparerQUST (02000800):Form..onEndState12457:POP:1148:4:CodeComparerQUST (02000800):Form..onEndState12457:PUSH:1148:4:CodeComparerQUST (02000800):Form..onBeginState12457:POP:1148:4:CodeComparerQUST (02000800):Form..onBeginState12457:POP:1148:3:CodeComparerQUST (02000800):Form..GotoState12457:PUSH:1148:3:CodeComparerQUST (02000800):codecomparerquestscript..test12457:QUEUE_PUSH:1148:4:None:utility.??.GetCurrentRealTime12466:PUSH:1148:4:None:utility..GetCurrentRealTime12466:POP:1148:4:None:utility..GetCurrentRealTime12467:QUEUE_PUSH:1148:4:None:utility.??.GetCurrentRealTime12477:PUSH:1148:4:None:utility..GetCurrentRealTime12477:POP:1148:4:None:utility..GetCurrentRealTime12477:POP:1148:3:CodeComparerQUST (02000800):codecomparerquestscript..test12477:PUSH:1148:3:CodeComparerQUST (02000800):Form..GotoState12477:PUSH:1148:4:CodeComparerQUST (02000800):Form..onEndState12477:POP:1148:4:CodeComparerQUST (02000800):Form..onEndState12477:PUSH:1148:4:CodeComparerQUST (02000800):Form..onBeginState12477:POP:1148:4:CodeComparerQUST (02000800):Form..onBeginState12477:POP:1148:3:CodeComparerQUST (02000800):Form..GotoState12477:PUSH:1148:3:CodeComparerQUST (02000800):codecomparerquestscript.test1.test12477:QUEUE_PUSH:1148:4:None:Debug.??.Notification12487:PUSH:1148:4:None:Debug..Notification12487:POP:1148:4:None:Debug..Notification12487:QUEUE_PUSH:1148:4:None:utility.??.GetCurrentRealTime12497:PUSH:1148:4:None:utility..GetCurrentRealTime12497:POP:1148:4:None:utility..GetCurrentRealTime12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12497:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12498:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12499:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12500:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp...etc...12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12514:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12515:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12516:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12517:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12517:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12517:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12517:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12517:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12517:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12517:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12517:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12517:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12517:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12517:PUSH:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12517:POP:1148:4:alias PlayerAlias on quest CodeComparerQUST (02000800):OtherScript..RemoteProp12517:QUEUE_PUSH:1148:4:None:utility.??.GetCurrentRealTime12517:PUSH:1148:4:None:utility..GetCurrentRealTime12517:POP:1148:4:None:utility..GetCurrentRealTime12518:POP:1148:3:CodeComparerQUST (02000800):codecomparerquestscript.test1.test12518:PUSH:1148:3:None:Debug..TraceUser12518:POP:1148:3:None:Debug..TraceUser12518:PUSH:1148:3:None:Debug..TraceUser12518:POP:1148:3:None:Debug..TraceUser12518:PUSH:1148:3:None:Debug..TraceUser12518:POP:1148:3:None:Debug..TraceUser12518:PUSH:1148:3:None:Debug..TraceUser12518:POP:1148:3:None:Debug..TraceUser12518:PUSH:1148:3:None:Debug..TraceUser12518:POP:1148:3:None:Debug..TraceUser12518:PUSH:1148:3:None:Debug..TraceUser12518:POP:1148:3:None:Debug..TraceUser12518:PUSH:1148:3:None:Debug..TraceUser12518:POP:1148:3:None:Debug..TraceUser12518:PUSH:1148:3:None:Debug..TraceUser12518:POP:1148:3:None:Debug..TraceUser12518:PUSH:1148:3:CodeComparerQUST (02000800):codecomparerquestscript..Track12518:PUSH:1148:4:None:Debug..StopScriptProfiling13911:POP:1148:4:None:Debug..StopScriptProfiling13911:PUSH:1148:4:None:Debug..StopStackProfiling13911:DONE:1148Log closed
  • Local Property ★
    Spoiler
    • Log
      [09/19/2012 - 05:19:59AM] === 'Local Property' ===[09/19/2012 - 05:19:59AM] Time elapsed (calibration offset) for an empty test: 1.198999[09/19/2012 - 05:19:59AM] Started 'Local Property' at: 26.525000 | Iterations to complete: 1000[09/19/2012 - 05:19:59AM] Finished 'Local Property' at: 26.534000 | Iterations completed: 1000[09/19/2012 - 05:19:59AM] Time elapsed (Raw) for 'Local Property': 0.009001[09/19/2012 - 05:19:59AM] Time elapsed (Calibrated) for 'Local Property': 0.000000[09/19/2012 - 05:19:59AM] Approximate time for each iteration (Raw): 0.000009[09/19/2012 - 05:19:59AM] Approximate time for each iteration (Calibrated): 0.000000[09/19/2012 - 05:20:08AM] Log closed
    • Profiling
      Stack_1148 log opened (PC)13913:START:114813913:POP:1148:4:None:Debug..StartStackProfiling13913:PUSH:1148:4:CodeComparerQUST (02000800):Form..StartObjectProfiling13914:POP:1148:4:CodeComparerQUST (02000800):Form..StartObjectProfiling13914:POP:1148:3:CodeComparerQUST (02000800):codecomparerquestscript..Track13914:PUSH:1148:3:CodeComparerQUST (02000800):Form..GotoState13914:PUSH:1148:4:CodeComparerQUST (02000800):Form..onEndState13914:POP:1148:4:CodeComparerQUST (02000800):Form..onEndState13914:PUSH:1148:4:CodeComparerQUST (02000800):Form..onBeginState13914:POP:1148:4:CodeComparerQUST (02000800):Form..onBeginState13914:POP:1148:3:CodeComparerQUST (02000800):Form..GotoState13914:PUSH:1148:3:CodeComparerQUST (02000800):codecomparerquestscript..test13914:QUEUE_PUSH:1148:4:None:utility.??.GetCurrentRealTime13914:PUSH:1148:4:None:utility..GetCurrentRealTime13914:POP:1148:4:None:utility..GetCurrentRealTime13915:QUEUE_PUSH:1148:4:None:utility.??.GetCurrentRealTime13918:PUSH:1148:4:None:utility..GetCurrentRealTime13918:POP:1148:4:None:utility..GetCurrentRealTime13918:POP:1148:3:CodeComparerQUST (02000800):codecomparerquestscript..test13918:PUSH:1148:3:CodeComparerQUST (02000800):Form..GotoState13918:PUSH:1148:4:CodeComparerQUST (02000800):Form..onEndState13918:POP:1148:4:CodeComparerQUST (02000800):Form..onEndState13918:PUSH:1148:4:CodeComparerQUST (02000800):Form..onBeginState13918:POP:1148:4:CodeComparerQUST (02000800):Form..onBeginState13918:POP:1148:3:CodeComparerQUST (02000800):Form..GotoState13918:PUSH:1148:3:CodeComparerQUST (02000800):codecomparerquestscript.test0.test13918:QUEUE_PUSH:1148:4:None:Debug.??.Notification13921:PUSH:1148:4:None:Debug..Notification13921:POP:1148:4:None:Debug..Notification13921:QUEUE_PUSH:1148:4:None:utility.??.GetCurrentRealTime13924:PUSH:1148:4:None:utility..GetCurrentRealTime13924:POP:1148:4:None:utility..GetCurrentRealTime13925:QUEUE_PUSH:1148:4:None:utility.??.GetCurrentRealTime13933:PUSH:1148:4:None:utility..GetCurrentRealTime13933:POP:1148:4:None:utility..GetCurrentRealTime13933:POP:1148:3:CodeComparerQUST (02000800):codecomparerquestscript.test0.test13933:PUSH:1148:3:None:Debug..TraceUser13933:POP:1148:3:None:Debug..TraceUser13934:PUSH:1148:3:None:Debug..TraceUser13934:POP:1148:3:None:Debug..TraceUser13934:PUSH:1148:3:None:Debug..TraceUser13934:POP:1148:3:None:Debug..TraceUser13934:PUSH:1148:3:None:Debug..TraceUser13934:POP:1148:3:None:Debug..TraceUser13934:PUSH:1148:3:None:Debug..TraceUser13934:POP:1148:3:None:Debug..TraceUser13934:PUSH:1148:3:None:Debug..TraceUser13934:POP:1148:3:None:Debug..TraceUser13934:PUSH:1148:3:None:Debug..TraceUser13934:POP:1148:3:None:Debug..TraceUser13934:PUSH:1148:3:None:Debug..TraceUser13934:POP:1148:3:None:Debug..TraceUser13934:PUSH:1148:3:CodeComparerQUST (02000800):codecomparerquestscript..Track13934:PUSH:1148:4:None:Debug..StopScriptProfiling13934:POP:1148:4:None:Debug..StopScriptProfiling13934:PUSH:1148:4:None:Debug..StopStackProfiling13934:DONE:1148Log closed

Note: Check out the profiling logs.
User avatar
Louise Andrew
 
Posts: 3333
Joined: Mon Nov 27, 2006 8:01 am

Post » Mon Nov 19, 2012 9:37 am

Thanks JustinOther :smile:

If I have that right, it's: 0.000021 (remote) vs 0.000009 (local) +/- 0.000012 diff per iteration. The log for the remote call is pretty crazy though. Probably not something that should run constantly, but for a switch/door/container/etc. with a message box, that's a really tiny margin. It would only run when in the area added by the mod, not everywhere/all the time.

In the example, I used "ObjectReference Property PlayerRef Auto", which probably should have been "Actor Property PlayerRef Auto"? So "0.000012" would be the cost of only having to edit GlobalScript rather than every script I may have declared player as "ObjectReference". That kind of stuff tends to sway me a bit by appealing to my lazy nature. :wink:

I guess I'm wondering, if I went the remote way, what would be the "Best Practice" for initializing the quest scripts (like in the bird trig example)?
User avatar
Cathrin Hummel
 
Posts: 3399
Joined: Mon Apr 16, 2007 7:16 pm

Post » Sun Nov 18, 2012 9:44 pm

Another important thing to keep in mind with having a PlayerRef property on one single "master" object that's accessed from many other objects is that only one thread can be active in your "master" object at any one time, so if one of your other objects is getting the PlayerRef property in it any other objects trying to do that will have to wait. This will slow down the method more than what you could see in this test, which never tried to access it simultaneously from multiple places.

To be honest, instead of seeing it as a difference of 0.000012 I'd be inclined to see it as the remote method taking about 2.3 times as long as a local property at best.

If you feel you really must access the value of PlayerRef from your "master" object, you could retrieve it in each of your other objects' OnInit events, but remember you need to fill properties in the Creation Kit anyway in order to access your "master" object so there shouldn't be any harm in doing it for PlayerRef as well if you just do "Auto-fill All".
Actor PlayerRefGlobalQuestScript Property GlobalQuest AutoEvent OnInit()	PlayerRef = GlobalQuest.PlayerRefEndEvent

I'm not sure I follow that (is there a page on that like http://www.creationkit.com/Variables_and_Properties?). Do you mean attach the the GlobalQuestScript and the ConfigQuestScript to the "BirdTrigger" activator form in that example? And by doing that, I can remove "Quest Property ConfigQuest Auto" from the GlobalQuestScript and just do something like this when it inits?:

Event OnInit()	If (!bInit)		Glob = GlobalQuest as GlobalQuestScript		Config = ConfigQuest as ConfigQuestScript		bInit = True	EndIfEndEvent
IE: No need to reference "Glob" when initializing "Config"?
What I mean is that you can treat GlobalQuestScript as just another type, like Quest, when declaring variables and properties. When filling a property using a custom type in the Creation Kit, only objects with that script attached will be shown in the list. See the snippet I posted just above as an example of what I mean - I've declared a property of type GlobalQuestScript. Its value would be set in the Creation Kit, and you would no longer require a line like this in your script in order to access your object as the correct type:
Glob = GlobalQuest as GlobalQuestScript

If you used an ObjectReference property for the player, I don't think it could be filled via the Creation Kit, but if you were to assign the correct value to it in an OnInit event or something then every time you want to call a function in the http://www.creationkit.com/Actor_Script on the player you'd have to cast it to Actor, and every time you passed the value to a function as an argument that expects to be of type Actor, the compiler will automatically cast it to Actor, which will make your script slightly slower each time this has to happen.

Cipscis
User avatar
Kit Marsden
 
Posts: 3467
Joined: Thu Jul 19, 2007 2:19 pm

Post » Sun Nov 18, 2012 8:50 pm

Another important thing to keep in mind with having a PlayerRef property on one single "master" object that's accessed from many other objects is that only one thread can be active in your "master" object at any one time, so if one of your other objects is getting the PlayerRef property in it any other objects trying to do that will have to wait. This will slow down the method more than what you could see in this test, which never tried to access it simultaneously from multiple places.

To be honest, instead of seeing it as a difference of 0.000012 I'd be inclined to see it as the remote method taking about 2.3 times as long as a local property at best.

Oohh, I hadn't considered that. Kind of defeats the threading. Well dang, it looked so good on paper. :confused:

I get what your saying, I was just thinking that if there's no downside besides a tiny speed loss for things that only happen here and there, it would be much easier. Having a bunch of scripts waiting around definitely isn't worth it though.

If you feel you really must access the value of PlayerRef from your "master" object, you could retrieve it in each of your other objects' OnInit events, but remember you need to fill properties in the Creation Kit anyway in order to access your "master" object so there shouldn't be any harm in doing it for PlayerRef as well if you just do "Auto-fill All".
Actor PlayerRefGlobalQuestScript Property GlobalQuest AutoEvent OnInit()	PlayerRef = GlobalQuest.PlayerRefEndEvent

What I mean is that you can treat GlobalQuestScript as just another type, like Quest, when declaring variables and properties. When filling a property using a custom type in the Creation Kit, only objects with that script attached will be shown in the list. See the snippet I posted just above as an example of what I mean - I've declared a property of type GlobalQuestScript. Its value would be set in the Creation Kit, and you would no longer require a line like this in your script in order to access your object as the correct type:
Glob = GlobalQuest as GlobalQuestScript

If you used an ObjectReference property for the player, I don't think it could be filled via the Creation Kit, but if you were to assign the correct value to it in an OnInit event or something then every time you want to call a function in the http://www.creationkit.com/Actor_Script on the player you'd have to cast it to Actor, and every time you passed the value to a function as an argument that expects to be of type Actor, the compiler will automatically cast it to Actor, which will make your script slightly slower each time this has to happen.

Ah, ok. I guess I was just trying to keep the number of properties needed per script to a minimum. Where I had a single property that I could use to access many others. So like instead of including an XMarker that controls something in many scripts, it could just be in "ConfigQuest", which could be accessed through "GlobalQuest". But really, from what I gather, there should be many properties and only a few places it needs to access other scripts to ensure speed/threading. Leave it to me to have it backwards. But hey, now I know.

Thanks for the info, much appreciated :smile:
User avatar
David Chambers
 
Posts: 3333
Joined: Fri May 18, 2007 4:30 am

Post » Sun Nov 18, 2012 9:09 pm

!!Disregard!! GetDistance works the same on both.

Game.GetForm(0x14)
Game.GetFormFromFile(0x14, "Skyrim.esm")
Game.GetPlayer()
Actor Property PlayerRef Auto ; Auto-filled in Creation Kit

By comparing these snippets, which should all be functionally identical to one another...

I was messing around with http://www.creationkit.com/GetDistance and I think there's a diff between "Game.GetPlayer()" and "PlayerRef" when in an exterior worldspace. With "Game.GetPlayer()", it's always the exact distance no matter which cell the object and player are in. But with "PlayerRef", it seems to return "0" for any object not in the same exterior cell as the player. I'm not sure of any others, but that might be something for the tutorials mentioned that may use "PlayerRef".
User avatar
Jodie Bardgett
 
Posts: 3491
Joined: Sat Jul 29, 2006 9:38 pm

Post » Mon Nov 19, 2012 5:21 am

From the http://www.gamesas.com/topic/1411305-quick-questions-quick-answers-thread-7/page__st__90__gopid__21584288#entry21584288 thread:

With how poorly this new system runs for time sensitive scripting why would they even make such "extra steps"?

The vanilla shield charge is listed on various Skyrim sties as known to give DELAYED results (the actor gets knocked to the ground a little while after the collision) so it is not like they themselves were not effected by script lag. It seems to me they would not have wanted a "convenience" like theses to add the the problem.

Maybe they did just did not know how bad the lag would be in the beginning when this was programmed?

http://www.creationkit.com/GetRef_-_ReferenceAlias is just the tip of the iceberg too. Many other convenience functions also add little to the script but add the extra overhead of an additional function call. They usually save a few keypresses, such as those involved in a longer function name or a cast. Some examples include http://www.creationkit.com/GetActorReference_-_ReferenceAlias, http://www.creationkit.com/GetActorRef_-_ReferenceAlias, http://www.creationkit.com/GetValueInt_-_GlobalVariable, and http://www.creationkit.com/GetActorBase_-_Actor.

GetRef alone is used 1596 times in 351 different vanilla scripts. All of these instances could be replaced with GetReference for no cost yet some gain.

Another problem is the difference between http://www.creationkit.com/GetPlayer_-_Game and either getting the value once and storing it or, even better, using an auto property pointing to the player. This function is used 4515 times in 2039 vanilla scripts. Despite the fact that this value never changes, one script (PlayerWerewolfChangeScript) calls this function 69 times!

Other functions, such as http://www.creationkit.com/GetBaseObject_-_ObjectReference, can also be called only once per script per object yet are often called multiple times per object in both vanilla and mod scripts.

On top of all of this, the output of the compiler can be further improved. I've taken to manipulating my scripts at the assembly level (scripts run through the compiler to convert Papyrus (*.psc files) to http://skyrim.nexusmods.com/mods/24009 (*.pas files), then through the assembler to produce compiled scripts (*.pex files)) at the moment, mainly to familiarise myself with the assembly language.

In a recent script, I was able to remove half of the "temp" local variables created by the compiler, and over a quarter of the instructions. I've also tested some of these optimisations with JustinOther's and my http://skyrim.nexusmods.com/mods/23782 and confirmed that this does make a measurable difference.

I hope to create utility to automate this process of optimising the assembly file so it can be done just as easily as compiling scripts normally. That would allow modders to produce slightly more efficient scripts at no cost to themselves after the initial setup and absolutely no cost to the end user.
Cipscis

EDIT:

I was messing around with http://www.creationkit.com/GetDistance and I think there's a diff between "Game.GetPlayer()" and "PlayerRef" when in an exterior worldspace. With "Game.GetPlayer()", it's always the exact distance no matter which cell the object and player are in. But with "PlayerRef", it seems to return "0" for any object not in the same exterior cell as the player. I'm not sure of any others, but that might be something for the tutorials mentioned that may use "PlayerRef".

Hmm, that seems unlikely to me, as the same object should be returned via either method and if I remember correctly I've compared them in a script to confirm this. Could I ask you to set up a test to compare the two and confirm your findings?

I'd test it myself, but I don't have access to Skyrim or the Creation Kit at the moment. If nothing's been done by the time I can test it myself, though, I'll do that.

Cipscis
User avatar
Lori Joe
 
Posts: 3539
Joined: Tue Jun 20, 2006 6:10 am

Post » Mon Nov 19, 2012 12:06 am

Another problem is the difference between http://www.creationkit.com/GetPlayer_-_Game and either getting the value once and storing it or, even better, using an auto property pointing to the player. This function is used 4515 times in 2039 vanilla scripts. Despite the fact that this value never changes, one script (PlayerWerewolfChangeScript) calls this function 69 times!

Bloody hell, we would almost need an unofficial vanilla script optimisation patch. Its hard to believe that many mistakes were made.

With Papyrus, is it best to have multiple small scripts or fewer longer scripts?
User avatar
Leticia Hernandez
 
Posts: 3426
Joined: Tue Oct 23, 2007 9:46 am

PreviousNext

Return to V - Skyrim