[Discussion] Generic X3TC S&M questions II

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

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

nap_rz
Posts: 1383
Joined: Sun, 25. Dec 05, 10:42
x3tc

Post by nap_rz »

not sure if this is the right place, but where is that easier hub plot mod?
User avatar
X2-Illuminatus
Moderator (Deutsch)
Moderator (Deutsch)
Posts: 25130
Joined: Sun, 2. Apr 06, 16:38
x4

Post by X2-Illuminatus »

The Community Script & Mod Download Library is the right place to look for the Hub Plot Very Easy version by apricotslice.
Nun verfügbar! X3: Farnham's Legacy - Ein neues Kapitel für einen alten Favoriten

Die komplette X-Roman-Reihe jetzt als Kindle E-Books! (Farnhams Legende, Nopileos, X3: Yoshiko, X3: Hüter der Tore, X3: Wächter der Erde)

Neuauflage der fünf X-Romane als Taschenbuch

The official X-novels Farnham's Legend, Nopileos, X3: Yoshiko as Kindle e-books!
User avatar
s9ilent
Posts: 2033
Joined: Wed, 29. Jun 05, 01:45
x4

Post by s9ilent »

(I'm to busy to make this my self, but I really think someone should make it)


Script Idea:
A standardized community (or bonus pack script) designed to run on game loaded/started, if a script package is present or not.


Why?
Because typically, if you write a script to check if your scripts are installed, that script it self would not be installed, creating this chicken and the egg problem.
By using a lib, it provides an external script (which if adopted by the bonuspack/community as a whole) will gaurentee that the check script is always correct.
The way this works is by using a init. script to run all the checks (so it has a very high loading priority) Which will allow you to handle how your script will halt it self.




Example:
1. You make a plugin.yourscript.IAmInstalled
A simple script, that takes no params, and just returns true.

2. You register your script with the library
so you would so something like
thislib.Register : 'plugin.yourscript.IAmInstalled'

-> When you register this script, It makes a global variable called "Registered." + your script name. So in this case:
Registered.plugin.yourscript.IAmInstalled

3. In your scripts "global" loop, you run a thislib.IsRegistered and it will return true/false.




The idea is that every time the game reloads. All the registrations are rechecked.





Other Ideas:
Auto kill all scripts with name: running on any ship






Who/How to use this?
If you have a script that runs on a continuous loop this script is most suitable for you. Your simply add into your continuous loop

while true
-if not call script thislib.IsRegistered
--return null
-end
-...
end



Benefits versus a handling this your self with a global variable?
hmm... Not to sure tbh...
If in your infite loop script you had cleanup methods in THAT script, it would be the same.
-I guess the key benefit would be the other ideas I had, how it would auto kill all processes. In that it would guarantees the script ends immediately at load, and ends before that script does anything else.
User avatar
EmperorJon
Posts: 9378
Joined: Mon, 29. Dec 08, 20:58
x3tc

Post by EmperorJon »

@ScRaT_GER


Thanks for your script for sorting out the string stuff.

AFAICS, it should work, however I'm getting an infinite loop from it.

Any ideas?


EDIT: Fixed.
______
I'm Jon. I'm mostly not around any more. If you want to talk, please message me! It's cool.
______
h2o.Ava
Posts: 349
Joined: Sun, 12. Oct 08, 04:04
x4

Post by h2o.Ava »

Any one know what is wrong with the following scripts?

First script: runs Main unless Main is running, else it adds the key and vars to the queue.

Code: Select all

* script's input arguments:
key (Var/Number)
vars (Var/Array)

* begin send string to main or queue
$running = get global variable: name='md.control.running'
$queue = get global variable: name='md.control.queue'
if $running
  if not $queue
    $queue = array alloc: size=2
    $q.keys = array alloc: size=0
    $q.vars = array alloc: size=0
  else
    $q.keys = $queue[0]
    $q.vars = $queue[1]
  end
  append $key to array $q.keys
  append $vars to array $q.vars
  $queue[0] = $q.keys
  $queue[1] = $q.vars
  set global variable: name='md.control.queue' value=$queue
else
  = [THIS]->call script 'md.control.main' : key=$key  vars=$vars
  = wait 500 ms
  = wait 500 ms
  = wait 500 ms
  = wait 500 ms
end
Last script: runs Main if there is a queue.

Code: Select all

$queue = get global variable: name='md.control.queue'
if $queue
  $q.key = $queue[0]
  $q.var = $queue[1]
  $key = $q.key[0]
  $var = $q.var[0]
  remove element from array $q.key at index 0
  remove element from array $q.var at index 0
  if size of array $q.key
    $queue[0] = $q.key
    $queue[1] = $q.var
    set global variable: name='md.control.queue' value=$queue
  else
    set global variable: name='md.control.queue' value=null
  end
  START [THIS]->call script 'md.control.main' : key=$key  vars=$var
else
  set global variable: name='MD.Control.Running' value=[FALSE]
end
The problem is that the first script overwrites the entire queue array with the newest data while increasing the array size by 1.
Meaning: If the queue array has 2 entries, then adding a new unique 3rd entry will create a size 3 array with 3 identical values which are equal to the new 3rd entry.
User avatar
ScRaT_GER
Posts: 1962
Joined: Tue, 8. Jan 08, 18:19
x3tc

Post by ScRaT_GER »

$running = get global variable: name='md.control.running'
set global variable: name='MD.Control.Running' value=[FALSE]
Why are these global variables named differently?
The problem is that the first script overwrites the entire queue array with the newest data while increasing the array size by 1.
Okay, but what does the second script do?
Meaning: If the queue array has 2 entries, then adding a new unique 3rd entry will create a size 3 array with 3 identical values which are equal to the new 3rd entry.
That seems very odd. What does md.control.main do? Are you aware of the fact, that arrays behave like pointers to the real data? So if md.control.main gets an array an manipulates it somehow, it wouldn't be local to the script, but to every reference to that array.

Your code looks right to me, so maybe the error doesn't arise there?

Greetings,
ScRaT
User avatar
s9ilent
Posts: 2033
Joined: Wed, 29. Jun 05, 01:45
x4

Post by s9ilent »

(Consider reading my below post before reading this one)

Code: Select all

if $running
  if not $queue
    $queue = array alloc: size=2
    $q.keys = array alloc: size=0
    $q.vars = array alloc: size=0
set global variable: name='md.control.queue' value=$queue <--------------------------Put here instead
  else
    $q.keys = $queue[0]
    $q.vars = $queue[1]
  end
  append $key to array $q.keys
  append $vars to array $q.vars
*  $queue[0] = $q.keys <--------------------------Not required
*  $queue[1] = $q.vars <--------------------------Not required
*  set global variable: name='md.control.queue' value=$queue <--------------------------Not required here, put inside if not instead
else
  = [THIS]->call script 'md.control.main' : key=$key  vars=$vars
  = wait 500 ms
  = wait 500 ms
  = wait 500 ms
  = wait 500 ms
end

Code: Select all

if size of array $q.key
    $queue[0] = $q.key
    $queue[1] = $q.var
    set global variable: name='md.control.queue' value=$queue <---- once again not required
  else 

The lines are not required, because the global var/array already contains the child array. After modifying the child array (via append/remove) you do not need to set parentarray = childarray, nor do you need to set globalvar = array again.






Code: Select all

$q.key = $queue[0]
  $q.var = $queue[1]
  $key = $q.key[0]
  $var = $q.var[0]
  remove element from array $q.key at index 0
  remove element from array $q.var at index 0 
I seem to have lost my comments on this bit of code... (its probably above/below)
Basically by removing now, if size = 0, you null the variable (BEFORE running the main script). Thus , if you run the first script again (right now, before main completes) it will have multiple instances







Suggested change (not very relevant)

Rather then doing:
If running, add to que
If not running, DONT add to que, start new with values

Consider separating the two, always adding to que, and start if not running. Just so the method used to start/que are separate, and consistent within them selves.



Second suggestion change
Seeing as how your using a [key,value] pair, I would consider, instead of having array{ array of keys, array of values } -> array[2,N]
Instead consider array { array{key,value}} -> array [N,2], so each row, is your key-value pair.





Note, your code seems to demonstrate a slight misunderstand of arrays and reference (aka pointer) variables. (I do apologize if this sounds a bit cold).
I've made a post about it on the MSCI hidden forum
link

Generally speaking, modifying an array, does not require set'ing it again. (I hope that makes sense :S it made more before i typed it...)

i.e.
The problem is that the first script overwrites the entire queue array with the newest data while increasing the array size by 1.
Meaning: If the queue array has 2 entries, then adding a new unique 3rd entry will create a size 3 array with 3 identical values which are equal to the new 3rd entry.
The original array, with 2 elements in it, IS, the array with 3 elements in it now. There is no oldoriginal[2] and neworiginal[3]. There is just the one array, original[n] (And n just happens to be 3 at the moment)







Note, the extra sets you have used are NOT causing any problems. I suspect a potention problem you have is here:

remove element from array $q.key at index 0
remove element from array $q.var at index 0
if size of array $q.key
$queue[0] = $q.key
$queue[1] = $q.var
set global variable: name='md.control.queue' value=$queue
else
set global variable: name='md.control.queue' value=null
end
START [THIS]->call script 'md.control.main' : key=$key vars=$var

You "clear" the variable BEFORE, it is run. Meaning that if there was only 1 in the que, you remove it, and run. So if you start the top script again, it will see the que is empty, and start another instance. (assuming your MD.Control.Running takes more then 0ms to run, resulting in multiple instances running at once)




Hope that's not too confusing :S






Oh one more thing. (suggestion) I generally suggest not having a bool running/notrunning. I would recommend instead using a 3state (or more),
running, shutdown, notrunning.

Because if you start and stop on a 2 state variable (before the script realizes it should have stopped), it will start 2 instances.
e.g. 2state
state = not running
Start. New script starts, state = running (script will check variable in x seconds)
Signal Stop. state = not running
Start again. state = running (before x seconds are up, new instance of script starts)
Original started script, checks the variable, and it says running, so it continues running. You now have instances running.

e.g. 3 state
State = not running
start, state = running, new instance of script
stop, set state to shutdown
start, if (state shutdown) { state= running}, if (state not running){new instace, state running}
Last edited by s9ilent on Tue, 21. Dec 10, 01:54, edited 1 time in total.
User avatar
s9ilent
Posts: 2033
Joined: Wed, 29. Jun 05, 01:45
x4

Post by s9ilent »

Rather than suggesting the 50 billion additions to your script, I thought it might help if I gave an example (in psuedo code)




1. Start script
Get global var que
if not global
-create it save it
end
* (using array[n,2] instead of array[2,n])

get global var state
if state = running
-return
else if state = shutdown
-state = running
else
-state = running
-Start new instance of main script (passing no variables)
end
return




2. Main script
get global var que
while true
-
-if state = shutdown
--state = not running
--return
-end
-
-size global var que
-skip if size > 0
--return
-
-current = que[0] or que current = que[size-1] (fifo/lifo which ever suits your requirements)
-que -> remove element from index (0/size-1, which ever you chose)
-
-do work
-
-
end
h2o.Ava
Posts: 349
Joined: Sun, 12. Oct 08, 04:04
x4

Post by h2o.Ava »

Thank you both very much.
I indeed did have a misunderstanding of arrays and I can't believe I typo'd that global variable, should all be lowercase.

:)

