Sunday, April 28, 2013

Developers Log. Release Date 3. Reflections

The game went live on Friday! I had suggested we do a live podcast to generate hype, and hopefully introduce the fan-base each team had generated to the other games. Friday we did just that, however between the three teams, (well, only counting three members of the Heroes of Rock team) we were able to get a max of 24 viewers online. That's almost equivalent to each of us securing one viewer! So not nearly as much hype as I had hoped, it was still a good experience. Also, Trippleslash was able to get the Indie Gamer  Chick to join, so that's awesome! It most definitely helps humanize us and secure in her mind that we are students.

With the game being finished a huge mantel has been lifted off of my shoulders. I'm toying with the idea of updating a patch to improve the camera a bit more. It just isn't as good as I would have liked. I probably will, as this is something tightly attached to my name, I'd like to be as proud as I can be about it!

All things said and done, it's a pretty fun game. It's fun to watch others compete with themselves to do better.  It's exiting to know you were able to make someone feel something. That's what it's all about right? It's art. I want to make someone feel an emotion, and I feel successful in that the emotion I most commonly see is displayed on those playing my game.

Having gone from conception to release, the game has changed a lot, and many times. We have a finished and published product, and that is awesome. I'm still sad that it's not a multiplayer game. How I wish it had been an arena based competitive death-match. I feel like I need to make one of those next, because I'd really love to make one!

Thursday, April 18, 2013

Developers Log. Development Date 151. Box Art

Up until now, we have had only one box art. The one on the left was the only one we had until I started making some waves about problems with the design. The one on the right contains the fixes.



The first one had shurikens to add a ninja feel, but we don't have shurikens in the game, so they had to go. Additionally, for whatever reason, half of the title was missing. Around the time that I made mention that these item should be changed, I sat down and designed a rough idea of how I thought we could improve the box art.

The first phase of designing our game during fall semester was to come up with a slogan that would be the driving backbone of our game. No matter what decision we made, it should always go back to that slogan, to see if it fit. Our slogan: Unleash your inner ninja. I feel that this current poster is less "Unleash your inner ninja" and more "Unleash your inner happy place."

I really wanted to capture our slogan, so I tried a few poses, the first being an avatar with a Katana in his hand, sort of following the cliche pose of today's triple A titles. However, after taking a somewhat different approach I fell in love with the three point landing pose. It's just so hardcore. Now, I'm no artist, so this was never intended to be amazing, but hopefully capture the general idea I was going for.


There are obvious problems here, poor quality on the avatar, the essence scarf around the avatar doesn't read well, and looks more like smoke than an attached scarf, and the title has several problems. The background is also too busy, but it was the best of the few screenshots I had on hand at the time of creation. The other leads didn't seem to impressed, as they only got hung up on the flaws, and didn't seem to catch the idea I was trying to create. They wrote it off as a "nice try" from a programmer. Well, I happen to believe in myself, so I set out to get some help from some of my friends who are artists to make the idea actually look good. I actually framed a shot (rather than using an existing screen shot,) was able to get a better picture of the avatar, had a Photoshop genius help me with the scarf, and had lots of input on title and the color pallet. This is the final result.
I still hope to get a better quality picture of the avatar, and am working on some code to extract a high def picture from the xbox. I hope to achieve this by writing the bytes of the current frame to console while debugging on the xbox, then re-creating the image in a separate program. Given our current hardware, we have no real way of getting a high def picture off of the xbox, so this is our last viable option without spending money. However, despite the small pixelation, I am very pleased with the result. The colors really pop and the framing fits so well. It really invites the viewer to unleash their inner ninja!

Tuesday, April 9, 2013

Developers Log. Development Date 142. Wrapping Up

The past week has been spent chasing down and fixing bugs and polishing up that which had no polish. We are doing our best to be ready to push for our final review so that we can release next week. The biggest issue we ran into was we had hoped to push the game Friday to catch any final errors we haven't seen; however, we could only push for play test, and not for review. The website told us we could not push until Sunday (marking two weeks from when we pushed for review last time.) We weren't expecting this, as our understanding was we only had to wait one week, not two.

I fixed a pretty major bug causing lag to happen the first time the player jumped, and the first time a player double jumped. The cause was the the audio controller had been written to not pre-load the audio clips, so the Content.Load calls used to retrieve the sound file was loading it mid-game. Tsk tsk.

