Author Topic: Trying to set a global variable without using(storage);  (Read 886 times)

ninekorn

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Trying to set a global variable without using(storage);
« on: August 02, 2017, 09:12:47 pm »
Hi,

Ive got this question about creating a global variable in VoidExpanse javascript. Again, its something super easy in Unity3d but im not sure i get it in VoidExpanse. For example i created this script called globalArrays.js to store global variables.

Code: [Select]
var globalSwitchForMining = false;


var globalArrays =
{
miningSwitch: function (args)
    {
globalSwitchForMining = args;
console.Print(globalSwitchForMining + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
    },

isMiningSwitchOn: function ()
    {
console.Print(globalSwitchForMining + "?????????????????????????????????????????????????????????");
return globalSwitchForMining;
    },
};


Then from another script I use this:
Code: [Select]
globalArrays.miningSwitch(true);

if (globalArrays.isMiningSwitchOn() == true)
{
  console.Print("YOU TURNED THE SWITCH ON");
}
else
{
console.Print(" THE SWITCH IS STILL OFF");
}

And in my last script to verify the global Variable i just use:
Code: [Select]
if (globalArrays.isMiningSwitchOn() == false)
{
console.Print("isMiningSwitchOn == false");
}


if (globalArrays.isMiningSwitchOn() == true)
{
console.Print(" WHERE AM I STUCK");
goMineSomeAsteroids();
canFollowPlayer = false;
}

and bam. Houston we've got a problem. the global variable is always false from the third script. If i cant create my own global variables then ill go back to use the using(storage) to set global variables.

ai_enabled

  • AtomicTorch Founder
  • Hero Member
  • *****
  • Posts: 1102
    • View Profile
Re: Trying to set a global variable without using(storage);
« Reply #1 on: August 03, 2017, 03:46:43 am »
Let me clarify how scripting works in VE.
All the JS files are loaded into isolated script engine instances. It means each script in the game (including topics) has independent global space. There are no shared global variables between script instances.
When you import another JS file into your JS file, its code is loaded separately into the same instance. But the global state is still not shared. So when you import another JS file, in fact, you're simply injecting its content into the importing JS file (it's totally different from C# "namespaces" concept, as you see). So that's why we also don't recommend importing huge JS files everywhere - only where you're really need.

Why is scripting in VE so limited? Because it was much easier for us to implement it this way. It allowed us to avoid many future problems. And we also using some global variables per-script/topic (from example, PLAYER_SHIP - when you're inside the topic script).

Another problem with global variables - we cannot serialize them easily and write into the savegame. So even if we had global variables (shared across all the scripts), it will be very easy to write bad code (which will prevent the game from properly saving the game state). So, we have storage scripting API instead. It's also very limited, but for the most cases, it was enough to get the things done.

ninekorn

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Trying to set a global variable without using(storage);
« Reply #2 on: March 18, 2018, 10:26:41 pm »
Hey!

This post is old but I still need some clarifications... So I have 6 scripts that were for the drone AI... 5 of those were libraries. I thought this became an issue since 2 drones seemed to be sharing the same variables... I thought, here we again with the script instances stuff... So I decided to combine the 5 scripts together (except the direction calculations which remains a library).

The AI script that is used by the drone or created at the same time as the drone with generator.addnpcshiptosystem is supposed to be a different "instance" from drone to drone right? So that script contains all functions now and shouldn't those functions be independant from npc to npc?

But my drones still share variables. I don't get it. Aren't they supposed to be different instances?

The main "update" function of the npc "AI" is "function Decision(args)".  I've decided to go crazy and put all I needed inside of there but still it's not working...

So I've found the main culprit. I use an "integer" to go from functions to functions. Example:

Code: [Select]
if(switchFunction == 0)
{
  //fetch list of asteroids
}
else if(switchFunction == 1)
{
    //check inventory if full or not
}
else if(switchFunction == 2)
{
   //Does asteroid still exist and if it does, MOVE to asteroid. check for distance... if distance is reached, switchFunction = 3.
}
else if(switchFunction == 3)
{
   //start mining
}


I don't understand why this really really tiny piece of code is not working... The moment that one drone is within the distance of the asteroid, the second drone that is NOT even near the asteroid stops and starts mining too?! I'm just baffled, we are talking about completely individual instances of scripts here... two drones with their own AI.

Are there limitations in ECMA Script 5 to the number of "else if" statements that can be used in a row?

Anyway... I've done the test "without" that type of "function switches" and my drones are acting normally... I just can't pinpoint why two different instances are somehow "linked"...

Any thoughts on this?
nine

EDIT: The reason I use those "switches" is to avoid "fetching the asteroid list at every frame" or "checking if inventory is full at every frame" (my mining "lasers" take 40 frames approx to mine something and so for 40 frames I am free to "disable" the inventory check) etc.... I don't wanna overload the script or make functions run that don't need to run hence why I use those "switches".








« Last Edit: March 18, 2018, 10:36:55 pm by ninekorn »

ai_enabled

  • AtomicTorch Founder
  • Hero Member
  • *****
  • Posts: 1102
    • View Profile
Re: Trying to set a global variable without using(storage);
« Reply #3 on: March 19, 2018, 12:12:53 pm »
Well, I was not really clear when wrote "All the JS files are loaded into isolated script engine instances".

Imagine that for each JS file (except libs) we create a "script instance". All "include(*.js)" are simply injected (inlined) into the JS file.

That means that we create the script instances only once (during the startup) and then simply reusing them.

And that means we're using the same AI script instance for every NPC ship which shares the same AI script name. So if we Trader.js AI script, we using the same instance of this script for every trader NPC in the game.

And you might have noticed that our AI scripts don't store any variables. If we need to store or access anything, we're using storage API.

Regarding the "switch" - it will not work if the switchFunction variable is global (and so shared across all NPC's using this AI script; BTW, next time you will ever need to debug something like that - wrap all writes of the global variable into a function with console.print() printing current and new values together with ShipID at the function first line - it will be obvious when a global variable is shared as different NPCs will modify the same global variable).

The only way to make it work is to use storage API or "objectives" API (npc.AddObjective(), npc.GetCurrentObjective() - see Trader.js for example).

Regards!

ninekorn

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Trying to set a global variable without using(storage);
« Reply #4 on: March 19, 2018, 05:58:39 pm »
Awesome! Thanks for the clarification ai_enabled!

I now understand... And for the record, there is no such thing as a "maximum number of else if statements" in ECMA script 5 (It was quite dumb to even mention that lol). I just didn't have any other clues why it wasn't working.  ::)

I'm gonna work again on the drone AI Mining/formation AI tonight hoping It will move forward... Lol I think I lost 3 nights in a row just thinking it was global variables of my custom Libraries that were causing the issues... Anyway, I prefer my current version of the Drone AI since it doesn't even lag at spawn even if it's already 1800 lines long. It's starting to get exciting ;) I just can't wait to have a full drone formation that I can send to mine and I am almost there.

thank you
nine

EDIT: Wow... yeah, both patrol.js and trader.js have super easy to understand objectives setuped... I can't believe I missed this the first time around.
« Last Edit: March 19, 2018, 08:20:19 pm by ninekorn »