EAE 6320-001 GameEngII Game Engine Project, Game Dev Adventures!

Final Project: Matching Game!

My FINAL game: simple one-click download below, unzip, play, enjoy!

NancyNewren_ExampleGame FinalProject!

What’s new
It’s a game!

Controls
Main object: Use arrow keys to move the 3D object to its matching card.

About the Game

Okay, so it’s not pretty, but sometimes you just need to get to proof of concept; beautifying the game can come later.

When I was making educational games for Waterford Research Institute I made a lot of mini games for preK curriculum: letter/word association, number recoginition, letter matching, and even an ethics game. I really enjoyed making these simple-to-play games for 4-5 year olds. They were fun enough that even my older play testers (20-year-olds) liked them. However I never got to make a shape matching game. But now I have!

This was fun to make, especially since it was in my engine, but slightly more complicated than I anticipated.

The first thing was paring down the game to its minimum essentials: for instance having animations wouldn’t matter if I didn’t have a game first. So what was essential? Well having four objects with four matching cards. Being able to detect a right and wrong guess, and upon such guesses having a response (moving onto the next object for the right guess, feedback to let you know it was wrong otherwise). Once that was determined I simply needed to set up the graphics objects and then create the basic right/wrong logic with a simple collision detection.

Everything we needed to draw to screen was done: but any game logic I had to write, though admittedly we had previously written the player controls and the essential game loop code (like the update functions in Unity) were already supplied previous to this final assignment.

I don’t think I had noticed previously how heavily a game relies on its graphics components though. Without those, regardless of any clever logic you may have written, you don’t have much of a game. And I think it took up a majority of my time to find, create, edit, and import into my engine all the assets.

Honestly I think the most difficult thing to do was just tracking all the different assets. In game engines such as Unreal and Unity it is easier to track them I think because there are prefabs and the editor to help you create your arrays of assets. However creating the c3DObjects class to manage all things for my 3D objects (mesh, effect, texture, transform, speed, and even id) made it much simpler to program the game. When I was trying to detect whether or not an object matched a card all I had to do was give them both the same id in their c3DObject instance. Which brings up something: the cards, though flat, were still meshes. As I didn’t want them drawn like UIElements, but to interact with the objects in world space, I had them as 3DObjects. The only thing I’d add to the engine would be a UIElement class (akin to the 3DObjects class, but fancier since I’d need to track scaling vs. anchoring, etc.), and the idea of prefabs. It’d really make things easier to track with those things in place. Well, I’d also add an animation project to make animations simpler too.

The only time that I wished I’d done something different in previous assignments was the way I stored graphics elements in my game logic. Before even started coding the game I did some refractoring in my game logic to make it easier to track my graphics elements.

I created two effects for right and wrong guesses that tint and make the cards transparent. Then it was a simple matter of just swapping out the regular effect (which everything 3D was drawn with) with a right/wrong effect. That decision also made it easy to animate the ending flash as I just swapped out right and regular effects. If I’d passed the color to the effect to draw right/wrong it would have affected all my objects, and not just the one I wanted to draw.

The other difficulty was randomizing the order of everything while keeping track of them! picking four (of seven) random objects to be the match objects, making sure the four card were the four matching ones, and then drawing the four matching cards in a random order on screen. Here’s how I chose my random objects:

The collision was interesting. I didn’t do what fancy game engines do: detect whether the bounding boxes have collided. What I did was much, much simpler! Knowing that my local meshes origins were all at the origin, this meant that their position were all in world space. And as I didn’t care when their boundaries collided, but rather when their local origins were within a certain range of each other, all I needed to do was check to see if a matching object was within a certain distance of the card. To further optimize, as square roots are inefficient, I only checked the distance squared, I only checked the player object against cards that hadn’t been matched, and didn’t check for collisions at any time when the player movemnet input was deactivated. I added the DistanceSquared method to the Math::sVector class.

float distSquared = eae6320::Math::DistanceSquared(i_pObj1->m_rigidBodyState.PredictFuturePosition(i_elapsedSecondCount_sinceLastUpdate), i_pObj2->m_rigidBodyState.PredictFuturePosition(i_elapsedSecondCount_sinceLastUpdate));

