Monday, October 21, 2013

Blog #2: Flash-UDK Workflow

Monday, October 21, 2013

Hello again. It has been a few weeks since my last blog posting, and I am back again to do another. This time around, I am going to explain the Flash-UDK Workflow and take you through something I created for my most recent project. I will be showing you how I made a custom HUD in Flash, with a checkpoint counter on it, and how I got it to work in UDK. Let's begin.

First off, I will show you the final product:


As you can see, the HUD does not really do anything except display the number of checkpoints the player has left to use in the lower right hand corner. This differs drastically from the normal UDK HUD which has things like health, ammo and what weapon is currently equipped. For our custom game, all we needed was this very simple HUD. Getting this working in UDK, however, is another challenge.

There are two ways to get a HUD in UDK. The first way, and not the recommended way, is to create your HUD, import it into UDK and use Kismet to open a GFxMovie to display your HUD. It works, but it can be very buggy and unpredictable. Especially if you need to use other Flash elements in your game. The way I did it, and the recommended way to do it, is to create your HUD, import it into UDK and make a custom gametype script that will tell UDK to use your HUD and not the default one. 

I am going to start by showing you the Flash first. Below is a picture of the HUD from the above picture open in Adobe Flash:


You cannot see anything as the text is colored white, but it is contained within those two blue boxes in the lower right. The left box holds text that is static, meaning it does not change. The right bow contains a dynamic text field, which means it can change at some point. Now, I have named the dynamic field CPLeft. Let's see the actual ActionScript that controls this HUD:

stop();

var checkpointsLeft:Number;

var keyListener = {};


function setCheckPointsLeft()
{
checkPointsLeft = 5;
_root.CPLeft.text = checkPointsLeft.toString();
}

function useCheckPoint()
{
if(checkPointsLeft > 0)
{
checkPointsLeft--;
}
else
{
checkPointsLeft = 0;
}
_root.CPLeft.text = checkPointsLeft.toString();
}

setCheckPointsLeft();

keyListener.onKeyDown = function()
{
    var theKey = Key.getCode();
if(theKey == 88)
{
useCheckPoint();
}
};

Key.addListener( keyListener );

NOTE: This code is attached to the stage itself, not the text fields. If you are unfamiliar with Flash, I suggest you look up how to add code to things in Flash.

Don't worry, I will go through this code line by line to show you how it works. First of all, the stop() call just makes sure that Flash will not advance to another frame. The next two lines are variable declarations, one being a Number (like int in most other languages) and the other being just another variable. In Flash, you do not need to give your variable types if you don't have to, which is why the keylistener variable has no type. 

The next two functions are purely declarations and implementations. They do nothing on their own. They are put in that spot to make sure they are declared before use. The function setCheckPointsLeft does a very simple job. It sets the global variable checkPointsLeft to 5, then assigns the number 5 to be written in the dynamic text field I described earlier. The call to the dynamic text field is quite simple, _root tells the code we are accessing the root of the stage (where the text fields are located), CPLeft is that name of the dynamic text field (can be thought of as an object) and text is the name of the variable that holds the text that will be written in the dynamic text field. The toString() function call turns the data in the variable checkPointsLeft into a string so it can be displayed by the text field. So, in simple terms, it sets the field to display the number 5.

The function useCheckPoint does what its name implies, it uses a checkpoint and subtracts it from the number left. The if-else statement is a bit of error checking to make sure the number displayed in the text field does not go below 0. Then the line _root.CPLeft.text = checkPointsLeft.toString() uses the same idea as the above description.

Then we call the setCheckPoints() function so it is run when the Flash is started (i.e. when UDK draws it on the screen). The next line is another function declaration. However, it is a little different from the other two. In this case, we are telling the keyListener variable to use its onKeyDown function in a certain way, which we define below that line. We create a variable to hold the key code that is returned from the keyListener. We then check it against whichever key we want that will serve as the button to decrease the amount of checkpoints we have left (meaning the key we setup in UDK as the set checkpoint key). 88 is the ActionScript keycode for the letter x, without having the shift button pressed. Then, after that function declaration, we tell Flash to add our custom keyListener and use it to determine if we have pressed the x button or not.

Now, that wasn't so bad. Let's move on to the UDK stuff. First of all, you would need to save your Flash file in this path (assuming you installed UDk to your C drive, otherwise change that letter to the drive letter where UDK is installed): C://UDK/UDKGame/Flash and put it into a folder with a different name. In my case, the file path of my Flash files was C://UDK/UDKGame/Flash/CPFlash. Now that it is saved, you will need to publish the Flash using FlashPlayer 8 and ActionScript 2.

Now, inside UDK, you would open the Content Browser and click the Import button on the lower left. Navigate to the place where your Flash is stored, and double click the file you want to import. UDK will create a package for you with the name being the same as the folder where the Flash is stored, then click OK. Now, we step into UnrealScript.

This part is not very hard. If you are familiar with how to write a custom gametype and get it to work in UDK, you can skip this step.

What we are going to do is create a custom gametype that will use our HUD instead of the default UDK HUD. 

