MyDream Video Game

By James S.

The Adventures of Kitty Wong: MyDream is my first 3D video game that I have programmed, using Microsoft Visual C++ 2008 and DirectX. The game is called MyDream since it has a built-in editor which I use to create the levels that I plan to keep in so that anyone who plays the game can edit the levels themselves and make them their own. In addition to being able to edit the placement of the objects there are also built-in editors to edit paths, 3D animation and more.

New: Updated: Development (07/06/18)

Updated: Development (31/07/13).

Updated: Development-Races

Updated: Development-Weather Skybox

Development-Better frame rate.

User guide.

Development.

Story.

You can email me at james.boshikoopa@gmail.com

Provided are typical behaviours you would expect from a 3D platformer which you can assign to any of the objects as well as ones that are more true to The Adventures of Kitty Wong. In this way you could, for example, emulate one of your favourite, existing games.

Note the spelling of MyDream: the lack of a space between the 'My' and 'Dream' is intentional, much like what you would see written online (i.e. lack of punctuation).

This is a work in progress and is currently in beta, and various versions will be released.

Please email me with your questions and comments at james.boshikoopa@gmail.com

Introduction

This games does not need installing, just extract the zipped file to somewhere on your harddrive and make sure all the files stay in that folder.

This game may not be suitable for very young players.

Story

Update: 14/4/9

The game is set in the BloodRose kingdom which is ruled by the nasty bat-lizard Queen Crystal. Princess Amy Wong, a well known catgirl thief has discovered Crystal's kingdom, seeing it as a perfect opportunity to steal yet more gems. But as soon as Crystal finds out about Amy and her thieving she orders her arrest.

Kitty learns of Crystal's vile ways of dealing with those who do wrong and as her days are numbered she finds out that Crystal herself is hardly well behaved even if she does make the rules in her kingdom.

It will be up to Amy to protect Crystal's people from their own queen, keep herself alive and eventually she will have to deal with Crystal face-to-face.

Development

Here you can read about new features that I have added to the game and details about how I programmed them.

The move to Assimp

(Added: 07/06/18)

When I first worked on MyDream I used a 3D modelling program called DeleD which was very simple but at least it was free (there was also a more advance and paid for version) but once I got hold of 3ds Max as a student I was able to create more complicated 3D models. The time came, however, when the student license expired and as you have to pay a monthly fee to own 3ds Max I returned to an old friend: Blender:

https://www.blender.org/

I probably had a look at Blender even before DeleD but got put off by Blender's complexity yet here I am many years later with a recent version of Blender and better skill and knowledge of how to construct 3D models. Blender may be very different compared to other modelling programs such as 3ds Max but Blender is a very good 3D modelling program and is free with a great deal of help available online.

I had been using Microsoft's .X mesh format for the 3D models and it was a good starting point but I had wanted to move to a more universal file format for a long while and as it is Microsoft have dropped support for .X mesh files in more recent versions of the DirectX SDK. Now that I was using Blender I researched different mesh formats and came across Collada (.dae) which Blender natively supports for importing and exporting 3D models. To load Collada files into my game I did some more investigating until I came across Assimp which can import (and export) various 3D model files including Collada:

http://www.assimp.org/

