Talk:Reference Variables

From the Oblivion ConstructionSet Wiki
Jump to navigation Jump to search

Update: Terminology Discussion[edit source]

This article needs to be updated to reflect the changes decided in the Terminology Discussion. First of all, it should be moved to Record Variables, and then the difference and reasons should be explained. I will probably do this myself, but I cannot at this moment, so I'm just leaving a note.
Dragoon Wraith TALK 21:04, 27 January 2008 (EST)

Can you link to the article you are referencing? I tried searching for it so I could study up on any decisions, but all I found was Community_Portal/Terminology_Discussion, which points to another page on another site... is that the page you mean? Thanks, -Laisren 01:11, 25 March 2008 (EDT)
That would be the one. Also, please use : to indent for replies - see Welcome_to_the_Wiki#Talk Pages.--Haama 03:03, 25 March 2008 (EDT)

Haama, I noticed you said you were going to update this - how up to that do you feel? I can't remember the original discussion too clearly, so I don't even know if you were there - but I've been meaning to do this for a long while, so if you would like me to instead, let me know.
Dragoon Wraith TALK 06:02, 25 March 2008 (EDT)

Let me give it another (50th) shot a bit later today. I think I'll leave it on a test page - as I've said before it will probably require collaboration to get it right.--Haama 11:55, 25 March 2008 (EDT)
OK, I've started on it and got the history and reasons bit down pretty well I think. I'm not sure how to include the basics of using the variable, though - Looking at the Variables category the set up doesn't make the most sense, so I've left some comments over there.--Haama 15:09, 25 March 2008 (EDT)
Also, should we create a Record Variable page and redirect? Would that create two pages in the Variables category?

Technical Workings of Ref Variables?[edit source]

How are reference variables stored internally. I'm having issues reliably accessing my reference variables when there get to be more than 16 user created ones in a cell. I get correct behaviour sometimes but not all the time. I can provide an ESP and simple instructions to replicate the problem. It is possible it is my code however which is why I would like to try and eliminate as many issues as possible, since you certainly don't have time to be debugging my scripts.

On further testing, I see that the same code works perfectly sometimes and not others. Is it possible to hit race conditions in scripts? I assumed they would be linearly processed with no interruption. If that's not the case, then the errors I am getting virtually require that the references I have stored are variable and not fixed as I would expect. Almost nothing else describes this behavior. --Tegid 00:16, 24 April 2006 (EDT)

I'm not sure what you mean by "race conditions in scripts". Script processing is threaded, however, so several scripts can be processed simulataneously, if that's what you're referring to. --Kkuhlmann 08:02, 25 April 2006 (EDT)

That's what I mean. So two scripts can be running simultaneously both of them operate on the same persistent data, we can have data races. Do you run blocks of scripts together (ie, do you split the scripts into separate threads on groups of 16 scripts (or 32)) I ask that because things work correctly, reliably with 16 new objects, but with 18 (I create two at a time) things stop working reliably (they more reliably fail to work). --Tegid 09:16, 25 April 2006 (EDT)

Unnecessary Caveats[edit source]

CAVEAT: Objects created by leveled lists do not process in low, if you set a reference variable from a leveled list, if your script tries to refer to that reference variable when that actor isn't loaded, bad things will happen. So don't ever do a "set myRefVariable to myXmarker.placeAtMe myLeveledList". Instead create an if-then section in a script which checks the player level, pick an appropriate base object for the players level, then do a "set myRefVariable to myXmarker.placeAtMe SpecificBaseObjectID".--Jduvall

This happens when you try to refer non-persistent objects or those that can be put in a container, not a specific problem with reference variables or leveled lists.--JOG 17:19, 24 May 2006 (EDT)


CAVEAT 2: You can not pass reference variables IN OTHER SCRIPTS as parameters to functions that take references. You must first set a local reference variable. For example: "myCharacterRef.look MyQuestScript.myReferenceVariable" will fail whereas "myCharacterRef.look myReferenceVariableDeclaredInThisScript" will work just fine. So in the local script just declare a "ref myReferenceVariableDeclaredInThisScript" and then set it to the external one "set myReferenceVariableDeclaredInThisScript to MyQuestScript.myReferenceVariable", and use the local one.--Jduvall

