Camera Obscura is available now!!!

A few months ago, Camera Obscura was greenlit on Steam, and now it’s available to purchase on the Steam store! This is incredibly exciting for everyone on the team, and we’re thrilled that people can access it on the largest digital distribution service for games. If puzzle-platforming is your thing, check it out at

http://store.steampowered.com/app/341500/

and be sure to let us know what you think of it!

Posted in Portfolio | Leave a comment

Updates!

So I just finished making my first Skyrim mod. It’s a small little dungeon that doesn’t have a main quest associated with it, but the radiant quest system (those miscellaneous quests) can take you there if you get lucky. If you want to play it and make me happy, you can find it on the steam workshop here (or if you prefer the nexus, here). It was a lot of fun to work on (even if the game itself is a little old now), and I’m planning on making a larger one with quests soon.

Dark Current (my senior project that we started working on back in January) is progressing along slowly but surely. We have a site now! It’s a little rough around the edges, but it’s there. Last week we added in a few enemies and changed one of the passive abilities available to the player. Now we can balance the game a little bit better, so we’re pretty excited about that. There’s still a couple of levels that we want to add to the game, and we want to make an interesting story with an ending, but we’re definitely well on our way to finishing the game. The mechanics are basically done, and there’s only a few bugs that we have left to fix. It’s looking nice.

It’s been busy, but productive. I’ll try to post more regular updates, so be on the lookout for those!

Posted in Portfolio | Leave a comment

Announcing: Dark Current

So I’ve been working on my senior project with a bunch of awesome people for a couple of months now, and we’re finally ready to start showing it off. It’s called Dark Current, and it’s a 2D arcade shooter/metroidvania game where you control a mystical fish fighting to avenge its family. There’s an early look at the gameplay in the video below:

As you might be able to tell, it’s not in a final state, and there’s quite a lot of work left to do. That being said, we’re really excited about it, and we can’t wait to put it out there for people to play. If you want to follow along with our progress, subscribe to our youtube channel where we periodically post new gameplay videos. That’s about all I have to say, so it’s time for me to get back to work! Thanks for reading.

Posted in Dark Current | Leave a comment

Unity Particle Systems Tutorial Series

Hello! If you’ve ever wanted to learn how to use Unity Shuriken Particle System, I have good news for you! I’ve started a weekly youtube series on each aspect of the particle system and how it works. You can see the first part below:

I’m going to be testing out other recording devices to see if I can improve the video quality for later videos. If you have any questions or if there’s anything in particular that you want me to go over, send me a message or comment below!

Posted in Tutorial | Leave a comment

Hailan Rising: An Intern’s Story and Perspective (Part 3)

The development team had accomplished a lot of work over the summer. Our programmers became familiarized with the code, got it into a playable state, and were able to distribute an alpha version of the game to a select few players. The animators fixed the skinning issues for the players, cleaned up the textures for the faces, completed the armor rigs, separated the armor models and textures into different pieces to be worn by the player, and corrected the UV mapping for the textures on the armor sets. Our level artist created a mountain town for PvE and tutorial purposes, as well as a large scale competitive map designed to hold hundreds of active players. The producers created and maintained a list of milestones that helped the team become more organized and agile, enabling us to complete weekly tasks and stay on track. I was able to learn how to create particle systems using Unity, and I created particle effects for all forty-five player activated abilities. Our lead designer/producer populated the starting area, Highroad, with enemy mobs, friendly NPCs, and vendors. However, even with all of this work done, we still had a long road ahead of us.

There were two major things that Hailan Rising lacked: enough content to keep players busy for an extended period of time and the manpower to create that content. This had been a team concern for some time now, but we were unable to hire more developers due to budget constraints. After some thought, we decided to do a kickstarter for the game and asked for a whopping $275,000. Of course, doing a kickstarter campaign involved a lot more work than we had initially planned, as our producer, design consultant, and even the CEO of the company were busy the entire month trying to do interviews, press releases, and publicity events. Unfortunately, this meant that development time was taken from the game to be focused on the kickstarter project.

One of the banners for the Hailan Rising kickstarter project.

One of the banners for the Hailan Rising kickstarter project.

