What is this?

This is the development blog of Black Golem, an indie games company from Austria. This blog shows smart-aleck mind dumps, all about designing games, making games and hopefully selling games!

Check out my book:

2D Game Collision Detection book

www.collisiondetection2d.net

Black Golem's Game:

nordenfelt vertical banner

Evergreen Content

A few posts I have written for www.blackgolem.com provide a large portion of the blog's traffic history:

traffic_peaks

The four highest peaks came from publishing the following posts on reddit.com:

If you did not yet try out reddit you really should head over and drop something interesting there. But beware: you can't show them any nonsense and hope for a Minecraft resonance. You have to give 'em something interesting to discuss, cool stuff to look at or useful how-tos. Otherwise they will give you only thumbs down, throw bad comments at you and your attempt fades into obscurity. Check out what others do there and follow their example.

The title of this post mentions evergreen content. The posts listed above are evergreen. Over and over people discover them via search engines and sometimes convert to followers, feed subscribers or fans. That's the payoff for the effort I had to take for writing them. Especially the Graphics Style Analysis series took some days for research and writing. Now they drive people over to my place every week. The more evergreen content you have the more people will discover your site. So pile it up. Not everything intended as great work emerges as expected. But some ideas will turn out to be real tidbits. Keep going and drop some nuggets into your blogging stream.

 

Cheers,
Thomas

 

Experimenting a Little

Some time ago I mentioned wasting too much time in my feed reader. So I cut the subscription list down to a small, bearable information stream. Now it has a size which provides joy while browsing through instead of the work load feeling I had before.

What to do with this free bare hour now? More of the same coding work I'm doing already the whole day long? No, that's boring. It's rather time to do something new, PR experiments for example. I have some ideas in mind like doing more comments on other blogs, helping out in forums, spreading my blogs a little bit more in the social babblesphere, asking other webmasters for a link exchange, improve my own websites, etc.

The basic idea is to try out some new tricks for a while and see how they work. The good ones are allowed to stay, the worthless get bounced. Google Analytics plays the judge as it does in most cases anyway.

Maybe I find some nice things to share here. We will see.

 

Cheers,
Thomas

 

No Kings

People who have products or services to offer sometimes get obsequious regarding their customers. This often leads to deep price cuts or unbearable effort. Give them an inch and they will take a yard. When you show weakness as a seller your opposite will become aware of it and will try harder to get benefits from you. On the one hand that's natural and the customers job. On the other hand it's the producer's job to create, sell and live from his/her products. Two forces, supply and demand, which have to be balanced.

"The customer is king" is a nice tag for everyone buying your games. It gives them some kind of power over you and your creations. And it's the slogan of business suicide. There should not be a superior position in the relationship of buyer and seller. Otherwise some kind of serfdom starts and destroys innovation, growth and progress. The current deadlock of AAA games is the best example.

There are some reasons why customers can/should not be kings:

No Authority

Kings would tell you top down what to do and you would have to follow their instructions. Game producers can completely ignore all their customers and do what they want. On their own risk, of course. It is even good advice to follow your own way. Kings can and will exploit their servants but not other leaders. A good reason to become a leader by not following the path of servants.

People Don't Know What They Want

They will tell you by reviews or feedback if they like what you do or not. But they hardly can tell what they want before they see what you will give them. Kings have to take right decisions even in uncertain situations or they will be toppled. I've never heard about a customer who was punished because he/she gave wrong feedback. Opinions are options, not instructions.

Producers Would be Slaves

If the customer is king you as producer would be a servant. Do you feel like a servant? Do you want to serve for a pittance? OK, the latter question is hard reality for some of us. :) Nevertheless, you may not start your own business to be subordinate for others. Then you could have kept your day job, right?

Kings Live in Ivory Towers

Their counselors show them only the nice things or whitewash bad news. I don't think customers should be treated like idiots and kept away from bad things. Feature cuts, delayed release dates or prices above (casual tier) expectations may put off some customers. But the truly interested will stay. It's like haggling at a bazaar. Even Cliffski has bazaar-like arguments giving him the money he demands: his cats.

Finally neither customer nor publisher/producer should be king. It's rather democracy: the leaders do what they want (as in real world politics) and people vote with their buys if they like it. If the balance is met both parties win. If one side takes more the system will collapse over time. History and current developments in North Africa prove this.

 

Cheers,
Thomas

 

Lone Wolfs Hunt Different

When I was employed my colleagues and I were required to follow coding guidelines, write reusable libraries and use cooperative tools. Fostering documentation, managing project staff and learning social skills were important points on my university's syllabus.

Now I'm working alone without any human interaction or cooperation. University and employment taught me what it needs to work in groups. But nobody told me how to work ALONE. Everything is centered around my own needs now. Nobody else sees how I'm working except I want it (e.g. in this blog post). One is the most efficient group size because there is no additional cooperation/communication effort.

The coding style for my private projects "decayed" over the years regarding interface design, non-intrusive extensibility and functionality grouping. No-nos like public member variables, lack of thread-safety, missing template specialization, lazy designed OO-hierarchies and faked algorithms became common. Some time ago I wrote about how ignoring best practice can kill your project. This stands in contrast to the following reflections. They are an excerpt of my current coding style, driven by experience and tradeoffs between usefulness and effort:

Do you really need these set/get methods?

Set/get pairs serve encapsulation, abstraction and interface consistency. Every exposed member variable should be wrapped this way. True, but also nerving because it needs two extra functions for each member variable:

inline void SetX(int x) { this->m_x = x; }
inline int GetX() const { return this->m_x; }

