Articles Archive
Articles Search
Director Wiki

3DISO: Adapting Isometric Scrolling Theory to 3D Worldspace, Part 6

March 14, 2002
by Andrew M. Phelps

Part 1 of this article discussed some of the impetus behind moving our existing isometric engine over to Shockwave 3D, and the basic theory behind scrolling games.

In Part 2 we went into the math behind scrolling, and introduced the concept of isometric landscapes.

Part 3 discussed mapping systems, where the tile grid is given a coordinate system and how that affects movement strategies..

Pathfinding using the A* algorithm made up most of Part 4.

To find out about scrolling and movement in a 3D tiled world, see Part 5.

Sample Director 8.5 movie source is available for download in ZIP or SIT archive format (both files are approximately 1.2MB). If you have Shockwave 8.5, you can view the 3DISO engine (~185K).

5 Optimizing the Illusion

5.1 Lighting

The lighting that exists in the sample is relatively simple. Essentially there are two main lighting values, both of which are setup in startmovie. The first is an ambient light value that provides a default level of visibility. The second is a spotlight that shines down from a position directly atop the character's center (direction = -y). This light is the kept at a constant height throughout the character movement operations such that it doesn't "bounce".

To better frame the character, this light can either be rotated so that it shines on the character from the front -- which creates a heroic appearance -- or so that it shines from the characters backside -- which leaves the face always in shadow and can create a sense of mystery. The important point is that the light is in the center of the world, which allows the extreme foreground to fade into darkness. This aids the overall illusion of depth because it allows the viewer to recognize changes in terrain elevation with ease.

5.2 Cameras, Fog, and Clipping Planes

The basics of the camera control system and the associated issues are described in section 4.3 (included in Part 5 of this article). In addition to the issues presented there, it deserves mention that the entire illusion of the space depends on some specific tricks and optimizations. First, the camera should not be allowed to descend below the ground. The demo engine presented here solves that problem in a simplistic fashion - it manipulates the divisor described in section 4.3 to make sure that the land scale can never exceed the minimum value for camera height. It is cheap, but effective.

The second trick to keeping the illusion of infinite space alive is fog. The fog (or lighting depending) is integral to the illusion in that the user cannot be allowed to see far enough into the distance to view the shifting edges of the tiles (you can see why this would break down in wire-frame mode). There are several ways to make sure that this viewpoint is maintained, but the standard methodology that is used in Isometric projections (which is to simply tile beyond the top of the screen) does not apply, because as the camera approaches the ground plane the number of tiles to fill the view-port grows exponentially. Indeed, in theory, a camera sitting exactly on the ground plane would need an infinite number of tiles as the representation in the view-port would never grow beyond a horizontal line.

The final trick is not one that developers in Shockwave 3D really have control over, but should be mentioned anyway for the sake of completeness. The idea of clipping planes was once very important to developers of DirectX/OpenGL-enabled applications. Much of this has been hidden from the developer in more recent versions of the API's (Microsoft's DirectDraw was famous for clipping annoyances). Shockwave 3D seems to encapsulate the clipping mechanism within the cast member (i.e. it is impossible to draw outside of it) although it is left unanswered from the documentation whether or not faces that are not in the viewport are still included in the rendering pipeline. Certainly faces that traverse the edge of the window are clipped and rendered correctly, so one assumes that the underlying structures from the API are safely incorporated, and that this optimization is at work.

5.3 Coordinate Space Conversions and Other Difficulties

This engine uses world coordinates rather than screen coordinates for measuring character movement relative to the larger map coordinate space. As such, the scale of the world is a factor, and it should be noted that changing the overall scale is possible if bigger or smaller tiles are desired. In using coordinate space, however, a number of issues arose, which are briefly dissected here:

One problem that this engine illustrates is an underlying annoyance with the Shockwave 3D implementation of pointAt. This method will apparently fail when telling an object to point at a position along a vector that it is already pointing at (i.e. requiring no change). This was exceedingly frustrating in getting the character bounding box to align with the landscape. The eventual solution was to rotate the character a bit before the pointAt method was used to align the box to the surface. Even then, inconsistencies occurred, and so eventually a slightly more complicated scheme was used, and is commented inside the Character3D object script.

A second issue with the use of world coordinate space became clear when I originally set out to convert the mouse interaction style from the 2D to the 3D environment. The ability to project the tile-space into 2D columns and measure against a bitmap is completely void, both because the angle of the camera is now variable, and because tiles in the distance do not project identically to tiles in the foreground. To avoid this issue, the new mouse interaction code makes heavy use of the ModelUnderRay construct of 3D Lingo. Essentially, the mouse fires a ray into the scene and returns what is hit, and the handler parses that list until it finds the first tile. There are some inconsistencies with this approach as users cannot click "behind" objects, but other than that it should provide a suitable base implementation for basic point-and-click navigation.

5.4 Movement and Daemons

Because of the high cost of calculating movement in engines such as these, a number of approaches have coalesced into a proposed "best practice". First, it is unlikely that the engine would perform well if each calculation was performed based on individual key events. This is due both to the fact that repeated key events are thrown at decidedly different rates by different operating systems[13], and that it is generally smoother and more acceptable to use a buffer to store input, and to check that buffer once per game cycle. This idea of key buffering has become a standard practice in the gaming industry for precisely that reason[14]; without it players could capitalize on a tight loop by moving very rapidly to slow enemy AI or other simultaneous action. This engine makes use of a modified version of the EvilKeyDaemon code, which was made publicly available by Scott / at / Evilfish.[15]