Meanwhile, the rest of the team was trying to pump out content and fix bugs. Our level artist was working on a PvE dungeon that would test our enemy AI and act as a raid for our current alpha testers. This cave level would give us a chance to see how our design philosophy for player progression would react to an end-game environment. The game also needed a more challenging area, since Highroad’s enemy mobs acted as cannon fodder for new players. The programmers were working on fixing the transaction bugs, movement prediction, and implementing the zone transfer system of the game. It was a lot of work for three programmers, especially when new bugs began to pop up every day. I began working on creating environment particles and loot table implementation after the ability particles were finished, and the artists had finished fixing the character armor issues from before. They then moved onto fixing the rest of the rigs for the enemy mobs so we could have a more diverse selection of monsters in the game.

A few weeks had passed, and initially it looked like our kickstarter was starting strong. We had a few backers that had donated enough money to make it into the top two tiers, and there were a couple dozen or so other backers that made contributions. However, that was just about all the attention our kickstarter got. Another few weeks had passed and the time for our fundraiser was up. We only reached about 10% of our initial goal. This was a wake-up call to the team, and we had to reassess what we should be working on. It was decided that we would push for an open beta in early February, and then officially launch the game a few weeks later. We all knew that the game wasn’t even close to being ready for a beta in a few months, let alone launch, so we started working even more like maniacs than we were before.

The level designer was able to finish the cave level, the producer/lead designer populated it with mobs, I created loot tables for these mobs and ambient particle effects for the dungeon. The animators and other artists began to simultaneously clean up the character animations while reducing the poly count of the models to help the game become optimized. The programmers fixed one bug after another with the help of the beta testers and our helpful QA team, while creating the territory control system that was a large focus for our game. We were busy. Eventually, we all began trying to fix things and add content in every way possible. I learned the basics of 3DS max and began to fix the sizes of the weapon models and import new ones into the game. One of the animators helped me polish the rough edges for the particle effects and create awesome, new ones. Another artist began putting particle attachment points into the models so we could finally place the particle emitters into the correct places. The level artist created a smaller, more enclosed multiplayer map for arena team battles. Our technical producer began working on facebook integration so our players could log in through facebook instead of creating a GamersFirst account. One artist was even able to update the icons for each type of game item. Everyone was trying to cram in years of polish and content into our game in a meager two months, and it was more than a little crazy.

Our smaller multiplayer arena.

Our smaller multiplayer arena.

The time for open beta had come, and we were equal amounts nervous and excited to see what the players would like and what they would break into little pieces. We only had about 50 or so unique users log in that day, but it was really cool to watch them run all over the place and play the game. The team stayed logged on to the game for most of that week, keeping an eye on the chat to see if anyone was confused with a game mechanic or ran into a bug that needed fixing.  We noticed that the core team of alpha testers still really liked the game, and were even helping out other players, but we also noticed that a lot of the new players were not happy with the state of Hailan Rising. They pointed out how dated the game looked, how the networking issues affected PvP, how the trades sometimes crashed the server, and about a dozen other issues that we weren’t able to fix. We noted all of the bugs, but eventually we had to prepare for the launch and stop monitoring the game, which meant that we needed to cram as much polish and bug fixing as possible before the deadline.

We were able to reduce the poly count of the player characters and armors, update the particle effects, fix some of the trading bugs, balance the player abilities, add new weapons and loot, create player-based loot that would encourage PvP, add tutorials that acted as achievements, and fix some of the client bugs that caused the game to crash for new players. However, there were a lot of things that we weren’t able to finish in time. The programmers were able to get a playable version of territory control, but unfortunately it wasn’t able to make it into the release build of the game. Our level artist and producer worked to improve the small multiplayer map by adding guardians for the spawn points and creating a death zone for the lava at the bottom of the map, but we weren’t able to get it to work in time. At the end of this mad sprint, our game looked better, but it was still in rough shape.

We only had four zones, the art was still very rough around the edges, and there were bugs with the guild system, player merchant system, and movement prediction. All in all, the game itself was ready for an alpha test, but we had to officially release it as a finished game the next week. There was marketing, bug-fixing, content creation, and art polish to do, but we didn’t have the time or the manpower to do it. So, we “released” the game during late February.

