Jump to content

  • Log In with Google      Sign In   
  • Create Account

slayemin's Journal

Month 2: Prototyping

Posted by , 30 July 2014 - - - - - - · 2,630 views
Indie, Game Dev, Production and 2 more...
For the first half of July, I was on vacation in northern europe visiting family and friends. As expected, that put a big speed bump into progress. That's okay though, I don't really have a hard due date to hit (yet).

It's always tough to pick up work where I left off after getting back from vacation. I at least had the sense to leave some detailed notes for myself on where I was at and what needed to get done, and just picked a few easy tasks as a way to get back into the code. One thing I'm thankful for is my code commenting and descriptive variable names.

As far as the prototype goes, I've slowed down on progress as I fix a bunch of problems and try to figure out how things should work. I'm a bit unsure on what should and shouldn't go into a prototype. The purpose of a prototype is to quickly test things out to see if they work before spending a lot of time on it in production. My initial thought was that this means you create a quick mock-up of your tentative game design and see how the mechanics work together. But, what about some of the technical challenges I don't quite know how to resolve yet? In my case, I've got up to a few hundred creatures on a battlefield in box formations. Writing the code for the formations isn't as straight forward as it would seem. How does the formation change when members die? How does the formation move from one location to another while maintaining cohesion (cue some flashbacks to bootcamp)? When should a creature attack an enemy creature? If attacking a nearby enemy creature causes the creature to leave formation, how do you determine when its appropriate to break ranks? What about creatures with a ranged attack who can see and target an enemy creature, but doing so requires a change in orientation which is different from the formation orientation. When does a ranged unit reorient themselves from their formation position to attack a nearby enemy? How important is it for a creature to value a command, such as a move order? How much can the creature deviate from that?
Player: "Move over to this position"
Creature: "Okay, got it."
*time passes*
Creature: "Oh hey, there's an enemy creature close to my current position. I'm going to go attack it before returning to my original order!"
Creature: "Hey, that enemy creature is running away and I'm getting pretty far off track. When should I abandon my attack and resume my original orders?"

My principles on prototyping has changed slightly. While the prototype is all going to be thrown away, it's a good way to find these problems and answer them. The exact code/solution discovered by prototyping and play testing can then be copied almost verbatim into the production version of the game and then polished. The uncertainty will always linger though: what is important enough to be included in a prototype vs. what is "just polish" and should be added in during production?

My tentative answer: "If the feature adds significant impacts to how the game is played, it should be included in the prototype."
Example: my creatures reorganize themselves in formation to fill in any gaps when a member dies. It looks pretty and pleases me, but also has tactical significance to the way the game is played because it keeps the front lines unbroken. If a creature dies, its position is filled by the back row, so the fighting continues and it's harder for enemy units to get a "surround" situation.

I ran into a significant challenge earlier this week. I had decided to use my Octree implementation. It was really buggy and causing lots of crashes. That meant that I needed to go back and rethink the code on it. I spent a good day and a half working on trying to get it to work as initially planned -- to update intelligently -- but that was way too complicated. On the train home yesterday, I was reflecting on what a show stopper this challenge was becoming. Once again, I was becoming a victim of premature optimization. Why exactly do I have to be intelligent about what part of the octree I update? It was just a part of an overly engineered wet dream. The whole purpose of an octree is to reduce collision checks to a manageable time, so that when you have hundreds of objects, you're not choking your CPU. I realized that there was no good reason not to just completely trash and rebuild the octree every single frame. The CPU costs of that are negligible and satisfy "prototype quality" code. If I was actually using my octree in production, it would be worth it to get it 100% correct, provided my existing solution is showing performance problems. Again, I know not to optimize prematurely and yet I do it anyways. To avoid that in the future, I need to periodically to a check on myself and think about what I'm doing for at least two minutes. If it costs me two minutes to realize I don't need to do two hours of work, it's worth it.

I have started working on rudimentary artificial intelligence for my creatures. Initially, my approach was very crude (prototype appropriate) but it wasn't robust enough to handle the changes I needed to add. I was creating a few scripted behaviors using if statements and math. If I needed to extend it, I had to dig into this mess of spaghetti code and it was daunting. On many occassions, it got too confusing and complicated and I ended up scraping it and starting over again, only to repeat the same thing. Today, I had a genius idea. Rather than creating a ton of spaghetti code or a large state machine with a massive switch statement, I would create a bunch of "Behavior" functions to handle every possible scenario I could dream up, and then write some code to look for a "situation context" when that behavior should be triggered, and then I use a function pointer which hits the appropriate behavior. It is so much more elegant, much less complicated, and much more extensible.

