Categories
Game Development

Chinese artists gave up?

I never told the chinese artists that I wouldn’t use them, maintaining hope that I could at least use some of their art in the game. It looks like the problem resolved itself. I haven’t gotten a daily report in 4 days and the last one was short and had an impatient if not hostile tone. I assume this is discouragement over consistently having their submissions rejected.

Legally, if such a thing applies here, all their work was for-hire and I didn’t accept any work so I’m not obligated to pay. Professionally, I was going to give them a pay-off anyway since they did put genuine effort into things. If they are just going to disappear though I won’t.

I’ll see over the coming days if I ever hear anything from them again.

Categories
Game Development

Up to the zone browser

It’s not much to look at but there’s a lot going on under the hood to get to this point.

Zone Browser

I can now start a local server and connect to it up to the point where I download the zone and player data. I’ll do a bit more work on this and next work on adding the chat capability to the bottom of the screen.

Categories
Game Development

New state design is working well.

I spent most of the morning getting the stupid “Remember Password” button working on the main menu screen. Irrlicht uses wchar_t instead of char*. Eventually I got fed up doing conversions so I added the ability to use setText with char* directly to their engine.

My design has every game state totally independent of every other state. When a state enters it is allocated and when it exits it is actually deleted. From a modularity perspective this is awesome because I don’t have to worry much about states not working if I run them more than once. I also don’t have to worry about new states breaking existing states.

This created a problem with “Remember Password” because the GDD specifies that if the checkbox is checked it still won’t remember the password unless you have a successful login. Since the connection state knows about login-success I have to transfer data between states.

My solution was to include a “StateStack” class which is just a structure that indicates the caller and state-specific derived data. It is passed from the old state to the new state and managed by the state manager. This has worked out very nicely and is equivalent to passing parameters to a function. It is independent of the states themselves, lets me easily pass all the data I want, and I can store all the data in the new state with a memcpy. Since the connection state is used by multiple states (both connecting to the server chain and to a particular server) I also store the followup state in the state stack. This fixes a big problem I had working on SOG. In SOG, the state manager would remember the current and last state. It was only through hacks that we could get shared states to progress to the next state that we wanted. This solution lets me specify all the data I need in the StateStack class so there is no ambiguity.

Some data set by states needs to be known to the entire game, such as the password to save on shutdown or the current resolution. Those are stored in the game class I derive from the application interface. So far there isn’t much data of that sort and it’s worked fine.

In somewhat related news, I designed the network packet handling architecture to pass particular packet types to the states themselves. If a state does not choose to handle a packet, it goes to a default handler, which either handles it or does an assert. This is nice because the state itself handles packets particular to that state, minimizing information exposure, grouping related data, and eliminating the need for an external controller.

In all my prior games there was a network class of some sort that was responsible for all packets and would control the game. In theory this sounds like a good modular approach. In practice it was pointless because there is no functional relation between any of the operations handled in that module. This design created a lot of work because I had to put in custom accessors for every possible multiplayer operation. Changing states was especially a pain in the ass and usually involved polling for a variable changed by multiplayer code. I had cases where I had a while loop inside of a function that did nothing but call NetworkUpdate (to read packets) and wait for a variable to be set. Inside the loop it would check a variable to see if the escape key was pressed to cancel. With my current approach I could do the same thing with a state enum inside the state class and update the enum when the packet arrived in the OnNetworkPacket function. I could exit the state in the OnKeyPress function. This is much easier and cleaner.

Categories
Game Development

Estimates vs. Reality

As I work on the game I am reminded again why I always multiply my original time estimates by four. When I got home today I thought it would be a simple issue to fill out all the packet types and negotiation for basic connectivity. In fact, I spent the entire morning just setting up parts of the framework I previously forgot. Then the entire night doing a single packet and setting up remembering the last password and username used. About half the time goes into refactoring existing systems to reflect updated design decisions.

A lot of the time I write some straightfoward code and use it for a while. Then later I need similar code for a similar but different circumstance. I’m very consistent when it comes to never duplicating code or data so everytime this happens I have to spend time refactoring, then debugging everything I just changed.

I’m not sure if I can get a vertical cross-section done in one month because even at full time work my estimate is 2 weeks. Multiply that by 4 and you get 2 months full-time. I’m only doing this part-time though so the time doubles yet again. I’m going to try to speed things up by leaving TODOs all over the place on anything that isn’t a gameplay feature (such as the DB or the server mesh).

My biggest current hinderance is my day-job. It takes time for me to get into the flow of things and working mornings and nights forces me to stop working just as I really get going. Then with GU I want to do a good job so I put my energy into that rather than my own game. That drains my enthusiasm and energy for programming my own game so by the time I get home I don’t feel like programming anymore. Even on the weekends lately all I want to do is play games because I’m getting burnt out from what is now going on a three month two-job crunch.

Categories
Game Development

Time to crack down

It’s very likely that a professional company is going to do all the art for my game starting the middle of next month. It’s going to cost me a lot of money although it’s cheap from a business perspective.

As a result, I really need to crack down and get a gameplay vertical cross section done by then in order to minimize the number of changes I need to ask for.

This includes:
All menus
Ships flying around
Ships shooting
Ships launching from carriers
Spawning carriers
Space stations
Radar system
HUD
Ship interaction (destroying each other)
Ship customization
Chat

