It’s been a long time since there has been any news of the Paradox engine. Apologies for that. The good news is the project hasn’t died. However, due to other commitments and distractions, development hasn’t been moving as fast or consistently as I had hoped. Never-the-less, I’ve been making some progress and am now ready to start talking about some of the features. The first thing I want to focus on is architecture.
The engine has undergone an entire re-architecture. Actually, I’m not sure I should say re-architecture as I had never formally gone through and given the design much attention. The engine evolved from prototype to prototype and existed as a proof of concept. Not anymore. It’s gone through a major overhaul. The changes have been focused in three major areas.
Now, before I dive in I just want to caveat that all schema, API, and code samples that I’m going to show may not be representative of the final product. The engine is still in the early stages and it’s likely there will be many changes before it’s considered complete. That said…
The first area of focus has been general clean up and restructuring to provide an architecture that will be flexible and extensible. The engine has grown to roughly 75 classes with the introduction of many abstractions, a formal model, command structure, data and rendering classes.
The second major focus area has been the schema and external data work. There are two new external data feeds served by three schemas that the engine consumes. The first feed describes a game, or virtual world if you prefer. A game consists of two primary components. Resources and Maps.
Resources are objects that the engine can load and manage access to. This might be artwork, audio files, or external code libraries used by the game. The important part is that the loading and management of the resources is handled by the engine in a simple, consistent, and cohesive manner.
Maps represent the 3D environments in which a player navigates. The most common use case for Maps would be to describe levels in a game. However, that’s not a restriction.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?xml version="1.0" encoding="UTF-8"?> <ParadoxGame xmlns="http://animasinteractive.com/paradox" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://animasinteractive.com/paradox Paradox.xsd"> <Resources> <Audio id="splash" url="splash.mp3"/> <Audio id="clank" url="clank.mp3"/> <Image id="home" url="home.jpg"/> </Resources> <Maps> <Map id="level1" name="Escape" dataUrl="level1.xml"/> <Map id="level2" name="Seek and Destroy" dataUrl="level2.xml"/> </Maps> </ParadoxGame> |
The URL in the Map element points to an XML file that describes the Map. This XML file is the second data feed mentioned above. Maps are made up from several parts. The major piece of this being the COLLADA file that describes the geometry in the map. The geometry can be broken up into multiple rooms which is described in the Map XML. Additionally, the Map can include Sky Boxes and Interactive Objects. As with the Game XML the Map XML can include Resources specific to the Map.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?xml version="1.0" encoding="UTF-8"?> <Map xmlns="http://animasinteractive.com/paradox" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://animasinteractive.com/paradox Map.xsd" modelUrl="maps/level1/level1.dae"> <Resources> ... </Resources> <SkyBoxes> <SkyBox id="sb1"/> </SkyBoxes> <Rooms> <Room id="courtyard" skyBox="sb1"/> </Rooms> <InteractiveObjects> ... </InteractiveObjects> </Map> |
Each Room is linked through its ID to a set of grouped geometry in the .dae. As the player navigates through the Map the Rooms are added and removed from the scene depending upon their adjacent Rooms. This allows for minimal geometry to be present and rendered in the scene at one time. Of course there is nothing to stop the creation of one huge room, but, the feature is there if needed and provides a much needed performance boost. As well, if a room does not link to a Sky Box the Sky Box is removed from the scene.
Not that I want to ruin the excitement but, I’m going to hold off on discussing Interactive Objects. There are some exciting features in this area to look at but they need an entire topic, or few, to themselves.
The third and last major architectural area of focus has been the engine’s ActionScript API. My goal has been to keep the API as simple as possible, encapsulating much of the inner workings, while exposing enough to keep it powerful. The following is a snippet of some basic usage of the API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | engine = new ParadoxEngine(); engine.addEventListener(ParadoxEvent.GAME_LOADED, handleGameLoaded); engine.addEventListener(ParadoxEvent.MAP_LOADED, handleMapLoaded); engine.setViewPort(new ViewPort(viewPortContainer)); engine.loadGame("Game.xml"); ... // in the handleGameLoaded method engine.loadMap("level1"); .. // in the handleMapLoaded method var player: Player = new Player("Player 1"); engine.play(player); |
This is basic usage. There is much more that can be done. For instance, it may be desired to show some game art work and a list of available Maps for play before jumping in and loading any one specific Map.
1 2 3 4 5 6 7 8 9 | // in the handleGameLoaded method var game: Game = event.game; var resourceManager: ResourceManager = game.getResourceManager(); var gameArt: ImageResource = resourceManager.getResource("gameArt") as ImageResource; // getResource returns an IResource type displayObject.addChild(gameArt.getImage()); // getImage returns a Bitmap object var maps: Dictionary = game.getMaps(); // show the maps in a list |
Through the engine’s API you can also specify Player preferences.
1 2 3 4 5 | var preferences: PlayerPreferences = engine.getPlayerPreferences(); preferences.walkForwardModifier = KeyboardUtil.W; preferences.walkBackwardModifier = KeyboardUtil.A; preferences.strafeLeftModifier = KeyboardUtil.S; preferences.strafeRightModifier = KeyboardUtil.D; |
Yes, I thought that might impress the discerning connoisseurs.
Other preferences include the look modifier and invert look flag as well as things like look sensitivity and travel speed. Here’s a couple more basic API methods.
1 2 | engine.pause(); // necessary pause engine.isPlaying(); // check to see if the engine is playing |
OK, I know, those are boring. Besides, I really can’t resist at least hinting at some of the more interesting functionality.
1 | engine.addEventListener(InteractionEvent.getProximityEvent(interactiveObjectId), handleInProximity); |
I’ll leave it at that. Comments welcome.
- What is it?
- What is this 3D engine for?
- Why is it called Paradox?
- Will Paradox be open source?
- How far along is the engine?
- What are the technical limitations?
- Why Flash?
- Why in the world do the demos use the e, s, d and f keys?
- Why do I have to mouse down in order to look around?
- Are there any games planned for Paradox?
In case you missed my original announcement, Pardox is a first person 3D engine built on top of Papervision3D and Flash.
Paradox began out of an interest to explore the possibilities of a first person 3D engine in Flash. The results of my experimentation have been much better than I expected and it is now my goal to build a robust reusable first person 3D engine. The primary use case for the engine will be for gaming but, there are plenty of other potential applications I can envision using this kind of technology for.
Because I never thought I’d actually see this kind of real time 3D in Flash for at least a couple of years. And more importantly, it sounds cool!
This is the big question. I don’t exactly have an answer for it at the moment which means that for the time being, no. Whether the engine ultimately ends up open source depends on a few things. It is something I’m seriously considering and I’m very appreciative of the open source projects I’ve benefited from. I would love to give back to the community with this as my offering. However, there is already a very real possibility of commercial applications for the engine. While I’m not actively exploring or searching for commercial deals if a deal was on the table and went through the engine would not end up open source.
Not very. Its current state is that of a giant spike. It started as a proof of concept and that’s still very much what it is today. I’ve been reluctant to spend too much time on the architecture without first knowing if the engine would continue to perform as several features were added. So far so good and I’ve taken a pass at refining the technical design of the engine. I’m really happy with how it’s coming together.
Probably too many to count! Because the engine is currently entirely software rendered in Flash there are plenty of technical limitations that will demand some crafty coding to find solutions to. There is a limit to how much geometry can be used. And, the limit is low. Well designed textures and optimized geometry will be a necessity. Additionally, the amount of animation and interactivity will be limited. As will the accuracy of the physics and robustness of the AI. That said, I feel good about what is possible and am confident that well designed games can make up for the lack of power in the engine. Besides, it’s not like Flash or computational power is getting any slower. It’s a perfect time to put the infrastructure in place, even if the platform isn’t quite there yet.
It’s the most ubiquitous platform in the world and history of software. It’s an incredible platform and I have no qualms about where it is headed.
This is a popular question. The reason for this is purely because of a personal preference. I prefer to use my little finger and the keys a, q, and z for secondary tasks. With w, a, s, and d my little finger is pushed over onto the caps lock, tab, and shift keys. It’s not a new idea and really is a superior setup, you should try it.
More importantly however, this will all be user customizable through the engine preferences.
This is a technical limitation. It’s a bit of a sore point for me but a fact of life. The problem is that it is not possible to lock the mouse to the center of the scene with Flash. The cursor will eventually leave the browser and Flash will cease to capture the mouse position. Because of this there is no way to continuously spin in circles without a secondary look modifier that can be enabled or disabled. The mouse down action is my preference. However, this will be customizable and able to be mapped to keys, inverted (click to stop looking), or turned off altogether.
Yes! The design is still in the very very early stages but my plan is to build a game on top of the engine. This will be highly beneficial for the engine APIs as it will help solidify the requirements for the engine and provide a real world implementation.
If you have any additional questions feel free to ask. I’ll do my best to get them answered.
