Gameplay Minimalism

February 8th, 2010

I have found a couple of games featuring minimalist gameplay recently. It’s surprising how much addictive can they get.

Usually the games offer a lot of complexity and you get hooked up on that. Take some (real-time) strategy games and dissect them. You have to deal with a lot of stuff in order to properly play these games – building your bases, climbing the technology tree, gathering resources, training and managing units, knowing their strengths and weaknesses. This type of games is both addictive and exciting, but takes a lot of time to learn. I would call gameplay in these games broad, as opposed to deep.

Now switch your thinking from the Command & Conquer franchise to something more simplistic, like Harvest: Massive Encounter.

Harvest is very addictive. It took the essence of turtling from real-time stratregy games and built its entire gameplay around it. You don’t get to manage units. In fact, you don’t even get to train any units at all. You just build your defenses and see how long can you stay alive. The simplified goal of this game is just to stay alive, as opposed to complex goals that classic real-time strategy games have: protect resources, expand, conquer.

And who doesn’t remember the good old Desktop Tower Defense?

Check out these two games: One Button Bob, Robot Unicorn Attack. You use just a single mouse button to play the first one, and it’s pretty challenging. The control is modal – pressing a mouse button results in a different action in every level, and you’re given no initial explanation – you have to figure it out on your own. The other one just uses two keys to control your actions. I spent quite some time enjoying these games and I tip my hat at their creators.

No conclusions here. Draw your own!

C++ MemoryStream

January 17th, 2010

When you have a file read into memory, and would like to use std::istream to access it, you have a couple of ways to do this. The obvious one is to create a std::stringstream from that memory location. It works fine, but it has a side effect of copying the data into its own buffer:

int main()
{
	char text[] = "Some text string";

	// this creates a copy of 'text' for std::stringstream
	std::string data(text);

	// this creates a reader that will use the copy of data
	std::stringstream reader(data);
}

With large files this adds unnecessary overhead. So what is the “right” way to do this? I came up with something like that:

class membuf : public std::basic_streambuf<char>
{
public:
	membuf(char* p, size_t n) {
		setg(p, p, p + n);
	}
}

int main()
{
	char text[] = "Some text string";

	// this creates a stream buffer at a given memory location
	membuf buffer(text, sizeof(text));

	// this creates an istream using the above buffer
	std::istream reader(&mb);
}

Pretty simple and effective. And does not use anything but STL.

How to rename a C++ thread in Visual Studio 2008 debugger?

January 10th, 2010

Sometimes it’s useful to rename your threads so you can find them easily in your Visual Studio debugger. In .NET-land it’s easy: you have to set the System.Threading.Thread.Name property of the thread you wish to rename and you’re done. It’s not that simple with native code, though.

For native code, when Visual Studio (and WinDbg) is attached, it listens for a specific exception being raised, with specific information in it.

struct VS_THREADNAME_INFO
{
	DWORD type;
	LPCSTR name;
	DWORD threadId;
	DWORD flags;
};

void SetThreadName(DWORD threadId, LPCSTR name)
{
	if (IsDebuggerPresent())
	{
		VS_THREADNAME_INFO tni = { 0x1000, name, threadId, 0 };

		__try
		{
			size_t s = sizeof(VS_THREADNAME_INFO) / sizeof(DWORD);
			RaiseException(0x406D1388, 0, s, (DWORD*)&tni);
		}
		__except (EXCEPTION_CONTINUE_EXECUTION) { /* do nothing */ }
	}
}

The code above should be pretty self-explanatory. Source: Setting a Thread Name (Unmanaged)

Who is this tutorial for?

December 7th, 2009

I’m currently doing some Windows Workflow Foundation related work. Like every developer I searched the Net for a couple of tutorials and downloaded Hands-on Labs for Windows Workflow Foundation. Quoting straight from the overview found on the website:

These labs are suitable for a .NET developer with 6 months experience who wants to learn about Windows Workflow Foundation.

And now, straight from a document found in downloaded files:

1. Open Visual Studio 2008 by going to: Start Menu | Programs | Microsoft Visual Studio 2008 | Microsoft Visual Studio 2008
2. In Visual Studio 2008, select the menu command: File | New | Project

