Most efficient way of referencing the Player?

Post » Tue Jun 19, 2012 4:01 am

I've been wondering what the most "optimal" way to reference the player is.

You can use:
Game.GetPlayer()

Actor Player = Game.GetPlayer()

Actor Property Player Auto
Player = Game.GetPlayer()

Which of these would be best? Which of these is a bad idea, if any? I feel like assigning him to a variable would be a good idea so you aren't "calling a method" every time you reference him, so I had set him as an Actor property. However the wiki states that it's not a good idea to set references as properties due to how they never "unload" from the game. But I wonder if that's even an issue since the player is always loaded anyways (right?). Just to be safe maybe I should set it as a normal actor variable?

In my scripts I am constantly referencing the player, and I'd prefer to do so in the most script optimal fashion, but perhaps I'm just over complicating this. Any thoughts?
User avatar
(G-yen)
 
Posts: 3385
Joined: Thu Oct 11, 2007 11:10 pm

Post » Tue Jun 19, 2012 3:59 am

wouldnt it depend on the event that is being run?

Some events can retrun an actor, so if you used the right event so that the return value will only be the player, you need not use any function at all to get the player.
User avatar
celebrity
 
Posts: 3522
Joined: Mon Jul 02, 2007 12:53 pm

Post » Tue Jun 19, 2012 2:00 pm

wouldnt it depend on the event that is being run?

Some events can retrun an actor, so if you used the right event so that the return value will only be the player, you need not use any function at all to get the player.
I'm not speaking of events. I'm speaking of functions. Functions that do certain things, and they do these things to the player. I'm not passing the player as an argument, nor am I returning any variables.

I'm talking about general usage from a quest script.
User avatar
Ashley Tamen
 
Posts: 3477
Joined: Sun Apr 08, 2007 6:17 am

Post » Tue Jun 19, 2012 11:42 am

Game.GetPlayer()

This (above) is a function call. Great if you only need to reference the player once.

Actor Player = Game.GetPlayer()

If you need to reference the player more then once in a single function (events are functions) you would do this (above). The life of the reference is the life of the function that this is called in.

Actor Property Player AutoPlayer = Game.GetPlayer()

The first line here makes the second line redundant. The Player property already points to the player. So we would reduce it and might use it as follows ...

Actor Property playerRef AutoEvent OnInit()	if ( self.GetTargetActor() == playerRef )		RegisterForSingleUpdate(1)	endifEndEvent

The example here is from a script that extends ActiveMagicEffect. It checks that the actor the effect is on is the player. We can use the pre-defined reference to playerRef again and again in other functions in our script. Pre-definded references (also known as a property in papyrus) have an additional use in that they can improve the readability of a script source file.
User avatar
Elizabeth Falvey
 
Posts: 3347
Joined: Fri Oct 26, 2007 1:37 am

Post » Tue Jun 19, 2012 6:48 am

Game.GetPlayer()

This (above) is a function call. Great if you only need to reference the player once.

Actor Player = Game.GetPlayer()

If you need to reference the player more then once in a single function (events are functions) you would do this (above). The life of the reference is the life of the function that this is called in.

Actor Property Player AutoPlayer = Game.GetPlayer()

The first line here makes the second line redundant. The Player property already points to the player. So we would reduce it and might use it as follows ...

Actor Property playerRef AutoEvent OnInit()	if ( self.GetTargetActor() == playerRef )		RegisterForSingleUpdate(1)	endifEndEvent

The example here is from a script that extends ActiveMagicEffect. It checks that the actor the effect is on is the player. We can use the pre-defined reference to playerRef again and again in other functions in our script. Pre-definded references (also known as a property in papyrus) have an additional use in that they can improve the readability of a script source file.
You can declare a variable inside the main body of a script and it will be global to all functions within that script. However this does not make it a property, and it does not work the same way a property does. This is why I am making the distinction.