Onward!


Sample data:
queue.array (key.array, vars.array)
key.array (key0, key1, etc)
key0 (9, 0, 0, 0, 0, 0)
key1 (5, 2, 5, 3, 1, 1)
vars.array (vars0, vars1, etc)
vars0 (0, 3, 1505)
vars1 (1, 1, 2055)

$q.key = $queue[0]
$q.var = $queue[1]
$keys = $q.key[0]
$var = $q.var[0]
is to withdraw the correct array.

control.main extracts the data from the arrays.

I'm using remove element to delete an entire array.

control.key is a gatekeeper, if there isn't a queue and main isn't running then it sends it to main. if it is running then it creates a que or appends it to the que. while running, only the que can send it to main. I can't see how I could use 3 variables in this instance.

standard flow pattern:
Key
Main
Reset
Key
Main
Reset
end

key is called multiple times before reset flow pattern:
key
main
key -> queue
key -> queue
reset
main <- queue
reset
main <- queue
end

the error i'm seeing is this:
queue.array (key.array, vars.array)
key.array (key0, key1, etc)
key0 = key4
key1 = key4
key2 = key4
key3 = key4
key4 = (9, 0, 0, 0, 0, 0)
vars.array (vars0, vars1, etc)
vars0 = vars4
vars1 = vars4
vars2 = vars4
vars3 = vars4
vars4 = (1, 1, 2055)
User avatar
Gazz
Posts: 13244
Joined: Fri, 13. Jan 06, 16:39
x4

