Jump to content

Fallout New Vegas GECK & Scripting Help 101


Recommended Posts

Guest tomm434
Posted

Not ShowWarning, do console print like:

PrintC "I will always appear in the console at this point"
DebugPrint "I will appear only with debug mode enabled for the mod"
 
SetDebugMode 1 ; this enables debug for the mod containing the script
 
; in the game console, you must specify the mod index in _Decimal_ not Hex, if you want to enable it like:
SetDebugMode 1 75
 
; I always add this to my main quests:
 
int iIndex
if GetGameLoaded || GetGameRestarted
    set iIndex to GetModIndex "MyModName.esp"
    PrintC "My mod version X loaded at index (hex): %x2 or (dec): %g" iIndex iIndex
endif
 
; this tells you the definite index in both hex and dec in case you want to do console stuff.

The quest not running suggests something crashed it, try adding console print at key sections to try and find where. Also, do you have any MenuMode blocks that may be running during dialogue?

 

Thanks. Well, okay, I found the reason quest crashed.

 

At the start of the scene I typed

set playercloneref to aaalabmarker1.placeatme 7 1

I create a clone of player for a cutscene.

 

And then after scene I wanted to get rid of this clone

playercloneref.disable
playercloneref.markfordelete

 I deleted these 2 lines and now script works perfectly.  But I've read a tutorial on "placeatme" command which says

 

 

Using the PlaceAtMe function in scripts without cleaning them up later is considered bad modding etiquette. This is because too many calls to PlaceAtMe leaves objects in the game and will lead to bloated save-games after a while, which impacts game performance and loading times.

 

If I leave only "playercloneref.disable" command everything works fine too. Why does it happen?I can't "markfordelete" the npc I created? And should I leave clone as it is?

Posted

I seem to remember someone mentioning that referencing a placeatme like that is unreliable.

 

Also, does that syntax work: 'aaalabmarker1.placeatme 7 1'? It implies to me you are placing one int '7' at some marker ref, according to GECK wiki documentation

 

Should it not be 'set PlayerCloneRef to aaalabmarker1.placeatme playerclone 1'?

 

---

an alternative if you want to clean up, is to create the reference in the GECK in some off map cell and moveto it when you need it (that way any refs in functions work properly too).

 

If you do use PlaceAtMe, another option is to attach an object script to the playerclone with something like:

float fTimer
Begin GameMode
 
if fTimer < 5
    let fTimer += GetSecondsPassed
    return
endif
 
set fTimer to 0
if MyQuest.VariableIndicatesIShouldDeleteMyself
    Disable
    MarkForDelete
endif
End
Posted

tom, use a if cloneref.GetDisabled == 0 in the condition at stage 21, it will avoid it to run twice for mistake. also, when you stage like that, you should always set the stage variable at the top and not at the bottom of the stage, so:

if (pdstage ==21) && (pdtimer >=10) && (playercloneref.GetDisabled == 0)
set pdstage to 22
playercloneref.disable
playercloneref.markfordelete
player.imod BlacksexISFX
endif
Guest tomm434
Posted

 

I seem to remember someone mentioning that referencing a placeatme like that is unreliable.

 

Also, does that syntax work: 'aaalabmarker1.placeatme 7 1'? It implies to me you are placing one int '7' at some marker ref, according to GECK wiki documentation

 

Should it not be 'set PlayerCloneRef to aaalabmarker1.placeatme playerclone 1'?

No, 7 goes for player ID. So I swap actor "7" at marker in quantity of 1. I don't know if creating another id, setting player as template will work. But I got the idea, If nothing works I can get rid of her after quets in another cell.

 

 

A.J., Thanks , I will try this.

Can you tell me how this works?

I mean I have script

 

And if we talk about

if pdstage==21
Set pdstage to 22
aaalabmanbref.evp
endif

Is there a slightest possibility that setting pdstage before remaining script will lead to game engine only executing this command(set pdstage to 22) and leaving aaalabmenref behind?

Posted

@AJ: why at the top? I would always change the conditional at the end of the block, that way if something fails for some reason it is easier to track down. Although, I would type the line first so I don't forget.

 

if 0 == Init

    ; do my stuff

    set Init to 1

endif

Posted

@AJ: why at the top? I would always change the conditional at the end of the block, that way if something fails for some reason it is easier to track down. Although, I would type the line first so I don't forget.

 

if 0 == Init

    ; do my stuff

    set Init to 1

endif

 

It does matter.  Sometime setting init locks at the top get skipped, but then again sometimes they get skipped at the bottom.  One or the other has always worked if the other one doesn't.  Sometimes I get angry and put them at the top and bottom and dare it to miss.

 

Posted

@AJ: why at the top? I would always change the conditional at the end of the block, that way if something fails for some reason it is easier to track down. Although, I would type the line first so I don't forget.

 