I also polished up the credits screen. It hadn't been coded to loop around, it had jitters, and I wanted to add our avatars to the screen. I fixed a lot of the code to be dynamic where it was static, which made adding the avatars super easy, whereas it would have been a nightmare with the static code previously there, hardcoding each position for each page. I had to also add a method for transforming positions for the UI x,y coordinate system to the X,Y,Z coordinate system of the camera. I simply find the corners of both, then I can create a translation and scale factor for moving between the two different worlds. This enables the avatar to scroll with the page.

I also made a small little class for getting, saving, and loading our avatar data. Today in class I will have everyone log in so that I can store their data, enabling us to ship our game with our avatars data forever stored. Now the credits screen can have our avatars full of life, sitting next to our names! There may also be cheat codes implemented to become the devs, who knows! :O


Tuesday, April 2, 2013

Developers Log. Development Date 135. GDC

GDC was disheartening. The Expo Floor didn't have wireless, at least not that the U of U booth could get to work. This big limitation our game has always had to deal with is being on the Xbox so that the Avatars display properly. As the game is not yet published, in order to play it, one needs to be connected to the internet and signed into a live account that has the creative club membership. Without the internet, we cannot show our game.

It was sad to not be able to show off and talk about my game as people played it. That was the main reason I went. I spent a lot of time time talking to Riot employees. I met some great peeps that did all sorts of fun things for Riot, and they all seem genuinely happy. Most valuable was when I was able to talk to Mike, a gameplay engineer, about what it's like to work for Riot as an engineer. As my interest is gameplay, it was by-far the most interesting and valuable conversation that I had at GDC.

I chose to go green and simply carry my resume around with me in pdf form on my iPad to email to people. This was my biggest regret, I should have printed copies and carried them around. The wireless didn't work for me down on the Expo floor, so I couldn't email it right then and there. Not having my Resume to hand to people also felt a bit hollow when talking to people about future careers since I couldn't leave anything tangible. For any future GDC adventurers, my advice would be to carry a stack of resumes around.

Thursday, March 21, 2013

Developers Log. Development Date 123. Polish!

It's been a month since my last post. Most of my work has been on improving the camera and player controls. I have been hoping to get a blog post about the camera up, but it's not quite there yet. I want to post some of the ideas and logic involved in making an intelligent camera for 3D platforming. The camera is working pretty great, but I hope to explore a few more ideas to really make it shine, so I will save my post on that until a later date.

Aside from that, I have been working on adding polish and tying up loose ends for our GDC demo. After all of the work on the camera, I needed something a bit lighter to restore joy to my soul. I added a small feature I have been hoping for since pre-alpha. I really wanted to help set the atmosphere for the player being a ninja, not just a parkouring guy.

 For this I explored different ways to add a mystical essence scarf that follows the player (like the scarf of a ninja mask.) I first attempted to use a model with joints to allow physics to cause the scarf to swish around as the player moved. In the end this didn't feel feasible in the time constraints I have. Without getting everything right the scarf would fly around like mayhem, crashing through the player and just looking terrible. I then moved onto using a trail renderer, which was simple and much more fitting to my scope of time. I hope to spend more time to find a good texture to use that really gives it the feel I want. For placeholder, I changed my blend type to allow me to just create a black and blue effect.  In the picture below it's much much longer than it is in the current build. This was taken at an awkward time for our scarf.


Part of my essence scarf implementation required me to set up a component that attaches itself to a specific bone of the avatar. The scarf attaches to the head, so that even when the player does a flip, the scarf follows his head. I was able to use this same component to attach a katana to his back, further adding to the ninja feel. Good stuff.


Thursday, February 21, 2013

Developers Log. Development Date 95. Controls!

