Hey all,

Before I start, in case you haven’t seen my game yet, it’s here:

Now, since 99% of the comments on my entry revolved around the fact it’s written in batch, I thought I’d put a small post about the game’s (or actually engine’s) architecture.

Before you run away to the next post:

– Most of this post isn’t really about batch, I believe many concepts here are relevant to any engine/language/game.

– However, since the game was written in batch, I will talk about some batch-related stuff. Skip them if you like.

Funky Batching

Well, the only thing you can really do in batch is execute simple DOS commands… WRONG!

Using some amusing techniques, you can:

– Create Functions. (The downside being a performance drop)

– Split your code into modules. (An even bigger drop)

– Parallelise your code. (If you execute two or more scripts at the same time using pipes, each will be interpreted by its own cmd.exe)

Basic Structure


Let’s go through the execution step by step:

Initialization: Basically here I create all objects (player, NPCs, walls etc.) and set global variables such as the screen size.
After everything is set, three modules are being started in parallel: The input module, the main logic loop and the display module.

Input: This is an infinite loop using the “choice”  DOS command for getting input from the keyboard and then writing it in the file “input.tmp”.

Display: This is also an infinite loop clearing the screen and using the “type” DOS command for printing “display.tmp” on the screen.

Logic: This infinite loop contains the core logic of the game. It reads the input from “input.tmp” executes a single game-step (moving things, playing/stopping animations etc.) and renders the result to “display.tmp” with the generous help of the rendering module.



 1st Attempt:



Well, that was the first attempt, with a single function going through the screen row by row and checking which objects should be drawn. The result would then be added to “display.tmp”.

The solution worked with almost-acceptable frame rate when the world had a total of 4 objects. The finished game has 9.

Something had to be optimised.

2nd Attempt:


Now that looks much better,

Since we’re rendering every row separately, we can actually render them at the same time! Thank you multi-core CPUs!

In this solution, the afore mentioned function is called three times simultaneously, each rendering only a third of the screen into lines*.tmp. After all three are done, the three files are being merged into one: the beloved “display.tmp”.

Rendering time was nearly cut in half!

Unfortunately, As I implemented collision detection, the game slowed considerably, and everything had to be optimised a bit more!

3rd Attempt:



Going through every row, through every object takes a lot of time.
So why can’t we go through the objects first, and check what rows they’re in! (and also store some useful calculations, to save time later).

That means we’re still going through every row, but then we only go through objects that are known to be in the row!

Furthermore, the original rendering function looked terrible at the time, and needed a full-rewrite that probably shaved some milliseconds as well.

Result? Awesome!

Debugging and Profiling

I think that at least half the time writing the game was wasted on profiling and trying to optimise code. Unfortunately MS Visual Batch Ultimate Profiling Tools haven’t been released yet.

The alternative I used was plain old logging, together with basic spreadsheets and it worked quite well!
The fun part was removing all the “ECHO After rendering: %TIME%>>time.txt” before release. 😀

I also had to debug with no debugger. Fortunately, DOS provides the awesome “SET” command that prints all variables. Yes, I had to remove all the “SET >before.set” and “SET >after.set” from the code as well. :)



Well, there’s a reason people don’t write real-time games in batch,
actually, there are a lot of reasons.

I hope you enjoyed the post/the game/the competition, I’d be happy to answer questions in the comments.

My code can be also browsed on github: https://github.com/ashdnazg/ld26

You might want to read my less technical post-mortem here

Leave a Reply

You must be logged in to post a comment.

[cache: storing page]