When Assimp is used to load a 3D model from a file it puts useful data (vertices, indices, material info, etc.) extracted from the file into a generic structure describing a scene (which could be as simple as a single mesh or contain additional objects) and from that scene graph a program can build its own structures containing the 3D data it requires (Assimp's scene graph is not intended for rendering directly the 3D models that are loaded). Unfortunately it took me a lot of work to get Assimp to load a 3D model as even for a simple mesh you need to take into account the scene hierarchy and then there was the problem of replacing D3DXLoadMeshFromX() which I had been using to load a 3D model from a .x file. I wanted to keep the ID3DXMesh mesh object interface and populated it with data obtained using Assimp to avoid adjusting as little code as needed. The D3DXLoadMeshFromX() function does a lot of work but its source code is not available but eventually I was able to write the code to replace it. What follows is a simple outline of how to transfer the data Assimp loads from a 3D model file to an ID3DXMesh object:

Call Assimp::Importer.ReadFile() to load a 3D model from a file. The parameters I used were:

aiProcess_JoinIdenticalVertices //Identify and join identical vertex sets

aiProcess_GenSmoothNormals //Generate normals if not already present

aiProcess_ConvertToLeftHanded //Use left-handed coordinate system, flip UV coordinates and adjust face order to CW

aiProcess_Triangulate //Triangulate all faces

aiProcess_SortByPType //Splits meshes with more than one primitive type in homogeneous sub meshes

Note that aiProcess_ConvertToLeftHanded is a necessity for Direct3D due to it using the left handed coordinate system.

After checking that ReadFile was successful call D3DXCreateMeshFVF() to create a blank mesh; you will need to iterate through all meshes to get the vertex and face total. You will need to create an array of D3DXATTRIBUTERANGE for the blank mesh we created which forms an attribute table containing the attribute ID, face start index, face total, vertex start index and vertex total for each mesh subset (typically the number of entries in the D3DXATTRIBUTERANGE array will equal the number of meshes in the scene that Assimp loaded). The purpose of the array is so that when DrawSubset() is called on a mesh we can specify the mesh subset to render allowing us to apply a texture and any special transformations especially for each sub mesh.

Next lock the mesh's vertex, index and attribute buffers. Now you will need to process all nodes in the imported scene and handle child nodes by using a recursive function call. When processing a node a stack of transformations will need to be maintained so that transformations of a parent will also be applied to its children as to keep the scene hierarchy by transforming every vertex by the combined accumulated parent and child transformations. For each node its mesh (if it has one) will need its vertices and indices copied to the blank mesh we created earlier using the previously obtained vertex and index buffer pointers as well as any other vertex data (normals and texture coordinates most likely). Remember that while a vertex can using any FVF (Flexible Vertex Format) of our choosing we must access them in a set order which you can see in d3d9types.h; each FVF constant is a binary value and that determines the order they are stored. So although it's quite simple to obtain a vertex's FVF through a function call that will only tell us what the vertex contains but not its order as that is fixed.

When we process a node that has a mesh as mentioned you need to copy the vertex and index values but our aim is to create a complete mesh from a number of sub meshes (unless there is only one mesh) and for this reason we must keep track of the current vertex and index in the appropriate buffers for the complete mesh. We also have to update the mesh attribute table for the current mesh so you will need to set the structure's members to the appropriate values; the attribute ID needs to be set to the current mesh index (with 0 being the first mesh). For every face we come across we have to update the attribute buffer by setting the current entry to the current mesh index. It is this value which links a face's attribute ID to the same value in the attribute table.

When all nodes have been processed for a loaded scene we need to call SetAttributeTable() on the mesh we created earlier and which now has been updated with the data that Assimp loaded from a 3D mesh file. If all is good we can create materials for the mesh and do any other processing before cleaning up (remember to release the vertex, index and attribute buffers, as well as the attribute table which will need to be deleted at program termination). Note that I do not call OptimizeInplace() on the mesh in case it alters the mesh vertex/index data and I wonder how necessary it is as Assimp does its own optimisation when loading in a mesh.

One last thing to mention on the topic of Assimp is that it comes with a viewer (assimp_viewer in the bin folder) which is very useful for checking that your model is displaying correct, possibly indicating that your program has an error when loading in the model, and the viewer can export to different formats (may not be the best exporter though).

Shadows and more

(Added: 31/07/13)

MyDream has come along way but one of the most difficult features I've added is shadows. There are two common techniques which are shadow maps and shadow volumes with shadow maps being the most commonly used technique. They both produce 'realistic' shadows unlike earlier methods found in older games which had circle or square shadows under the objects.

While there are far more important parts of a game to program, shadows do help to bring a game to life and they give the player a better sense of depth. They can also add to the atmosphere of the game to, for example, give a spooky feel.

I have been following a Microsoft example on using shadow maps which was not done very well and I ended up trying to fix a problem that turned out to be something quite simple to fix. There seem to be only a few tutorials online on creating shadow maps using Direct3D 9 (I have kept with the older Direct3D so that the game runs on a greater number of computers than if I had only supported the newer Direct3D) and they are very different to the Microsoft example.

Below you can see a screenshot showing off my game with the shadow map on. Shadow maps have a lot of problems with them-many of which can be fixed-and if you look at recent games many of them have poor shadows (i.e. very pixelated). So while I'm still sorting out the shadow map I shouldn't be too hard on myself; my aim has always been to get reasonable shadows working.

The screenshot shows when I was testing out the shadow map and is set up to have the light pointing on the Z axis, like in the Microsoft example. I had disabled showing the player as to not get in the way and create a box-like mesh with cylinders and a sphere; the spikes and door are objects.

The cylinders cast shadows on the far wall but yet the cylinders are in shadow and for some reason there is what appears to be patches of light on them. I have since found that self-shadowing is a big problem as the cylinders are part of the box mesh. Self-shadowing is a real life phenomenon in which an object casts a shadow onto itself (for example, your arm may cast a shadow onto the rest of your body). Commonly people online talk of self-shadowing as if it shouldn't happen; it should, but when it does in a 3D virtual world it often causes problems.

I always had it at the back of my mind while adding support for shadow maps to allow them to be switched off. This way the game can fall back on the simpler lighting model and for those with older computers shadow map can be turned off to boost performance.

Picking

I wanted the editor to be as easy to use as possible and this is something that faces many designers and programmers. One of the best ways to do this is to use 'picking' which allows the user to click on objects in the game world. Once an object is selected, it can be moved and altered in other ways.

I have picking now programmed in but at first it did not appear to work. This was done to a simple mistake whereby certain parameters were becoming corrupted. Through debugging I discovered the problem, which was then simple enough to fix.

Direct3D class

Sometimes it really is better to get something done as soon as possible rather than put it off for as long as possible. When I first started programming MyDream even before I had thought of that name I was learning how to use Direct3D, so the main class contained all the programming for the graphical side as well as everything else.

When I added a class to handle the 3D meshes that helped keep some of the graphical work from the main class but not enough. I knew I needed to write a class that handled all of working with Direct3D but that would mean making big changes. But it was worth it and now I have that sorted I can move on with improving the game so much more.

In particular, I am working on a 3D animation editor and the ability to load exactly what graphics you want. Also, I've decided to keep with DirectSound and leave XACT alone for now.

Version 1.3

Version 1.3 will feature the following (and more):

* Much easier to use level editor.

* Support for level tiles and level collision.

* More behaviours.

Version 1.2

* Textured text is used which looks much better than plain text and can have fancy effects such as a background behind the text and transparency.

* Title screen added.

* 3D animation viewer.

* HUD icons.

* Easter egg.

* Better rain.

Races

Using the editor, races can be set up against the AI with the player riding an object. It is just a simple matter of placing some invisible objects and linking them together to determine the path of the AI.

Tiles

Tiles differ from the objects in that once set up in the editior they cannot be transformed (moved, rotated, etc) again. Also, they can only use 3D graphics and simply have a certain surface type, such as solid.

Weather Skybox

I now have it so that the skybox changes depending on the type of weather (currently sunny or raining). Normally, when creating a mesh the textures will be created using the filenames from the mesh file. This would be a problem for selecting different textures to use for the skybox, since it would only load the usual six.

The solution was to tell the mesh class which mesh is the skybox, forcing it to load a set of textures instead of those mentioned in the mesh file. Then when it came to rendering the skybox the weather type is checked and then the correct set of six textures are used.

Better frame rate

Previously I had only used a timer for updating the objects and rendering the graphics but in levels where there were many triangles to draw, there was a noticeable slower frame rate. I have now changed that so that although the objects are still updated during the timer event, the graphics are rendered whenever the game is idle, that is, when there are no messages to process.

New modes

So you can make levels exactly as you want, I have added two new modes and they are on rails mode and 2.5D mode. In on rails mode the player is always moving, either along the ground or in the air, and you move a cursor instead of the player and can fire up to 10 missiles at once.

In 2.5D mode the player and certain objects can only move up, down, left or right much like in the 2D platform type games. But the player can still be turned around, and you can have all the graphics and behaviours from any of the other modes.

Interaction

One thing I have been aiming for while programming this game is plenty of interaction, such as the player getting stuck in a sticky bomb and having to try to escape it. At times the player may become gagged, which of course won't help with trying to talk to people. At the moment some of these features only apply to the player but I plan to let them effect all objects.

Controls

If you don't like using the keyboard to control the player then you can use an Xbox 360 compatible wired controller. There are two ways you can interface with an Xbox 360 controller, either using DirectInput or XInput.

If DirectInput is used then you can make use of any controller that is designed for a computer but you won't be able to use all features of an Xbox 360 controller such as vibration. I chose to use XInput as to get the most out of the controller at the cost of only supporting Xbox 360 type controllers.

You can use both DirectInput and XInput together but XInput is so much simpler to use than DirectInput that I stuck with just XInput.

3D animation

I have chosen a more complicated form of 3D animation in which the positions of the body parts are calculated as you play the game, rather than use pre-calculated values. This can allow for more variety of animations, for example, when the player is killed one time she will be in a certain pose another time it will be slightly diiferent.

The way I handle this time of animation is to assign a simple behaviour to each body part. Conditions are checked-is the player running, jumping, and so on-which decides which behaviour to use for the body parts. The behaviour may rotate the body part, scale or transform it in some way.

It is harder to program and there are other complications but I think it's well worth the effort and makes for a more unique game.

Conversations

There are objects that the player can talk to and although currently limited you'll be able to have conversations with people. Just press action to talk to them and press action again to hear what else they have to say (if anything).

Items

A carton of milk restores some of Kitty's health.

Money comes in the form of gold coins.

A cat icon gives Kitty another life but she can have no more than 9 lives.

Torch

I have started work on a torch that follows the player that can be switched on and off at any time to help see in dark areas. It uses a virtual rechargeable battery so while it's on the battery will drain and should it run down completely it will switch off to charge. It was inspired by Lara's LED torch from Tomb Raider Legend.

Requirements to play this game

* Windows XP (will also run on Windows Vista and Windows 7).

* .NET framework version 3.5 or later.

* DirectX 9 or later.

* Available disk space for level and other save files.

Download

Will be added when the next release is ready.

Currently being tested by the following people (my thanks to them):

spyke4995

Romaniangirl10 (Joanna)

Randomness099

blabla381

megamario2007

And many others.

Technical details

The game runs on my Kitty Wong 3D game engine which I built up from my original Kitty Wong game engine that was designed for 2D games (it powered my The Adventures of Princess Peach game as well as others).

Special features:

* Built-in level editor.

* Real time lighting.

* Weather effects.

* Different modes (3D platform, on-rails, 2.5D and others).

Guide

For instructions of how to play the game please see the attachment below.

All content of this and related pages is copyright (c) James S. 2009-2018