return distSquared <= m_distAmountSquared;

The last thing I did was add in the sprite images upon a correct solution. This had multiple purposes: 1) it hid the no longer drawn match object, 2) It hid the sudden movement of the next object to match to the starting player position, and 3) It gave some fun, and funny, feedback to the player that they are on the right track.

If I had had more time (I did this all in about about 15-20 hours), I would have added:

  1. Movement animations
    1. For instance: Locking the “match” object to the center of the card before checking for a match, then moving it back to the beginning
  2. Setting boundaries the player can’t move outside of
  3. Beautifying the game: better match object models and cards, a better background too
  4. Add fun audio
  5. I also really wanted to do lighting

I enjoyed how it turned out though, and so did my play testers. 🙂

What I learned this semester

What I think the goal of the assignments were

I think the most important goal of the assignments was to teach us what good interfaces can do for us. For instance once we set up our one interface which behind the scenes dealt with our different platforms, we didn’t write any platform dependent code. That is very cool! We didn’t have to think about what each platform might need, instead we only connected with our interfaces and let the interfaces do their job.

We learned about building good asset pipelines. At the beginning we only had shaders, but by the end we had textures, meshes, and shaders. We separated out our algorithms from the data. I really liked this (especially creating the binary files!). Doing this makes it much faster and easier to change our assets as data is easier to update than code, and doesn’t require a recompile! We only need the built asset and that can plug-in to our code.

Another big point was to write code that is human readable, understandable, and easy to debug. Ultimately, whether it is someone else or yourself, someone is going to have to read your code to understand how to code against/interface it. If the programmer can’t understand and debug your code (which is really sad when you’re the programmer in your own code and you can’t do this!)  they’re just going to have to either spend a long time to understand it or are going to have to rewrite it, which if it’s a large amount of code is going to take a lot of time. But if you make it human understandable then they should understand quickly what is being done in the code and should be able to code/interface with it quickly, which is very important!

What I got out of this class

I learned so much this semester. I used to always be scared whenever I had to set up build dependencies and references, what the differences were, and why they mattered. I never felt like I could do it on my own. But I don’t feel afraid anymore! In fact, I learned it well enough that I was able to explain to someone else the differences and help him troubleshoot his code, and to recognize when another of my classmates had done it incorrectly in his own code. I say that not to point out that he did something wrong, as we all make mistakes, but that I know enough to know when it is done incorrectly now. And that is also not to say that it’s always easy, but I feel confident that I can figure it out, and to NOT PANIC when I get linker errors! J

I learned…

A lot about graphics for a non-graphics class (I actually understand, on a very high-level, what the graphics card does now).

A more-different way to essentially have shared pointers without the overhead of shared pointers through reference counting.

Oooh, after class one day I asked JP about how shaders do absolute value so quick and so I became aware of the intrinsic functions of the graphics card.

Also, D3D has different debug output in VS than OpenGL.

The difference between handles and pointers.

A side effect of all that we did in the code for me was using the c11 standard as I’ve never worked on projects before that used it (we were in the dark ages I suppose 😉 ).

The, unfortunately short, discussion we had about lighting was very interesting. I hadn’t thought about digital lighting as taking away light, but it made sense.

I also think I would enjoy doing graphics more than I thought I would. Every time we got into talking about graphics I got really excited. The math is pretty basic, but can also be really interesting. I really thought I would hate the discussion on lighting, but I found it fascinating.

My thoughts on good engineering architecture and design

I usually like to try to play the line between very structured and “design as you go”. However I knew there would be a lot of refractoring from assignment to assignment and there’s nothing I hate more than having to undo complicated architecture, and since I also didn’t know what the end goal was, I purposely chose to play on the side of “design as I go.” Otherwise I would have drawn out a more architectured structure. There was only one assignment that I wished I would have architected more in a previous assignment, but even in that case my friend who chose more architecture in the previous assignment only finished about an hour before me, and I know he spent more time making the architecture in the first place. So it was basically a wash.

