Game Design, Programming and running a one-man games business…

The big wide world

It’s a big wide world out there. What percentage of that world is buying my games? Well obviously it’s a tiny chunk, but more relevantly, what percentage of them are in any position whatsoever to buy my games even if they wanted to?

Well first of all, they need internet access, but frankly there is nothing I can do to help there. Then, they need a way to pay for them. I use a number of stores now, including direct sales through BMTMicro, who will take credit cards, debit cards, amazon payments, Google and PayPal, so that’s a LOT of people covered.

Then they have to speak English.

Wait! What? Lets backtrack a bit. The problem with being an English Speaker is you are historically linked to either the UK, North America, Australia or New Zealand. two of these are remote islands where you aren’t going to routinely travel to see foreign-speaking neighbors. One if a country so huge you can travel extensively and still never leave it. Another had a huge Empire and thus arrogantly assumes everyone understands English anyway… As a result, people who speak English tend to think everyone else speaks it. And they don’t. There is a huge world of non-english speaking gamers out there! Now let’s assume that a lot of them speak a language that requires unicode, and my games don’t support it (ouch!). Lets also assume that some are in developing countries and can’t afford games (or piracy is rife). Let’s assume cultural differences prevent a lot of others from considering buying my games. That STILL leaves a huge audience for them that could be enjoying Democracy 3  and my other games if they were translated. How big? Well certainly bigger than the population of New Zealand (4.43 million) If you suddenly found a group of 4.43 million people who might like your game, wouldn’t you go to the effort to sell to them? I’m planning to.

frenchcat

Democracy 3 can now be bought in English German and as of today, French! (BONJOUR!!!). I may not stop there. The biggest hurdle is simply admin. The hassle of new steam builds, and the management of getting the relevant linux/mac builds done is the bottleneck. This is the LAST game where I will have this hassle. GSB2 will have multiple language support built in from the start and handled entirely by an in-game option. All I’ll need to handle is different store pages. I still have other things to tweak. BMT Micro store pages need to be multi-lingual, as do the confirmation emails and download instructions. I’ve still never sent out a foreign-language press release yet.

I can’t see any reason why the MAJORITY of GSB 2’s sales should not be from non-english speaking people.

In other news you can now get Democracy 3 on the Apple App store, if for some reason you refuse to shop anywhere else…

 

 

Cleaning the engine

It’s tricky to get the timing right. Some people do nothing but update their engine. they have re-factored it so much and re-implemented everything so often that it is a true work of art, worthy of actually putting in books on how to code. These people never ship a game. The other extreme is people who are still using assembly language routines for loading in ini files because they wrote them in 1996. These people have tech support issues galore, and are probably still using Directx3.

In between there somewhere is common sense, if you *are* going to write your own engine and not use someone else’s. I think, from chatting to devs and surfing a lot on developer forums, that people tend to want to redesign their engine after every game. They consider that quite a major compromise compared to their real hidden urge to do it every morning. The thing is, if you are doing that you aren’t really writing an engine, you are just writing a new game from scratch all the time.

lexus

I tend to go with a system of marginal improvement. I still have some code from about 5 games ago (non critical stuff like ini file loading, text handling, game timers and some math stuff), but a lot of it is fresher. The graphics stuff, as you would imagine gets a major refresh more often, and my engine only contains some pretty ‘raw’ directx wrapper and vertex buffer / text engine stuff. The actual ‘scene management’ for my games is done in the game itself.

Despite the occasional between-project update and maintenance, occasionally you have to step in and clean things up. The last big update was when I went from Directx7 (Democracy 2, Kudos games…) to Directx9 (GSB,GTB,Democracy 3). This time I’m updating almost everything BUT the directx version.

I recently bought Visual Studio 2013, mostly for the concurrency profiler to enable me to experiment with multi-threading more. This was a good opportunity to take a look at some of the flakier things in my engine. I have a lot of warnings in there for data-conversion and other sloppiness. I also have code I never use (I’m culling it), and the worst and most embarrassing thing is that I can’t decide if I like char* or std::string. I Figure that std::string must be at least a bit better, more robust and safe than char*, so I’m trying to purge all that char* from the engine, and eventually, the game. I’m also planning on re-wiring stuff so that the main game code doesn’t have any FILE* or other old fashioned stuff, but uses my file wrapper more.