You can't use ANY variables this way.--JOG 17:19, 24 May 2006 (EDT)

Persistence?[edit source]

Looking at this description from the article:

Keep in mind, that References to non-persistent objects aren't accessible when the object is not in memory (i.e. in another cell) The same applies to inventory items that are currently within a container. Trying to access a non-accessible reference might have no effect at all, but it's equally probable that it will crash the game. While there are safeguards in the CS to prevent you from accessing such references directly, you can bypass them by using reference-variables.

...If I'm understanding that right, a variable that stores a reference to a non-persistent object (such as one created via placeAtMe) is valid as long as the cell is loaded, even after the cell has been reset or a savegame is loaded? Scruggs 00:23, 20 July 2006 (EDT)

Yes, persistent means they're accessible by scripts from wherever they are (i.e. the references are always loaded into memory) non-persistent means they're just accessible when the cell is loaded.--JOG 10:22, 20 July 2006 (EDT)
Thanks. Scruggs 10:45, 20 July 2006 (EDT)

Quest as Function Reference?[edit source]

Dragoon Wraith TALK 11:51, 14 August 2006 (EDT): JOG, you just added this: "Uninitialized reference variables act as if they referred to the scripted object or quest itself" - what do you mean? What functions can take a quest as the calling object?

All of them, of course there usually is no effect.
If Getquestrunning ReferenceVariable
Works fine for example
set MyReference.variable to 1
Can be used to set a variable in a quest.
You can also set Reference-Variables to Base Objects and cells and use them as placeholder for the EditorIDs in the appropriate commands:
If GetIncell Referencevariable
Ref Currentammo
Set Currentamo to Arrow1Iron
Player additem Currentammo 1

--JOG 13:10, 14 August 2006 (EDT)

Dragoon Wraith TALK 23:21, 14 August 2006 (EDT): That's cool, good to know, thanks JOG!


Save a reference in a quest with Getself?[edit source]

I'm trying to save a reference in a quest with this script on an item:

Begin onactivate
 set quest.reference to getself
end

but it dosen't seem to work. Anyone knows a way to do it in another way? --Vswe 09:45, 19 August 2008 (EDT)

What sort of item and where are you trying to get the reference? References do not work on carryable items if they are in inventory (i.e., on an actor or in a container).--dev_akm 10:53, 19 August 2008 (EDT)
when i had this problem it turned out i had started my quest ID with a number. putting quotes around the quest ID seemed to fix the problem, but it would be better to not use numbers at the start of quest IDs or any editor IDs for that matter since it might cause other problems as well. It's definitely recommended against. --Bruneauinfo 12:40, 30 December 2010 (EST)

Isolation?[edit source]

How it is possible for scripts to declare and use a reference that is set in a separate script? Let me give you some context. In a mod that I am working on I have a better (yes, how we all love to outdo Bethesda) version of The Saviour of Bruma Statue. Mine can be updated and removed at will etc. Please note that I am not altering the Bruma Statue but merely have a similar in my abode.

My dilemna is that I have only been able to get the effectshader I am playing on the Statue to run in GameMode blocks. I wish to have be able to use something a little more comprehensive like an OnLoad block the challenge is having a reference that an OnLoad block can use. I anticipate that a seperate script will be required for this. The game would be forced to run this block on my statue without fail due to the way I am adding it to the game.

The Proof, If you look at the scripts that handle The Saviour of Bruma Statue you can see that the creation of the statue is handled in one script (MartinScript) and other finer points by another (MQ14StatueScript). In MartinScript the statue is assigned the reference variable of playerstatue. This reference is used in the MQ14StatueScript. I was under the impression that such reference's were isolated to the script in which they are set and declared. Despite the already cluttered nature of this page I will post the relevant parts of the aforementioned scripts below.

MartinScript

ScriptName MartinScript

ref playerStatue
short scriptKill			; set to 1 if a script killed Martin, for debugging problems

