| Register
Sunday, May 11, 2008   

Understanding _root & Scope

Created By  Benjamin Mace, at  12/18/2005 - 19 comments.

Click to view this author's website.

Recently was called up to fix an issue with a client's SWF file that we were trying to use on one of our channels. The file worked on its own, but not in the container SWF on our site. Jumping into the client's code, I immediately spotted the problem where their developer declared a class instance used in their movie on the "_root" timeline. Since we loaded their SWF into a movieclip within our SWF, the scope had changed, breaking the entire file.



Scope is one of the first things I usually check for when debugging ActionScript. It's easy to make errors related to scope and it seems that many Flash designers and developers don't have a 100% grasp on the idea of what it is. That's sometimes due to the Normal Mode in our editor, through free Flash tutorials or through the copy and paste learning pattern of the self taught (guilt am I of this at first.) So why is using "_root" such a headache when it's provided for us to use? In reference to "_root", I think it's the fact that we learn it as an absolute path which doesn't always hold true. In addition it's knowing how to code with good practice and trying not to cut corners. Let's take a look at some types of scope and use of them within Flash.

Understanding _level

The keyword "_level" refers to the absolute main timeline of a specified level (ie: _level4). When you start with a SWF file, that movie is always referred to as "_level0", the first in any possible stack of movies. By using "_level", your code will only work in the intended "_level" order. If code tries to reach data on "_level4" and we rearrange our stack in another project, the data won't be there, breaking our code. Levels can be thought of like floors on a building, when loading new SWF files into additional levels, they reside on top of one another. It's not necessarily bad practice to use "_level", you just need to understand the consequences of being tied to a rigid structure.

Understanding _root

The keyword "_root" is used to refer to the absolute main timeline of a given "_level". Depending on where a SWF resides, the reference to "_root" can be different. When using a SWF file all on its own, that file is "_level0". In this case, referencing the file's main timeline with "_root" is the same as saying "_level0". If the same file were loaded into "_level5" we would be referencing the main timeline of "_level5" with "_root". However, if we load that same SWF file into a target movieclip vs. a "_level" our scope changes because the SWF isn't used being used in the context of a "_level" anymore. What was referenced as "_root" in the SWF's main timeline while used on its own now points to the main timeline of the SWF loading it. It's important to know that using "_root" as an absolute can be misleading and for all intents and purposes it should be avoided.

Contrasting _level & _root

The above explanations are similar when described but they are very different when used. Code using "_level3" for example, written on a given timeline in a given movie will ALWAYS refer to the main timeline in "_level3" regardless of its position. In contrast, if you're working in a SWF and using "_root", your code will refer to the main timeline of the current "_level". Where the use of "_level" will always be the same, "_root" changes based on where your SWF file is used. Even though both are considered "absolute" paths in Flash's ActionScript dictionary, "_root" in my opinion is actually a "relative" path based on where your clip is used. While it does always point to "_root" as an ideal, "_root" can vary based on load position.

Understanding _global

In contrast to "_root", the "_global" scope never changes and, unlike the other two fore mentioned spaces, "_global" isn't a physical location. If you think of a timeline as a physical location (ie: places you can attach objects to like graphics and movieclips), "_global" acts differently. It's a name space within Flash where only code can reside. You can find a lot of articles with pros and cons to using "_global" but all I'll say here is that you can always set data within the "_global" space and your path will never change. Once set, anything can access that data from anywhere inside your movie. Data written to "_global" should be limited due to the chance of overwriting other references in that scope.

Wrapping Up

Portability is king. As a developer or designer, you should write code that is portable and can be reused. You don't need to reinvent the wheel every time you start a new project. Using relative paths and reference variables within classes and even simple pieces of Flash work enables you to reuse code that you have already written.

This will allow you to reuse script within different locations of different movies, as well as load those movies into others without losing functionality due to broken paths. There are many articles on what is referred to as the Singleton Pattern on the web, which some consider an alternative to "_global" as a reference point within class structure. GSkinner has a good example as well as other discussion on scope.

So the next time you decide to just drop in a quick reference to "_root" or "_level" consider the file's future use. That quick and dirty solution can be done in a better manner and save you (or someone like me) even more time down the road. There is always a better solution to a given problem, you just need to take a moment to find it.

Need Professional Help For Your ActionScript Project?
ActionScript.com Consulting Services provide top quality professional ActionScript consulting to businesses around the globe. If you have a professional project in need to world-class talent, tell us about your project by requesting a quote today.