Why? Mostly because I can see me heading towards cross platform eventually. maybe not with the next game, but baby-steps and all that… Plus it makes life easier if getting my engine ported is a less messy business. I’m sure after a few days of sorting out this stuff I’ll be climbing the walls and wanting to code some explosions again…

Redshirt on sale! get your space career at a 50% off discount

redshirt_Logo_transparent_500width

Attention crewmembers! Did you know you can have a life IN SPACE for 50% off the normal cost? It’s true! Our wonderful space comedy life-sim game Redshirt is now 50% off, whether you grab it from the redshirt site or from steam!. If you are on the fence, you might want to know that redshirt is the only game to feature bisexual aliens that stalk you through social media. If that doesn’t guarantee a sale, I don’t know what will, but here is a reminder of the megalodon nine recruitment video for you:

And of course you might want to check out the redshirt website before buying. Now either grab it from this buy link here, or from steam at this linky here.

Enjoy! And don’t forget to tell everyone about the sale using social media, which is of course amazingly ‘meta’ given the game…

Positechs website (explicit numbers inside!)

Positech has been around a long time. I am OLD. I remember before VHS. I remember before CD’s. i was there when Sauron was defeated and men were shown to be weak. As a result, I’ve had a website for a long time, and probably due to mere inertia, it’s got a lot of SEO from inbound links, and a lot of (my) games on it, and therefore, it acts as quite a good funnel for traffic and sales. I’ve also advertised a lot over the years and pointed at it, so that has boosted traffic too.

Lets look at some numbers.

In the last year, my direct sales have been $170,000. That actually surprises me. I thought it was less than that. Not bad for an indie website in these days of ‘everybody buys on steam’. If I look at web traffic I get these stats over the last 365 days:

2,700,000 unique visitors according to awstats

23,000,000 pages according to awstats.

site1

That seems pretty good to me. Maybe some of that is my games checking for updates? If I check google analytics, the site got 1.8 million visits. 417k were from organic search. That’s a decent figure. I’d love to know how it compares with other indies sites, and smaller portal/bundle sites. I should also state these figures ignore redshirts site and the gratuitous tank battles site, both of which have their own base domains.

What this has got me thinking is that in effect, I own a mini-portal. I’d wager indies get a fair few emails along the lines of ‘We are an exciting new game store and we would like to grab 30% of your revenue despite having virtually no traffic, if you agree to sell through us!’. I know I do, and I wonder if those sites have less traffic than me. I have signed deals in the past that have earned under $10k a year in sales through a channel, even under $5k. 5% of my direct sales is more than that. You can probably see where I’m going with this?

I have zero time and mental bandwidth, but I do muse over the idea of saying to indies who refuse to sell direct because ‘it’s too much hassle’ something along the lines of ‘I’ll do it for you, and take 15%’. This is just an idle thought, and I’d have to be very impressed with a game I’d add to my own site. But it is worth a thought.

I have been slowly investing in my site over the year. Check out the forums. They now support facebook, google and twitter as logins, and the individual forums have custom graphics. ooh!

 

Thread Concurrency bug. Any expert advice?

I’m new to multithreading, and the visual studio concurrency visualiser. I have lovely multithreading code working. basically my main thread throws the Threadmanager a bunch of tasks. The threadmanager has a bunch of threads which all spin doing nothing until told to do a task. Once they finished their task, they set an IDLE flag, and the main threads WaitForAllTasks function then assigns them a new one. It works just fine…. but I notice an anomaly.

See below (Click to enlarge enormously)

bug

The highlighted connection shows thread 4828 sat on its fat ass waiting for the main thread, when it clearly idle and ready to do stuff. The things is, the main thread function is just this:

    bool bfinished = false;
    while(!bfinished)
    {
        bfinished = true;
        for(int t = 0; t < MAX_THREADS; t++)
        {
            if(CurrentTasks[t] == IDLE_TASK)
            {
                //maybe get a queued item
                if(!QueuedTasks.empty())
                {
                    THREAD_TASK next_task = QueuedTasks.front();
                    QueuedTasks.pop_front();
                    CurrentTasks[t] = next_task;
                    SetEvent(StartEvent[t]);
                }
            }
            else
            {
                bfinished = false;
            }
        }
    }

Which basically does sod all. How can this take any time? Setting event sets an event which the worker threads function is calling WaitForSingleObject() on. Again…how can this take any time? Is there some polling delay in WaitForSingleObject? Is this the best I can hope for? It’s the same case for all those delays, it’s just this one is the largest. I’m new to this. Any ideas? :D