And this goes on for good 3 pages, with screenshots, just to tell me: “Create a new Sequential Workflow Console Application and rename the default Workflow1 to HelloWorldWorkflow”.

And such gems for developers with 6 months of experience can be seen in most of the dozen of documents included in the labs.

Seriously… WTF? I thought someone with six months of experience (that’s just a bit over one thousand hours of full-time work, assuming a standard 168-hour working month) should have an idea how to create a project. Obviously the person who created this doc has been told to write a certain number of pages and ran out of content. Don’t get me wrong – these labs are quite good to learn the basics, but there’s way too much (20%-30%) padding.

Why don’t just cut down on the padding and make everyone happy? After all, good developers != monkeys.

CComPtr<IDirect3D9> MemLeak Gotcha

November 17th, 2009

Everyone else but me probably has figured this out already, but I think there’s a chance this post will help someone else with this problem, too.

The other day it took me a good hour of guessing and cursing to get this one figured out. I got all cocky and thought: “Who the hell needs to read CComPtr documentation at all?!?”, and wrote this simple piece of code, before it turned out I should have read that documentation first:

#include <d3d9.h>                 // For IDirect3D9 and WinMain
#include <atlbase.h>              // For CComPtr<T>
#pragma comment(lib, "d3d9.lib")  // Add a reference to d3d9.lib for linking

INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	// Check for memory leaks at program shutdown
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

	CComPtr<IDirect3D9> direct3d = Direct3DCreate9(D3D_SDK_VERSION);
	return 0;
}

After you run this under DirectX Debug Runtime, you will get useful information in your Output window in Visual Studio:

Direct3D9: (INFO) :MemFini!
Direct3D9: (ERROR) :Memory still allocated!  Alloc count = 10

One would think that when CComPtr gets out of the scope, it will Release() the COM resource it’s pointing to, and… he would be right. The less obvious thing is – when you assign a T* the CComPtr<T>, the assignment operator calls another AddRef(). The instance passed as a right-hand side argument of the assignment already has a reference count of 1. Therefore, if you assign it to the CComPtr, it will have a reference count of 2. When it gets out of scope, its destructor is called, and only one Release() is called for the IDirect3D interface, and therefore we have a resource leak.

The right way to assign the IDirect3D9 interface to CComPtr<IDirect3D9> is:

CComPtr<IDirect3D9> direct3d;
direct3d.Attach(Direct3DCreate9(D3D_SDK_VERSION));</span></pre>

If you hover your cursor over the Attach method, your trusty Intellisense or Visual Assist will tell you:

void CComPtrBase<IDirect3D9>::Attach(_In_opt IDirect3D9* p2) throw()
// Attach to an existing interface (does not AddRef)

Voila! Exactly what we need! The whole rest of the IDirect3DXxx references can be used as CComPtr<T> pointers. The DirectX 9 API will do the right thing for you. If you just consistently use CComPtr<T> for what it was designed for, you will probably never see a resource leak again. And yes, CComPtr<T> can be used whenever the Direct3D API expects T* as a parameter, even as an output parameter.

Blender, Direct3D, Meshes and You

July 10th, 2009

I’ve spent last couple of days writing a custom mesh exporter for Blender. It all seemed pretty trivial in the beginning (“it’s just conversion of data structures”). It’s easy to iterate over all the faces in the mesh, and then over vertices and then reading their position and normal. Everything seems fine, but there’s a difference in how Blender stores the data, and what format will a Direct3D VertexBuffer accept. Specifically I had two major annoyances.

First problem – flat faces vs smooth faces. If you look at Blender’s Python API Documentation, you will see, that a MFace is just marked as smooth and there’s all to it. If a face is smooth, the normals get interpolated for positions between the vertices. This works the same in Direct3D world. What about flat faces? Well, in Blender a MFace is not marked as smooth and has another attribute – no (short for “normal”). Therefore, if you want to have a flat-shaded face in Direct3D, you have to duplicate the vertices and use their original positions and replace their normals with face normals. This introduces another problem – your exported vertex buffer will have additional vertices in it, which won’t map easily (1-to-1) to the indices Blender has.

