[SOLVED] GLOBAL VARIABLE : really ?

Started by Baguettator, Sat 27/06/2020 20:50:10

Previous topic - Next topic

Baguettator

Hi every one,

I post here for a problem I don't understand, really I can't figure out why it doesn't work...

I have defined 10 global variables : zombies1, zombies2, zombies3 etc... until zombies10.

Thanks to that, these variables can be used and verified in any script, aren't they ?

So, in the script of the room 7, I wrote something like :

Code: ags
zombies1=Random(11);
zombies2=Random(11);
zombies3=Random(11);
zombies4=Random(11);
zombies5=Random(11);
zombies6=Random(11);
zombies7=15;
  zombies8=15;
  zombies9=15;
  zombies10=15;


That way, I have some buttons that get visible if I need them : Pionzombie1, Pionzombie2, Pionzombie3 etc... until Pionzombie10 (to explain the whole thing : if Pionzombie1 has to be seen, there is a chance that it become visible, so I make zombie1=Random(11) and if (zombie1 < 3)  Pionzombie1.Visible=true;   Anyway, that doesn't matter, it not the point of my problem).

So after these variables have been assigned to a value (a Random for some of them, and a fixed value of 15 for the others), I have a button that is scripted like that :

Code: ags
if (Pionzombie1.Visible==true && zombies1 < 12) Pionzombie1.Visible=false;
else if (Pionzombie1.Visible==false && zombies1 < 12) Pionzombie1.Visible=true;
if (Pionzombie2.Visible==true && zombies2 < 12) Pionzombie2.Visible=false;
else if (Pionzombie2.Visible==false && zombies2 < 12) Pionzombie2.Visible=true;
if (Pionzombie3.Visible==true && zombies3 < 12) Pionzombie3.Visible=false;
else if (Pionzombie3.Visible==false && zombies3 < 12) Pionzombie3.Visible=true;
if (Pionzombie4.Visible==true && zombies4 < 12) Pionzombie4.Visible=false;
else if (Pionzombie4.Visible==false && zombies4 < 12) Pionzombie4.Visible=true;
if (Pionzombie5.Visible==true && zombies5 < 12) Pionzombie5.Visible=false;
else if (Pionzombie5.Visible==false && zombies5 < 12) Pionzombie5.Visible=true;
if (Pionzombie6.Visible==true && zombies6 < 12) Pionzombie6.Visible=false;
else if (Pionzombie6.Visible==false && zombies6 < 12) Pionzombie6.Visible=true;
if (Pionzombie7.Visible==true && zombies7 < 12) Pionzombie7.Visible=false;
else if (Pionzombie7.Visible==false && zombies7 < 12) Pionzombie7.Visible=true;
if (Pionzombie8.Visible==true && zombies8 < 12) Pionzombie8.Visible=false;
else if (Pionzombie8.Visible==false && zombies8 < 12) Pionzombie8.Visible=true;
if (Pionzombie9.Visible==true && zombies9 < 12) Pionzombie9.Visible=false;
else if (Pionzombie9.Visible==false && zombies9 < 12) Pionzombie9.Visible=true;
if (Pionzombie10.Visible==true && zombies10 < 12) Pionzombie10.Visible=false;
else if (Pionzombie10.Visible==false && zombies10 < 12) Pionzombie10.Visible=true;


Assuming that when zombie1=15, Pionzombie1 isn't Visible, and won't be visible at all because we don't need it. So when I click on the button, all the "Pionzombie" that are visible (with the value of Random(11) ) become Invisible. If I want them to become Visible again, I click again on the button. Normally the "Pionzombie" that we don't need to show in any case won't change Visible or Invisible, because their attached variable is equal to 15 (so >12).

The problem is that when I click the button, ALL the "Pionzombie" that are Visible (those with an attached variable equal to Random(11) ) become invisible, and ALL the "Pionzombie" that are Invisible (those with an attached variable equal to 15) become Visible. When I click again on the button, the exact opposite results. When I check the value of the variables during the game, I can see that the variables have the right value that I want them to be (Random(11) or 15, depending of the case).

So, the problem is that the script of the button is not checking the value of the Global Variable. The condition "zombie10 < 12" is true if zombie10=Random(11), but also if zombie10=15.

Maybe I didn't understand how Global Variables work ? It is like the game don't read the values like I need...

If someone understand my problem and know a way to explain that... That will be helpful !! :)