Navigate to your UDK install folder, and go to Development/Src/MyMod/Classes. Create a new text file and name it NewGame.uc. Open that file and paste in this code:

class NewGame extends UTDeathMatch;


DefaultProperties
{
    HUDType = class'MyMod.NewHUD'
    bUseClassicHUD = true            
}

The first line tells us the name of the class (MUST BE THE SAME AS THE FILE NAME) and what it extends from. In our case, NewGame is extending from UTDeathmatch. DefaultProperties can be found in all UDK scripts, and is the place where variables can be set. So, we are telling UDK that our HUDType is of a class we are going to create soon called NewHUD. Then, the bUseClassicHUD = true tells UDK that we are using a classic HUD. Save this file.

Next, make two new text files in the MyMod folder and name them NewHUD.uc and NewGFxHUD.uc. Open NewGFxHUD and paste in this code:

class CPGFxHUD extends GFxMoviePlayer;

function Init(optional LocalPlayer PC)
{
  Start();
  Advance(0.0f);

}

function UpdateHUD()
{
}

DefaultProperties
{
 MovieInfo = SwfMovie'<insert name of package where your Flash is stored in UDK>.<name of Flash file>'
}

Again, we are first defining the class and what it extends from. Then, our Init function tells UDK to start the Flash file with Start() (this MUST be called) and to keep executing the function with Advance(0.0f). Putting something larger than 0 in the parameter list of Advance() will make UDK sleep for that duration before continuing.

UpdateHUD does nothing, but if we wanted to have dynamic health bars or ammo counters, we would put code in that function to update those specific HUD elements when needed. The DefaultProperties is where we tell UDK what Flash file to use for the HUD. We are setting it to the Flash file you imported into UDK earlier. Save this file.

Open NewHUD.uc and paste in this code:

class NewHUD extends UTHUDBase;

var NewGFxHUD HUDGFx;

simulated function PostBeginPlay()
{
  super.PostBeginPlay();

  HUDGFx = new class 'NewGFxHUD';

  HUDGFx.setTimingMode(TM_Real);

  HUDGFx.Init(LocalPlayer(PlayerOwner.Player));
}

event PostRender()
{
 HUDGFx.UpdateHUD();
}

DefaultProperties
{

}

We are declaring our class and what it extends from, and then creating a variable named HUDGFx that is of type NewGFxHUD. Remember the class we created earlier with the same name? We are using an object of that class to tell UDK to draw our HUD. The function PostBeginPlay is defined next. The first line super.PostBeginPlay() tells UDK to call the PostBeginPlay function and continue from that point. Then, we set the variable to a new object of type NewGFxHUD. Then, we set the timing mode of the HUD to Real, which tells UDK to keep updating the Flash, no matter what. We then call the Init function from our previous class and tell it to set the HUD to the Player so that they can see the HUD.

The next function is not really a function, but an event. This even calls the UpdateHUD function from the previous class. DefaultProperties can be left blank in this class, but it has to be present or UDK will error out.

Now, save that file and close it. You will now have to navigate to UDK/UDKGame/Config and open DefaultEngineUDK.ini. Navigate to the line that says ;ModEditPackages=MyMod and remove the semi-colon. This tells UDK to include scripts you wrote in the MyMod folder, as it does not do this by default. Then save that file.

Open UDK and you will be prompted to rebuild the scripts. Click yes and let it run. If we did everything right, it will have no errors or warnings. Now, open UDK again and it will load the editor. Under the View menu, click World Properties. Then, expand the Game Type field and change both dropdowns to NewGame. Then start the game by clicking the green arrow in the upper right corner. I would suggest testing this on a pre-built level. If everything worked, you should see your HUD on screen. Press the X button to make sure our HUD updates the number of checkpoints left.

I hope you enjoyed this tutorial. The above example can be applied to anything that has to be counted down (or up, by changing the Flash) on key press. We used it to keep track of the number of checkpoints left, but you can edit it to be anything you want.

Monday, September 30, 2013

Blog #1: Grayboxing

Monday September 30, 2013

Hey all, this is my first blog in a long time. As of right now I am in GSP 340, which is Level Design and Modification. This blog is going to focus on one portion of this huge topic, which is grayboxing.

What is grayboxing? Grayboxing is a technique used by level designers in order to map out in rough detail the shape and design of the level they are working on. With a graybox level, there are no textures, particles effects and minimal lighting. The object of building a graybox level is to see how the level flows from its different areas and if the proportions you planned out are either too big or small. It can also help you determine if your initial design is going to work or not. In our group project, our graybox level was a real pain to build, but that is because the shape of our towers is octagonal and not very easy to line the brush up with. Since UDK has weird snapping when you change the rotation of an object, some of the geometry isnt flush with the walls. Just something to keep in mind if you decide to build octagonal towers.

In our graybox, which I will post a picture of below, you can see that we have no textures whatsoever. The only texture/lighting is the skydome and the sun that allows us to see everything we need to.