Second problem – UV mapping. In Blender you can create a UVLayer. It’s just a set of UV coordinates mapped to vertices in faces. What does Direct3D expect? UV coordinates mapped to vertices… not faces. Blender stores UV coordinates as an attribute of MFace, as list of UV vectors. Notice how a single vertex can belong to multiple faces, and therefore can be assigned a different set of UV coordinates for every face. This means we can’t reuse this vertex in VertexBuffer (or I don’t know a way to do so). Direct3D VertexBuffer will have to hold a copy of this vertex with its original position and normal for every pair of UV coordinates it’s assigned. This again introduces problem of vertex indices not mapping easily (1-to-1) between Blender world and Direct3D world.

The indices problem can be solved by reindexing the newly created vertices and matching them with the faces. Of course that would work, as long as it would be done in a deterministic way (vertices not changing their indices between exports and mesh modifications). And everyone knows indices are needed for the DrawIndexedPrimitive call.

After spending a couple of hours thinking about an elegant solution, I gave up. I’ve decided to go with less elegant, simpler DrawPrimitive calls. So I just iterate over all the faces in the mesh and create vertices as I go – three new vertices per every face. I realize there will be more data to process for the GPU, but I’m just beginning to write my engine and need to make progress. I have more interesting problems to solve at this very moment. After all, I write abstractions for the low-level stuff and can always optimize the mesh later. Using NvTriStrip comes to mind as one of possible ways to achieve that. Or something smart, as I’ll get to know more about Blender and Direct3D.

From C to C# to C++

July 3rd, 2009

It’s amazing, how much computing has evolved in just a dozen years. In 1997 I started learning C, just after I got comfortable with MC680×0 and x86 Assembly. It was natural to think about the data structures in terms of their layout and alignment in memory. It was natural to think about “what will the CPU do if I do that”. It was very natural to think of all these details, to the level of bare silicon. I remember how happy I was when my first inline assembly optimization started working. I remember spending hours with a simple debugger, watching the memory and CPU registers change after every instruction – and I remember enjoying this time a lot. Every little optimization counted, because the resources at hand were very scarce. My PC at that time was a Pentium MMX running at a whopping speed of 75MHz, with 64MB of RAM and S3 ViRGE video card. Can you imagine using one of those today? The code people used to write wasn’t even called “native”. There was no “managed” code yet. The code was just “code”. A couple of months later I started learning C++ and were using the two alternately, whenever I wanted.

Fast forward to 2003, the time of .NET Framework version 1.1. Somehow I have never seriously used Java, therefore C# and .NET Framework was my first “managed” programming environment. I loved C# for its readability and simplicity. There were no pointers and memory allocations that needed to be taken care of. There was no header file mess, everything got neatly compiled. The managed environment took a lot of burden off the programmer, but not without a cost. The programs written in managed code were really resource hungry, which wouldn’t be acceptable six years earlier. The focus was on writing code fast, instead of writing fast code. Of course it had its advantages – I learned quite a lot about real object oriented programming, software architecture, design patterns (well, I learned the names of some tricks I’ve been using, and learned a couple of new ones) and code maintainability. I think I wouldn’t be able to learn that if I were using C++. I worked on semi-enterprise level applications.

I used .NET and C# for six years. Then I decided I needed a change.

Right now I’m re-learning C++, and learning the modern approach to C++ programming (existence of which I wasn’t even aware). The first few weeks were a horror. I couldn’t live without good refactoring tools (Visual Assist X isn’t even half as good as Resharper). I’ve made total mess in my code, because I was used to not having to think about the header files. Class construction worked the opposite way I was used to. Resource leaks in my code were ubiquitous. The C++ syntax caused pain in my fingers. And a couple of weeks later, I still make newbie mistakes I wouldn’t make in C#. And again, I’m enjoying the hell out of my time in front of computer screen, solving problems that would be nonexistent in “managed” code. It’s fun, because again it feels like solving a puzzle. And again, programming till late night is a fun thing to do.

I think everyone should try something new (or old) every now and then. It’s really refreshing.

Besides, all modern games are written in “native” code for a reason…

The Spring Project

April 9th, 2009

A short post, due to lack of time.