Crimson Wizard

How and where exactly did you define these variables, can you show how do you declare them?

Also, where in the room script do you set them up?

Baguettator

These variables are defined in the Global Variables Pannel, with a starting value of 0.

In the room, they are defined in Room_before fade in.

After the fade in, when I check the values, the values are the good one I attempted : Random(11) in some cases, or 15 for the others.

But the script of the button (this button is in a GUI that appears before the fade in too) is in the Global script, and it is like it doesn't know that these variables aren't equal to 0 (or anything else < 12...)

I thinked that Global Variables are readable for each scripts, even the rooms. But... there is something I don't understand...

Crimson Wizard

Quote from: Baguettator on Sat 27/06/2020 21:25:04
I thinked that Global Variables are readable for each scripts, even the rooms.

This is true, and this is how they suppose to work.

What you describe sounds like what happens when you declare them in script header incorrectly (without import keyword), because in such case every script creates its own separate variables.

To double check, you have not put variable declaration in script header anywhere and just have them in Global Variables panel?

If not, maybe there are reset to 0 somewhere in script?

Cassiebsg

QuoteBut the script of the button (this button is in a GUI that appears before the fade in too) is in the Global script

Isn't Global script read before room script?

Think like, CW says, you need to post all your code that deals with these functions, also the code where you call the GUI.
There are those who believe that life here began out there...

Baguettator

No, they are not reset to 0 elsewhere because I made a "Display" that show their values when I press a key, and it shows me that they have the value that I intended.

The GUI with the button that make the "Pionzombie" Visible or Invisible is scripted in Global Script, as far I know, it is an obligation, I can't put a function "Button_OnClick" elsewhere. Maybe I'm wrong ?

All the codes are given in my first post. The GUI is set to Visible in the Room_before fade in. The button's script is in my first post, in the Global Script. These variables are NOT anywhere that in the Global Variables Panel. And even if the variable zombie9=15, when I click on the button, "Pionzombie9" get Visible or invisible, even if I scripted :

Code: ags
if (Pionzombie9.Visible==true && zombies9 < 12) Pionzombie9.Visible=false;
else if (Pionzombie9.Visible==false && zombies9 < 12) Pionzombie9.Visible=true;


So... I'm a bit lost :)

Cassiebsg

Can you copy/paste the entire code? Including the function names?

This should not make a difference, but try changing < to <=or =< ... if it makes a difference then something is off with the engine logic.

Code: ags

    if (Pionzombie9.Visible==true && zombies9 < 12) 
   {
      Pionzombie9.Visible=false;
      Display(String.Format("pionzombie9 was true and zombies9 = %d"), zombies9);
    }
    else if (Pionzombie9.Visible==false && zombies9 < 12) 
      {
       Pionzombie9.Visible=true;
       Display(String.Format("pionzombie9 was false and zombies9 = %d"), zombies9);
      }


Also, try calling the GUI, after setting the variables. That is At the end of your if/else conditions.
There are those who believe that life here began out there...

Mandle

Quote from: Baguettator on Sat 27/06/2020 21:25:04
These variables are defined in the Global Variables Pannel, with a starting value of 0.

In the room, they are defined in Room_before fade in.

If a variable is global you don't need to define it in any room scripts. You can just use it everywhere.

Crimson Wizard

#8
Quote from: Baguettator on Sat 27/06/2020 21:25:04
In the room, they are defined in Room_before fade in.


Thanks to Mandle, I realized that I missed this sentence.
By that do you simply mean "used", or do you actually redeclare them second time inside a function? Because if you do that means you created separate local variables under same name, and that is another case that could explain what's happening.


Another unrelated thing, just an advise, your code may be simplified.
Code: ags

if (Pionzombie1.Visible==true && zombies1 < 12) Pionzombie1.Visible=false;
else if (Pionzombie1.Visible==false && zombies1 < 12) Pionzombie1.Visible=true;