During open beta, the player base had been slowly dropping, and by the time we released, the only people who were consistently playing were the dedicated players that had been with us since late summer. The company’s board of directors was understandably displeased with the amount of concurrent players that were logging into Hailan Rising. We knew that it was a flop, so the team had to think of different ways to save the project. For the next week or two we had some crazy ideas, but in the end, it wasn’t enough to save the project. The team was either reassigned to other projects, or let go from the company at the beginning of March.

Hailan Rising had many flaws, and mistakes were made by all along the way, but we were able to make something that at least a few people really enjoyed. Our small team of developers that grew, then shrank, and then grew again, was able to create a small, free to play MMORPG. We were able to create a silly, fun, multiplayer game while overcoming a myriad of challenges that threatened to sink the project before it could even see the light of day. I am truly grateful that I was able to work there, and my co-workers were some of the most creative, fun people to work with. Thank you all for helping me along the way, for putting up with my questions and ideas, allowing me to branch out and try new things, and for being awesome when I was down. It was a roller coaster experience, but I don’t regret it at all.

Now, after almost eight months, it’s time for me to move on. Thanks for all the memories.

Cheers,

Tyler Wissler

Posted in Hailan Rising | Leave a comment

Hailan Rising: An Intern’s Story and Perspective (Part 2)

Sorry that this took me so long to write. School and side projects have been keeping me busy…

The team was in a pretty bad position. The game was scheduled for closed alpha testing in a few months, and we were nowhere close to meeting that goal. Our lead programmer left, the artists were still cleaning up the assets received from the outsourced art company, the design was far beyond what we would be able to do, and the new programmers had a lot to catch up on. We got to work.

The level artist and designers began making a starting zone for new players, while the programmers dug through the old code, trying to understand how the game worked. Once the design for the zone had been completed and finalized, the designers began working on game systems again, to bring them within scope, and the level artist began building. I started learning the old quest system, and began making quests for the next couple of weeks. However, after the programmers had studied the code, it became clear that there wasn’t going to be enough time to finish coding and fixing the quest system. I discussed what I should do next with the producer of the game, and he suggested that I learn how to create particles with Unity’s particle system. As a result, I dropped the quest system, and, for the next month, began creating particle effects for the player-activated spells and abilities.

Meanwhile, our level artist had finished the first zone for the game, and the programmers got it working with the code. We all jumped in and started running around, looking at the new zone. It was a pretty cool mountain town set above the clouds, and the producer immediately began populating it with npcs and mobs. At this point, the game was almost playable. The characters could move around the world, and could see other players as well. Combat wasn’t working quite yet, the inventory caused crashes, and the movement prediction didn’t exist yet. It was definitely a start though, and the team was getting excited again.

The starting city for Hailan Rising

The starting city for Hailan Rising

Now that we had a semi-playable prototype working, we updated the game’s forums with the recent changes and news. There was a core group of about 5 – 10 players that had been following us for a while, and were very interested in the game. They had played another MMORPG that the company published called Knight Online, and the producer was familiar with those players from his days as a GM. We decided that they would be our alpha test group, and we began making preparations for them to get the game. The team’s programmers continued fixing the inventory and combat systems, and, with a few rough patches, they managed to get it working within a couple of weeks. They also created a downloadable version of the game, and we sent it to the forum users near the end of the summer.

This was the first time players would jump into Hailan Rising, and while we knew it was rough, we were excited to see what they thought of it. We all logged in, and, one by one, the small group of invited players started to pop into the game, running around, exploring the level, and killing the low-level mobs. The team helped them when they were stuck, and soon we began talking with them about the game. These new players gave us suggestions, pointed out bugs, and voiced their concerns, but they were generally happy with the game. They knew it was going to get better, and they couldn’t wait to see what we would put in next.  Needless to say, this cheered us up by quite a bit, and we were beginning to feel confident that we would be able to create a game that people would enjoy playing. However, there were still numerous obstacles that we had to overcome.