After you are satisfied with the design and function of your graybox level, you can begin adding textures and static meshes into your level. If you built geometry that is serving as a placeholder for a static mesh or other actor, you can delete those and put in the correct object. It really is a simple concept, but it helps tremendously in the planning and initial building of your level. It keeps you from having to constantly delete textures/meshes/lighting that would mess up your level if you had those things placed in there. Not having textures/meshes/lighting allows you to work with the simplest form of your level.

That's all for today, keep an eye out for my next blog in a few more weeks.

Tuesday, June 25, 2013

Dev Blog #7

Tuesday June 25, 2013

Here we are, at the end of our journey. Matt and I have worked tirelessly on this project for the past 16 weeks, and we are very proud of the things we accomplished. We both learned a ton from making this game from the ground up and we have become better programmers for doing so. You can find the website for the game at LINK where you can see some information about the game, Matt and myself and view the trailer we made for the game. There is also a download link on the website so you can try the game for yourself and let us know how you like it and what we could have done to make it better. I will admit that the game is very short, but the point of this class was to take an idea from concept to code and make it work. We did that and our game came out really good.

I hope you enjoyed reading about the game and, at least, my ideas behind the game. You got to see some code that no one else got to see. I also hope you learned something or got a different view on something you already knew. Thanks for reading. Until next time.

Wednesday, June 19, 2013

Dev Blog #6

Wednesday June 19, 2013

Here we are, down to the final week of development. Matt and I had our weekly meeting with our professor on Monday and he seemed really happy with what we had. He only had a few requirements of us. The two major ones are animations during battle and a gear system. The battle animations are an easy fix. All we need to do is create either another sprite sheet for each monster or make more cells in their existing sprite sheet that has a few frames in it. The frames would alternate between the entity being drawn and not drawn, and when played would give a flickering effect. The gear is a little bit trickier. Matt has to create a new menu that will show equipped gear and I have to make sure that the items draw in the correct slots. That shouldn't be too bad. Then I have to make sure the gear affects the stats correctly, which won't be too bad either.

Matt also has to send me his information for the website and has to create the trailer for the game, as I am handling the website. We also have to make posts to our Career Web Portfolios with information about this project, as DeVry is making that a bigger part of our curriculum. We shall see how this week plays out. Until next week.

Thursday, June 13, 2013

Dev Blog #5

Thursday June 13, 2013

Sorry for this blog being late. I totally forgot last night to write one. This week I will have a code snippet to show you guys in illustrate one of the issues with OOP that can be somewhat frustrating to fix if you don't know where to look.

The problem stemmed from a bug Matt and I were having with items. You could use items just fine and buy items, but that is where the problem reared its nasty head. When you would go to buy potions from the merchant, the game would show you buying 1 potion and then get stuck at 2 potions left in the shop. If you left the shop interface and opened your inventory, there were 2 potions there, even though the game only showed you buying 1. If you used 1 potion or both, the amount in the shop would go down to 1. It frustrated me for days. Finally, I had a breakthrough two days ago.

I saw that we weren't giving the player a brand new version of the item he was trying to buy. We were essentially copying the exact item the merchant had, which is not a good idea in languages like Java. Java passes everything by reference by default, so if you gave the player an item directly from the merchant, those two items were tied together in memory. So, my idea was to set a bunch of variables to hold the data from the item you were trying to buy and then pass those to the constructor for the Pickups class. Then, that Pickups constructor was used as a parameter for the giveItem() function that is part of the InventoryManager class. I will show you in the code snippet below:

This is only a partial code snippet, but it illustrates my point:

if(tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getStackable())
{
int i = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getItemID();
int d = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getDefence();
int a = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getAttack();
int h = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getHealth();
double s = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getSpeed();
String n = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getItemName();
boolean b = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getStackable();
int m = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getMaxStack();
String type = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getItemType();
EntityManager.getInstance().getDaniel().getInvManager().giveItem(new Pickups(i,d,a,h,s,n,b,m,1, type));
}

Blogger isn't the best on HTML tags, so I just pasted in the code. If it is difficult to read, I apologize. The initial if-statement checks to see if the item you are trying to buy is stackable. Why, you ask? Because stackable and non-stackable items are handled differently by the engine. Above this initial if-statement there is another one that check to see if the item you are trying to buy is already in your inventory. If it is, there is a different part of the code that just adds 1 whenever you buy that item. If it isn't in your inventory, the engine creates a brand new object (you can see this happening in the last line of the code) and places it into an arraylist.

Moral of the story: Be careful about how you pass object around. It could have some nasty consequences that will leave you with a ton of headaches over such a simple coding error.

Wednesday, June 5, 2013

Dev Blog #4

Wednesday June 5, 2013

This past week Matt and I submitted our QA build for testing. We spent a lot of hours the day and night before fixing bugs and implementing features that needed to be tested. When we were done, we submitted the build to our professor. Monday rolled around and our game was there, up and running for people to test out. It really is an amazing feeling seeing something you worked so hard on being tested and critiqued by others. All of the people that I watched test the game seemed to like it a lot, although there were a few bugs that were unintended. First off, the area boss was unbeatable. No matter what you did, you couldn't beat him. That was my bad. I overestimated the amount of stats the player would get by killing all of the other enemies in the area when I set up that feature. Although, the battle system worked beautifully. There was a funny bug that was discovered through testing.