This may be written as
Code: ags

if (zombies1 < 12) Pionzombie1.Visible = !Pionzombie1.Visible;


The "!" means "negate value", so you are assigning opposite value of Pionzombie1.Visible to Pionzombie1.Visible.

It could be reduced further if for example you used array instead of 10 variables, but I won't go there before the main problem is fixed.

Khris

I recreated this using 5 variables, initialized the first three to Random(11) and the remaining two to 15.
The button code works exactly as expected: only the first three buttons are toggled when I click the button that calls the visibility code.


Baguettator

If by "defined" you mean that I wrote :
Code: ags
int zombies1=0


So my answer is : NO, in the room before fade in, I didn't wrote that. Just :

Code: ags
zombies1=15
//a lot of script that doesn't link with the problem

zombies1=Random(11);


I really don't know what happens. I tried with something like :
Code: ags
if (zombies1 > 30) Pionzombie1.Visible = !Pionzombie1.Visible;


And, hurra, nothing happens. I check the values, they are all under 30 (15 or Random(11) ).

But with the good code, I check the values before, it shows the right values, but each button is affected like each variable was < 12...

I check in the Global Variable Panel for "find all usages" of the variables, no problem from that side.

I really don't understand what is happenning... It's a good thing that Khris managed to get it working, that shows that AGS engine has no problem. But I have a problem (certainly my head's engine ^^ )

Baguettator

Another detail : I'm using AGS 3.50. Source of the problem ?

Baguettator

OOOOOOOOOOOOOOOOOOOOOOOOOOWWWWWWWW....

I'M SOOOOOOOOO SOOOOOOOOOORRRRRRYYYYYYYYYYY...

I realized my mistake...

Everything is working ! I just forgot something, it is a bit long to explain, but it is like "I want Pionzombie1 visible if zombies1<3, so I write zombies1=Random(11), and if the luck is with me, Pionzombie1 will be Visible, and by clicking a button I will set it Invisible or Visible again. The problem was that if zombies1 > 3, it is ALSO < 12 (because : RANDOM(11) !!!), so if I want that only the Pionzombie that have been "chosen" (with their attached variables < 3 when they are set to Random(11) ), I have to do something like that :
Code: ags
zombies1=Random(11);
zombies2=Random(11);
zombies3=Random(11);
zombies4=Random(11);
zombies5=Random(11);
zombies6=Random(11);
zombies7=Random(11);
zombies8=Random(11);
zombies9=Random(11);
zombies10=Random(11);

if (zombies1 < 3)
{
  Pionzombie1.SetPosition(346, 336);
  Pionzombie1.Visible=true;
}
else zombies1=15; // the LINE of the HELL
if (zombies2 < 3)
{
  Pionzombie2.SetPosition(464, 336);
  Pionzombie2.Visible=true;
}
else zombies2=15; // again the LINE of the HELL
// etc until zombies10 and Pionzombie10...


So, to conclude : scripting is a good work to loose weight, because by get fire in your head, you loose a LOT of calories :)

Many thanks to those that tried to help me ! AGS has no problem, the men and women that worked on that are genious :D

And "Spaciba Balchoï" :p

Khris

#13
Right, glad you found the problem :)

Now let's move this to arrays:

Code: ags
// global header
import int zombies[10];

// top of global script
int zombies[10];
export zombies;


This creates ten global variables,  zombies[0]  through  zombies[9].

In your button code, you can now do something like:

Code: ags
  for (int i = 0; i < 10; i++) {
    if (zombies[i] < 12) gZombies.Controls[i].Visible = !gZombies.Controls[i].Visible;
  }


(Assuming that Pionzombie1 is the first Control of the GUI and has an ID of 0, and so on; otherwise you need to use  i + 1  to offset accordingly)

Regarding the placement, using the same loop:
Code: ags
  gZombies.Controls[i].SetPosition(346 + i * 100, 336);
  gZombies.Controls[i].Visible = zombie[i] < 3;

Baguettator