I’ll say this about good architecture: while I was programming my game I made a decision early on to have a GetMatchObject(const unsigned int i_index) and GetCard(const unsigned int i_index) functions. This made it so that later on when I changed how I retrieved cards I only had to change it in one place: my “interface” function.

A good software architecture allows for flexibility in adding new items to the code, but isn’t so abstract and complicated that it is unclear what the interfaces are good for. I.E. it’s easy to read, understand, and debug, and allows for quick and easy iterations.

A good design will be platform independent: so that you only have to write code once! A bad design will have multiple files with only small changes in each for every platform (whether the platform is OSes, websites, or databases). A good design will allow for quick creation of new types that fit into the same interface. A bad design will require a new object or interface for each new type. A good design is faster to refractor. A bad design requires gutting of the interior for even small changes. On the other hand, a good design also isn’t over-architectured either. For instance, there is no need to create a reusable interface (no matter how neat) if you are only ever going to have one type that uses that interface. Good design is about being aware of the parts of code that need to be reusable, what needs to be able to be interfaced, and what can be done top-down as it were, because it’s not going to be used more than the once.

Acknowledgements

Thanks to Zeno for letting me bounce ideas off of him, and my Dad for proofing my write-up.

Many thanks also to my play testers who really just had fun playing: Zeno Saviour, Monika and Erik Tolman, my sister Deborah, and my brother Zeke (who tested it on linux with wine and it worked!).

Advertisement
EAE 6320-001 GameEngII Game Engine Project, Game Dev Adventures!

Assignment 6: Textures and Reference Counting (again)

NancyNewren_ExampleGame 06

(Simple one-click download. Once downloaded, unzip, play the executable, enjoy!)

Press space to change the humerus texture and find your funny!

About the Project

The first thing I did was add files to the Graphics project to manage textures in code, and then added a TextureBuilder project (to build the textures which are then loaded into the cTexture class from the files in the Graphics project added previously). There were no instructions given on how to do this. Normally I panic because on previous assignments I’ve really struggled with this part, but this time I went in with the attitude that I could figure it out! And I did! So there were two obvious references needed to add to the Texture builder: DirectXTex (because it uses function calls), and AssetBuildLibrary (which was glaringly obvious since one of the TextureBuilder classes inherits from one of AssetBuildLibrary’s classes). With those added there were still 10 linker errors, but I knew that this reference didn’t belong on the Texture Builder because the linker errors were having issues with AssetBuildLibrary (ABL), which needed to have a reference to the Platform project. This may seem strange that ABL didn’t need it in our previous assignment, but that’s because the projects that use ABL were adding Platform as a reference to themselves. Once I added Platform as a reference to the ABL (where it actually should have been liked in the first place) I was able to remove the superfluous Platform reference from the other projects.

The other fun thing to figure out was the build dependency for TextureBuilder. Now the AssetBuildExe uses TextureBuilder to build the textures, but AssetBuildExe doesn’t actually need TextureBuilder during the build. No, it only needs TextureBuilder when it is executed. Well AssetBuildExe gets executed by BuildExampleGameAssets. That means that, even though AssetBuildExe needs TextureBuilder to build the textures, it’s actually BuildExampleGameAssets that has the build dependency on TextureBuilder, because BuildExampleGameAssets is what executes AssetBuildExe, which then uses TextureBuilder.

I added textures to the sprites for this assignment. Since Iadded the textures I needed to use uv coordinates to draw the textures on the sprite. Dealing with the uv’s was fairly simple as I just assigned the vertices of my sprite to the normalized device coordinates. For both platforms that is 0->1 for u. Bt for v, in D3D the values go 1->0 top down, and OpenGL is oppisite that. So when I was assigning the values in the sprite for the x,y screen space coordinates, I assigned the u,v coordinates there as well. So the user doesn’t have to do anything for the u,v. Since I did this inside the scope where I defined the x,y values, there was no code sharing between the platforms. (Since I am dealing with vertex winding and now the different normalized device coordinates for uv, it was simpler to keep them separate). But all this is “behind the hood” so to speak for the game programmer, so all I specified for the sprites were exactly the same things I had for the last version of the game.

