Jump to content

Fallout New Vegas GECK & Scripting Help 101


Recommended Posts

Guest tomm434
Posted

You need to use 

If Blah.IsFormValid == 1
Posted

You need to use 

If Blah.IsFormValid == 1

 

"Blah" isn't my variable, it's just the scope of the variable which is called ref. So if anything, it should be Blah.ref.IsFormValid but that also gives a syntax error.
Posted

if(IsReference Blah.ref == 0)

 

isn't NV scripting lingo.

You declare the variable first before you start the script block, then only use the name

 

ref Blah

 

Begin someBlockType

 

if IsReference Blah

Posted

You need to use 

If Blah.IsFormValid == 1

 

No no no.. ;)

 

If it's not valid, that's just going to crash.

 

if (IsFormValid someRefVar)
; it is
endif

if (0 == IsFormValid someRefVar)
; it is not
endif
 

 

if(IsReference Blah.ref == 0)

 

isn't NV scripting lingo.

You declare the variable first before you start the script block, then only use the name

 

ref Blah

 

Begin someBlockType

 

if IsReference Blah

Also this.

 

The normal boilerplate is basically something like this:

 

scn someScript

ref myRef

Begin GameMode
  ; some stuff is here setting/getting myRef

  if (IsFormValid myRef)
    if (IsReference myRef)
      ; myRef is fully valid, proceed.
    else
      ; myRef is a valid form, but not a valid ref.  It might be a basetype
      ; or some other form type, but not a reference.
    endif
  else
    ; myRef is entirely invalid.
  endif
End
Posted

As I understand it, asdf0's variable is named 'ref' and 'blah' is (for example) the QuestScript where the variable is declared. And in his example he wants to check the variable outside the original script (so he has to write blah.ref ... or better 'QuestScript.TestRef') and this doesn't work as it should?

 

So maybe you have to go the long way and have to write something like this? (Im not on my modding computer)

 

ref CheckREF

 

let CheckREF := QuestScript.TestREF

 

