Global Variables in AS3

EDIT – 09/03/09 I decided to update this article in response to some of the comments about the potential dangers of using global properties. Its a convenient way to store variables that are accessible from anywhere in your project, but with great power comes great responsibility :).

Yes, we know it can get sloppy, but sometimes is just makes sense to create variables that are accessible from anywhere in your project.

Prior to AS3 it was really easy… there was the _global object: _globals.myvar = 'mystring'. You are most likely reading this because you are trying to use the _global object in AS3. Ecmascript (the standard on which AS3 is based) does not support this notion, rather it forces you to create your own globally accessible object if you so desire. They are encouraging instance based data coupling, because it’s a lot more structured and less error prone. If you are working on a large application, I will encourage you to not use global variables (especially if unit testing is a requirement). However, if you don’t give a damn about what us programming snobs say, have no idea what unit testing is, or just want to use some global variables in AS3, then don’t feel bad, they can be quite handy!

So how do we create variables in AS3 that are globally accessible from anywhere a project? Well, its as easy as building a class with a static variable container. Let’s use an Object as our variable container as they are dynamic meaning we can add properties (our variables of any type) at runtime. Here is the class:

package com.greenethumb.utils 
{
    public class GlobalVarContainer 
    {
        public static var vars:Object = {};
    }
}

To use this global variable container, just import GlobalVarContainer into whatever class you would like to read/write/create your global variables. Here is a sample:

package 
{
    import flash.display.Sprite;
    import com.greenethumb.utils.globalvars.GlobalVarContainer;
    public class Main extends Sprite
    {   
        public function Main()
        {   
            GlobalVarContainer.vars.groupingID  = 1 
            GlobalVarContainer.vars.mediaID = 4 
            GlobalVarContainer.vars.facultyID = 5 
            GlobalVarContainer.vars.studentID = 2 
        }
    }
}

Werd up… globally accessible vars in AS3

