Jump to content

Photo

Set and Let observations and Conclutions

set let

  • Please log in to reply
8 replies to this topic

#1
Pellape

Pellape

    Faithful poster

  • Members
  • PipPipPipPip
  • 2,068 posts
Sometimes scripts works, sometimes they do not. I yse xOBSE 21.5 which works perfect with COBL and everything else. This can be related to 21.5. IDK and I do not care. It works for me. 
 
I finally discovered something, after loads of odd behaviours in game. Scripts that should work but they do not. I will give 2 different examples when they do not work and how I make them work. This is my observations and my conclusions and solutions. We do not really need to argue about this. Use your own judgement.  :D  If it works for you, fine, this does not work for me. :D  Just so we clear that out, so we do not do the same in this thread as we did in another thread, but then it was about what is what, use the right names for stuff. :wink:  I am open for dialogue anyway really. I love an good argument.
 
Let and Set do not work the same way, even if it may look that way.
  • Set this variable to XXXXX
  • Let this Variable be XXXXXX
At most cases they both work just great but in some cases they do not. WAC has a lot of items starting with the number 4, so we make an object that we call 4XXX and we try to add that into an array we call xxxArr and we add it to slot 4.
 
Let xxxArr[3] := 4XXX
That looks good right?  Compile it in CSE -->  No problems find.
 
(4th number is 3 --->  0 to 3 is 4 numbers.)

Run it in game. Nothing happens, look at the console.
 
ERROR in script 8949204 offset 0x67 (or what ever as we get an error - Cannot use Let)
 
So in this case we must use the old ways as it works and we must skip the array here and make a separate script.
Ref xxxRef
Set xxxRef to 4XXX 
Works perfect.
 
-----------------------------------------------------------
 
Example 2 is a bit more complicated i guess and it sure took me a long time to really understand this and accept it. Hopefully I remember this now when i write it down as writing this down, will help me think more clear. It helps me make scripts to work so I cam focus in creating, not debugging scripts. So where do we start with this example? Let me start with, we will not use WAC stuff as we use any object in this example, or rather reference as this is happening in a cell, outside the inventories.
 
Let me first say, this way of making scripts is still a bit new to me, as I did use the old ways a long time and did find a way to optimise it and increase the cell performance, nothing special but it differ a lot from the old way. I did ran into some problems in the process, and now I really understand how to make a work around for this odd behaviour and make everything to just run perfect.
 
So lets make a list of objects and scripts in this example
  • Object 4xxx is reference ff123abc when we add it into a Triggerbox. It is a weapon from WAC in this case. It does not matter as we only use the reference here and will only use ff123abc. 
  • Script1 runs at the Triggerbox
  • Script2 runs at a button
  • Script3 is a quest script, that will hold everything together. It runs default 1 time every 10s in my case. Doesn't really matter for this example.
Edit: I refer to scripts, not the references in the examples below. Script 1 and 2 are running inside each items, 2 references, set with a proper name and are both persistent.
 
Lets start by taking out this weapon from a container and put it inside the Triggerbox. The Triggerbox will now add this weapon to an reference in its script.
 
I will use simple examples, not real in game scripting or the scripts will be to long and we loose focus. If you read this, you know scripting and will get it anyway, or we can make real examples later if this makes no sense. I am up for making cool and more real examples really.  :D
 
Script1
Ref WeaponRef

----
Set WeaponRef to (Whatever is trigging the box and it is ff123abc)
PrintC "%i %n", WeaponRef, WeaponRef
 
So the Triggerbox is now spamming ff123abc WACWeaponREF inside the console with PrintToConsole -> PrintC
 
We did add an array inside the quest script called WeaponARR and initiated it properly
 
Script3
array_var WeaponARR

----
Let WeaponARR := ar_construct Array
 
We will now push a button and a lot of stuff will happen or not happen when we push it. Lets see what will not work for me.
 
Script2
Ref WeaponRef

-----
Onactivate bla bla

Set WeaponRef to Script1.WeaponRef
Let Script3.WeaponARR[0] := WeaponRef
 
So the set command will work perfect but the let command will do nothing....  It does not work. No errors, no nothing, the number 0 slot will be empty like the void it self.  This can be checked with ar_size
 
Short DatabaseSize

-------
Let DatabaseSize := ar_size WeaponARR
 
So I solve this by writing the code vice verse in both scripts...   We push the button again with the new scripts, Script2 and Script3
 
Script3
Short State 
Ref WeaponRef
Array_var WeaponARR 

------------------------------

	If ( State == 7 )
		Set WeaponRef to Scrpt1.WeaponRef
		Let WeaponARR[0] := WeaponRef
	EndIf
	