I also spent a lot of time writing the back end game mechanics infrastructure. To my own surprise, I'm starting to get to the point where all of these detailed game mechanics are coming to life and it is quite thrilling to see it all in action. At this point, my archers use their equipped short bows to shoot arrows at enemy targets which are within their cone of view and in their area of attack. The arrows fly and deal damage to the enemy units, provided they actually hit. Dead units turn into skulls and their positions are filled by surviving members of a unit. I almost have everything done on the tactical battle mechanics front. The last bit is a morale system. Then, it's moving on to letting wizards cast spells on the battlefield, adding additional spells, adding additional units, adding additional weapons, more game mechanics, and trying to keep things balanced and most importantly.... FUN!

If the prototype isn't fun, it's not worth going into production until it is.

I signed my team up to go to a day long game dev conference at Digipen being hosted by Intel. They have some sort of indie game challenge for indie game devs. The top prize is some marketing exposure or something. I certainly am not ready to enter anything into that, but I'm hoping I can get my prototype into a stable, working state by then. If I can, I'll plop it onto my laptop and shop it around informally for some feedback. We'll see. I hope the conference is worth all of the opportunity costs I'll be incurring. I still haven't thought of a game title or company name. That's surprisingly difficult. When people ask me, "Who do you work for? What's you're game called?" I don't really have a good answer. That's going to turn into a problem as time progresses.

Next update in a month! I hope to work hard and bring you something tangible to look at by then!

New Studio: First month in review

Posted by , 02 July 2014 - - - - - - · 1,232 views
business, gamedev, production and 2 more...
This week is a bit unusual. I'm taking a planned vacation on Friday and will be gone for two weeks. All I see is costly expenses and that's causing me to grit my teeth a bit, but I'm trying not to be too concerned about it. Life is too short to not take a moment to relax and enjoy it, right?

So, I finally tabulated all of my business expenses for the month of June 2014. I thought I'd share them so that anyone who wants to get an idea on costs can use my experiences as a measuring stick:

Line No.Line ItemCostPayerPurposeDate
1Artist Computer Parts (Online Purchase)$740.42EricArtist's work computer6/5/2014
2External Hard Drive Enclosure$15.95EricWork File Backups6/9/2014
3Artist Computer Parts (Fry's Electronics Purchase)$1,131.03EricArtists's work computer6/9/2014
4Prorated Office Rent$550EricWork place facilities6/10/2014
5MSI 1333 LGA Motherboard$183.94EricEric's Computer Upgrade6/10/2014
6Intel i7-4770K CPU$314.99EricEric'sComputer Upgrade6/10/2014
7Parking Fee$27EricTransport Computer Equipment to Office6/11/2014
8Artist's Wages (40 hours)$961.54EricEmployee Paycheck6/16/2014
9Orca Card Load up$50EricTrain Tickets for transport to/from work6/21/2014
10Maya 2015$4,024Eric3D Modelling Software for artist6/21/2014
11Mudbox$542.03Eric3D Modelling Software for artist6/21/2014
12Unreal EngineMonthly Payment$19EricSoftware Subscription Payment6/30/2014
13Artist's Wages (96 hours)$2,307.69EricEmployee Paycheck7/1/2014

Final Total: $10,868

Keep in mind that a lot of these expenses were one time expenses which are involved in the setup of a new workspace, so I won't be spending $11k on a monthly basis. My projections for the next month are as follows:

$750 - Office Rent
$4,600 - Wages
$19 - Unreal Engine Subscription

Which puts me at around $5400 / month.

Taking a two week vacation doesn't mean my expenses take a vacation too. I'll be paying $2700 in proportionate expenses while I'm gone and I won't be there to work. Add on top of that the costs of the vacation (air fare, food, transport, etc) and it becomes another expensive month. Those are the direct costs, but the opportunity cost of me not working will probably increase that spread even further. So, I have to mentally check myself to make sure I'm relaxing and not feeling guilty ("Hey! Are you relaxing?! feeling relaxed yet? how 'bout now?"). Luckily for myself, I have a pretty easy-going temperament so it shouldn't be too much of a challenge.

Enough talk about money for now. Let's talk about the game project.

I realized I will need an object manager for my prototype. So, I spent the beginning half of the day moving all of my game object code into an octree (related article) I had coded up a few months back. Then, I found bugs. Mysterious bugs! The problem with heavy code reorganization is that when you get bugs, you don't know if its a bug caused by the moving around of code, if its a bug in the underlying system (octree), or if its a legitimate bug in the prototype code which I overlooked or ignored. The problem was that on some seemingly random occasion, a single creature would disappear completely. The first challenge is to replicate the bug consistently when it occurs at a seemingly random time. After the bug can be replicated, the next challenge is to insert a breakpoint into the code and dig into the memory to see if there is any funky stuff going on and try to figure out what's causing the funkiness. Well, after about two hours, I found the cause of my bug. It was being caused by a special feature my octree implementation which didn't show up during my very light testing. I had this "brilliant" idea that memory allocation costs a bit of time and I should try to shave some of that time off. So, if I can borrow an idea from memory pools and "hot memory", I can delay deleting an unused octree node. If that node becomes used again, I didn't have to allocate new memory again (and time is saved!) -- but, what about the extra CPU costs in maintaining this additional overhead code? Did I actually save CPU cycles, stay the same, or did my optimization backfire? Who knows, because I didn't run any rigorous testing and profiling to find out! Lesson: Learned.
Anyways, the bug sat in my node decay code. After the node became empty, a count down timer would be initialized. If an object entered the node while the timer was active, the object should reset the timer, double its duration, and pause it. One of those things was not happening correctly, so an object would move into the node space and then the node would continue counting down, as if it were empty, and then delete itself, even if it contained objects. Hence, on rare occasions, objects would just disappear without explanation. Fixing it "correctly" wasn't that important since this is just prototype code now, so I just put in a simple "If node is not empty, don't delete it!" instruction.

On Tuesday, my artist was still confused on the ambiguities in my game design idea. I'm learning an interesting lesson here as well. People aren't mind readers. They can't just tap into my head and figure out what I'm thinking and then build it. I have to communicate this stuff as clearly as possible and with as much vivid detail as possible. At the end of this communication process, I should have a detailed document which someone else can take and build a game out of it, exactly as I've envisioned. If I get hit by a bus, it should not be a problem for the project progress -- the final product lives in the design documentation, not in my head. This starts to sound very much like a "waterfall SDLC" instead of agile documentation. I was told in university that waterfall sucks, and we were told to explain why. And then the professor caveats it all by saying, "Waterfall has been successful on many projects, just be aware of its weaknesses". Well, okay, if we put documentation on a gradient with one extreme being "full design up front" and the other being an agile "design as you go", then we're moving more towards the "full design up front". But hey, the sweet spot for agile documentation is "Just Barely Good Enough" (JBGE), which in this case, may actually mean that the JBGE state is actually a lot more documentation and design than I thought. So, the interesting epiphany I'm having is that the JBGE amount of documentation for a single, solo developer (me) was 25 pages of somewhat detailed hand waving. That would work for a solo developer since the purpose of the documentation would be to nail down the ideas and the small missing gaps would be figured out during the course of development. For a project with two or more minds (and no mind readers on the team), the JBGE point is much, much more detailed design specs. There should be zero confusion about what's being built.

It's time to start story boarding with a lot more detail. My artist comes from an animation and film background, so his idea of story boarding is a bit different from mine. He thinks that we need a separate frame on the storyboard for each and every action, to the point of detailing mouse roll overs for buttons. I don't have much experience story boarding to counter this absurdity, and more detail is always better, but I'm still a devout follower of JBGE. The approach I'm taking is to do quick, high level story board sketches of the game play, starting from "New Game" all the way to the end of "Teach the player how to play your game". Then I show it to my partner to get a sanity check. Am I going way to crazy with this aspect of the game design? Is this the direction we should go? Once I have a pretty good idea on each step in the game play and how it transitions to the next step and makes sense, I can go back through and spend more time and detail on each storyboard frame, indicating things like "These are were the buttons go, this is the GUI which shows up when you click on it. This is what happens when you do action X". Then, the work is not wasted time because its on track and not insanely over-scoped.

So my goal for the remaining days of this week are to get really detailed design documentation on all of my game systems so that there is no confusion on what's being built and how it works together. This should give my absence a little less impact on the project progress. When I get back, it's time to hit the prototype implementation hard. That may take up to a month of work. Then comes some quick play testing and refinements, and then we tentatively move into production. We start building the game in Unreal Engine 4, of which I'm still uncomfortable with due to my inexperience with it. That'll be okay though, the challenge there will be focused on "how do I implement this prototyped game code in UE4?" instead of "What am I trying to build? How do I build it in UE4?" which is a recipe for confusion and fiddling around. We'll see how things go!

As far as journal entries go, the next update will most likely be at the end of July 2014.

July 2014 »


Recent Comments