The animators and artists were still fixing up the armor, and while they were almost done, there were still rigs, skins, and textures to fix for some of the mobs, player skins, and npcs. As a result, the animations for the players and mobs had to be rushed. Hundreds of animations were created by a single animator in the span of months, and while this is an incredible feat, the animations were rough around the edges, and some of the mobs didn’t have animations yet. As for particle effects, we had some basic effects, but they were very old. I created new, updated particle effects for the reduced list of player abilities, but since they were created in a few months time by a beginner, they were also rough around the edges. There were also problems with getting the particle effects into the game and attaching them to the correct positions on the player or enemy. This led to some bugs with the particles that continued for some time.

An example of one of the older particle effects.

An example of one of the older particle effects.

Meanwhile, the team wanted to test the game’s design and code by creating a territory control situation that was popular with their previous game Knight Online. This involved two teams of hundreds of players all fighting for control of level. They fight a pylon in the middle of the map, and whoever takes down the pylon gets the bonuses associated with that level. We wanted to test if our engine could handle the load of players and if the design that we had was fun. First, we needed a level large enough to accommodate the number of players, so the designers started mocking up a level along with the level artist. We designed a large, two-team level with defensible points for each team along with a large, open center area for the pylon. The level artist began making the level, creating spawn points near the base of two hills connected to a large mountain in the background. Our idea was that players would travel down from Highroad to fight each other on the newly surfaced beach, where a relic had been discovered. This would be the first PvP level that we had created, and with it, we were getting to the point where the game would be feature complete.

Posted in Hailan Rising | Leave a comment

Hailan Rising: An Intern’s Story and Perspective (Part 1)

Hello there! I thought it would be a good idea to explain my background in game development with a personal story about Hailan Rising, and to shed a little light on its troubled development cycle. Now, I want to make it clear that this isn’t going to be a rant, trash talk session, or a sob story. I want to focus on a series of challenges and circumstances that a group of inexperienced developers faced, and how we made it past some of those challenges, while struggling through others. This is by no means a complete account of the development cycle, and is merely my perspective as an intern and contractor. Since there is a lot of ground to cover, I’m going to be breaking this up into a series of posts, instead of one obnoxiously long one.

First off, if you haven’t heard of or have played Hailan Rising, you can watch a video of it here:

Or, if you feel adventurous, you can download the GamersFirst client and play the game through that.

Alright, now let me tell you a little bit about the current state of this game, and my connection to it. Hailan Rising, the free to play MMO, is a dead game. After about three years of development, GamersFirst decided to stop development on the game, and reassign or lay off the people working on it. If you go to the game forums, you’ll see a lot of angry, confused players, and a long farewell letter from the producer. Unfortunately, it’s quite the mess.

So how did that happen, and where do I fit in? Well, a little over a year ago, I started working on Hailan Rising as a design intern from UCI. I was lucky enough to have a friend and classmate who had been working there for a while, and when he told me they needed additional help, I was pretty eager to jump on. Who wouldn’t be? I was a sophomore dissatisfied with my classes, and here was an opportunity to work on a game! An RPG no less! So, one interview and a few contracts later, I was officially an intern at GamersFirst.

Now, I was pretty aware of what I was getting into. The team was fairly inexperienced (in terms of making an MMORPG), and there were only about five to six people working on the game (with only one programmer!). Most of the art assets had been contracted out to another company, and the art that we got back was… broken. The animators in the development team were forced to spend most of the time fixing the models, rigs, textures, etc., instead of animating (more on that later). There was also definite tension between some of the team members, and there had been some pretty ugly arguments over the design aspects of the game.

A picture of the large town that we originally had in the game.

A picture of the large town that we originally had in the game.

When I first started working on the project, the team had recently gone through a pretty brutal “civil war”. The main arguing point was the overall design of the game, with one side fighting for the original design ( a semi-traditional PvP oriented game based on one of their previously published titles), while the other side wanted an event-driven game (imagine an open-world PvP version of Guild Wars 2). Combine that with a large series of layoffs a couple of months before, and you get a stressed, emotionally tired team. However, just before I got there, the team reconciled with each other, and decided to go for a merge of the two ideas, and for better communication between all of the team members. To facilitate this, the publishing side of GamersFirst transferred a couple of additional programmers to ease the workload, and hired a design consultant/producer to help organize the team and create milestones. Additional artists were also hired to help fix the character models, armors, and animations. Our little team was getting a little bigger.