The other thing I did was use a handle for loading my textures. The handle makes it so that we don’t load more than one asset from file (using the path as the unique identifier), since loading from file is an expensive operation this makes our game run more efficiently. Then when another object asks for that asset, instead of reloading, it just passes a reference. This is why we had to increment the reference count for the handle manually. To think of it in other terms, we were passing to the graphics thread the handle, not the texture itself. So instead of increasing the number of references on the texture, we increase it on the handle.  Really a way to increment the reference count for handle could have been provided, but I think this was not done to emphasize the that the handle wasn’t the object itself.

Now I did use the handle-provided way to decrement the reference count after rendering was done. The reason for this is because when the reference count reaches 0 and you haven’t used the handle appropriate way to decrement the memory won’t be released properly.

The last thing I did was add a space bar press and time change to two of the textures. It’s quite humerous.

Struggles and Helps

This entire project was much more involved than I anticipated it being, and I really struggled with the last requirements. I spent a long time on the first part: determining project dependencies and setting up my shaders correctly for drawing textures on my shaders. But I was able to really help one of my classmates understand the difference between build dependencies and references because of all the thought I put into it, so it was worth it.

I definitely wouldn’t have finished the project on time without Arpit’s help. I could not get submitting textures to work. My game was completely broken and he helped me get it working so I could complete the assignment. He stayed up late to help me do this after he’d completed his assignment.

Game Dev Adventures!

Game Projects I: Week 15 — New Design Meetings!

We got a playable point-click in 3D. The producers started to argue about the camera, but I suggested we just prototype some different ones and see what was best rather than waste time arguing. That stopped the argument, at least from happening around me. Hailin was able to quickly make the camera prototypes and we were able to play test them. After giving them all a go we decided to go with an angled camera that was Diablo-like: it followed the characters position, but never rotated (like a third person camera is always rotates when the character does, ours just followed the positon of the character, never rotating).

When I noticed that things weren’t moving along in design and story and even from art in a way that I needed as lead engineer because there was no unified vision, I talked with my friend Brenton Walker about the issues we were facing. He told me how his team was organized and how they do a 30 minute design meeting every class period right after stand up. That’s were tey come up with their list of to dos and pass then allow the leads to pass on tasks to their teams.

I thought that was an excellent idea so I proposed it to the team and they all agreed. And so on Thursday we had our first ever design meeting. It helped us nail down so many of the issues and come up with a unified design to move forward with. This design meeting was critical for us to be able to make the game.

This was a key point in turning our idea into a working demo. Without the design doc there was nothing firm that we could focus our efforts on. Everyone was working hard, but a lot of it was on long term efforts, some of it on extraneous tasks, and the short term goal for EAE day was going to be missed.

With the design doc created and updated from the meeting I was able to divvy out all the work that needed to be done to all the engineers and to our artists so we had everything we needed.

Game Dev Adventures!

Game Projects I: Week 14 — A Blur

So much is going on right now in this semester! This week is a bit of a blur and it just happened! Here’s what I remember…

Dayna, Sean and I had an AI design meeting. We discussed the properties the AI should have, how we would design their reactions, and how to make it a dynamic AI system so that the narrative would be more f an immergent rather than a branching narrative. it was a really cool discussion. I left it to Dayna as lead AI and Sean as lead design to manage the recording and implementation of our meeting.

I did a lot of partner programming this week helping Hailin and Dayna with what they were doing. Binoy was doing research into reading in from xml and came up with a demo and I discussed the issues with doing that with him. I also took Hailin’s prototype and built it to Windows 8 tablet, which is not as simple as it seems. It took us two hours to get it worked out as we couldn’t quite remember how to do it. It took Me, Hailin, and Binoy to get it.