begin OnLoad
	if getstage MQ14 >= 50 && MQ14.createStatue == 0
		set MQ14.createStatue to 1
		MQ14PlayerStatueMarker.enable
		set playerStatue to player.CreateFullActorCopy
		playerStatue.removeItem torch02 1000	; make sure the statue doesn't have a torch
		playerStatue.addscriptpackage MQStatuePose
		playerStatue.moveto MQ14PlayerStatueMarker
		playerStatue.setalert 1
		playerStatue.setghost 1
		playerStatue.setunconscious 1
		playerStatue.setdestroyed 1		; so you can't activate player
		playerStatue.setscale 1.8
		playerStatue.setav speed 0		; so you can't move it around

	endif

end

MQ14StatueScript

scn MQ14StatueScript

short statueYear
ref playerStatue
short distancecheck

begin OnLoad  ;for playing an effectShader this is more comprehensive than a GameMode Block
	if playerStatue == 0
		set playerStatue to MartinRef.playerStatue ;!!!!!!HOW!!!!!!
	endif
	if playerStatue != 0
		playerStatue.moveto MQ14PlayerStatueMarker
		playerStatue.addscriptpackage MQStatuePose	; shouldn't be necessary but oh well
		set statueYear to MQ14.victoryYear
		playerStatue.pms effectstone
		playerStatue.pickidle
	endif
end

The winning bit of code seems to be this line:

set playerStatue to MartinRef.playerStatue

It seems to me that the above line uses a reference from the other script. Ideas anyone, how is this achieved?
--Antares 08:31, 8 September 2008 (EDT)

I'm confused. You are familiar with the dot construction for referencing the local variables of other objects, yes? Actually... This is one of those things that is really basic and therefore poorly elucidated on the Wiki. See here for what I am talking about. That should (I think) answer your question.
The short answer is, though, that this is just how it works. You can use the variable from another object (as long as it is in memory, so it has to be a quest or a persistent reference) by using quest.variable or persistent_reference.variable. This includes reference variables.
The important point is that you cannot do something like quest.ref_variable.function, you need to do something more like set local_ref to quest.ref_variable / local_ref.function. This does introduce some frustrating limitations, unfortunately.
Dragoon Wraith TALK 11:26, 8 September 2008 (EDT)
Thanks DragoonWraith, no I wasn't familiar with the dot construction.... Your explanation and the link in cooperation have provided a good answer though. In my case I don't think any limitations will be a problem as I am simply recreating a more robust version of something that is already perfectly functional by Bethesda in-game. Had I read the UseReference page without your explanation I doubt I would have found it very helpful. I think some more information should be added to articles both here and there.
--Antares 22:26, 8 September 2008 (EDT)


Problem with object references?[edit source]

I have a problem with the use of reference variables. To me, it seems that the references can be used in script with any function, but I'm unable to access variables on these references. That means, while

ref refVAR

set refVAR to anyReference
refVAR.activate
refVAR.pms effectShield
refVAR.setDestroyed
;and so on

works as expected,

ref refVAR

set refVAR to anyReference
set refVAR.anyVariableStoredInTheReferencesScript to x

does not even compile and neither does

ref refVAR
short anyVariable

set refVAR to anyReference
set anyVariable to refVAR.anyVariableStoredInTheReferencesScript

I always get a message of an "unknown variable" and a missed parameter. It's not the message itself, which I don't understand, but the reason for that behaviour, especially since

set anyReference.anyVariableStoredInTheReferencesScript to x

compiles at least.-Diarrhoe 12:44, 14 November 2010 (EST)

The reason is that the compiler does not know which reference might be stored in the ref var at run time, therefore it cannot determine the script attached to that reference in order to check if there is a var with that name.
To access vars in other scripts, you must explicitly refer to the reference or quest by its EditorID: MartinRef.playerStatue or Arena.Timer QQuix 13:19, 15 November 2010 (EST)
Ah thanks. I thought of that possibility as well but I was hoping I just did some mistakes in my scripting method. A pity, since this would provide the opportunity to keeping the script short by guaranteeing the singularity of the reference at the same time.
Diarrhoe 13:57, 15 November 2010 (EST)