The main focus of this week was controls. I started off the week working on adding the ability to slightly adjust velocity for left/right movement. Last week I locked movement when in air, but I wanted the player to be able to add small corrections to their landing position. I accomplished this by adding two methods to the inputController (well, I slightly modified one we had been using, then added the other.)

 public override Vector3 GetWorldVectorRelativeToCamera()  
 {  
    float horizontalValue = ThumbSticks.Left.X;  
    float verticalValue = ThumbSticks.Left.Y;  
   
    Matrix cam = Matrix.Invert(Camera.View);  
   
    Vector3 vec = (cam.Forward * verticalValue) + (cam.Right * horizontalValue);  
    return new Vector3(vec.X, 0, vec.Z);  
 }  
   
 public override Vector2 GetLeftThumbstickRelativeToCamera()  
 {  
    Vector3 directionVec = GetWorldVectorRelativeToCamera();  
    float horizontalValue = Vector3.Dot(directionVec, physicsBody.Orientation.Right);  
    float verticalValue = Vector3.Dot(directionVec, physicsBody.Orientation.Forward);  
            
    return new Vector2(horizontalValue, verticalValue);  
 }  

GetWorldVectorRelativeToCamera returns the vector in world space of the left thumbstick. So if the player press forward, it returns the vector of forward from the camera (the camera can rotate 360 degrees around the player.)

GetLeftThumbstickRelativeToCamera returns the value one expects from calling Thumbsticks.Left but relative to the camera and player. This came into play for when the player was locked in a certain orientation. The player could be jumping in a direction that is equivalent to the camera's right. If the player pressed down on the thumbstick, the controls need to be the same as when the player is on the ground. If the player is on the ground and presses down, he runs at the camera. If the player is jumping right and presses down, he needs to slowly move towards the camera, still keeping his velocity and orientation going to the right of the camera.

In addition to in air controls, I added a new sliding state, for when the player slides down a wall, changed horizontal wall runs to cause the player to fall after 500 milliseconds rather than auto jumping for them. Requiring the player to jump rather than doing it for him/her adds a better feeling of play. Also, I now account for thumbstick directions when jumping to slightly alter the jump direction. This value needs testing, but it might be too small of an influence currently.

Outside of controls I added a few features to our level editor to make creating triggers easier on the level designer. I finished connecting all of the trigger creation for killzones, checkpoints, and ability pickup. Earlier in the week I helped architect the way we wanted to do triggers, I wanted to ensure we were taking advantage of our component/entity system.

We have a trigger component that listens for collisions from the physics body. This trigger can also have a flag set for what can trigger it (just a player, player and AI, bullets, etc.) When triggered, it raises events so that any other component that subscribed to the trigger will be notified. This is sort of a shadow to Unity3d's broadcast functionality, but I prefer this method.

Here is an example of how this pieces together:

Trigger class
 public class Trigger : Component  
 {    
     public delegate void TriggerEnter(Entity entity);  
     /// <summary>  
    /// Methods to be invoked upon the appropriate entity colliding with this trigger.   
    /// </summary>  
     public event TriggerEnter OnTriggerEnter;   
   
     ... [within collision handling, relative to whatever physics engine you are using]  
     if (OnTriggerEnter != null)   
       OnTriggerEnter.Invoke(entity);  
     ...  
  }  

Some component that uses the trigger.
 public class ExampleComponent: Component  
  {     
     public override void Initialize()  
     {  
       Trigger trigger = OwnerEntity.GetComponent<Trigger>();  
       if (trigger == null) 
           throw new System.NullReferenceException("Trigger component did not exist on owner entity");  
       trigger.OnTriggerEnter += OnCollide;  
     }  
   
     protected override void OnCollide(Entity entity)  
     {  
         // Do something, play a sound, do damage, etc  
       OwnerEntity.Dispose(); // delete trigger  
     }  
 }  

Using this method, I can attach several components to an entity that has a Trigger component, and each one can listen for the on collide, and activate their respective code when that happens. Very dynamic, flexible, light, and powerful.

Tuesday, February 12, 2013

Developers Log. Development Date 86. The saving of a level.

Two weeks since my last update. Last weeks post sits as a draft, 90% complete, but due to things getting crazy it was never completed. Last week we realized the level we had was unusable. The artist that created the assets in Maya had not exported the models at the origin, this was causing discrepencies when we loaded the models at their positions in XNA. We had developed a tool in Unity3D to build the maps then export them as XML so that we could re-build the level in XNA. By modifying the model and setting it at the origin, the level would become messed up in Unity (as expected.)

I spent some some time scripting a Python script for Maya that would center the pivot on the model, then center the model at the origin (relative to the pivot), then it would freeze the transformation and clear the history. I created a second method to loop through all fbx files in a given folder and all sub-folders, importing the fbx into Maya, running the centering script, then re-exporting the fbx file. Next I scripted a Unity editor script that adjusted each model relative tot he original offset in Maya, so that everything matched up.