Roger came in and gave us some feedback about our story. What it needed was a topical hook. Two of the producers took this as our story sucked and a two-hour argument broke out. All the writers agreeing that all that needed to be done was to come up with a hook, and the two producers arguing that the story had to change. It really put a hamper in my work. This wasn’t uncommon actually. Arguments like this happened a lot among the producers. The engineers mostly didn’t know about them though because I mitigated all the arguments and then just passed on the feedback/direction that I got from these discussions so that they could focus on their work.

Bob talked with the engineers about what was new as he wanted to make sure we had something new we could show. We had a new story, new engine. Yes, yes he nodded to that but what else? We’re going to demo the game on tablets. Okay he said. Get to it.

Sold!

 

Game Dev Adventures!

Game Projects I: Week 13 — Engine, AI, Story

I organized the engineering team and gave them their roles, or rather defined the roles within what they wanted to do. Binoy and myself were the game engine engineers. I was lead and he was assistant lead. We would do any necessary partner programming and fill in wherever necessary. I also managed version control. Hailin was lead gameplay programmer, and Dayna lead AI.

Engineering team go together and we had what was basically a mini design meeting. We broke up the work and research that we would need to do the engine (more below), AI, and gameplay. We came up with our second prototyping plan: choosing between thoughts popping up or having to click, and a 3D camera. Hailin was in charge of this. I and Binoy partnered with her as necessary.

Binoy and I really wanted to explore multiple options on the game engine which included the possibility of making our own. I was never able to get full support from the producers on this effort despite the research that Binoy and I were able to do that showed we should have been able to do it if we were making a simple 2D point-click game.

I explored bindings between c# and c++, outside libraries like SFML, we could use to improve our engine quickly. I also did research for fmod and wise for sound and their c++ “plugins”.

We also had our writing meeting and came up with a story that we all agreed on. We pitched the idea to the whole team later and the professors and they all agreed on the idea and the professors told us we could move forward with it. We came up with the characters as well. It’s a really fun story!

 

Game Dev Adventures!

Game Projects I: Week 12 — Pulling the Trigger, Lead Engineer

Tuesday we finally pulled the trigger on the game we were going to make. We got lots of good feedback at GDC and we believed that we could do either. My favorite feedback was what Sean shared and that was when he pitched Ragwheel with projections (instead of as ghosts) the persons he pitched it to immediately grasped the idea and liked it.

We were split though and had to get the faculty to help us vote. The deciding factor was a weighted vote: each person got three votes that they could put towards whichever game they wanted. The vote was close: 17 to 13. Make a Man Thinketh won. I was fine with either game so I am not disappointed.

We then immediately had an engineer meeting about which engine we would make the game in. We discussed several: flash, flex, unity, gamemaker, flat red ball, and scratch. We also got our artist in on the conversation and we all decided the same thing: Unity.

I then organized the team into writing and design teams.

Most of our class time was taken up on Thursday with a lecture. Directly afterwards we had a meeting to choose leads. I was surprised by the overwhelming nominations I received in getting voted in as engineer lead. While others who got nominated for their lead roles got passively voted in by others, I had multiple people nominate me, giving reasons and support for the role. I felt very honored.

I then went to my desk and thought about what had happened. I was lead. That’s a huge responsibility.

Cool Stuff!, Game Dev Adventures!, Helping Hand

Game Projects I: Week 11 — Game Developer Conference (GDC)

GDC was amazing. This was my first time going and I’m so glad I went! I would have loved to be there for more of it, but family business took me away for two days in the middle of it. However I got to listen to some amazing talks. The Friday before GDC I actually pulled out my Mathematics for 3D game programming and Computer Graphics by Eric Lengyel and read throught chapter 2. I’d been avoiding linear algebra stuff since most of it didn’t fall into my area of math expertise and I remember some parts of the class being very overwhelming even though I did get an “A.” However, when I got to the part in chapter 2 about Vector Spaces I knew I wasn’t in the same place I was as a freshman in college. Vector Spaces are just special groups. It was group theory! I’d taken Modern Algebra my senior year (study of groups) and I’d never had a reason to look up my linear algebra theory until then. It made so much more sense. It’s funny what sometimes how new knowledge makes once difficult things simple. After taking modern algebra and lots of time for my to think on the idea, Vector Spaces got a new slot in my brain.