56 Responses to 'Global Variables in AS3'

  1. syler says:

    thanks, I’m confused by this problem.

    this post is great help to me.

  2. atishay says:

    but how do you do access the global variable from inside the fla file.

  3. Jon says:

    hey atishay,

    the _globals object no longer exists in AS3. It is not a part of the Actionscript Virtual Machine 2 (Flash player 9’s AS3 runtime). You can use this static GlobalVarContainer class to replicate the functionality of the _globals object. If you need to reference the GlobalVarContainer in your FLA, you do it the same way as you would access it from a class in a package: import the GlobalVarContainer class and read and write properties to its vars property. Hope that clears things up.

  4. Johan Nyberg says:

    Thanks Jon, this was really helpful!

  5. Johan Nyberg says:

    One question – where is the document class instanciated? Is there a way for other objects in the fla to access public properties of the document class?

    Can’t seem to find your email on the site, so it you care to drop me a line I’d be really grateful. :-)

  6. Jon says:

    Hey Johan, the Document Class is instantiated when your SWF is initialized. The Flash Player will automatically call the constructor function of your Document Class when your SWF initializes. If you do not specify a Document Class for your project, the compiler will automatically create a MovieClip instance an assign it as your project’s document class.

    It is possible to reference members of the your Document class from other elements in your FLA. For more details on that have a look at http://greenethumb.com/article/23/understanding-root-and-the-document-class-in-as3.

  7. hey, just a heads-up re AS3’s ‘static’ keyword. i’m not sure whether this is a bug or a deliberate design decision, but the ‘static’ness of a variable does not propagate up the document tree to the root.

    let me give an example. suppose you have a document class MyDocumentClass that loads as two children movie_a.swf and movie_b.swf. suppose also you have class MultiLangManager, with a static function GetInstance() that fetches the static singleton instance, constructing a new one if necessary. like this:

    class MultiLangManager() {
    private static var instance:MultiLangManager = null;
    public static function GetInstance() : MultiLangManager() {
    if ( ! instance ) {
    trace(“constructing singleton instance”);
    instance = new MultiLangManager();
    }
    return instance;
    }
    }

    (ps your blog commenting system’s ‘@’ code modifier is broken)

    now, at some point movie_a.swf calls MultiLangManager.GetInstance(). MultiLangManager goes ahead and constructs the singleton. sometime later, movie_b.swf calls MultiLangManager.GetInstance(). you’d expect MultiLangManager to return the existing instance. it is static, after all, right? wrong. what you get is another singleton, that is also static, but only ‘locally’ static. you know this, because the console says “constructing singleton instance” not once, but twice.

    thanks Adobe. you suck. when on earth this could be useful, i have absolutely no idea.

    the way around this is, if you add to the MyDocumentClass constructer, the line
    MultiLangManager.GetInstance()

    it will construct a properly singleton properly static instance that is then visible by both movie_a.swf and movie_b.swf.

    which means, of course, that MyDocumentClass has to know which static things both movie_a.swf and movie_b.swf are going to access. considering the fact that ‘static’ is supposed to be an elegant work-around to the problem of sharing data between instances without requiring some tight coupling in the middle, Adobe’s implementation is somewhat broken, to say the least, since it brings the coupling issue right back to the foreground.

  8. ex says:

    Meh, so much work for global variables.
    Why the heck couldn’t they add a global var myvar=1;

    to make things simple.

    >_< I hate Adobe.

  9. Anyone who needs a cross project (multi SWF file) please read carefully the comment above me by damian Stewartws. Only his fix makes it work cross-SWF.

  10. thanks for the tips guys. i have not run into this prob yet… could it be when you are loading in your child swfs they are not given access to the DocumentClass’s application domain? Not sure… just wondering…

    and yeah, posting code in comments on this blog is pretty broken :)

  11. Jim Smitze says:

    Im confused… So how is this set up in th FLA?

    I put the as code above with the GlobalVarContainer statements in an as file and import it yes? Then what in the fla?

  12. Jonathan Dumaine says:

    Good tip, thanks!
    Let’s say I have 3 classes. Is it possible to have a public static boolean that can permeate through each class? I’m worried that by importing the var into another class and changing it’s value there it won’t reflect the change if used in another class. Or will it?

  13. Thomas Brown says:

    Is there a way I can send a _global value from AS2 to AS3? The main movie is created using AS2 then we migrate to AS3 and I made a mistake of using AS3 in the child movie that needed to be called into the main movie (AS2). Now I have a problem sending the _global variable from the main movie that the child movie (AS3).

  14. Nick says:

    Thanks so much. I’ve been having problems with development ever since global vars were taken out.

  15. John says:

    Ref message 25, can you explain more? I tried the code below but get “1046: Type was not found or was not a compile-time constant: GlobalVarContainer.

    import com.greenethumb.utils.globalvars.GlobalVarContainer;
    var gvc:GlobalVarContainer = new GlobalVarContainer;

    gvc.vars.groupingID=1;

  16. Eric Stewart says:

    As to the comments regarding static properties in the use case of Singletons. If you load movies using the same context, your Singletons (and static properties) will function as you expect.

    Adobe has provided different contexts for each movie that is loaded externally. This, my guess anyway, is a security feature to help sandbox externally loaded SWF files. But it doesn’t explain why calling the Singleton once from the main movie before calling it in the loaded movie also fixes the problem. That unfortunately makes no sense at all to me.

  17. John says:

    eerr you can do it like this? why all that package and complex stuff?

    var strGlobal:String = “Global”;
    function scopeTest()

    {

    this is from the adobe site i think
    trace(strGlobal); // Global

    }

    scopeTest();

    trace(strGlobal); // Global

    this is from adobe site i think

  18. Atro says:

    Thanks! I was sick and tired of sending events around

  19. paulcortez says:

    Thankz a lot Jon. but I was wondering why static on declaration of variables.

    This is my first code before I seen this site:

    package gv{
    	
    	public class globalVars{
    	
    		private var sessID:String;
    		
    		public function setSessID(sessVar:String):void{
    			sessID = sessVar;
    		}
    		
    		public function getSess(sessVar:String):void{
    			sessID = sessVar;
    		}
    		
    	}
    }
    

    I was wondering why I get ‘Could not assign to static class [somthing]‘. Are Strings or Objects normally constructed as static? My apology I have a little background on OOP.

    Thankz a lot.

  20. Jonathan says:

    Hey Paul,

    When a property is declared with the ‘static’ attribute, it means that that property is accessible on the Class level, not the instance level. By declaring a static method or property, you can access it without constructing a new instance of the class. You have probably used the Math class before. When you call Math.random(), you are really calling the static method ‘random()’ on the Math class. If the random() method was not static you would have to do something like:

    var myMath:Math = new Math()
    var rand:Number = myMath.random();

    instead the:

    var rand:Number = Math.random() is a nice shortcut.

    Static methods and properties are used a lot in Utility classes.. or classes that just store or process information.

    In your example above, you would have to create a new instance of the your class and write your sessId variable to that instance. You could run into problems, because you could have more than one instance of your global vars object, meaning more than one sessId.

    Although it might be getting out of the scope of this thread, a Singleton Pattern might be of some use to you, although this GlobalVars example will only allow for a single instance of itself :)

    btw, sorry for my comment code tags being busted… ill fix that eventually

  21. matt Booth says:

    How do you access the global variables set from other classes within the project?

  22. empirecola says:

    this article just saved my sanity. Thanks boss!

  23. Scott says:

    fantastic! seems I’ve been coming to your site more and more lately… hmmm

    Thanks!

  24. awesome stuff! This is quite useful :D

  25. Joe says:

    Perfect! Thanks :)

  26. Brian says:

    Great tutorial but using static objects or variables creates global state which eventually leads to tons of headaches when you don’t know what class is modifying what static variable.

    It’s best to avoid using static unless it’s const variables that never change.

    If you need some variable it should be passed into the constructor.

  27. Jonathan says:

    Yes, global dynamic properties can open a can worm worms (not to mention make unit testing pretty hairy), but it can also be a convenient way to share data across your project. It’s one option, and it might or might not make sense to use based on your project. Thanks for mentioning the pitfalls though, I realize this article doesn’t speak to them.

  28. developar says:

    Hi, can you explain how to use it in timeline, I tried and it is giving me this error:
    1119: Access of possibly undefined property vars through a reference with static type com.greenethumb.utils:GlobalVarContainer.

  29. Jonathan says:

    It sounds like you are creating an instance of the GlobalVars class and attempting to access its ‘vars’ property at the instance level, but since the ‘vars’ property is static, it can only be accessed at the Class level.

    Use it like (Class level):
    GlobalVarContainer.vars.foo = ‘bar’

    not like (instance level):
    var gvc:GlobalVarContainer = new GlobalVarContainer()

    gvc.vars.foo = ‘bar’

    Also, if you are using the timeline only, you can just append and update properties to the root of your FLA as well, like: MovieClip(root).foo = ‘bar’.

  30. TURRICAN1024 says:

    all I wanna do is make a global score … and it says it cant be nested.

    AS3 is totally stupid… AS2 worked just fine

  31. arctelix says:

    Could you explain what you mean by instance based data coupling. An code walk through would be great.

  32. Jonathan says:

    sure, its basically storing data on an instance of a class, instead of on the class itself.

    Here is an example to illustrate the differences between static and instance based properties:

    You are writing a game and want to track a user’s score. You write a ScoreKeeper class that has static property ‘score’ which is globally read/write-able from anyway in your app. Easy to use, cool!

    However, you now decide that you want to make the game multiplayer, and you still want to use the nice logic you wrote for your scorekeeper class to track all the users’ scores. Since ‘score’ is a static property of your ScoreKeeper class, all references to ScoreKeeper.score refer to the same variable- thus you cannot use that property for more than one player.

    If you made the ‘score’ an instance level property, then you could just generate a new ScoreKeeper class instance for each player, and track individual scores like:

    scoreKeeper1.score = ‘10’;
    scoreKeeper1.score = ‘20’;

    etc..

  33. Anthony says:

    This was a very nice tutorial thnx a lot

  34. wayne brady says:

    thank you. spent hours trying to solve this problem!

  35. pedrodle says:

    niice, works perfect, thanks

  36. Shailesh Mewada says:

    Very helpful!!!

  37. stevenschiavone says:

    I have been using global variables to get data in and out of functions in my code. So I need global’s and I know nothing about packages classes or importing I need help and I have no guidance what so ever. Anything you can tell me would be great

  38. Alan says:

    @damian Stewart

    Actually it is not broken because you are loading in two document trees below your root. Each has its own namespace. This is necessary because otherwise when you load in swfs if they share the same namespace it would be a pretty miserable experience.

    While it may make what you are trying to do in this one instance difficult, overall it is a good thing. Perhaps you simply need to change how you are approaching this problem.

  39. stevenschiavone says:

    Another day another problem just wondering this global variable container that is mentioned above can it contain arrays as well as variables?

  40. Jonathan says:

    yes, its just an Object instance, so you can add whatever properties to it that you like. for instance:

    GlobalVarContainer.vars.myArray = [1,2,3,4,5];

  41. Nick says:

    I had to find this page again to give you a thank you, this really helped me a great deal, thank you: )!

  42. danbo says:

    3 years after your first message.
    Many thanks for this short lesson. Really helpfull for me, in many uses for games, scientifical calculations, flash planings for companies, and so on.

  43. flashjonas says:

    @ damian stewart: Exactly what I was looking for! Had seen Static classes work and not work with double/triple-swf, you explained why. Thanks a lot :)

  44. Pj says:

    Thank you! I’ve been searching this for ages!

  45. Dmitriy says:

    thanks from Ukraine

  46. Mikhail says:

    What is globalvars? Is it a name of file?

  47. Henry says:

    HI….i made a package like this…

    package nl.globalVars{
    public class globals{
    public static var data:Object = {};

    }
    }

    and in my .fla document I put this script :

    import nl.globalVars.globals
    displaybut.addEventListener(MouseEvent.CLICK,display);
    function display (e:MouseEvent)
    {

    dintext.text=globals.data.myVar1;
    }
    saveb.addEventListener(MouseEvent.CLICK,save);

    function save (e:MouseEvent)
    {
    globals.data.myVar1=inptext.text;
    }

    ….there are two buttons ..one that stores the data in my global variable …and one that display the data from my global variable…
    but the problem is when:
    I’m accesing the swf file ….I write something i press the save button and i close the swf…BUT when i’m accesing again the swf and
    i press the display button …nothing appears in my dinamic text box….WHY????…why the data doesn’t remain stocked in global variable????

    PLEASE HELP ME !!!!!

    • Jonathan Greene says:

      Sounds like you might be expecting the variables to persist through out different FlashPlayer sessions. this is not possible so far as I know. It sounds like you might need to store this data in a server session somewhere if you need it to be accessible from SWF instance to SWF instance.

  48. Henry says:

    Hey…more exactly i made a game on my site … http://www.eandngames.uv.ro
    and i want to put some top highscores in the game … so everybody who
    accses the game can see the highscores….

    • Karanum says:

      You might be better off looking into the SharedObject class if you want the scores to persist throughout different sessions. Assuming you’re not using AIR, SharedObjects are an easy way to store data both locally and server-side as far as I know. Correct me if I’m wrong though.

      • Jonathan Greene says:

        Shared objects totally slipped my my mind! They would work if you wanted to persist a user’s score data. However, showing the top high scores from any user(s) would require some sort of database and retrieval layer.

        My previous mention of using cookies falls victim to the same limitations of shared objects.

        Shared objects would be the clear choice over server sessions. They are much cleaner to implement.

  49. Paul says:

    Many thanks! Just what I was looking for, I’m building a multi-lingual language learning app in flex 4 and this is just the thing for the client-side static data component.

    Supperb, clear, and so helpful!

    Best regards,

    Paul.

  50. Paul says:

    Many thanks! Excellent, just what I wanted.

    First Class!!

    Well done.

  51. Sebastien says:

    I have a package like the GlobalVarContainer that contains 3 boolean variables, let’s just call them b1, b2 and b3

    I have a Toggle_Button class which creates a box and label with the onMouseDown Event, which is reacting properly to set it on and off.
    And of course I have 3 instance of this.

    Is there a way to assign a pointer to the global variable itself, separately for each instance. I’ve tried using the global in parameter when creating the button object, but it uses the value instead of passing the object itself.

    The objective is that when i click on the Toggle Button T1, it will recognize that is has an “assignation” to the global variable b1, and will modify the value of b1. ( same goes for T2 & b2, T3 & b3 )

    Thank you.

Trackbacks/Pingbacks
  1. [...] looking at a short example on http://www.greenethumb.com/article/11/global-variables-in-as3 in which the author creates a separate package as [...]

Leave a Reply

Your email address will not be published. Required fields are marked *

*