Why shouldn't I expose the variable directly? When a set/get pair would be nothing more than a proxy you may think about making the member variable public. There would be no difference.

Member constants are good candidates for being exposed directly. They can not be changed, so shielding is senseless. Try to make as many members constant as possible.

Modules are sophisticated... for behemoths

Separating code in modules became necessary when programs started to get bigger and treated by more than one person. Was it in the 50's? 60's? I don't know but many, many years ago.

Lone wolf coders have a limited need for modules. Sure, they are great for bundling/reusing functionality and canning third-party code. But before splitting your code you should think about the gain. It will be an extra layer in your tool chain to manage. Sometimes IDEs don't recognize changes in a base module during compilation and link to the old, buggy version. Zombie bugs you already squashed reappear in your game. The same can happen with single files but with modules you have one more predetermined breaking point.

When functions start to pay for themselves they should be extracted into separate libraries, modules, packages, whatever. That's a good reason for splitting up code. Chopping up your game for the sake of it is idiotic. I know it because I did it and suffered from it. :)

Supporting features you "may" need some day is for dreamers

As you code away happily you encounter a cool feature in an API you use for your game. There is no need for it at the moment but you decide to support it in your own code base you write atop the API. Due to code's organic nature this feature will grow up to higher levels of your game engine. Its support effort will grow to. This can become quite some extra work for a feature you don't need (yet). Simply don't propagate it until your game demands it.

Write as few lines of code as possible

This advice goes hand in hand with the last one. When I learned joiner back in the last millennium I was told "good joiners need just a few wood shavings to square the board". When you're figuring out your algorithms take a step back and rethink if there's an easier solution. Easier means less time to write, debug and maintain. You can always go more complex.

God gave templates... just to waste your time

Java, C#, C++ and even Ada have the great feature of templates/generics. You can write generic functions, classes or even meta-programs. The dream of heavy reuse motivates you to write specializations for templates to cover all possible instantiations. Forget it! If there is no obvious benefit RIGHT NOW to write a function/class template: leave it alone, go straight. Templates soon get very complex and need a high coding discipline and knowledge about how they work. It's the chainsaw of coding, powerful enough to cut down big trees as well as your foot by accident.

Threading is the current holy grail - as long as you know the right chalice

Do you know the scene in Indiana Jones and the Last Crusade where they have to choose the right chalice for eternal life? Only one is the right, all the others let you rot within seconds. OK, maybe that's not the best metaphor for threading but it comes close. When you parallelize your code you have to take care. Some languages like Erlang or Stackless Python are well suited for this job. C/C++, C# or Java can do it to but need deep knowledge and experience how to program concurrent beasts.

If you want your game to run on older machines (5+ years) you can forget threads confidently. Many old crates just have one core. AFAIK multiple cores became common after 2005.

Stealth in bright sun light

Interfaces, my favorite. They are so cool because they guard your implementation guts from public inspection and corruption. The smaller the interface the better. The PIMPL idiom is a well known practice to hide away what clients should not see. I've used it many times in Nordenfelt so far. Some time ago I've rethought why I should hide away all the implementation details like a broody hen covering her eggs? After a little pondering I decided to "pimpl" just classes which tend to get altered often for saving compile time as well as memory allocation time. Everything else in my C++ code is written the same simple way Stroustrup designed the language initially. Finally it's just me who has access to the interface... and the implementation.

Do it like JIT compilers

Hard-code your constants initially. Only if you find yourself modifying the constants over and over again (especially during gameplay tweaking) they become candidates to get extracted into a configuration file. JIT compilers (at least older Java VMs) do it the same way. First they interpret the byte code as it is. Over time they compile often used parts into the OS-native format which is much faster.

Premature generalization

That's the offline cousin of premature optimization: do it only when measures are bad.

For helping functions or classes I formed the habit to implement them right in the cpp-file where they are used. Only if these helpers can be used somewhere else to I'm going to extract them into separate classes/modules. Much code I thought would be useful in own modules turned out to be hardly used. Now I extract it only when I see the need for sharing.

Impose first

The last but maybe most important one: implement as impostor if possible.

Like the impressive scenery of a shallow stage set in a theatre there are many opportunities to mock complex functionality by simpler algorithms. Some of them will be replaced by better implementations, others can be left there as they are. This can be applied to AI, simple physics or prototyping as a whole. You may be surprised how often mocks can be used.

 

Maybe you already made some similar decisions for your own coding style. When we work in cooperation with other programmers it's important to follow shared guidelines and best practices. But when we work alone there is no need for conformity. Just do as it works best for you. That's the only rule when you are independent.

 

Cheers,
Thomas

 

Game Dev History

I just was tripping down memory lane as I remembered my dead and gone project BIONIC (german project site, screenshots). It was and isometric adventure game with focus on puzzles:

bionic1

I've lost the game's demo and code some months ago when my backup hard-drive decided to quit. Showing you this old non-starter would have been cool.

Anyway, BIONIC was my first attempt of making a full game which failed miserably. I've paid dearly pushing this project forward from 2001 until 2005. Studies during the day and spending the night on BIONIC for years drained my health to a burnout. That was the first lesson I had to learn:

Health is not granted.

In the end BIONIC failed for other reasons:

  1. hardly any experience in writing games,
  2. constant feature creep and
  3. building everything from scratch

When I'm checking Nordenfelt against these points I'm happy to see that the first two points are no longer a problem. The third point still was an issue but is done now.

Looking back on older projects is always fun. It gives you a feeling of improvement and you can have a good laugh about what you thought looks good back then.

 

Cheers,
Thomas