And a lot of other things. This is going to be a lot of work and even if I had a month full time I’m not sure I could do it. So I need to spend every available moment from now on accomplishing as much as possible.

I might use my vacation days from work to try to get more done in time.

Categories
Game Development

Effective commenting

I’ve been dealing with a lot of code lately at work where I have to look again at stuff I last changed for some particular context 3-6 months ago. Either that change had a side effect or it broke some other edge condition. This is especially true with magic numbers, where I tweak the numbers until they work in one particular case in one particular level.

In general, for both myself and others, I see that the most effective comments are those that explain the why, rather than the how or what. Yet the most common type of comments explain the how or what, rather than the why.

For example
// Move foward on the balance beam
if (InDistance(10)) then PressStick(foward);

This is much better than nothing but I can usually figure it by in the context. Here’s another way to comment it

// This will ensure that we reach the threshhold range of grabbing the edge
if (InDistance(10)) then PressStick(foward);

With the first comment, I had no way to know if changing the 10 would have broke the code or if pressing forward had other effects. With the second comment, I could delete the code entirely and implement something else without breaking the dependency.

The golden rule of commenting IMO is to reveal intention. Code Complete says to comment variables over code but this is just an effect of commenting intention. Variables tend to reveal intention better than code does. I’m going to add this to my coding rules on the front page.

Categories
Game Development

Switching artists

The chinese artists work hard but I can see the communication barrier is too great. After a month they still don’t understand normal mapping and after many times trying to explain it they still just don’t get it. All I get are emails “We worked so hard for 2 days on this technique” which winds up totally missing the point and all it accomplished was for me to once again repeat what I already explained.

I have to admit I’m getting annoyed because they have the editor there already. If they simply spent a day experimenting they could have figured it out. Instead they rush forward like bulls with blinders focused on the wrong target rather than spending a minute looking around first. But I understand this is why artists are artists rather than technical people. If I had someone there who was fluent in both chinese and english and could manage them it would have worked out.

If I can I’ll have them properly finish what they can in the time available but it’s a risk to the project to rely on them. So I’m going to go with a professional to do this.

Categories
Game Development

First chinese ship to meet basic requirements

Once they get the normal mapping correct this should be acceptable.

Dreadnought

Categories
Game Development

Effective Design

One of the things I like about being the lead programmer on a game is my exposure to architecture. This is something most programmers don’t get to experience very often and I enjoy it.

Architecture is difficult because it’s high level planning. Like all high level planning you deal with unknowns or partially knowns. The human brain is designed to skip over the flood of small details we encounter constantly through our senses so it’s definitely a learned skill.

Some people propose doing very detailed architecture. I disagree with this because, at least for me, it’s impossible to come up with detail that solves all useful cases. While a high level architecture is beneficial, once you start thinking at a function level there’s just too many mistakes, wrong assumptions, and forgotten cases to be usable as a spec. We’ve all seen cases of architecture that causes bloat but doesn’t solve any real problems. This is a fundamental problem caused by a detailed architecture with wrong information.

The approach I try to use is to first think of any obvious cases where architecture is necessary or beneficial. For example, I know that the client and server will both need shared code. So I split the project up into client only, server only, and shared. However, in other cases it’s harder to tell. When I pass a data stack between states how much architecture should I put into it? Is it worthwhile to put the stack structure in the state itself to avoid copying the data on state start? Should I handle memory allocations automatically or should I handle it per-instance?

I don’t know. So once I solve the high level problems I can accurately think about, I just write the code using the simplest case possible. Every so often I try to take a break and think back about what I did. If, armed with new knowledge, I think of a better way to approach the problem I refactor. This is also what extreme programming proponents advocate.

Refactoring throughout the day takes discipline and can be annoying because it involves rewriting a lot of already working code. However, if I don’t do it the program will quickly become unmaintainable.

As I gain more experience I think I get better about seeing the cases where I should think about planning ahead, rather than at the planning itself.

Categories
Game Development

Outsourcing part 2

My outsourcing experiment isn’t working out as well as I hoped. I anticipated communication problems but hoped they would be speed bumps on the road of progress as opposed to the 10 foot deep potholes they are turning out to be.

The causes are fourfold:
1. English is not their native language.
2. Most artists aren’t good at writing or logical thinking, which is necessary for email exchanges.
3. They work when I’m asleep AND
4. They don’t have reliable always-on internet access.

These map to the following problems:
1. I can’t make complex ideas understood and even simple ideas don’t get across very well.
2. They have a hard time meeting technical requirements even when they do know them.
3&4. Every email exchange takes 1 day. This means that your normal office-type 5 email exchanges now take 5 days instead of 30 minutes.

This is why, now like a month later, I still don’t have a single correct model and I’m still repeating the same requirements that I told them at the start of the project.

On top of that they are slow. I understand they are students but it shouldn’t take three people three days to remove some polygons from a model and add a few texture details. This is a constant problem I’m facing.

I think outsourcing could work with the proper setup. For example, if I had a technical person there who was fluent in Chinese that would overcome the communication problems. My wife calling them in Chinese helps immensely and is the only reason I’ve gotten anything at all. But she is not technical and I can’t rely on her to call them that often.

Their work is pretty good. It’s just not good enough for what I’m doing. I sincerely hope I can make this work but given the choice between releasing the best possible game and spending more money I’ll spend the money.