The bug stems from me not range checking the damage done during battle. In this build, it is possible to do negative damage, which would add health to your enemy. The lower level enemies were also able to do negative damage to you, which would heal you. Another bug came from almost the same thing. When trying to select the Use option on an empty inventory slot, the game would crash. This came from the game trying to check an element in an array that simply wasn't there. I fixed that bug earlier, and it was a simple fix.

Matt and I have a lot of work to do over the next few weeks. We have a lot of features to fine tweak, balance to do on monsters and levels to create. It is going to be a hectic next few weeks trying to get everything done in time for our presentation in Week 8.

Wednesday, May 29, 2013

Dev Blog #3

Wednesday May 29, 2013

This past week was an exciting one. Matt and I revised the game code to allow it to read in levels the same way the level editor reads in levels. We also got the game to display multiple monsters on the screen at the same time. We were also able to interact with both of those entities separately, which is a major stride. Matt began creating the QA level in the level editor and it will be finished by the end of the week. We are going to work on implementing code that would randomly disperse the monsters around the QA level and spawn more over time. We want people to be able to level up at least once or twice in order to test balance with the experience ratios and the stat upgrades when people do level up.

I may end up tweaking the experience per level before testing begins. I think it is going to be really high if I leave it the way it is, but I have not tested it yet. Friday will be interesting as that will be our first glance at how the testing level will work out. We should have everything we need for the level to work correctly. Matt just has to take care of allowing the player to see their stats and experience in a menu. He designed the menu system, so I do not like messing with it. It is a rather complex framework, but it works really well.

Wednesday, May 22, 2013

Dev Blog #2

Wednesday May 22, 2013

This past week Matt and I finalized the level editor for our game. It was a major triumph seeing the output from the editor in the correct format, after coding the save function once. The only change I had to make to that function was making it output the actual number, not the data stored in memory at that location. Minor flaw, but nonetheless it was practically a one shot success. In programming, nothing feels better than getting something right the first time.

I ended up rewriting the whole battle system, which included moving the damage calculations out of the battle state and putting them into the player and monster base classes. This gives direct access to the stats of each entity, instead of having to access them in long strings of function calls in the battle state. I also had to rewrite some other functions inside the player and monster classes, which meant moving some of them into the base Entity class, of which monster and player are extended. Simple ones that every class needed to have, so the move was inevitable and I am glad I did it now.

For next week, Matt and I are going to finalize the text parser we have for reading in data, creating an area for the QA testing portion of the class that will include enemies and an area boss and creating some assets. The player will be able to level up in this testing area so we can tweak the leveling process.

The leveling process was written by me haphazardly. I found some formulas online for experience gain and experience needed for the next level, and I adjusted one of them to output much less experience. Basically, I cut it in half.

More next week after we get the testing level set up and ready to go.

Wednesday, May 15, 2013

Dev Blog #1

Wednesday May 15, 2013

Matt and I are off to a great start. Over the spring break Matt began working on a level editor that we can use to quickly and accurately create maps that have the correct data we need for the game to run. It is almost done, he just needs to implement the export function that will write the data to a text file and will allow us to read in that text file into game data.

I worked this week on adding in functionality to the player and monster classes that allow for leveling up and experience gaining. This is really not as hard as it sounds. It was merely adding in a few variables in both classes, their respective setters and getters and some other functions that are either for debug purposes or that give us added features that may or may not stay in the final build. I have to focus next on re-writing the entire battle system to move the damage calculations into the monster and player classes. This will allow us direct access to the stats of each entity without needing multiple functions calls if we keep it in the battle state. I also need to implement the experience gaining system for when the player defeats an enemy. Matt is going to work on getting items to randomly drop from defeated enemies. A message box will pop up saying something like "Entity dropped an item! Would you like to take it with you?" and the player will be able to select yes or no. That statement is generic and will contain specific elements like the enemy's name and the name of the item that was dropped. We figured that this way was much easier to accomplish than actually having an item drop on the ground and be visible to the player. It is less coding and a lot of games do it this way.

Tuesday, April 23, 2013

Development Blog #7

Tuesday April 23, 2013

This is going to be a very short blog. I worked on fixing what I could in the GDD, and sent it off to Matt for approval and for him to add a couple screenshots of certain menus that we did not have programmed the first time we submitted the GDD.

We also worked over Skype on implementing the shop feature and sounds. Matt walked me through how to use the code he wrote for our menu system, as I have yet to really touch it. He has been handling all of the menu stuff, and it is about time that I learn. We got the shop feature working and were able to see the bought item in the player's inventory.

That is all for this session and GSP 361. I will be writing again on the development of Project: DImension (still a working title) when GSP 362 starts up in a few weeks. Until then, happy coding.

Saturday, April 20, 2013

Development Blog #6

Saturday, April 20, 2013

So here we are, down to the wire on this project. The Alpha build presentation is coming up on Wednesday and the game is shaping up to be something really neat. Matt and I are both very proud of the fact that we wrote an entire game engine from scratch that is mostly non-game specific. It could be applied to any other game we wanted to write, with minor changes.