Many thanks Khris and Crimson Wizard for the help to "simplify" the code !

About that, I was asking myself : is bad scripting a reason that the game could be "heavier" than it could be ?

By "heavier", I mean it can be 1,5 Go for the whole built game whereas it could be only 1 Go if the code has been simplified (less lines, so liter ?), and if the number of GUIS or buttons has been reduced to the strict needed.

In fact, as I started scripting with AGS a month ago, from the beginning (no experience in that at all), I realize that I have already scripted a lot of things that I could simplify a LOT, and maybe it could make the game a bit liter than it is actually.

For example : in many situations, I made several GUIS that have the same "design", exactly the same, only the "text" of the button is different and of course the script of each button is different, but very short and not so much different. I think it could be easily simplified to one GUI with the "design" needed, and the NormalGraphic of the button can change when the GUI is called, according to the situation. Then, the script can easily be reduced to the "generic buttons" script, with conditions "if/else".

Other example : A GUI with a LOOOOOT of buttons, because I need 50 buttons (1 for each character), and when I click one of them, the button disappear and a new one (at the same position) appears, with the only difference of a green cross on the character to show if it has been selected. It results in 100 buttons, while I think I can reduce that to 50, and only change the NormalGraphic when it is clicked. For the script, with "bool" and "int", I can easily reduce a "two buttons script" in "one button script" with conditions.

So, by reducing the script height and the number of GUIS and Buttons, I think it could decrease the Game Size. What do you think about that ? :)

Snarky

#15
Inefficient scripting makes no significant difference to game size (it could potentially cause it to run slower), but reducing GUIs and buttonsâ€"as long as you also delete the associated spritesâ€"might.

The game size is almost entirely made up of graphics (sprites and room backgrounds) and audio. Importing the same graphics multiple times, or being inefficient when you have small variations (huge sprites that are nearly exactly the same except for a small difference, instead of just having the static part as one sprite and the bit that varies separately) tends to bloat the game size. Also avoid excessive frame-by-frame animations, which should instead be done as videos. If an animation is more than say 100 frames (of individual sprites), you may want to rethink. Many things can be done in-engine instead of being pre-rendered as separate sprites. Similarly, many, large room backgrounds take up a lot of space, and there are ways to store them more efficiently (typically using tile-based drawing or other standard elements that you can reuse in order to create different rooms from the same small set of graphics).

For audio, it's mostly about using efficient sound compression, e.g. OGG format (and of course not importing the same sound multiple times, or sound you're not using).

Edit: That's not to say that you shouldn't simplify and clean up your code. Bad code is difficult and tedious to work with, and can drain your energy for working on the game. If you've learned a significantly better way to do it, it's often worth going back and fixing it. (Though at the same time, if it works, you shouldn't put so much work into polishing it that you don't make any other progress.)

Crimson Wizard

Quote from: Snarky on Tue 30/06/2020 08:24:04
Edit: That's not to say that you shouldn't simplify and clean up your code. Bad code is difficult and tedious to work with, and can drain your energy for working on the game. If you've learned a significantly better way to do it, it's often worth going back and fixing it. (Though at the same time, if it works, you shouldn't put so much work into polishing it that you don't make any other progress.)

Right, this is the first reason to simplify the code :) Improving game's perfomance is a reason to optimise it, but that's kind of a different thing (and sometimes you have to write more complex code when doing that).

Baguettator

OK, thanks a lot for your replies about decreasing the Game's Size. Effectively I could  decrease that by separating existing sprites in several sprites (one for the part that doesn't change, for example the "background" of a button, and other sprites for the part that changes, for example the "text" of the button.). Maybe also by using "labels" for some texts, but labels are less "flexible" for text alignment, so I have to test before.

About audio's format (OGG you said), I will take a look at that. It won't be difficult to change that quickly since I use a very few audios in my game, and it is still not ready to play.

What's about image's format ? I'm using basically PNG and BMP, but I didn't think a lot about that, and I am not an expert about compressing the image, or choose the right format...

Khris

AGS imports images and uses its own format to store them. The original filesize / format doesn't matter.

SMF spam blocked by CleanTalk