[Solved!][SCRIPT][X3LU] local variable woes

The place to discuss scripting and game modifications for X³: Terran Conflict and X³: Albion Prelude.

Moderators: Moderators for English X Forum, Scripting / Modding Moderators

Post Reply
lostProfitssssArrgh
Posts: 161
Joined: Tue, 22. Aug 17, 13:14

[Solved!][SCRIPT][X3LU] local variable woes

Post by lostProfitssssArrgh » Mon, 25. Sep 17, 13:07

Hi again!

Is there anything that can prevent a local variable from being manipulated properly?

Like, for example:
- obscure station parameters inherited from the TFile
- being set/accessed by more than one ship
- dataType intricacies
- dynamic link with a $var used to set the local variable
- ...

Thanks again,
-lpa
Last edited by lostProfitssssArrgh on Mon, 25. Sep 17, 16:06, edited 1 time in total.

User avatar
Jack08
Posts: 2993
Joined: Sun, 25. Dec 05, 10:42
x3tc

Post by Jack08 » Mon, 25. Sep 17, 13:24

I'm a bit confused about the question, but if your asking "will there ever be a situation where 'set local variable' will fail", then no... it will never fail.

The engine is single threaded, so you have no race conditions (except perhaps ones of your own making via waits, but no preemtive race conditions). TFiles have no bearings on local variables, local variables have no vartype restrictions, there are no "dynamic" links, the only thing of the sort would be an array/(LU)table, which is set by reference, not by value.

Is there any specific behavior your seeing that you cant explain?
[ external image ]
"One sure mark of a fool is to dismiss anything that falls outside his experience as being impossible."
―Farengar Secret-Fire

lostProfitssssArrgh
Posts: 161
Joined: Tue, 22. Aug 17, 13:14

Post by lostProfitssssArrgh » Mon, 25. Sep 17, 13:54

Jack08 wrote:Is there any specific behavior your seeing that you cant explain?
Damn, I hope this isn't another painful oversight like the other post...



Somehow, the local var $whLocVar attached to $home gets reset when starting the command on a second ship:

Code: Select all

$whLocVar = 'LPA.warehouse.scrapers'
$ship = [THIS]
$home = $ship-> get homebase

* Get number of scrapers
$scrapers = array alloc: size=0
$nullTest = $home -> get local variable: name=$whLocVar

if $nullTest == null
|   * Set the locVar to empty array on creation
|   $home -> set local variable: name=$whLocVar value=$scrapers
else
|   $scrapers = $home -> get local variable: name=$whLocVar
end

if not size of array $scrapers
|   * this when the command is run for the first time
|   append $ship to array $scrapers
|   $home -> set local variable: name=$whLocVar value=$scrapers
else
* Remove duplicates
|   * Manage cases where ships had their command stopped
|   for each $scraper in array $scrapers using counter $s
|       $running = $scraper -> is named script 'Cmd.LPA.ScrapeSanctuaries' on stack of task=0

|       skip if $running
|           remove element from array $scrapers at index $s
|   end

|   append $ship to array $scrapers
|   $home -> set local variable: name=$whLocVar value=$scrapers
end
The local var isn't changed past this point, only read.

User avatar
Jack08
Posts: 2993
Joined: Sun, 25. Dec 05, 10:42
x3tc

Post by Jack08 » Mon, 25. Sep 17, 14:56

Alright, i'm not entirely sure why, but lets simplify your code first.

Code: Select all

$whLocVar = 'LPA.warehouse.scrapers' 
$ship = [THIS] 
$home = $ship-> get homebase 

$scrapers = $home -> get local variable: name=$whLocVar 
if not is datatype[$scrapers] == [DATATYPE_ARRAY]
   $scrapers = array alloc: size=0
   $home -> set local variable: name=$whLocVar value=$scrapers 
end

-----
Past this point, do not ever call set local variable, or get local variable, for $whLocVar, its is unnecessary.

Arrays & (LU) Tables, are stored via references once you set them in globals, you only have to retrieved (and only if you dont already have a reference from setting it). Only these 2 types are stored by reference, everything else (int, string) is stored by value and changes need to be set to be reflected.

Also if this is a LU specific script, consider using a table here instead of an array.

I cant see anything specific in your code that would delete the value, but eliminating excess set calls may help.
[ external image ]
"One sure mark of a fool is to dismiss anything that falls outside his experience as being impossible."
―Farengar Secret-Fire

lostProfitssssArrgh
Posts: 161
Joined: Tue, 22. Aug 17, 13:14

Post by lostProfitssssArrgh » Mon, 25. Sep 17, 16:06

Jack08 wrote:Arrays & (LU) Tables, are stored via references...
...and...

https://forum.egosoft.com/viewtopic.php?t=286717
mark_a_condren wrote:The resulting clone is independent of the source array, which is kind of the whole point of this command. This however does have some ... Quirks ... see example 2.

Example 2.

As described in this topic, arrays copied via normal assignment ($array2 = $array1) share their data.
The clone array command on the other hand, will create an independant copy by copying every element of the source array.
That's what I didn't realize... :headbang:

Further down in my code I had:

Code: Select all

* Check if another scraper is servicing the current station
* Remove current ship from check list...
$serviced = 0
$servChk = $scrapers
$scraperIndex = get index of $ship in array $servChk offset=0
remove element from array $servChk at index $scraperIndex
...
Which according to the definitions above, was actually modifying the original array. So replacing the code with:

Code: Select all

$servChk = clone array  $scrapers : index null ... null
fixes everything.


Who said learning was easy..?
X-Quotes wrote:"Education is a progressive discovery of our own ignorance."

- Will Durant 1885-1981
Indeed sir.



Marking the post as solved. Thanks everyone!
-lpa

User avatar
ubuntufreakdragon
Posts: 5195
Joined: Thu, 23. Jun 11, 14:57
x4

Post by ubuntufreakdragon » Mon, 25. Sep 17, 16:31

Jack08 wrote:

Code: Select all

Past this point, do not ever call set local variable, or get local variable, for $whLocVar, its is unnecessary.
The statement still remainders the reader that the var is changed here, so leaving it inside the code but commented out would be preferable.
And never edit such arrays without copying them first or you change the var, too.
My X3 Mods

XRebirth, things left to patch:
In General; On Firing NPC's; In De Vries; Out Of Zone; And the Antiwishlist

User avatar
Jack08
Posts: 2993
Joined: Sun, 25. Dec 05, 10:42
x3tc

Post by Jack08 » Mon, 25. Sep 17, 17:02

ubuntufreakdragon wrote:
Jack08 wrote:

Code: Select all

Past this point, do not ever call set local variable, or get local variable, for $whLocVar, its is unnecessary.
The statement still remainders the reader that the var is changed here, so leaving it inside the code but commented out would be preferable.
And never edit such arrays without copying them first or you change the var, too.
I'd never say never, most of the time editing the existing (source) array is actually the desired behavior. I've only used the clone array command once in my entire time scripting; Clone array can get very expensive depending on source array size.
[ external image ]
"One sure mark of a fool is to dismiss anything that falls outside his experience as being impossible."
―Farengar Secret-Fire

Post Reply

Return to “X³: Terran Conflict / Albion Prelude - Scripts and Modding”