The final things we are taking care of are implementing the shop feature for the city level (we already have the merchant drawn on the screen, just need the functionality), drawing the enemy on the battle screen (we already have the player drawn), allowing the player to move between the city and the forest level and implementing interaction between the bear enemy and the player in the forest level that will initiate a battle. These are all very easy to implement and will take minimal code to accomplish. I want to take this time to thank Matt for all of the work he did with the heavy graphics portion of this project. I am not a graphics genius by any means, and he made something so simple and easy to use. I look forward to completing this project next session with him.

Looking forward, Matt is going to write a level editor over our spring break which will allow us to quickly create levels for the game (as for now the are hard coded into the game itself). This will spit out a text file with symbols in it, which will then be read in by the file i/o system we have in place. The symbols will correspond to a specific tile, and that tile will then be drawn on screen. We also want to add in small touches to different aspects of the game, like animations during battle so you can see both the player and enemy attacking. We also want to implement the team feature we designed in the early stages of development which would allow the player to have a team of animals and people to help them fight their way to the end of the game. I may or may not post something here for download that you would be able to test out and see what we have. That might come at the end of next session, when the game is fully developed.

Friday, April 12, 2013

Development Blog #5

Friday, April 12 2013

Today was a long, laborious day. Matt and I worked on a lot of bug fixes and polishing of the framework that we know works. I had to re-write the entire Sound engine today, as something was going on with Lightweight Java Game Library and OpenAL. Something about corrupted files inside the LWJGL libraries. I have no idea. So, Matt did some research and found that the Slick util libraries handle OpenAL on their own as well (as, I guess, Java supports .wav files out of the box on its own). It turns out, there was about half as much code needed in order to write the Sound engine using the Slick utils.

So we tested the Sound engine, and lo and behold, it worked flawlessly. We tested it with playing two sounds at once, and it handled that beautifully as well.

I also spent a lot of time re-writing the way we are reading in data from text files. Originally, there was an outer While loop and an inner For loop that handled the saving of data from a text file into actual objects. The problem was that the loop seemed to both reset itself and would never exit the loop (that one was purely my fault, as I never closed the BufferedReader after I was done using it). I ended up redoing the loops and using two While loops to get the job done. It is ugly and hacky, but hey, it works. I just now have to figure out how to exit a try-catch without throwing an exception (because the try portion completes successfully  but it still goes on to the catch due to a bug that I am trying to fix).

Saturday, April 6, 2013

Development Blog #4

Saturday, April 6 2013

I apologize for this being late, as I totally dropped the ball on posting yesterday.

So, this week Matt and I wanted to focus heavily on getting our battling system up and running with some dummy data. And lo and behold, we succeeded. Below you will find a code snippet from the battle system we are using:


do{
if(playerTurn == true)
{
while(playerTurn == true){

KeyListener();
Display.update();
Display.sync(60);

if(chosenAttack != null)
{
enemies.get(0).setHealth(enemies.get(0).getHealth() - calcDamage(chosenAttack));
//check to see if enemy is dead
if(enemies.get(0).getHealth() <= 0)
{
enemies.remove(0);
}

playerTurn = false;
}
/*if(chosenItem != null)
{

playerTurn = false;
}*/
}

enemyTurn = true;
}

if(enemyTurn == true)
{
Attack a = enemies.get(0).getAttack(Vector.random(0, 3));

player.setHealth(player.getHealth() - calcDamage(a));

System.out.println("The enemy did "+ calcDamage(a) + " points of damage.");

playerTurn = true;
enemyTurn = false;
}

Display.update();
Display.sync(60);

}
while(player.getHealth() > 0 || enemies.size() != 0);

If that looks a little ugly, both the Blogger formatting and the actual code, I know. I tried for hours to get something onto Blogger that would look like a scrolling code box, but nothing wanted to work (and I am not a web programmer).

So, what you see there is the meat of our battle system. There are a few portions missing, as I worked on it on Matt's laptop towards the end of our meeting yesterday and forgot to grab a copy of it, but you get the gist. The first portion of the code, which you cannot see here, checks to see which attacks the player has enabled out of their repertoire of attacks. This forces the player to only have 4 attacks available to them during any battle. They can change these attacks outside of battle, but not inside. The other part you do not see is the code where we determine who goes first, the player or the enemy, based on their speeds. That part is fairly straightforward, so I will not go into detail about it.

What you see above is how the actual battle system works. It is encased in a do, while loop in order to keep the battle going until either the player dies or the enemy dies. The chosenAttack variable you see stores the attack the player chose from the menu that shows up during battle. We needed a way for the UI to interact with the game, and that was the solution we came up with. The piece of code you may not understand is this portion:

Attack a = enemies.get(0).getAttack(Vector.random(0, 3));