if 0 == Init

    ; do my stuff

    set Init to 1

endif

 

Sometimes some vet reminds it in this thread even if I don't know if it's for the same reasons. Generally, these kinds of script blocks break when the gameplay is involved. So, if "do my stuff" is an easy block that doesn't involve visual or audio things for example, you probably won't have any issues at all. If it implies more "heavy" things like creating clones, playing sounds, dressing the clones, moveto, placeatme etc.etc as Tom is doing, it's definetely better. Redundancy on conditions like these is essential, but if you put conditions on actions that require more than a frame, it doesn't make the trick, these must be tweaked (like with a timer that slow them down) and tested a lot. If in a stage you are creating a clone and in the stage condition you place "if clone is not created" sometimes you risk that it creates more than a clone before it really realizes it created it.

 

The first example I remember... there was a playsound inside a doonce block (just like your example), or maybe it was a explosion.placeatme, anyway the effect was that the sound was playing for 3-4 times in a row, you were hearing something like bo-bo-bo-boooooom, solved it putting the set doonce to 1 on top.

 

Note that these issues are 100 worser when you have a modded installation, I usually make them coming out when I activate my ENB. Since a quest mod is supposed to be played in a generic modded installation, I really think it deserves to be noted and tested in a heavily modded environment. Also they often don't occur with slow delay time, but quest mods often require fast reactive scripts, you know.

Guest tomm434
Posted

 

@AJ: why at the top? I would always change the conditional at the end of the block, that way if something fails for some reason it is easier to track down. Although, I would type the line first so I don't forget.

 

if 0 == Init

    ; do my stuff

    set Init to 1

endif

 

Sometimes some vet reminds it in this thread even if I don't know if it's for the same reasons. Generally, these kinds of script blocks break when the gameplay is involved. So, if "do my stuff" is an easy block that doesn't involve visual or audio things for example, you probably won't have any issues at all. If it implies more "heavy" things like creating clones, playing sounds, dressing the clones, moveto, placeatme etc.etc as Tom is doing, it's definetely better. Redundancy on conditions like these is essential, but if you put conditions on actions that require more than a frame, it doesn't make the trick, these must be tweaked (like with a timer that slow them down) and tested a lot. If in a stage you are creating a clone and in the stage condition you place "if clone is not created" sometimes you risk that it creates more than a clone before it really realizes it created it.

 

The first example I remember... there was a playsound inside a doonce block (just like your example), or maybe it was a explosion.placeatme, anyway the effect was that the sound was playing for 3-4 times in a row, you were hearing something like bo-bo-bo-boooooom, solved it putting the set doonce to 1 on top.

 

Note that these issues are 100 worser when you have a modded installation, I usually make them coming out when I activate my ENB. Since a quest mod is supposed to be played in a generic modded installation, I really think it deserves to be noted and tested in a heavily modded environment. Also they often don't occur with slow delay time, but quest mods often require fast reactive scripts, you know.

 

 

if I have vanilla fallout(except some combat overhauls and quest stuff) with no graphic mods or ENB and a good PC(4 cores, Ati 7850 etc) - that doesn't mean that my mod will work as intended on other PC? You mean that some scripts can be skipped if PC is too weak etc?

 

Posted

well it depends by scripts but if they're only staged cutscenes as the ones you showed me I doubt it. Usually my problems come out on heavy operations like when in low delay scripts I setpos while calculating sin and cos etc.etc. in these cases I really see a drastic difference from a modded environment (especially with ENB) and a clean vanilla.

If you copied the stages I used in creating a clone and didn't capside things or removed stages, you shouldn't have many issues on that. Still the problems that could happen are with AI packages, those can't be foreseen...

 

In your case I suspect the CTD is made by erasing that clone ref in the wrong moment or it takes the operation twice. I hope the redundancy I wrote can do the trick. I had more than once a problem like that. In one case, I managed to erase the reference in a different moment, in a different quest stage, since the player was moveto another place he couldn't see that. In another case, I really couldn't do that without a timer, I didn't want to use it so I removed the placeatme, changing it with a moveto of an already existing reference in a dummy cell. Generally placeatme references should be erased because they could cause save bloats, but also it depends by how much you abuse of placeatme of course. If you're going to create all these cut scenes, I would erase them

Posted

 

It does matter.  Sometime setting init locks at the top get skipped, but then again sometimes they get skipped at the bottom. 

 

 

Terrifying. Perhaps this is only for per frame scripts? I was always start them with an 'if fTimer < x.. return' which maybe avoids it.

 

Is there ever a time you would want to run something every frame? Seems like you couldn't do anything reliably anyway if there is, it puzzles me they made object GameMode/EffectUpdates always do it.

Guest tomm434
Posted