I then spent a lot of time getting quests and quest objectives to go from our unity level to our XNA level. Part of this included setting up triggers and the quest manager. The Quest Manager loads the first quest, spawns all of the objectives, then after all objectives have been completed, the next quest loads. Standard stuff.

After the playtest, I slept for 12 hours. Following that a little ranked League of Legends, a man must keep his elo up, of course.

This weekend I spent working on improving the controls. The biggest issue from the playtest was the controls are slippery. People seemed to really enjoy the game, the concept and the feel they got from doing ninja moves, but they couldn't master the controls the way that is essential to having this game succeed.

When I first sold myself on this game idea, before I pitched it, my selling point was having tight and sexy controls. I haven't had the time to sit down and make them sing, I've been needed on too many other fronts. Everything is coming together well, and I finally now have the time to really baby our controls.

First I improved our camera. It now considers more of the player to determine if the player is in view or if the camera needs to do something to get the player in view. I will be looking into either making objects transparent, or improving our logic for moving the camera in the coming days.

Next I removed rotation of the player whilst in the air (again.) This time, however, I added the ability to change direction when using the double jump. This feels great. I also added the ability to slightly shift to the left/right mid air. So while not turning and moving as freely, the landing position can be slightly altered.

The wall jumping was one of the biggest challenges during the playtest. The answer was "mash jump" to scale between the two walls. Terrible. I added a slide when holding your thumbstick towards the wall, megaman style. This slows down the jumping so the player can make precise and timed jumps. This has helped a great deal, but I will be re-visiting this soon to further improve it.

I'm excited to see these improvements coming along so well, and am also excited to finally be able to focus my time on gameplay.

Tuesday, January 29, 2013

Developers Log. Development Date 72. Animations and Profiling

Woops, forgot to blog last week. I blame the respiratory virus that had me in bed all week.

The first issue I addressed was animations. Our animations have been really glitchy. They would reset halfway through and/or flicker. I finally allocated time to go figure out why. It was a simple fix once the bugs were found (related to a poor implementation of a student last semester of my animation code and some blending animation code from the Microsoft education catalog.) Essentially some animations would be called to play twice or reset mid play-through. 

Second I found a profiler to help us identify where our draw and update calls are spending most of their time. It seems pretty solid but has awkward interface controls, so I lightly wrapped the controls to allow us to toggle the display on and off, enabling us to turn it on when we need to check what is going on when we start to see performance hits.

Lastly I worked on some scripts to help convert a level created by one of our artists in Unity to fit the format we have designed to be accepted into our content pipeline. Within a few clicks all of the prefabs become converted to the format now.

Tuesday, January 15, 2013

Developers Log. Development Date 58. A New Year!

With the end of alpha I never found time to return to the blog before the semester had ended, and had no ambition for blogging amid the Holiday break. With the spring semester of my Senior year here, it is time to rekindle the blog for our XBLIG game (current code name: "Ninja Avatar: The Trials.") Despite being MIA in from the blog over the past few months, I continued to work on the game.

I took advantage of the break to work on a some Unity3D scripts for the editor allowing us to harness the power of control and ease-of-use unity offers for level and prefab creation for our XNA level creation. The artists can now create a model, then use unity to set up custom collision walls, and save it as a custom xna prefab. They can even use the same model (and different ones) to build a collage of models into one prefab. (When loaded in xna it still only has to load the fbx just once, however.) These models are used for the level creation. Both the models and prefabs use xml serialization. On the XNA side we will simply reconstruct the prefabs as we build each level. This will greatly improve our performance and ideally our level creation/maintenance time. It was also key for quest/objective design for the levels.

Since the semester started back up ago last week, I have been adding some functionality to the tool such as an opacity slider for the display/collision models. I've also fixed several bugs and cleaned up the process the user has to go through to make it a more smooth experience.

In addition to working with the tool, I've been working on tightening the controls for the game. This game absolutely needs tight controls, and they just aren't there yet. I've spent some time with Overgrowth (an indie game under development involving light parkour) observing the controls hoping to get a better feel for what makes something feel so good and tight.

Additionally, in my spare time, I began doing some research for prediction and smoothing for out networking side of the game.