if (IsFormValid CheckREF ...

 

???

Guest tomm434
Posted
No no no.. 

If it's not valid, that's just going to crash.

Wait wait wait - does that mean that this code

If MyRef.GetType !=0

will crush too if MyRef Doesn't exist in any form?

Posted

 

No no no.. 

If it's not valid, that's just going to crash.
Wait wait wait - does that mean that this code

If MyRef.GetType !=0
will crush too if MyRef Doesn't exist in any form?

 

Yes, probably. GetType may be special, but it's best to never take chances.

 

If there's any chance that a ref may be invalid, use IsReference with an argument -- not as a member function of the ref.

Posted

I only use that syntax if I check first as described, or if I'm working on a reference I know is valid -- e.g. playerRef, or something else hardcoded as a ref. Never on random ref vars without validating them first, and usually not even then. Too much chance of it going wrong, especially in frame-split scripts where you might check it at the start -- then it turns up invalid in the next stage of the script a few frames later.

 

Of course sexout sometimes breaks this rule in a few larger scripts I need to fix (sometimes checked/set in one frame, used later without rechecking).

Posted

Eh, I don't always check if a previously captured ref is still valid either - I catch up when I think of it.

What I meant though was that because a lot of scripters start out using actor/ref functions first (entry-level functions like getav, additem etc), they get used to ref syntax, and then try to apply it to forms that can never be refs (races, quests, formlists etc), especially if passed to a ref var. Functions like IsFormValid & IsReference already imply you don't know if it's gonna be a reference, so object syntax is the only way to go. GetType is in the same area.

Guest tomm434
Posted

Thanks - I'll use object syntax from now on!

Posted

The whole ref method syntax and implied ref syntax were huge mistakes on beths part. It's best to just ignore them. Also, slap whatever oblivion wiki person wrote that this is bad:

 

set self to GetSelf
self.someBlah
and this is 'better'

someBlah ; implied ref
That person got that exactly backwards and wrong. The first method is the better method. Being more explicit is never 'bad'. You have to do some checking when it comes to getself vs. getcontainer but it's a small price to pay for code that Just Works no matter where you put it.

 

---------

 

As an aside, from an OOP standpoint, "ref.foo" is perfect "object syntax." I would call them function syntax and method syntax.

 

someFunc(someRef); -- function syntax, you call it like a procedure/function in a non OOP language.

someRef.someFunc(); -- method syntax, you call it like a class/object method.

 

That said.. just avoid using the latter unless you have no choice. It's not any shorter to type, and the very real pitfalls outweigh the perceived (but mostly not real) benefits. GECKScript isn't an OOP language, and pretending that it is just leads to even more heartache (and heartburn, and headache).

 

 

Edit: disclaimer... this in no way applies to skyrim. Papyrus is in fact an OOP language, more or less.

Posted

Wait wait wait - does that mean that this code

If MyRef.GetType !=0
will crush too if MyRef Doesn't exist in any form?

 

 

EDIT: no wait, it was if GetType MyREF, my bad

 

Being more explicit is never 'bad'. You have to do some checking when it comes to getself vs. getcontainer but it's a small price to pay for code that Just Works no matter where you put it.

NV vanilla does it very often. It uses explicit ref even when it's obvious than an implict would still work. I guess they think like you :)
Posted

It's the "right way" to do it. Not only is it obvious what the script is doing, it also means it will still work with minimal changes if you copy/paste it somewhere else.

 

Some wiki thing (I think the page for CIOS, I'll go look) said that this is "bad bad bad, don't so it"

ref self
set self to getself
self.cios somespell
and said instead to just do

cios somespell
The second example is much shorter, but the first one is much more robust, and nothing 'bad' about it. The first time I read that, I thought there was some actual technical problem with doing it the first way, they made it sound so bad. There isn't. It works fine, and is reliable.

 

If you need to move that code somewhere else later, like out of a spell script and into a quest script, you only have to change one line (the getself needs to do something else like get an NX var or quest var) and it will still work. If you do it the "wiki recommended" way you have to write all that stuff I wrote in the example anyway so...... yeah.

 

Implicit refs, bad.

Method calling syntax, bad.

 

Explicit refs, good.

Function calling syntax, good.

Posted

It's the "right way" to do it. Not only is it obvious what the script is doing, it also means it will still work with minimal changes if you copy/paste it somewhere else.

 

Some wiki thing (I think the page for CIOS, I'll go look) said that this is "bad bad bad, don't so it"

ref self
set self to getself
self.cios somespell
and said instead to just do

cios somespell
The second example is much shorter, but the first one is much more robust, and nothing 'bad' about it. The first time I read that, I thought there was some actual technical problem with doing it the first way, they made it sound so bad. There isn't. It works fine, and is reliable.

 

If you need to move that code somewhere else later, like out of a spell script and into a quest script, you only have to change one line (the getself needs to do something else like get an NX var or quest var) and it will still work. If you do it the "wiki recommended" way you have to write all that stuff I wrote in the example anyway so...... yeah.

 

Implicit refs, bad.

Method calling syntax, bad.

 

Explicit refs, good.

Function calling syntax, good.

 

I don't really follow how implicit refs are quite so 'bad', considering the only advantage you mention is being able to easily transfer let's say a spell script to a token script. I also don't think keeping things explicit is in any way bad either.

What you call method syntax is obviously unavoidable with reference functions - so maybe calling it bad isn't such a good idea either  - you wouldn't want people to shy away from a simple MoveTo. Also, dual-syntax ones usually apply to the ref or the base depending on how you call it, and sometimes you'd rather not touch the base, which could be... bad. ;)

 

Speaking of cleaning up the wiki page, does anyone know if this still applies, or ever has:

  • GetSelf will return 0 if called on a reference that has been created dynamically (for example, created via PlaceAtMe, or dropped from an inventory into the game world).
Posted

I don't really follow how implicit refs are quite so 'bad', considering the only advantage you mention is being able to easily transfer let's say a spell script to a token script.

 

What you call method syntax is obviously unavoidable with reference functions - so maybe calling it bad isn't such a good idea either  - you wouldn't want people to shy away from a simple MoveTo. Also, dual-syntax ones usually apply to the ref or the base depending on how you call it, and sometimes you'd rather not touch the base, which could be... bad. ;)

Well they're "lazy" and as a developer, I find that "bad". The advantage of being easier to transport also makes potential problems more obvious. A "simple moveto" (I assume something like just "moveto playerref" is what you mean) only looks simple, but it's effectively doing the same thing as the longer code. If you see that longer code when you're working on it, you may recognize more quickly that it's wrong in another context. It may not be as apparent with just the one liner.

 

I'd absolutely want people to "shy away" (as in "never use") such a "simple moveto." Not using shortcuts is a habit I've formed over working in a lot of different languages and on different projects. Sooner or later they lead to problems that aren't always easy to find. I advocate the "if (1 == somevar)" rather than "if (somevar == 1)" syntax for the same reason, even though the technical reason behind it doesn't apply to geckscript.

 

Good code is cross-platform. Good coding technique is, as well. ;)

 

Speaking of cleaning up the wiki page, does anyone know if this still applies, or ever has:

  • GetSelf will return 0 if called on a reference that has been created dynamically (for example, created via PlaceAtMe, or dropped from an inventory into the game world).

I have no idea, but it sounds bogus, like much of what's been copied over from the oblivion wiki. Speaking of that, some weeks or months back they changed the layout of that wiki or something. Every link on every GECK wiki page that goes to an oblivion wiki page is broken.

Posted

I've always followed a simple rule, and YES, it's because when I started programming we were still storing everything on magnetic tape or punch cards, but that rule is a good one to follow:

 

Explicit is always preferred to implicit.

 

Implicit code was created to promote elegance NOT functionality. IMO, elegance is vastly overrated... it's elegance that confuses people who are inexperienced.

 

When you write code like...

MoveTo PlayerREF

...vs. code that says:

ref rSelf
set rSelf to GetSelf
rSelf.MoveTo PlayerREF

...you run into various problems which aren't obvious at a glance.

 

The first example is relying on implicit compiler/interpreter behavior. If that behavior changes, the code runs differently.

The first example depends on the programmer understanding that implicit compiler/interpreter behavior to understand the code itself.

The first example is NOT self-documenting and thus is harder to debug at first glance.

 

I can tell you from experience, and I mean 30+ years of it, IMPLICIT bugs are the hardest bugs to find, especially if they're the result of implicit compiler/interpreter behavior changing. EXPLICIT code is self-documenting... the above second example is very clear as to what it does, the code itself documents what it's doing. It is easier to find bugs in explicit code, usually at first glance.

 

And... I'm preaching at this point, so I'll stop... besides, you get the idea...

 

EDIT: Or... I coulda "liked" Pride's posts... meh.

Posted

With the moveto comment, I no longer referred to implicit refs, but this:

 

someFunc(someRef); -- function syntax, you call it like a procedure/function in a non OOP language.
someRef.someFunc(); -- method syntax, you call it like a class/object method.

 

 

in combination with:

 

Implicit refs, bad.
Method calling syntax, bad.

Explicit refs, good.
Function calling syntax, good.

 

 

which in the context of this thread, geck scripting, seems to warn people off using reference syntax at all, including when you have no choice in the matter as with ref functions like moveto

Posted

As I understand it, asdf0's variable is named 'ref' and 'blah' is (for example) the QuestScript where the variable is declared. And in his example he wants to check the variable outside the original script (so he has to write blah.ref ... or better 'QuestScript.TestRef') and this doesn't work as it should?

That's exactly it. Anyway, I "solved" it; instead of

if(IsReference Blah.ref == 0)
	set Blah.ref to 0
endif
which can't be compiled I now have

ref tempRef
set tempRef to Blah.ref
if(IsReference tempRef == 0)
	set Blah.ref to 0
endif
and everything is working great.

 

 

Different problem: I have some scripts that add creatures to new factions (and sometimes remove them from these new factions later) during gameplay, and I've noticed that most creature enemies (e.g. Deathclaws) are "allied" to the player (GetFactionRelation player -> 2). The weird thing is that once I remove their original faction (e.g. DeathclawFaction; 00021474 in FalloutNV.esm) with RemoveFromFaction, then their faction relation to the player is immediately reset to the correct value (which is 0) but none of the loaded mods alter DeathclawFaction or PlayerFaction in any way (I checked with FNVEdit) and of course Deathclaws are not normally allied to the player or vice versa.

 

Just in case, I checked whether the player had been erroneously added to DeathclawFaction (which is the only faction DeathclawFaction is allied with) but of course that wasn't the case.

 

So what is going on here?

 

 

Edit: Also, is there an in-depth explanation on faction relations somewhere? My understanding is that when the player is involved, the friendlier of the two relations is applied to both directions; i.e. "player.GetFactionRelation enemy" will always return the same value as "enemy.GetFactionRelation player". But I don't know if this is true.

Posted

which in the context of this thread, geck scripting, seems to warn people off using reference syntax at all, including when you have no choice in the matter as with ref functions like moveto

Ah no, I did say to not use it unless you have no choice. If you have no choice, go ahead. ;)

Guest luthienanarion
Posted

 

Speaking of cleaning up the wiki page, does anyone know if this still applies, or ever has:

  • GetSelf will return 0 if called on a reference that has been created dynamically (for example, created via PlaceAtMe, or dropped from an inventory into the game world).

I have no idea, but it sounds bogus, like much of what's been copied over from the oblivion wiki.

 

In my experience, this is correct: GetSelf will not return a dynamically-generated reference.  However, PlaceAtMe returns a reference to the created object. In order to do something with a PlaceAtMe-created object:

 

let refVar := someRef.PlaceAtMe someObject 1

This is outlined in the wiki page, as I recall.

  • 2 weeks later...
Posted

As in game effect, AddSpell inside a script will visualize on top left corner the string called sAddItemToSpellList. I would like to remove it, but it doesn't allow some "1" extra parameter like it happens for AddItem for example. However, if I simply set the string to no characters, I will see the empty box effect on top left. Someone has an idea on which path I should take to solve it?

 

EDIT: this was very bad explained.

AddSpell MySpell

This script will let a box appearing on top left, with the word "added" on it. This word comes from the ini setting sAddItemToSpellList. I would like to remove the whole box, but I can't simply put that ini setting to an empty string because the box will still appear (an empty box) and I don't want it.

But on the other side, it's not like for AddItem, where I can put some extra parameter to mask the message on top left. Someone has an idea on how I could solve this?

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...