Things were going pretty smoothly for a while. The team’s morale was higher than it was before, we had a clear idea that we were building towards, and the team was communicating well with each other. Plans were made, workloads were being figured out, and it looked like we were on track to release the next year. However, things started going downhill again as this is where we got a little carried away with the redesign of the game. The lead programmer decided that a new engine would need to be built to support the new design, and the rest of the team decided to scrap the previous two years’ worth of work in favor of the new design. Zones, quests, mobs, abilities, and many other art assets were thrown out, which meant a lot of wasted work, and more than one disappointed developer. With the new engine being built, the rest of the team decided to come up with new systems and levels that would support the new design, while the artists continued to patch up the art.

An overview of the original four areas that we had in the game, all in one zone.

An overview of the original four areas, all in one large zone for the players to run around in.

We came up with multiplayer systems, lobbies, arena levels, and all sorts of crazy ideas. While it seemed like a good idea at the time, in hindsight it caused months of wasted work and arguing. It’s never a good idea to completely redesign a game in the same year it’s supposed to be released, and many of these ideas were thrown away later, because we ran out of time. We went way out of scope and completely off track, but unfortunately we were too excited by the possibilities to notice. Meanwhile, tension between the programmers were steadily rising, as the lead was not getting along with the newcomers.

After about a month, the lead programmer left the company to work on other projects. Our producer decided that enough was enough, we were going back to the old engine, but we were going to make new levels and zones to reflect the design changes that were made. The team then scrambled to get additional programmers to finish the game, and we were fortunate enough to find three experienced programmers. However, they had a lot of work ahead of them. Before the redesign, the game was in a barely playable state, so the new programmers first had to figure out the old engine, and then complete the features that were half-done or broken. The already large mess was quickly getting messier.

Posted in Hailan Rising | Leave a comment

Tutorial: How to map texture coordinates to points on a box

Hello, and welcome to my first tutorial! Today I’ll be attempting to show you how to calculate a UV coordinate for a 3D box given a point on the box, the minimum point, and the maximum point of the box. A bit of a fair warning first though. This may not be the best or most optimized way to do this, but its the only way I know how. If you have any other suggestions or algorithms, I would be more than happy to learn!

Alright, the goal here is to calculate a 2D coordinate between 0 and 1 that will tell our program where to find the color for our 3D box from our 2D texture. If you don’t know what UV coordinates are, it might be a good idea to read up on them. Here’s a little picture that shows what we know so far:

Here's what we know.

Here’s what we know.

The first thing that we’re going to need is the surface normal of the face that p1 sits on. Since we know p1, the min, and the max, this isn’t too difficult to compute. The distance between p1 and either the maximum or the minimum will tell us the normal of the face, as well as which face we are dealing with. Here’s a little bit of C++ code that shows what I’m talking about:

// left
if (abs(p1.x - Min.x) < epsilon_value)
{
        normal = Vec3 (-1, 0, 0);
}

 // right
 else if (abs(p1.x - Max.x) < epsilon_value)
 {
        normal = Vec3 (1, 0, 0);
 }

  // out
  else if (abs(p1.y - Min.y) < epsilon_value)
  {
        normal = Vec3 (0, -1, 0);
  }

  // in
  else if (abs(p1.y - Max.y) < epsilon_value)
  {
        normal = Vec3 (0, 1, 0);
  }

  // down
  else if (abs(p1.z - Min.z) < epsilon_value)
  {
        normal = Vec3 (0, 0, -1);
  }

  // up
  else if (abs(p1.z - Max.z) < epsilon_value)
  {
         normal = Vec3 (0, 0, 1);
  }

In this example, z acts as our vertical axis and y acts as the in/out axis. Since we want the distance between these two points, we only want the positive difference between the two locations of the points. If this distance is insubstantial (in this case, less than 1/100), then p1 lies on that plane. We then check every other axis to make sure we have the correct normal.

Now, we only use the normal to find out which face of the box we are dealing with, and we don’t actually use it to calculate the UV coordinates of the texture. However, it is important to know for bump mapping calculations, which can lead to some pretty interesting effects. Since that isn’t the goal of this post, we’ll be moving right along!