Well Monday morning of GDC I was looking forward to a day of math tutorials. I knew my friend Skip would be there. While I was riding the escalator up to the room I took a look at the day’s speakers. First up, Eric Lengyel on grassman algebra. No way! I was just reading his book! It was so cool to get to hear a talk by someone who’s book I was readig. Eric’s talk was by far my favorite and I can’t wait to implement the grassman algebra he showed us into my game engine.

There was one other talk during GDC that I loved. It was the post-mortem on the Human AI for The Last of Us. It made me feel so much better about all the crazy meshes and ray casts I was doing and thinking about doing for the projections (previously known as ghosts) in Ragwheel. It made me feel like it was doable as well and that I was on the right track, so to speak, to making the projections a reality.

I had a hard time at the career fair my first day there. I ended up just going to a couple talks instead. Then I went to my school’s booth. I’m so glad I volunteered to work there! It helped me break out of my shell and start talking to people. It was fun being on the other side of it and I understood both sides. It got me really excited to go to the career fair the next day and talk to some people!

The career fair was awesome in that I wasn’t looking for a job from there, just feedback on my resume. After breaking myself to talking to people again the day before, I was able to get some excellent advice on my resume.

Advice for people going to GDC: take some printed copies of your resume and ask people to give you feedback. The very least you’ll get some good advice on what to make better, the most they may LOVE your resume and you could get an interview! I didn’t stop by anywhere that I was sold on working for, and most places weren’t looking for interns or weren’t taking resumes, but I got what I wanted. It gave me what I needed to improve myself as well as a game engineer. It gave me more focus and I got to learn about some companies and whether or not I actually wanted to be there.

Also, if you have the opportunity and you’re a bit shy, like myself, and just need a kick start to talk to people, then volunteer at a booth. It will really help you see the otherside and help give you the confidence to go talk to other people. Getting a wingman to go with you is always helpful to. I chose to go by myself so that I wouldn’t chat with my friends and possibly miss opportunities. This also allowed me to meet some cool people in line while we waited. However the wingman thing isn’t a bad way to go either. It’s best if you go with someone in a different area of expertise. For instance a game designer and an artist. A producer and an engineer. Or if you’re two engineers than make sure to distinguish yourselves. That way you’re not competition to each other. Even if you’re both game engine, which areas do you focus on. Or perhaps you’re both graphics but one does more gameplay and the other more engine, etc. Just always present yourselves as doing two different things, even if you overlap in what you like. You’ll hear about more job opportunities and have more to talk about with the recruiters.

 

Cool Stuff!, Game Dev Adventures!, Helping Hand

Game Projects I: Week 10 — Spring Break

Spring break was amazing! I got to go to my brother’s work and meet his team and bosses. We set up a meeting with his bosses and I got to interview Christina. She was really nice and open. She, like myself, had a degree in something other than computer science for her undergrad and then switched to computer science for her masters. She was doing really well in the company and had excellent experiences. She asked me what I wanted to do and I told her I was open to new experiences. Then she gave me some excellent advice: make a list of all the things you want in a company that you want to work for. For herself, her company met everything she wanted.

She also told me, in talking about being a woman in engineering, that she’d never experienced discrimination. Being in the workforce in California where they’re more forward-thinking and woman are urged to seek more professional jobs, if anything she’d experienced anti-discrimination where she was actually helped out a bit more because she was a woman.

On that same note she told me to always think of myself as an asset.

“You’re an asset to the company. You are. You’re worth every dollar they spend on you. Be confident.”

Game Dev Adventures!

Game Projects I: Week 9 — Industry Panel

The industry panel was awesome! We were one of the only teams where the industry panel couldn’t decide which of our games we should move forward with. They were very polarized: very passionate about both the games. We got, “You must make this game!” for both games! Rory from Eat Sleep Play came up to me after the panel and we talked about the difficulties of the ghosts. He’d worked on a game with the same idea and they had finally scrapped the idea because they were never satisfied with how it felt. It was also very time consuming engineering wise which meant it took a lot of time away from playing with other things in the game. It was very reassuring to me that even industry professionals struggled with what I was trying to accomplish because it meant that I wasn’t the only one having issues with it!

