Mar 6, 2012

A Closer Look at the Scene_Base Architecture

Some people have been asking me how to write new scenes using my Scene_Base architecture. Here's an overview of how it works, and how different it is from standard RMXP's scenes.


RMXP's Standard Architecture

Here's a pseudocode template of a standard RMXP scene.
class My_Scene
  def main
    create windows and sprites
    process transition
    begin loop
      update frame
      call update
      check if another scene was created, and if so, abort loop to end current scene
    end loop
    erase windows and sprites (dispose)
    prepare for next scene's transition
  end def

  def update
    update each window/sprite
    check for inputs and do the appropriate stuff for each key
  end
end class
Seems perfectly fine as is, now doesn't it? However, when you think about it, several issues can arise with that simple, straightforward architecture:
  1. If you want to add a new window to the scene, you are forced to rewrite its main method entirely, because it's in a single piece. Thus you cannot use two scripts at the same time, which modify the same scene, because the latter will systematically override the former one.
  2. All RMXP scenes rely on this same architecture, thus the same lines are written over and over again, which is unnecessary repeating.
  3. Because of 2., if you'd like to tweak all scenes at once (for example modify the transition at the beginning for all scenes), then you have to rewrite all of them one after one.
Of course, as long as you're not dealing with editing scenes/making new scenes, you have little concerne for such issues. But since I've had the occasion to make some heavy on scenes, I thought it was about time to do something about it, and that's how I came to write the Scene_Base class.


Moonpearl's Scene_Base architecture

The Scene_Base class was written to address the previously stated issues. It was meant to:
  1. Provide easier writing for new scenes since you don't have to rewrite all the base code.
  2. Handle scenes in a more modular fashion to allow easier editing.
  3. Make it possible to tweak all scenes at once
Here's an overview of how the Scene_Base class works.
class Scene_Base
  def main
    call setup
    begin loop
      frame update
      call update
    end loop
    call terminate
  end def

  def setup
    create windows/sprites and list all of them in @sprites
  end def

  def update
    update all windows/sprites listed in @sprites
  end def

  def terminate
    erase all windows/sprites listed in @sprites (dispose)
  end def
end class
Now let's see how we could write an entirely new scene using this architecture.
class My_Scene under superclass Scene_Base
  # No need to redefine main method

  def setup
    create windows/sprites and list all of them in @sprites
  end def

  def update
    call superclass's method
    check for inputs and do the appropriate stuff for each key
  end def

  # No need to redefine terminate method
end class
One can easily see the first benefit, which is a substantial saving of code, which in turns means a substantial saving of time and energy. But that's not all. Suppose we further want to edit our new scene as an independant script, while not rewriting everything from scratch. Here's how to add a new window/sprite:
class My_Scene under superclass Scene_Base
  # No need to redefine main method

  def setup
    call former code
    create a new window/sprite and add it to @sprites
  end def

  # No need to redefine update method

  # No need to redefine terminate method
end class
This is just enough since our new window/sprite is listed in the @sprites Array, which means both update and terminate will handle it as any other previously created window/sprite. Likewise, suppose we now want to ass new functions to our scene, for example make it able to respond to a new key.
class My_Scene under superclass Scene_Base
  # No need to redefine main method

  # No need to redefine setup method

  def update
    call former code
    check for the new input and act accordingly
  end def

  # No need to redefine terminate method
end class
As you can see, we stick each time only to the necessary edits. Furthermore, this allows several edits of the same scene to coexist, because we do never rewrite a part of the code, we only expand it with new features, always calling the older version.

As an example of how powerful this architecture can be, you can have a look at my Scene_Menu_Base class, from the Animated Custom Menu System. This allows all menu scenes to exhibit common features (namely, a background image and a scrolling overlay). Basically, it's written that way:
class Scene_Menu_Base under superclass Scene_Base
  # No need to redefine main method

  def setup
    create background image and add it to @sprites
    create overlay and add it to @sprites
  end def

  def update
    call superclass's code
    move overlay
  end def

  # No need to redefine terminate method
end class
Now we just have to write new scenes listed as subclasses of Scene_Menu_Base, and since we'll keep on calling formerly written code, the background/overlay will automatically show, and the overlay will automatically scroll, with no need to state those explicilty in our new scenes.


Conclusion

I hope this quick overview could persuade you how the Scene_Base architecture can be useful and handy. If you were trying to write your own scenes with it, I encourage you to do so, and I also hope it did clear things out for you.

No comments:

Post a Comment