Alternately, if the MOVEMENT_STYLE parameter is defined as 1, then the GameLoop will call methods of the Character3D script that invoke a point-and-click-driven interface. In either event, the character is allowed one movement cycle per "frame" which, in addition to producing animation, makes it possible to call other routines in sequence without the player outstripping the engine. See comments in source code for more detail.

It should also be noted that this engine operates entirely through the use of Lingo timeout objects, without regard to more traditional frame lopping mechanisms. This is primarily due to the fact that prepareFrame, enterFrame, and exitFrame events are involved directly with the sprite engine inside Director, while the Shockwave 3D sprite is not. Because every effort has been made to continue to allow the Shockwave 3D world to operate in direct-to-stage mode, it is pointless to call handlers that redraw either the sprite (which is unnecessary) or attempt to layer the world sprite relative to others. The speed increase in using timeout objects was incredible, but it should be noted that this is primarily due to the fact that the world is drawn when needed, based on the time value in the timeout object. It is very likely that slower machines would suffer from this strategy while machines at the higher end will benefit dramatically.[16]

6 Conclusions

These engines are expressions of both success and failure. On the one hand, they represent the possibilities of what Lingo is now capable of, and should provide a basis for more optimized solutions and Shockwave games. On the flip side, they also speak to the level at which developers must understand the tool in order to create fully featured engines, and it is nontrivial. It is unclear, as this work continues, whether or not this is a better approach than a more "low level" language. Nonetheless, it is my belief, after constructing these samples, that Shockwave 3D is capable of creating game engines that were previously unavailable to the Shockwave crew, but are (most importantly) easy to deliver online.

This cannot be overstated. As of this writing, most game engines are developed in C/C++ environments that are highly optimized for a specific environment (i.e. Win32, MacOS, etc). Lingo and Shockwave can transcend all of that, developing on a base of code that is already available (the Shockwave runtime engine). We can only hope that S3D will be available for Linux / UNIX in the near future. On one hand, this is offensive to the larger game community because it is not as highly optimized and less of a "real" engine development platform. On the flip side, this engine is a first step towards creating environments that can offer game play similar to current C/C++ games, which is my ultimate aim. If a system could be developed in Lingo it would be highly desirable from a distribution point of view because of the ease with which Shockwave deploys to multi-user web environments -- and while it is still unclear how far I can push it, I am optimistic after this initial test of a world system.

7 Future Work

This engine is still very much in its infancy. The pathing and spline code still needs to be ported from the original 2-D implementation. Most notably, the character prop needs to be replaced with a boned model that supports key frame animation similar to the "Terrain Demo" created by Tom Higgins at Macromedia. This should not be tremendously difficult, and has been tested (though not yet published). The map needs to be generated from a proper file format instead of the simplistic array used in this demo, and should reduce its dependency on the string data type (using integers to reference a cast sequence springs instantly to mind). Additionally, the files should be capable of being dynamically loaded and unloaded, similar in style to the "Maze" demo published previously by this author. Such work will go a long way towards extending the usefulness of this engine.

Beyond this, the Holy Grail of this engine will be the inclusion of network support and multi-player functionality. This module will include support for character creation, modification, deletion, inventory tracking, world modification, map-tracking, etc. Additionally an AI unit will be needed to generate appropriate NPCs and control them as appropriate. Once this base is established, with appropriate database support, it should be possible to begin building a game, it is my dream to transform this work into an eventual multi-player RPG.


This work stands on the shoulders of the discussion that are regularly presented on the dirGames-L list, as well as my peers at the Rochester Institute of Technology. In no particular order I would like to thank: Barry Swan for his tireless efforts to push Lingo beyond it's limits, NoiseCrime for publication of an excellent set of imaging materials, C. Leske and Tom Higgins of Macromedia for both their publicly available samples (the 3-D normal alignment of my character is taken almost directly from Higgins prior work on the subject) and their support of the DirGames community, Darrel Plant for tirelessly promoting DOUG and for editing and publishing my work here, Jeff Sonstien and Steven Kurtz for being decent people to work with and for sitting at my whiteboard for countless hours trying to figure this stuff out, and finally Scott Southworth at Evilfish for providing snap-in code for tons of common gaming problems (which is just a cool idea, period). So needless to say this engine, while still in its infancy, owes a lot to a lot of different people and their influences on my own work. Again, thank you all.

Artwork provided by the author and Shawn P. Boyle, Information Technology Dept., Rochester Institute of Technology, College of Computing and Information Sciences.

All colorized Lingo code samples have been processed by Dave Mennenoh's brilliant HTMLingo Xtra, available from his site at

Andrew (Andy!) is a professor at the Rochester Institute of Technology (RIT) serving in the Dept. of Information Technology, specializing in Multimedia and Web Programming. While completing his MS in Information Technology, he became increasingly interested in multi-user virtual spaces. He is also developing a game programming curriculum, with an emphasis on Lingo based solutions as well as more traditional approaches. Visit his home at

Copyright 1997-2019, Director Online. Article content copyright by respective authors.