Reader Comments

  1. zikey  Replied:
    ( 12/20/2005 At 7:38 AM)

    I always use the mathod "loadMovie",so the levelN is always "level0".

  2. Frog  Replied:
    ( 12/20/2005 At 7:09 PM)

    Thanks,
    I've been puzzing about levels in relation to _root recently. In particular, the combobox component has a bug (i.e. doesn't work when loaded into a movie from an external swf) and loadMovieNum was suggested as a work around, hence using levels.

  3. senocular  Replied:
    ( 12/20/2005 At 7:21 PM)

    It's also important to note that there can be multiple _global objects when loading swfs into the Flash player that are either different versions (e.g. version 6 and version 7) or from different domains.

  4. BJ  Replied:
    ( 12/21/2005 At 6:38 PM)

    True.. good point.

  5. Flash-Ripper  Replied:
    ( 12/22/2005 At 6:04 PM)

    AS2 classes are always stored in _global scope, isn't it? I think this is the one of the strongest evidences that _global rules ;-)

  6. BJ  Replied:
    ( 12/23/2005 At 12:49 AM)

    True dat again. Hence limiting the use of random data in that scope.

  7. depth  Replied:
    ( 12/26/2005 At 12:59 AM)

    technically, no, AS2 classes are not stored in _global scope. but, true to ECMA-script specs, classes are visible from anywhere within the same package (file folder). a great way to maintain constants that are used across classes is to use static vars.
    also, benjamin, surprised you don't mention flash 7+'s _lockroot property. you can lock _root references within a movieclip to always refer to the top level of that file by setting this._lockroot = true on your main timeline. you can also set _lockroot = true on movies loaded with mc.loadMovie().
    _lockroot's super handy when devs/designers are making bad use of _root, but of course benjamin's suggestion to avoid it entirely is generally most prudent.
    on macrodobe's livedocs:
    http://livedocs.macromedia.com/flash/8/main/00002482.html

  8. BJ  Replied:
    ( 12/27/2005 At 8:56 AM)

    _lockroot just threw me for a loop. I have never heard of it mostly because i haven't had a chance to become wel versed in 8 yet. That's really damn cool. I should revise this to reflect that as an option in 7+.

  9. jackie patil  Replied:
    ( 12/27/2005 At 10:14 AM)

    I want to be more clear about the _root

  10. lucas  Replied:
    ( 12/28/2005 At 7:37 PM)

    Thanks for this article,
    but there's something i don't understand, what is the relation between _levelN and depth ? I mean, i am always using loadMovie, and loading all my movie clips to differents depth in the same level, would it be better to use loadMovieNum and load the movie clips in different levels ?
    thancks :)

  11. Corey Richards  Replied:
    ( 2/24/2006 At 3:32 AM)

    This is a nice article. I understand the concept, however, I need a little help with the actual syntax. I have a music selector swf that I made that works exactly how I want. It dynamically loads various music from the library when the user clicks on the button, however when I import that swf into my main timeline it does not work. It cannot find the song. So now the music selector is a movie clip on my main timeline. Once inside of the music selector movie clip, my buttons have this on them

    on (release) {stopAllSounds();
    song1=new Sound()
    song1.loadSound("Beat.mp3", true)
    gotoAndPlay(3);


    }

    I know it has to do with the _root and it not being able to find the song because it is not on the same timeline, but how do I change the syntax to make it work. Help me if ya can. Thanks!

  12. Benjamin Mace  Replied:
    ( 3/4/2006 At 2:53 AM)

    That might be a timing issue based on which library loads when or another issue. I'd have to see what was located where and how each was loaded in to help you out more.

  13. Corey Richards  Replied:
    ( 3/15/2006 At 7:02 AM)

    Okay. If you would like, I can give zip the .fla and put it on my website so you can go into it. Does the timeline inside of a movieclip still able to dynamically load things from the library, such as the main timeline does? I know this may be straying from the topic of this tutorial a little, but I would really appreciate the help. Thanks for replying!

  14. Jack Medina  Replied:
    ( 3/31/2006 At 7:16 PM)

    Corey,

    Have you tried passing the current object scope to the Sound constructor? You can try.

    song1 = new Sound(this);

    That may solve you problem.

    Best regards

  15. vijesh vv  Replied:
    ( 6/19/2006 At 2:33 AM)

    Hi all I'm new in this site, It's very helpfull, thank you.

  16. Geoff Bullen  Replied:
    ( 2/5/2007 At 5:06 PM)

    I have a problem with loadMovie and lockRoot.
    From my testing if you load a SWF that uses components, then the lockRoot does not hold true for the component.

    main.as does lockRoot on the clip
    then loads test.swf

    test.swf
    trace(_root) = displays _level0.container
    but then is you attachMovie( 'step', ...)
    and you do a trace inside step, as in
    class step extends MovieClip {
    function step () {
    trace(_root);
    }
    }

    the trace says: _level0
    rather than _level0.container

    Do you understand why?

  17. Matthew Knighton  Replied:
    ( 3/11/2007 At 5:47 AM)

    Hey, I think all of these methods suck.

    Never use, parent, root, global or level.

    use owners.

    So If I create a clip within a clip I target it and send the owner to it. I can then communicate back to my parent clip by using the owner object.

    This is way better and means that you can move you code into any level or any scope.

  18. Satori Canton  Replied:
    ( 3/14/2007 At 6:23 PM)

    Hey Matthew,

    _parent, and _root are lame. When I see that in someone else's code, I know they're lame. _global is a little bit different. AS 2.0 compiles backwards and makes big use of _global. Sometimes, when you need to full on hack someone else's code, you have to go there (either because it's old code or dirty code). Singletons are a good example of things that could be written in the _global scope.

    Satori

  19. Mudit Tuli  Replied:
    ( 3/28/2007 At 4:27 AM)

    Hey Mathew can you tell me more about owner object or share a link.

Login to post your comments. If you do not have an account with us please Register.
Copyright 2005 by ActionScript, Inc.   |  Privacy Statement  |  Terms Of Use  |  ActionScript Client Extranet