This piece of code sets an Attack object a to a random attack pulled from the attack ArrayList that every monster has. The Vector.random is a function Matt built in order for us to be able to generate a random number between a minimum and maximum value. The enemies.get(0) is a hacky piece of code we are using at the moment until we get actual data to work with. It pulls the first object from the enemies ArrayList that is local to the battle system. When we have actual data to work with (which means, more enemies to fight at any given time in a single battle), this portion of the code will change to reflect whose turn it is in the battle.

Hope you all enjoyed a look into the code of our project in its current stage, and if you have any questions, leave a comment below.

Friday, March 29, 2013

Development Blog #3

Friday, March 29 2013

Well, I guess I can announce the working title of our game. We have decided to call it Project: Dimension for the time being. Hopefully next week I will have some code snippets to share, as that is when the real development work will begin.

This week Matt and I worked on our file I/O system that is going to help us keep the processing time of the game down. What we are doing is storing all of the NPC, monster and item data in separate text files. At game initialization, the game reads in these files and creates objects with the data that is stored in the text files. These objects are the stored in different array lists that are a part of the InventoryManager class and the EntityManager class. We feel that this way is best as it allows us to create more items/monsters/npcs on the fly, without having to hard code anything in. We did, however, run into one major problem.

The problem is still persistent as I have not figured out how to fix it yet. The issue arises when I try to test this file I/O system with some dummy data. The data is read in fine and stored into the array before being passed the the portion where the object is created. Once it hits the creation step, the program crashes and gives me a "No OpenGL data in the current thread". I know that this means I am trying to use something from the OpenGL library before OpenGL is initialized in the program, but I cannot for the life of me figure out where the error stems from. I think it has something to do with the way we are handling textures in the code, but we are in the process of changing over to sprite sheets. Sprite sheets may help avoid this issue as there will not be a separate texture file for each object. The data passed from the text file will have to contain some data on where on the sprite sheet the texture for the object is located. I have a feeling the sprite sheets are going to make this a heck of a lot easier. I am not a graphics guy, so it is somewhat of a foreign language to me. However, I am confident that Matt will be able to walk me through it the next time we meet.

Thursday, March 21, 2013

Development Blog #2

March 21, 2013

Earlier this week I finished up coding the Inventory system and the Entity system. The inventory system handles all of the inventories, including the hidden ones that allow monsters to drop items when they die, if we choose the implement this feature in the future. The entity system has 3 classes derived from it, being the Player, the NPCs and the Monsters. There is also an entity manager and an entity generator that control the generation of all of the characters and monsters in the game at initialization. The manager does not, however, control the player. The player is going to be its own object outside of the entity manager. 

In our meeting today we talked about some ideas for how we are going to implement maps into our game. My idea was to make a giant image of the entire game world, and then create some sort of coordinate system in order to determine the player's position and what portion of the game world is visible to them. This turned out to be a bad idea, as it would take a lot of extra coding in order to get this to work. The idea that Matt and I settled on is to create a text file with symbols inside of it. The symbols will be arranged in the order that we would like the tiles that they represent to be in. This is how we are going to create our playable areas, for now. We are going to have to create tiny (32x32 or 64x64) tiles for this to work, which should not be that hard. 

I have to begin creating some artwork for the game. I am going to create some item sprites and weapon sprites for us to test our File I/O system with, so we know that it works. We also need to test drawing the objects to the screen, to see if we need to adjust our code or rethink the way we are handling textures. 

Thursday, March 14, 2013

Development Blog #1

Thursday, March 14

This week Matt and I started to really hunker down into the code of our game. He has been working on getting a menu system to work in the Light Weight Java Game Library (LWJGL). This is the same engine that Minecraft runs on, so we are certain that this choice in engine is going to make our lives a lot easier. I have been working on the base classes for almost everything in our game. We have two base classes called Entity and Item. Entity is extended by Player (the main player), NPC (game npcs) and Monster (game monsters). Item is extended by two different types, Equippables and Pickups. I chose to write the code this way, as Equippable items have certain features that regular Pickups do. Also, Equippables are not stackable, which is one of the main differences between the items in our game. There is also an EntityManager and an EntityGenerator that will handle all of the entities within the game and handle dynamic spawning of entities. The IventoryManager handles the player's inventory, as well as the monster's inventory if we decide to make the monsters drop items when they are killed. It is a Singleton design, which allows each object to have only 1 instance of the manager inside it at any given time. We have not decided on the style of our artwork and graphics yet, but we are getting to the point where we need to. We will need to know if we are going to use things like sprite sheets or not, and what the resolution of the artwork is going to be. I like 8-bit, but for this game it may be too low-res.

Right now the biggest problem I am having with the code is inside the InventoryManager. In this class, there will be a function to remove an item from the inventory. The problem lies in distinguishing between the two different types of items, as the Pickups type has the ability to be stackable, and we do not want the entire stack (if there is one) to be deleted when the player uses an item from the stack. Matt and I are going to brainstorm on this tomorrow when we meet for our weekly work session.

Tuesday, February 26, 2013

Final Class Thoughts

February 26, 2013

This is not going to be a technical blog, but rather my final thoughts on the GSP 261 class as a whole.