End
So at Script 2 we write:
short Button

-------
bla bla button bla

If Button is ADD-the-bloody-WEAPON
Set Script3.State to 7
 
The set command will work between the scripts, crossing the values, the let do not. Let + arrays or rather Let xxxxArray works perfect internally inside a single script but crossing that value fails, pushing it to another script.
We cannot set a value to an array, so we cannot compare them with arrays. We can Set and Let ordinary variables.
 
Set WeaponRef to abcd
Let WeaponRef := abcd
 
We cant
Set WeaponObjID to 4cde
Let WeaponObjID := 4cde
Well the set works, the let will fail.
 
Use Set and let in the right context, when it makes sense to use one or the other. Inside a single script both Let and Set works to 95% for the same stuff. Someone ones wrote, skip set completely, use Let as much as possible.  :smile:  All i want right now, is to use what I figured out will work, make my Quest script to do what I want it to do.
 
When we push the button now, it will take up to 10s for the weapon to move. When i put the weapon at the Triggerbox, I also add this to Script1
If the triggerbox is triggered.
Set Script3.fQuestDelayTime to 0.1
Will it help?  No way...  Or I do not wait long time enough to figure it out.  I do see in the console that the value changes to 0.1 at some point.
 
I hope these simple examples will be helpful in case you run into similar issues, trying to optimise a cell, removing stupid GameMode code at several Objects that really are unnecessary and only extend the FPS and slow the cell down. Lets try to make Oblivion run at such a high performance as possible and this way to code is helping me to really make a cell run as fast as possible. So I ran into these problems, remade the same mistakes over and over, di peek back at some scripts... hey, what makes this script to work??   Rewrote the new scripts again and voila: The damn sh't is working...
 
Pekka --> Now remember this stuff, do not forget it, do not repeat failures.  
Pekka: Yes sir  :D   I will do my very best.
 
So this is also happening in my Library, using Stroti's pelts as beds. ( Yes madame, I will do my very best )

Edited by Pellape, 05 May 2022 - 11:30 AM.


#2
RomanR

RomanR

    Enthusiast

  • Members
  • PipPip
  • 131 posts

If I may, I would make some comments:

Let xxxArr[3] := 4XXX

If not using straightforward number constants or strings, I wouldn't recommend using "Let" command this way. If the record in your field will change, I would use indirect way through variable always.

set xxxRef to 4XXX
let xxxArr[3] := xxxRef

This should always work.

 

 

And regarding your scripts in second example:

Script3 (Quest Script):

Short State ;button is triggered
Short init 
Ref WeaponRef ;weapon from script1 (triggerbox script)
Array_var WeaponARR ;same weapon, but in a field 


Begin GameMode
  if init == 0 
     let WeaponArr := ar_Construct Array
     let WeaponArr[0] := 0 
     set init to 1
  endif	
End

begin MenuMode
  (same as in GameMode)
end

I think it's practically useless to add weapon in "low speed" quest script if there are already every-frame scripts running. So I'm using this script only for variables and init of a field.

 

Script2 (Button script):

short Button

-------
bla bla button bla

If Button is ADD-the-bloody-WEAPON
   Set Script3.State to 7
   If Script3.WeaponRef != 0 && Script3.init != 0 ; weapon is valid and field prepared
      Let Script3.WeaponArr[0] := Script3.WeaponRef ;copy reference
   endif
------
Endif

In fact why to use weapon in a field is beyond me, I just want to show that before accesing the field in another script you must always make some checks.

 

And Script1 (Triggerbox script) at last:

Ref WeaponRef

----
Set WeaponRef to (Whatever is trigging the box and it is ff123abc)
Set Script3.WeaponRef to WeaponRef
PrintC "%i %n", WeaponRef, WeaponRef
If Script3.State == 7 ;somewhere our button was pressed?
   (command to add a weapon) ;add my weapon
   Set Script3.State to 0 ;reset to avoid multiple adding
Endif

And finally we are there, after checking that button is pressed, this script should add a weapon. 

 

Edit: And of course you can compare field records against variables and even straight strings, but you must use "eval" command for it.


Edited by RomanR, 06 May 2022 - 03:46 PM.


#3
Pellape

Pellape

    Faithful poster

  • Members
  • PipPipPipPip
  • 2,068 posts

I think it's practically useless to add weapon in "low speed" quest script if there are already every-frame scripts running. So I'm using this script only for variables and init of a field.
 
In fact why to use weapon in a field is beyond me, I just want to show that before accesing the field in another script you must always make some checks.