Post by Gazz »

s9ilent wrote:Script Idea:
A standardized community (or bonus pack script) designed to run on game loaded/started, if a script package is present or not.

The idea is that every time the game reloads. All the registrations are rechecked.

Auto kill all scripts with name: running on any ship

Benefits versus a handling this your self with a global variable?
hmm... Not to sure tbh...
For at least one of my scripts (I think MD Mk2) I use a live zero signal to determine if the script is installed and active.
(lastloadtime is useful there as a time stamp that stays constant with a game session)

Other scripts would still check a global variable to determine the state.
Should the MD Mk2 scripts ever be deleted without cleanup, the global variable would still be there but have an invalid value, showing that the script is not present in a working state.


That can cover the most likely blunder - deleting the script files without using a proper uninstall.
If the user is more creative about sabotaging his installation, like with deleting some files of a script package, well... every scripter would recommend a reinstall to fix that mess.


This requires no "official" watcher script but offers a similiar functionality.
My complete script download page. . . . . . I AM THE LAW!
There is no sense crying over every mistake. You just keep on trying till you run out of cake.
h2o.Ava
Posts: 349
Joined: Sun, 12. Oct 08, 04:04
x4

Post by h2o.Ava »

the bug is in here:

Code: Select all

$queue = get global variable: name='md.control.queue'
if $running
  if not $queue
    $queue = array alloc: size=2
    $q.keys = array alloc: size=0
    $q.vars = array alloc: size=0
  else
    $q.keys = $queue[0]
    $q.vars = $queue[1]
  end
  append $key to array $q.keys
  append $vars to array $q.vars
  $queue[0] = $q.keys
  $queue[1] = $q.vars
  set global variable: name='md.control.queue' value=$queue