I stumbled upon an interesting project while researching frameworks and engines I could use for my game. The Spring Project is an open source 3D RTS engine, which looks pretty extensible, and the screenshots look all right, too. I briefly skimmed over its code, and saw it’s nice and object-oriented – definitely something worth having a look at.

How to get access to MSDN for just 100 USD?

March 31st, 2009

Disclaimer: This post deals with contracts and license agreements. I am not a lawyer, and no parts of this post should be considered legal advice. If you need legal advice, please bring any contract or license in question to a professional and have him interpret it for you.

… Having washed my hands…

Let’s start!

If you’re running a web business, and if you’re looking for ways to save money by getting cheap software, here’s a deal for you. Microsoft is offering startups their operating systems and development tools, as well as production licensing for hosted solutions. All of that for a mere hundred bucks.

Oh, and you have to pay that hundred bucks when you exit the program.

The startup program is called BizSpark.

Where’s the catch?

First of all, only privately held software development companies are eligible for the program. Small print tells you that you have to be developing your own product or a service that will form a core of your business. Next: your company has to be in business less than 3 years, and have less than X dollars in annual revenue. The X is different for different countries: for US it’s a $1,000,000, for China – $750,000, for Greece, Korea, Malaysia, Poland, Russia, Spain and Ukraine – $500,000, for Egypt, Pakistan, Thailand, Turkey and Vietnam – $250,000. If your company is in a country that’s not on the list, consider yourself lucky, because your revenue has to be less than $1,000,000. So far, so good, right?

The real catch is here: you must be also developing a new “software as a service” solution… on any platform. That’s right, you may be as well running on a LAMP stack, using Ruby on Rails, or programming in Django – you are still eligible. Why is that? I am not sure. I am guessing Microsoft just wants to increase awareness of their development tools, without pointing a gun at anyone’s head – I am not a lawyer, but I couldn’t find any catches in the contract. It looks like in the end you don’t even have to develop a web solution using their technology. This seems fair to me, considering there’s a bunch of free options to choose from (think: a multitude of Linux distributions). Also – if I’m working on a website, I have to make sure that it looks fine in Internet Explorer, and I can’t get it for my Mac or my favorite Linux distro, right?

A Microsoft employee has been contacted and asked about this program. So far, my interpretation has been confirmed by him.

My experience with BizSpark

I enrolled in the program a couple of weeks ago, and I am using software I downloaded from MSDN. The registration process is very simple – you have to find a “network partner”, you have to contact him providing basic information about your company and confirming that you’re eligible for the program. The partner sends you a registration link, which you use to create your account. A couple of hours later you may enjoy your MSDN subscription (operating systems, Office system, development tools, Expression tools, SQL Server, and others).

Exiting the program

Three years after registration, or when your annual revenue exceeds X dollars (see above), you automatically exit the program. You will be sent an invoice for $100.00, and will lose access to MSDN downloads. If you’d be using BizSpark production licenses, you’d have to switch to another type of license (buy the software you need, or go with SPLA). Frankly, it shouldn’t be very hard when your revenue exceeds X. If I understand correctly, your operating system, office and development licenses will still be valid.

What about game development?

For some reason at first it didn’t click in my mind that this software could be used to develop an online game (e.e.: Internet RPG, Internet RTS, Internet FPS) or a game that has online elements (e.g.: a client to puzzles downloaded from the net, or a game with a shared online high-score board).

What is this blog about?

March 30th, 2009

This blog is about game development and web development.

I think I have quite a lot of programming experience, yet I have never released any complete product on my very own. Playing computer games has always been one of my favorite pastimes, so I figured – why not create games? This blog will document the experiences throughout the entire process – working on ideas, developing games and finally selling them. This should be quite interesting, as I don’t have much background in game development – only some in Direct3D and OpenGL.

Web development is what I have been doing for a living. I worked with two companies that developed web products and services. I have a couple of years of experience here, so every now and then I will post about the web projects that I work on.

I have quit my full time job and decided to focus on growing my one-person company. Therefore, I will post about things that may be of interest to the likes of me – budding entrepreneurs. Hopefully, this is the beginning of a long-lived undertaking.