You can read why in my WIP for my big mod project, specially for my Display Room. I store over 100 weapons in a Array. Maybe even 200 Weapons. I do that to increase Performance. The racks how ever set RigibodyMass 0 every frame now. It does not help against weapons with odd and home made collisions. I will make a new report. It is all in my WIP and I write about it at both page 35 and in previous pages, like 34. Debating problems in that room is initiated around 2020 as I been changing this room for periods since then. Trying to make it work for every broken weapon I found and also for none broken weapons, like Bethesda originals. Most of those weapons works great. Some custom made weapons still cause issues.
 
Adding a weapon is best to be left alone. When i test stuff, I go to the weapon, grabs it with Z key to se how it acts. In most cases, nothing happens. If the weapon is custom made, it drops in many cases. If I add the weapon and just let it be there om the wall. Nothing happens. Performance is higher then ever. 30 weapons added. I will fill the room soon with a weapon at every available slot, and see how it is working.
 
It all started with this video 2020. Today it is impossible to use spells against the weapons i tested, original weapons. They sit steady at the wall and i used 2 different spells that push stuff, like the destruction spell Flare.
 
Lets go back to the year 2020, November - Low frame rate, as very big textures bloating the small racks (Using Qarls textures by default on that rack. I guess the original wood is 128 or 256 and Qarl's is 512 or 1024 and texture packs can kill a cell, if used - So adding so many items do require a custom texture really). The new textures is 128 x 128, which made a huge difference on them. I have loads of those small racks in that room. Frame rate is 4 times higher right now. From 8 to above 30. I do hit 2 flies in one smash now. Lower textures + Optimised scripts - I learn new stuff, make new observations for each day and try new solutions  :D


Edited by Pellape, 06 May 2022 - 05:16 PM.


#4
RomanR

RomanR

    Enthusiast

  • Members
  • PipPip
  • 131 posts

Ah yes, with this explanation, using a field for this has surely some meaning. I just tried to make this part of forum a little more lively - it's a little boring with only one person speaking, wouldn't you agree? However your Hobbit Home is very nice, keep up the good work.



#5
Pellape

Pellape

    Faithful poster

  • Members
  • PipPipPipPip
  • 2,068 posts

Thanks a lot RomanR. Well i write so much, i could had explained it better but I really tried my best to focus at the problems, not include some vital details.  :D  I did write more details in my WIP.  :D  At several places even...  :wink:   It is a very long WIP though....  2 years of Pekka typing a lot of rubbish....  :D  My brain dump for Oblivion...

 

I will try my very best  :D   It now needs some polishing of the quest that helps the player to get started in the Display Room, at the first visit. It was a quest i made over a year ago. I will add some warnings in it, informing of the quest delays. Also that I added a timer, a countdown in console if you wanna peek in it if nothing seems to happen. It can take up to 10s before the weapon moves but it will move, sooner or later. At a few occasions, nothing did happen and then I click the rack again and then it adds the weapon immediate. When a weapon is placed at the table, I do tell the Display Room quest to change from 10s delay to 0.2s delay. So at that point it will look like it is fast. But when the weapon leaves the table, and gets added, the quest is set to return to 10s. A book, a manual will be added too at a proper place.

 

Why 10s? Well if you look in that video, it takes approx 10s before the weapon stops to move when it leaves the rack. It have to stop moving and bouncing before i try to put it back again with auto and to make them stop moving, i talked to my NPC and just waited in her inventory for a while so you see when I stoped talking to her, less weapons where moving and sometimes they stopped moving and bouncing. It must stop moving. Otherwise it will fall again. Each rack did had a RAND, so you see that the weapons falls and gets back randomly, one by one. They disturb each others. The collisions that is.

 

If it is set to move back every frame, it can start to shake in place instead, specially at the divider where the weapons are placed in vertical position and that was so annoying and made me pissed of and nervous just watching the show and it lagged some too. I have tried all kinds of different solutions during a year now or more. This latest solution is the one that works best and also give highest possible performance. It is clear now for me when to use Set and when to use Let.  :D  That feels so good. I feel I have control now. (I hope)

 

I do feel some modder's use Object scripts in GameMode to often when it may not be needed. If possible, it can be put in a quest script and the result will be the same. It is up to us to set a proper delay in each quest, depending on the purpose of the quest. I use it as much as possible. I try to limit my quests and add more functions to the ones running right now. One step in a time.  :D   So far, no impact in performance really. Some stuff do not need to be updated every frame.


Edited by Pellape, 09 May 2022 - 11:38 PM.


#6
glowplug

glowplug

    clumsy catbird

  • Premium Member
  • 616 posts

Skimming this thread I'm seeing the same warnings as documented on object/variable name prefix by number.

Let can fail for numeric prefixed object/variable names that will extend through esp/esm parenting - only use Set for these.

If there is any reason to use Set then only use Set.
If there is no reason to use Set then only use Let.

Don't use numeric prefixed variable names when scripting.

 

This should comply OBSE#/COBL.

 

Correct me on whatever I've missed.



#7
Pellape

Pellape

    Faithful poster

  • Members
  • PipPipPipPip
  • 2,068 posts
You can skim this thread as much as you like. Be my guest and write whatever you want glowplug. The more info we can gather, the better, no matter what.
 
Yes, my sorting scripts are not released, not the ones that sorts the 4xxxxxxx stuff. It is for personal use. So the sorting of 4xxxxx with the set commands and the old way of dealing with them are in separate functions. The rest is in separate functions called from a main script:
;main script simple example

Call SortingNumberStuffOLDFunction
Call SortingOtherStuffNewWAYFunction
Call SortMoreStuffNewWAY

;One script for different chests, depending on if it is resources or stuff to auto sell or whatever to keep it organised for my personal setup.
It all works just fine  :wink:
 
Lets see how I do in the end of the New scripts. This is my personal sorter as simple as it can be made I guess but can be used by anyone fancy it:
;bla bla bla - Move Pelts to my Pelts Chest, a Persistent Referenced container

scn PekSortbasicStuff05Fun


array_var ObjectArr

Ref MyItem

Short Turns
Short NumberOfItems
Short ObjectNumber

Begin Function {}


	;***************   Move pelts to Pelts Resource Chest   ******************


	Message "Sorting 05 Started"

	Set Turns to 0
	Let ObjectArr := ar_Construct Array


	Let ObjectArr[0] := WACskinLynx
	Let ObjectArr[1] := WACskinWolfTimber
	Let ObjectArr[2] := WACskinJaguarBlk	

	Let ObjectNumber := ar_Size ObjectArr

	While ( Turns < ObjectNumber )
		Let MyItem := ObjectArr[Turns]
		Set NumberOfItems to player.GetItemCount MyItem
		
		If ( NumberOfItems > 0 )
			Player.Removeitem MyItem NumberOfItems
			PekPeltsChest.AddItem MyItem NumberOfItems
			
			PrintC "Turn %.0f - Moved %.0f of %n", Turns, NumberOfItems, MyItem 
		EndIf
		Let Turns += 1
	Loop

	

	Message "Sorting 05 Done"
End     ;   scn PekSortbasicStuff05Fun

It can be optimized with Foreach instead of While but I like While. I feel comfortable with While-Loop (I do have more than 3 pelts in that static function)



Old way, in separate functions:
	Set MyItem to 4xxxxxxxxxxx
	Set NumberOfitems to Player.getItemCount MyItem
	If ( NumberOfitems > 0 )
		Player.RemoveItem MyItem NumberOfitems
		efShopModItemChestRef.AddItem MyItem NumberOfitems
		PrintC "Moved %.0f of %n", NumberOfItems, MyItem 
	EndIf
It works, 7 lines of code for each item, divided in 3 functions. So much code, so not optimized, but it is needed to deal with 4xxxxxxxx I guess...

I do combine this with my dynamic sorter that I soon release. Sort anyting to anywhere spells. Add and remove chests and items as you like IN GAME during normal playing. Sort whatever you want, when you want. Stop fiddle with manual boring sorting and focus at fun stuff. Sorting your inventory manually is not fun stuff. Dungeon Crawls is funnier. Loot everything, do not bother of cluttered inventory and use auto sorting. I do peek in my inventory AFTER I sorted it, and ussually it is very clean and opens immediatly without LAG. But if I forgot to sort first, then it takes a minute to open it, but it feels like an hour. My cluttered inventory has no impact in game performance, as long as I autoloot and autosort. Inventory is boring. Open a chest manually is boring :D

Edited by Pellape, 15 May 2022 - 10:57 AM.


#8
glowplug

glowplug

    clumsy catbird

  • Premium Member
  • 616 posts

In one way, replying after skimming, especially when over tired, I was mistaken. On the other, your response to that clarifies a lot of what I was missing.



#9
Pellape

Pellape

    Faithful poster

  • Members
  • PipPipPipPip
  • 2,068 posts

Cool. :)   I am overtired all the time, skim stuff, write no sense and babble - Every day...  I better go and take a nap, get some new energy. I do not feel like starting CSE right now really. The bed is calling me...  ;)







Also tagged with one or more of these keywords: set, let

IPB skins by Skinbox
Page loaded in: 0.955 seconds