end
I'm intending this code to get the global variable array of arrays of arrays (i made it into two global arrays of arrays and it was still broken) add one array to each of the deepest arrays then recompile the arrays and save it to the global variable.

every time it gets the global array of arrays of arrays it loses its reference (i'm guessing). The every array entry in the array $q.vars becomes equal to the array $keys.

any idea on how to create a que mechanism where the first is run though a script one at a time?
Free cookies if you throw one together for me. :P
I've spent way too long trying to get this to work.. it's burning me out.
User avatar
s9ilent
Posts: 2033
Joined: Wed, 29. Jun 05, 01:45
x4

Post by s9ilent »

View my first post, about where you should put the set, for the global var in the ifnot, and remove the unnecessary lines.

But that bit of code is fine, (you are setting too often, but it should not cause any errors)

Which suggests your errors are else where.
User avatar
Gazz
Posts: 13244
Joined: Fri, 13. Jan 06, 16:39
x4

Post by Gazz »

A far more reliable check would be

Code: Select all

$queue = get global variable: name='md.control.queue'
if $running

$index =  size of array $queue
skip if $index > 1
$queue = null
if not $queue is of variable type [array]
...
That filters out any gibberish you might have in there from your tests.


Personally, I'd also move the SET but that's mainly for understanding...

$queue = array alloc: size=2
set global variable: name='md.control.queue' value=$queue
My complete script download page. . . . . . I AM THE LAW!
There is no sense crying over every mistake. You just keep on trying till you run out of cake.
h2o.Ava
Posts: 349
Joined: Sun, 12. Oct 08, 04:04
x4

Post by h2o.Ava »

edit: removed erroneous information
Last edited by h2o.Ava on Fri, 24. Dec 10, 00:36, edited 2 times in total.
User avatar
Gazz
Posts: 13244
Joined: Fri, 13. Jan 06, 16:39
x4

Post by Gazz »

h2o.AvA wrote:If you set an array as a global variable.
Then you must clone that array before you can send it to another script or set it as global/local.
That is not true.
Your mistake is probably to see the array as a "physical thing".

An "array" is always always always (yes, I mean it) a pointer to the place where the array actually resides.

You can pass this pointer to as many scripts as you like and they all will access the exact same array at the same time.
My complete script download page. . . . . . I AM THE LAW!
There is no sense crying over every mistake. You just keep on trying till you run out of cake.
h2o.Ava
Posts: 349
Joined: Sun, 12. Oct 08, 04:04
x4

Post by h2o.Ava »

!! You are right, that isn't how I got it working.. that was the process I attempted before I got it working.
Sorry, the true solution is:

Working code using unique arrays every time the create queue script ran:

create queue:

Code: Select all

$running = get global variable: name='md.control.running'
if $running == [TRUE] 
  $q.num = get global variable: name='md.control.q.num'
  inc $q.num =
  set global variable: name='md.control.q.num' value=$q.num
   
  $q.num = convert number $q.num to string
  $q.k = 'md.control.queue.key' + $q.num 
  $q.v = 'md.control.queue.var' + $q.num 
   
  set global variable: name=$q.k value=$key.array
  set global variable: name=$q.v value=$vars.array
   
  = wait 20 ms
else
  set global variable: name='md.control.running' value=[TRUE]
  START [THIS]->call script 'md.control.main' : key=$key.array  vars=$vars.array
end
run queue:

Code: Select all

$q.num = get global variable: name='md.control.q.num'
if not $q.num 
  set global variable: name='md.control.running' value=[FALSE]
else
  $q.pointer = get global variable: name='md.control.q.pointer'
  inc $q.pointer =
  set global variable: name='md.control.q.pointer' value=$q.pointer
  if $q.pointer <= $q.num 
    $q.pointer = convert number $q.pointer to string
    $q.k = 'md.control.queue.key' + $q.pointer 
    $q.v = 'md.control.queue.var' + $q.pointer 
    $key.array = get global variable: name=$q.k
    $vars.array = get global variable: name=$q.v
     
    START [THIS]->call script 'md.control.main' : key=$key.array  vars=$vars.array 
    set global variable: name=$q.k value=null
    set global variable: name=$q.v value=null
  else
    set global variable: name='md.control.q.pointer' value=null
    set global variable: name='md.control.q.num' value=null
    set global variable: name='md.control.running' value=[FALSE]
  end
   
end
Where does it actually reside?
The non-working script is run by null and creates the multi-array, then sets it to a global variable. Then the script is run a 2nd time by null with new input single-arrays, then appends the new inputs to the multi-array. The process repeats.
I think it was overwriting the data at its location, thus the pointer was pointing to the script. Each time the data changed the pointer location was the same for every appended entry, thus resulting in a bad multi-array [[4,4,8000],[4,4,8000],[4,4,8000]] instead of the correct multi-array [[1,5,300],[6,7,200],[4,4,8000]].
Last edited by h2o.Ava on Fri, 24. Dec 10, 00:36, edited 2 times in total.
User avatar
Gazz
Posts: 13244
Joined: Fri, 13. Jan 06, 16:39
x4

Post by Gazz »

h2o.AvA wrote:Don't set multidimensional arrays as global variables.
Working code using single dimension arrays only:
There is no such thing as multi-dimensional arrays in X3 so any such distinction is flawed. =)