well it depends by scripts but if they're only staged cutscenes as the ones you showed me I doubt it. Usually my problems come out on heavy operations like when in low delay scripts I setpos while calculating sin and cos etc.etc. in these cases I really see a drastic difference from a modded environment (especially with ENB) and a clean vanilla.

If you copied the stages I used in creating a clone and didn't capside things or removed stages, you shouldn't have many issues on that. Still the problems that could happen are with AI packages, those can't be foreseen...

 

In your case I suspect the CTD is made by erasing that clone ref in the wrong moment or it takes the operation twice. I hope the redundancy I wrote can do the trick. I had more than once a problem like that. In one case, I managed to erase the reference in a different moment, in a different quest stage, since the player was moveto another place he couldn't see that. In another case, I really couldn't do that without a timer, I didn't want to use it so I removed the placeatme, changing it with a moveto of an already existing reference in a dummy cell. Generally placeatme references should be erased because they could cause save bloats, but also it depends by how much you abuse of placeatme of course. If you're going to create all these cut scenes, I would erase them

 

Thanks. I was getting worried I would have to rewrite script again.

Posted

Yes per framer.  I've had a group of elseifs all return true right down the line because of that ordering.  That only happened once though.  It can definitely ruin your day trying to figure out what's wrong.

Guest tomm434
Posted

Ehmm. maybe a stupid question but why didn't Bethesda implemented a simple "wait" command. Like "Wait 2 gameseconds". Is that THAT difficult? That would solve a lot of issues. I've been modding GTA Vice City when it was popular and even that game had wait command.

Posted

 

Is there ever a time you would want to run something every frame? Seems like you couldn't do anything reliably

 

 

I've noticed all the operations like setting variables, timers etc. everything that's purely numbers, abstract, they are very much reliable. The problems come when you start modifying the gameplay environment, trigger a visual effect, play a sound, let a npc do certain action etc. I really think these can still be enough reliable, but they need more redundancy and/or the script must be slowed in some ways. Now this is a different case but for example in Skyrim when I mod it a lot I can see even VANILLA npcs acting strange and scripts break, I mean I really doubt there's a 100% perfect way to tweak a mod which requires some specific timing in a full modded environment. In these past weeks I'm starting to think that the best way is tweaking the response by MCM, as the user can raise the delay time if something doesn't work properly, that's the best solution I found without killing too much what I have in mind instead of favoring high modded environments... I mean it's better if users tweak it when something doesn't work properly, just like when you drop your graphic resolution if the game isn't enough fast...

Posted

Is there some kind of max scripts per frame in the engine?

 

Quests have a priority, does this mean the game runs all the ones due for that frame starting at highest, but if it hits the 'max' any left over wait until the next frame. Or is quest priority unrelated to scripts?

 

-------

 

@tomm434: there is:

float fTimer
if fTimer < 2
    let fTimer += GetSecondsPassed ; or ScriptEffectElapsedSeconds, this the time since the script _last_ ran, _not_ first ran
    return
endif
Guest tomm434
Posted

 

float fTimer

if fTimer < 2

    let fTimer += GetSecondsPassed ; or ScriptEffectElapsedSeconds, this the time since the script _last_ ran, _not_ first ran

    return

endif

Well, I know how timer works. it's just I have to create additional timer every time I want to, for example imod player vision(FadeinBlack) and move him to new location.  Or I need to set timer to 0 every time I use it. In GTA VC I just had to type "Wait 2 s" and  game waited 2 seconds without me getting worried about setting quest dealy to 0,001 before the scene.

Posted

Yeah the erroneous returns on the first scan is one reason most of my scripts have at least a 9 scan count before executing and it may help lag a bit too as I set some to only run every 500th scan.

I have seen some weird stuff at times where scripts just refused to run at all but reloading the save they started ok.

Guest tomm434
Posted

You're expecting to solve problems using linear model solutions when the model is purely event driven.

 

You have to start thinking of scripting for FO as managing a state machine.

 

You're right. The games and engines are very different. But it still would be good to implement wait command - for example I type "Wait 10 seconds" and game creates temporary timer which expires after 10 seconds and script continues, then timer(float variable) deletes itself.

 

 

 

Ehm. I've got a question again. Is there any way to make unconscious actor conscious instantly? I've tried lots of commands but nothing seems to work. Of course I can disale\enable them but I would have to do that in front of player so this option is a no-go. "Modav Fiatigue" doesn't work either.

Posted

What about a CIOS that damages the fatigue? I never tried that but it's the first thing I can think about

Guest tomm434
Posted

What about a CIOS that damages the fatigue? I never tried that but it's the first thing I can think about

 

So, if npc is unconscious by spell he will get up instantly when I delete spell?

Posted

if he doesn't, what about a CIOS to restore some fatigue? :P

Guest tomm434
Posted

if he doesn't, what about a CIOS to restore some fatigue? :P

 

Ok, we'll see if that works.

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...