This was the first GSP class that I actually had to sit down and think about what I was doing. I am not the world's greatest modeler, but I can do somethings fairly well and can work my way around Maya. Having to learn 3DS Max was a huge threshold for me as I do not entirely like the program. I feel that Maya is a much better modeling program, and Max should really only be used for animating. But, those are just my thoughts on the subject. The part that I had the most trouble with was the character modeling and animating. I learned very quickly that I was not cut out to be a character artist nor an animator, and not everyone is. Shannon was an amazing modeler and animator, and I was lucky to have her in my group. Matt was an amazing modeler as well, as he has had years of experience working with Max. I picked a pretty decent group.

Every other part of the class was relatively easy, but some were more tedious than others. The audio portion of the class was probably the most tedious, as only certain effects could generate the sounds you were looking for from the source audio. It did get easier as I worked on more pieces of audio, and in the end I was able to produce some pretty decent sound effects, for being a student that is.

The cinematic turned out fantastic. There were a few things pointed out to us during the presentation that would have made it so much better, but in the end we produced a very respectable cinematic. Every part came together beautifully and seamlessly.

I enjoyed this class very much, and I will be able to use what I learned in almost all of my forthcoming classes.

Friday, February 22, 2013

Group Update #4

February 22, 2013

I know this is horribly late, but I still need to get it done.

The group has gotten all of the audio bites done and imported into UDK. I began, on Tuesday, by first making a Matinee sequence in Kismet and setting up all of the cameras we were going to need. Here is a screenshot of the final Matinee sequence with everything added and animated:

As you can see, it is quite a complex mess. This is our first real work done with Matinee, and I think we did pretty well. The cinematic came out to be exactly 2 minutes long, which was a real shock as I had some reservations about how much content we had and if we were even going to make it to 1 minute. I did run into a ton of problems doing this cinematic, however. Most of the issues arose from movement tracks for different groups, but the main one was the chase camera we use to show the main character from behind. This camera was a complete and total mess to work with. Whenever I tried moving the camera and setting a new key in the movement track, after one had already been set, the camera would move in weird ways. I also ran into an issue with Matinee itself, as when I would close the Matinee editor, it would sometimes move things around that were supposed to remain where they were originally located. The main culprit was the chase camera for the main character. That was a complete nightmare. I am still having an issue with playing the cinematic in PC mode. The issue is that the PC mode will come up, but crash before it even gets to the cinematic. It is really irritating.

The cinematic is finished now, I am just waiting for an email back from the professor regarding the crashing issue. Otherwise, all is good.

Tuesday, February 12, 2013

Group Update #3

February 12, 2013

This week our group put together the environment that our cinematic will take place in. The level was built in UDK using Additive Geometry, with Subtractive Geometry used to make doorways. This process was relatively easy for me, as I have done it so many times before. I build the level, Matt added in the lights and Matinee for flickering lights and Shannon found textures for all of the walls, floors and ceilings. Here is what the main laboratory chamber looks like in the editor:


I really do think the blue specular color is a nice touch. I do not know how Shannon managed to get that effect into the specular map, but it looks really cool. The idea is to have the hero, Jane, run through an abandoned asylum full of mutants. The initial entry point and first area where action will take place looks like this:


Around the corner in this screenshot there are more doors. One of them is propped open, where our legless mutant will come crawling out and chase Jane around the level. My one concern is that we do not have enough in here to make a 1-2 minute cinematic. We shall see when that part of the class rolls around. I made the asylum really big in comparison to the character size. I wanted it to have the feel of being almost not real, but real enough to scare the player. I want to add in blood splatters around the level to give it that really creepy feeling. That will come later when we put the final touches on the level and get ready to film the cinematic. The lights in the whole level flicker constantly, which adds another layer to the ambiance. We hope to find some decent sound effects including screams, footsteps, slithering (for the legless mutant), maniacal laughing and others, just to name a few. We are most likely going to have 2 music tracks that will play during the cinematic, and one will shift into the other at a certain time. I think it is coming along nicely.

Tuesday, February 5, 2013

Group Update #2

February 5, 2013

This week our group was tasked with creating two characters for our final cinematic, texturing, rigging and animating them. I had the job of UV mapping and texturing the mutant model (made by Matt) and rigging the Jane model (made by Shannon). I did learn something from this, however. When Shannon was finished creating a custom running animation, I immediately tried porting the character to UDK. Aside from forgetting to rename the second spine in her model (oops!), nothing was wrong. It ported just fine to fbx and then just fine into UDK. The problem came when I tried previewing the animation in the Skeletal Mesh previewer. When I set the AnimSet and the correct animation sequence and clicked play, nothing happened. I was puzzled for a good hour. I tried everything from re-exporting the fbx to force deleting everything in the package and re-importing. It came down to me opening the model back up and taking a closer look at the animation layer of the CatParent. When I looked at the animation in Max, I noticed nothing at first. Click play and the animation played just fine. However, I looked down at the timeline and there was the problem. Can you guess what it was?