The industry panel told us to get rid of the ghosts (for aforementioned reasons), but Owen, Binoy and myself still felt they were a valid part of the game. Especially with our playtests where when the ghosts were missing the players got quickly disinterested.

The following day the faculty gave us some feedback too. They were again mixed. The one thing that crept up continually for Make a Man Thinketh was that it should be mobile. Roger gave some great feedback for Ragwheel as well. He said that the ghosts weren’t a bad idea they were just pitched poorly. He then suggested the perfect new name for the ghosts: projections. 

The following days we got together and discussed the possibilities of both the games. I had spoken with several people on the MAMT project, and the game was about to be abandoned. Then I pitched the game as a 3D mobile game and everyone jumped on board: Shane, Sean, Binoy and myself. Binoy told me I was killing it with the ideas. Even Dayna said she’d go for it, and even though Hailin loved the 2D she was willing to try out 3D for the sake of our artist who is a 3D artist.

Casey also approached me and asked if I was going to be lead writer on Make a Man Thinketh and that got me thinking about another aspect of myself that I love.

Ultimately we couldn’t decide on a game and so decided to take spring break and the week of GDC to think over the possibilities.

 

Cool Stuff!, Game Dev Adventures!

Game Projects I: Week 8 — Crunch Time

One week to industry panel! We knew this game was going to be difficult to make, so no one was surprised by the amount of work left to do before the industry panel.

At this point I had had conversations about how to do the ghosts on several occasions with Owen, Binoy, and especailly Shane who was always more than willing to help out with creating meshes and art whenever we asked. I was having another such conversation, drawing up problems and possibilities with Sean, Owen, and Ryan, when my fellow mathematician, Skip Fowler, listened in to our conversation and we started talking about how I was going to calculate the metrics for the ghosts and place them in the scene (neither an easy nor straightforward task). It started like this.

Skip: “How are you going to do that?” Curious.

Me: I explained several of the issues of with having to place an object on the scene when it’s position is determined dynamically by two different sets of inputs but is also reliant on track position.

Skip: “How are you going to do that?” Truly pondering the scale of the problem.

We then talked lengthily about the mathematics behind calculating the metric of distance in R3. Thank goodness for his real analysis background. The solution, long term, is line integrals! Genius! Knowing the answer in myself, but wanting confirmation I asked Skip if I could do it in a week. He laughed and shook his head. “No way.”

All righty then, back to where I was at. I had to come up with a cheat.

The other issue was placing the car on the track. Once I knew the metric I was also having issues placing it in the right position. It was a continual issue.

Shane had designed a new 3D track and Binoy had conquered the flip turns, at least enough for a playable demo. So it was my challenge to get the ghosts in the right positions.

I spent the weekend in the lab. Shane was often there, and at times Binoy, but mostly Shane. Brad joined us as well to make videos and prepare the slidedeck for the presentation.

I got a little frustrated with not being able to get something to work. Shane’s new 3D track allowed me to still cheat the metric easily: z-displacement. But it also introduced a huge problem: Now the rotation of z was also dependant on the relative position of the player to the track. Calculating the rotation of the ghost dynamically had already proved a problem earlier in the process and it wasn’t proving any simpler.

So I decided to add something flashy. I gave both the cars trail renderers and added some particle effects to the car that was in the lead determined by the same metric as the ghosts. The trail renderer added another visual cue to the player about where their opponent had gone if they were behind by only a couple seconds. And if they were “in the lead” the particle effects gave them a visual cue for that as well. The two together added to the ultimate goal of communicating to the player their relative distance from their opponent without using a HUD, and added to the overall head-to-head feeling.

I then returned to the issue of the ghosts and HUZZAH! At the end of the night with some creative ray casting (at least I thought it was creative) and special meshes from my artist I got the ghosts to follow the correct path! WHAT!!! It was so exciting! There were several cheats still in play, but it was working in 3D space.