Alright, now that we know the face our p1 is on, we know which points to use for our UV calculation. Firstly, we need three vectors that are all on the face of our block. This is because each point on our block shares a relationship with the plane it is on. This relationship is expressed through the equation P1 = (A + (B – A) + (D – A)), where A,B, and D are the corner vertices of our block face. Since we are essentially calculating the position of P1 relative to the size our texture, we can modify our equation to find the UV coordinates. We introduce two scalar values “u” and “v”, each between 0 and 1, and these will represent the distance to be traveled to find our UV coordinates. Now, our equation looks like this: P1 = A + u( B – A) + v( D – A).

if P1 was located on the top plane of the box, then we would use these vectors.

if P1 was located on the top plane of the box, then we would use these vectors.

Now, in order to find s and t, we need to do some linear algebra. We can use three vectors on our plane to find both u and v by taking the dot products of these vectors, and dividing by their length squared. How do we find these? Well, we know the points of each edge of our face, and the point on our face, P1, which we can easily form three vectors from. For this example, we are going to use  D – A, B – A, and P1 – A. To find our u, we take the dot product of (D – A) and (P1 – A), and then we divide by (||(D – A)|| ^ 2). As for v, we take the dot product of (B – A) and (P1 – A), and then divide by ((||B – A)|| ^ 2). Finally, to find our point on the texture, we multiply our u,v coordinate by the size of the texture. Now we can apply that color to the our point on the box!

But wait! How do we find the points for our vectors? Well, since we know the normal of our face, we can calculate each point based on the min and max vertices that we have. Here’s what it looks like:

Depend on your axes definition, this may need to change for you.

Depend on your axes definition, this may need to change for you.

And here’s what it all looks like in code:

// left
 if (abs(p1.x - Min.x) < epsilon_value)
 {
        normal = Vec3 (-1, 0, 0);
        A = Vec3(Min.x, Max.y, Min.z);
        B = Vec3(Min.x, Max.y, Max.z);
        D = Vec3(Min.x, Min.y, Min.z);
 }

// right
 else if (abs(p1.x - Max.x) < epsilon_value)
 {
        normal = Vec3 (1, 0, 0);
        A = Vec3(Max.x, Min.y, Min.z);
        B = Vec3(Max.x, Min.y, Max.z);
        D = Vec3(Max.x, Max.y, Min.z);
 }

 // out
 else if (abs(p1.y - Min.y) < epsilon_value)
 {
        normal = Vec3 (0, -1, 0);
        A = Vec3(Min.x, Min.y, Min.z);
        B = Vec3(Min.x, Min.y, Max.z);
        D = Vec3(Max.x, Min.y, Min.z);
 }

 // in
 else if (abs(p1.y - Max.y) < epsilon_value)
 {
        normal = Vec3 (0, 1, 0);
        A = Vec3(Max.x, Max.y, Min.z);
        B = Vec3(Max.x, Max.y, Max.z);
        D = Vec3(Min.x, Max.y, Min.z);
  }

  // down
  else if (abs(p1.z - Min.z) < epsilon_value)
  {
        normal = Vec3 (0, 0, -1);
        A = Vec3(Min.x, Max.y, Min.z);
        B = Vec3(Min.x, Min.y, Min.z);
        D = Vec3(Max.x, Max.y, Min.z);
   }

   // up
   else if (abs(p1.z - Max.z) < epsilon_value)
   {
        normal = Vec3 (0, 0, 1);
        A = Vec3(Min.x, Min.y, Max.z);
        B = Vec3(Min.x, Max.y, Max.z);
        D = Vec3(Max.x, Min.y, Max.z);
   }

   Vec3 d = D - A;
   Vec3 b = B - A;
   Vec3 e = p1 - A;

   uv.x = (e * d) / (Length(d) * Length(d));
   uv.y = (e * b) / (Length(b) * Length(b));

Here’s what the result looks like when using a grid-like 128 x 128 texture in a standard ray tracing program:

A simple scene that is partly in shadow.

A simple scene that is partly in shadow.

And that’s it! If you have any questions, comments, or suggestions, please feel free to message me! Thanks, and I hope you learned something!

Posted in Programming, Tutorial | Leave a comment