The problem was that when Shannon made her original animation, she edited the default running animation, which has no keys set on the timeline. It is built directly into Max. Since her animation had no keys set, the fbx file had no keys baked into it, but no information at those key marks. So when UDK tried to play the animation, nothing happened because it had no information on what was occurring in those key frames. This was such a simple fix. All I did was find the end point of her animation (which was 30 frames in), then set keys every 5 frames for a smooth animation. When I re-exported and imported back into UDK, the animation worked. Huzzah! Such a simple fix, but I overlooked it a thousand times trying to figure out what was wrong. Occam's Razor is indeed true.

EDIT: Turns out she didn't just edit the default walking animation. She created her own. I still don't understand how keys were not used in the animation.

Tuesday, January 29, 2013

Character Animation

January 29, 2013

Today I finished animating my character for this week's iLab assignment. This was probably the biggest pain out of all of the modeling steps we have covered so far. I initially had a different character modeled, but giving him bones turned out to be too difficult due to the size of his hips and legs, so I made a new one and shrank down the final model before attempting to give it a CAT system. The new character was much easier to put bones into, which I suspect is a side effect of me scaling him down after the modeling portion was completed. This is what the model looked like after some initial messing around with the bone structure:


I know his texture is quite creepy, but it was a quick and dirty texture that allowed me to test the skinning portion of the animation process. This is what his inner bone structure looks like:


He is made up of a pelvis, 2 legs, 2 arms and 2 spines. The second spine, which you can see above the first one, is used to animate the neck and head regions. It is the only way to do so, which I find weird. I wish there was a head option, or something like it, which would add in a neck and head box on top of the spine. This would make it easier as you would not have to determine how many bones the spine needs to have.

The next sequence of images shows one of his animations cycles. It is a kicking animation. Please excuse the extreme warping of his skin, as I did not take the time to paint weights onto the bones. Painting weights onto the bones would allow me to control which areas of the skin each bones can act upon.




I also made a clapping and punching animation. I still cannot figure out why his right hand (our left) ended up in such a weird position from the start. Never could fix it properly either. I assume it is from having an issue with the weighting system, which I would have to go in and manually fix. It is a gigantic pain, so I will save that for a later date and later models. This was just a quick and dirty set of animations.


Tuesday, January 22, 2013

Group Work Update #1

January 22, 2013

Today after class our group finalized our design with the selection of models to make in 3DS Max. We are going to be making an in-game cinematic that is from a horror game. The story is fairly simple (and a little cliched) as it centers around an investigative team that runs into trouble in an abandoned insane asylum. When the group enters they setup their gear and go exploring. Over a couple of hours, the mad doctor that still inhabits the asylum, Dr. Wilson, begins to take group members hostage. Jane is the only one left, and she is tasked with finding her friends before Dr. Wilson turns them into abominations through experimental medical procedures.

The cinematic will show Jane running through darkened hallways with flickering lights, broken doors and eyes peering at her from dark rooms. There will of course be creepy music and sounds, just to add ambiance to the scene. The meshes that we have chosen to create for this cinematic are science equipment (syringes, beakers, etc.), an iron door, a gurney, a wheelchair and fluorescent lights. We believe these meshes, when paired with lighting and music, will have the greatest impact on the viewer. I have chosen to model the iron door and the gurney. The iron door will be quite easy, but I am going to make two models of it. One will have a little slider that you see on prison doors, and the other will have that slider missing so we can have things come out of the slider in the cinematic. The gurney will be a bit tougher, as 3DS Max does not make filling holes in geometry very easy. In the end, it shouldn't be too difficult to model these things. We shall see.

Thursday, January 10, 2013

Soda Can UV Mapping and Texturing

January 10, 2013

Today I wanted to work on the UVW mapping and texturing for the soda can model I made the other day. The soda can was a hard task as it was, due to my minimal knowledge and skill set within 3DS Max. I started out by opening my model and putting the Unwrap UVW modifier on it. Since the can is mostly cylindrical, with a flat portion on the top and bottom and some flared edges at the top and bottom, I decided to map the UVs for the can body by themselves in a cylindrical manner. I also decided to map the flared edges on the top and bottom with the body as well, as when I tried it earlier they just came out looking weird.

Flared edges on can

The UV Mapping itself was not very difficult once I started getting results I liked. I just chose to map the can body and flared edges as one unit, the top cover of the can, bottom cover of the can and the sides to the top cover, as the top cover was extruded from the can body. The can body I did with a cylindrical mapping, the top cover and bottom cover were done with planar maps and the top cover sides were done with a cylindrical mapping.

UV layout for soda can

As shown in the picture above, I chose not to stitch or weld anything together. It was much easier for me to just break them all apart into the sections I wanted and place them accordingly. It also made painting much, much simpler. Here is what the final texture looks like (excuse my lack of artistic ability. I was going for the feel of a Coke can without having to write out Coca-Cola or find a can texture. Also had to change filetype to a JPEG, as Blogger doesn't accept .tga filetypes).

Soda can texture

The completed model, with texture applied looks like this. I know there is a little silver in the red area, but I am no artist.

Model with texture applied

In hindsight, I should have UV mapped the flared edges on their own. it would have kept me from getting that little bit of silver in the red area of the can body, and would have looked a lot cleaner.