An array can contain other arrays, yes - but the content of an array (even if it's other arrays) makes no difference whatsoever to it's pointer.
And the pointer is the only value you ever transfer to a variable or to another script.

Sometimes I have wrapped up several arrays into one array just so I could put the entire structure into a single global variable and pass it to multiple scripts. One array, one pointer, one value...

The most common issue with arrays is not getting the pointer thing. Once you wrap your head around that one, the problem won't even exist because it's so obvious...
Last edited by Gazz on Fri, 24. Dec 10, 00:28, edited 2 times in total.
My complete script download page. . . . . . I AM THE LAW!
There is no sense crying over every mistake. You just keep on trying till you run out of cake.
User avatar
ScRaT_GER
Posts: 1962
Joined: Tue, 8. Jan 08, 18:19
x3tc

Post by ScRaT_GER »

Don't set multidimensional arrays as global variables.
I do that ALL the time. ;)

There is no problem with that.

Greetings,
ScRaT
h2o.Ava
Posts: 349
Joined: Sun, 12. Oct 08, 04:04
x4

Post by h2o.Ava »

edited the prior post.
Perhaps the issue is that I was using the same script to edit the same array, thus creating unique arrays every time fixed it.





Any other colors besides these?
[BLUE]
[CYAN]
[GREEN]
[MAGENTA]
[RED]
[VIOLET]
[WHITE]
[YELLOW]
mark_a_condren
Posts: 1468
Joined: Wed, 3. Aug 05, 05:05
x3tc

Post by mark_a_condren »

@h2o.AvA
Any other colors besides these?
You can find info on available colors here.

MarCon Utilities / Demos
See second post.


MarCon

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