I'm asking which is more efficient for the game. IE: If I were to reference the player 5000 times in one script, what would have the least amount of FPS impact? Would it be better to have 5000 Game.GetPlayer()'s, 5000 Player references that were properties, or 5000 Player references that were just normal variables.
User avatar
AnDres MeZa
 
Posts: 3349
Joined: Thu Aug 16, 2007 1:39 pm

Post » Tue Jun 19, 2012 10:40 am

And you can declare a variable inside the main body of a script and it will be global to all functions within that script.

Yes. And that would make it a reference variable which you can change at will. But in the case you gave where we are referencing only the player, it will never change, so you would make it a property, especially given that the player is already persistant.

I have no idea what the difference in clock cycles would be, but a function call needs to be pushed onto the stack and returned (which has overheads), whereas a property or reference variable (which are pointers) do not. And since the example given is for the player alone and the player is always persistant, a single property definition and 5000 references to it should win out.

With anything other than the player, the biggest consideration will likely be http://www.creationkit.com/Persistence_%28Papyrus%29. The word "Optimal" could have more than one meaning in the context of papyrus.
User avatar
Leanne Molloy
 
Posts: 3342
Joined: Sat Sep 02, 2006 1:09 am

Post » Tue Jun 19, 2012 9:20 am

If you're only referencing the player once in your script, Game.GetPlayer() is just fine. If you're going to be referencing that more than once, consider assigning it to a variable so you don't need to keep calling the same function (like you had above: Actor = Game.GetPlayer())

I don't know what the performance hit is for calling the function over and over again but I doubt it 'costs' more to reference a variable 10 times than it does to call the function 10 times.
User avatar
lolli
 
Posts: 3485
Joined: Mon Jan 01, 2007 10:42 am

Post » Tue Jun 19, 2012 9:28 am

Yes. And that would make it a reference variable which you can change at will. But in the case you gave where we are referencing only the player, it will never change, so you would make it a property, especially given that the player is already persistant. I have no idea what the difference in clock cycles would be, but a function call needs to be pushed onto the stack and returned (which has overheads), whereas a property or reference variable (which are pointers) do not. And since the example given is for the player alone and the player is always persistant, a single property definition and 5000 references to it should win out. With anything other than the player, the biggest consideration will likely be http://www.creationkit.com/Persistence_%28Papyrus%29. The word "Optimal" could have more than one meaning in the context of papyrus.

Alright. That's pretty much what I was wondering, thanks.
User avatar
Tikarma Vodicka-McPherson
 
Posts: 3426
Joined: Fri Feb 02, 2007 9:15 am

Post » Tue Jun 19, 2012 3:09 am

Game.GetPlayer() is slower then accessing a variable (whether in the object or in a function) because it’s a function call.

A property will depend on a few things. If the property is an auto property and you’re calling it from the same script you defined it in then the compiler optimizes it and makes it just as fast as a variable. If the property isn’t an auto property, or you are accessing the property from a different script, then a function call is involved and the speed will depend on how “busy” the script that contains the property is (because the caller may have to wait).

Also, in the example posted by Rocket, playerRef will not have any value unless you give it one in the CK, or assign it a value somewhere else (like in your OnInit event).
User avatar
lydia nekongo
 
Posts: 3403
Joined: Wed Jul 19, 2006 1:04 pm

Post » Tue Jun 19, 2012 5:03 am

Game.GetPlayer() is slower then accessing a variable (whether in the object or in a function) because it’s a function call.

A property will depend on a few things. If the property is an auto property and you’re calling it from the same script you defined it in then the compiler optimizes it and makes it just as fast as a variable. If the property isn’t an auto property, or you are accessing the property from a different script, then a function call is involved and the speed will depend on how “busy” the script that contains the property is (because the caller may have to wait).

Also, in the example posted by Rocket, playerRef will not have any value unless you give it one in the CK, or assign it a value somewhere else (like in your OnInit event).
Sweet. Thanks for the extra info. I'll use a property then.
User avatar
Emma Pennington
 
Posts: 3346
Joined: Tue Oct 17, 2006 8:41 am


Return to V - Skyrim