
Dirty Coding Tricks - LaSombra
http://www.gamasutra.com/view/feature/4111/dirty_coding_tricks.php?print=1
======
dcole2929
That last one about the guy who tucked away 2 extra mb of memory for a rainy
day is one of the most bad ass things I've ever read about a programmer (never
thought I'd say those words). That's next level, old vet, been around the
block a few times, stuff right there.

~~~
netcraft
I came across code in a legacy web application one day, on a page that was
probably the most used part of the application that was really nothing more
than sleep(1000); I went through the version control history and found that is
was a previous employee that would go in periodically and lower it any time he
wanted to act like he had been working - he had started around 3.5 seconds.

Which reminds me of being a kid and mom telling me to turn down the tv - I
would "accidentally" hit the wrong button and turn it way up for a few
minutes, then just turn it back down to where it was.

~~~
3pt14159
If I ever found out someone did this not only would I fire them, I wouldn't
keep it a secret. I'd make sure everyone on the team knew exactly why he was
fired. That is acting is gross bad faith. Think of the time it had cost all
those people around the world just because he wanted a day off here and there.
Blows my mind that someone would do that.

~~~
pc86
I understand where you're coming from, and I agree with you, but we can't
pretend that 1 second from 10,000 people is the even close to the same at
10,000 seconds from 1 person (or really anywhere in between).

The entire concept of "we saved 10 million hours of productivity by shaving
1.8 seconds off this process" is bunk. You saved 1.8 seconds of productivity
_n_ million times, which adds up to not a whole lot of extra productivity.

Put another way: Whether $APP takes 0.1 seconds or 1.9 seconds to do something
does not at all change what time I'm leaving at the end of the day.

~~~
sunfish
User behavior when interacting with a program that responds in 0.1 seconds is
drastically different than with a program that responds in 1.9 seconds; see
[0] [1] etc. I agree it's not very meaningful to just compute the total number
of seconds saved, but on the other hand, the productivity gain could easily be
far greater than what that number suggests too.

[0] [http://googleresearch.blogspot.com/2009/06/speed-
matters.htm...](http://googleresearch.blogspot.com/2009/06/speed-matters.html)
[1]
[http://www.webperformancematters.com/journal/2007/7/10/accep...](http://www.webperformancematters.com/journal/2007/7/10/acceptable-
response-times.html)

------
koala_man
I knew some people who wrote a graphical demo at a small, local demoscene
party. One of their effects had a static, vertical tearing artifact that moved
around based on their parameters but which they weren't able to entirely get
rid of.

One of them noticed that the projector screen that the demos would be shown on
had a vertical splice. He eyeballed the location and tweaked the parameters to
make the artifact line up with it.

No one noticed.

~~~
marcosdumay
My assembly classes at undergrad had a final project consisting of writting a
tetris clone in x86 assembly. Shortly after the deadline, my program had a bug
that made pieces fall up, instead of down, and I was completely unable to find
it's cause...

In the end, I just rewrote the score checker to verify the top of the game,
instead of the bottom, and delivered a game where pieces felt down. Everybody
not just noticed, but I had a line of people wanting to play it.

------
shinymark
I'm Mark Cooke, I wrote the first entry in this article a few years ago. Of
all of them, it's the least related to interesting code, but it does reflect
the reality of the kinds of crazy last minute hacks that can go into shipping
a game.

Unlike many other types of reusable code, this sort of gameplay hack will be
thrown away and won't be used again in a subsequent game. To an extent it
justifies its use in a pinch. But no craftsman is ever happy shipping
something like it.

It has been my experience that at the end of game development projects many of
these sorts of hacks start flying. Most of them are unnoticed by players.

No game is ever perfect. With limited resources and time it's important to
keep in mind what players care about and focus on those things. I care deeply
about providing a good experience to players and one of the most interesting
and challenging components of game development is deciding where to apply
resources when under tight constraints to deliver the best experience. I
haven't worked outside the game industry in a long time but I'm sure this is
true in most consumer software businesses.

~~~
barbs
Out of curiosity, what was the game you were working on in the article?

------
dividuum
One of my favorite tricks is this one (I thought I read about it in that exact
collection but it isn't there, so here you go):

 _Back on Wing Commander 1 we were getting an exception from our EMM386 memory
manager when we exited the game. We 'd clear the screen and a single line
would print out, something like "EMM386 Memory manager error. Blah blah blah."
We had to ship ASAP. So I hex edited the error in the memory manager itself to
read "Thank you for playing Wing Commander."_

~~~
Kurtz79
My choice would have been "640K ought to be enough for anybody".

(This will be understood only by those who lost countless hours tweaking their
autoexec.bat and config.sys to squeeze that last KB of memory needed to run
the game they were supposed to spend the weekend playing ).

------
debacle
I always try to explain to people I work with that you can't get away with
hacks at the deadline if you've been hacking from the start, but if 90% of
your system is an ivory tower, it usually doesn't hurt that 10% is a nefarious
back alley.

------
jheriko
That packing the controller id into a pointer, which you couldn't use to point
at a controller id because it gets freed before you can use it?

I must misunderstand something because the hack is going to fail too, except
that you are going to end up with some controller id in your allocator's free
list or some other such nonsense...

That last one is best. After having to struggle and fight for 640k for /the
heart of a renderer/ if someone had left 2MB lying around that would have been
great. Then again so would not using loads of memory for all sorts of weird
and wonderful things that are much less important... like C struct padding, or
making everything into memory pools, before you have any memory problems. :)

~~~
cbhl
You'd probably only need two or three bits to pack a controller id. Depending
on how much memory the system has, and and things like data alignment, you can
find some bits in the pointer that will always have a specific value (say,
zero). Then, you can store the ID in those bits, and mask them away when you
actually want the pointer.

Edit: You probably shouldn't do this in new code, but in the context of
memory-constrained C code it's a nice hack.

~~~
United857
Interesting enough, the current 64-bit ObjC runtime does something similar,
with so-called "tagged pointers".

[https://www.mikeash.com/pyblog/friday-
qa-2013-09-27-arm64-an...](https://www.mikeash.com/pyblog/friday-
qa-2013-09-27-arm64-and-you.html)

------
codyb
Great article. I'm not a game developer but I enjoyed reading about the
constraints they face daily and the solutions they used and how those
eventually backfired. I've always figured I'd never want to be a game
developer but this gave the feeling I might enjoy it a bit more than I think.
Boy, the experience of seeing a fully 3D game run and and run well, that must
feel pretty good.

I really liked the final problem's solution!

Anyways, just rambling a little :-).

~~~
barbs
I totally agree with you. For me, this is what programming is all about -
creative problem solving :).

------
VBprogrammer

      Spurred on by the success of "if A==bad then NOT A", I used this tool to patch several more bugs -- which nearly all had to do with the collision code.
    

This reminds me so much of a developer I work with, why figure out the root
cause when you can throw a try / except / pass around it. If that doesn't work
upgrade a package and see if that helps. If that doesn't work throw in a hacky
fix.

~~~
raverbashing
OMG what about those

They're also the first to blame "GCC/Python/JVM/etc" and saying there's a bug
there.

------
mVChr
Seen this a few times before, but I am always entertained on reread and enjoy
the reminder that sometimes you need a scalpel and other times a sledgehammer.

~~~
ConnorG
Always is a great read. Can't help myself into rereading these stories every
time I see this post.

------
raverbashing
This is a good reminder for the "avoid technical debt" crowd and other
advocates of sterilised development practices

Sometimes the rubber hits the road and you don't have time or money or any
more cognitive energy to understand why your code that calculates a lot of
things from a lot of data is not working in that 0.01% of cases

So you come up with a quick fix that's not exactly what it has to be done but
it works it ships and it pays the bills.

Of course I don't advocate such solutions on critical paths, ate least not
without some double checking.

~~~
nostrademons
You do want to have your _default_ setting be "avoid technical debt", so that
these sort of hacks are just that - hacks. Projects get into trouble when
people do them as a routine matter; they're saved when a project that's
otherwise healthy needs to do something naughty to work around a tricky bug.

~~~
raverbashing
You're right, however, there are two issues.

1 - People "avoiding technical debt" by overengineering.

2 - (As you mentioned) sometimes it's not even your fault that you need a
hack. (It may not even be a bug on what you're using, but just an unfortunate
impedance mismatch, like the Playstation problem mentioned)

------
barbs
Also worth reading is the three-part article by Patrick Wyatt on the issues
encountered whilst developing Starcraft[1], which were a huge factor in its
delayed release. Of particular interest is the path-finding hack they used [2]

[1] [http://www.codeofhonor.com/blog/tough-times-on-the-road-
to-s...](http://www.codeofhonor.com/blog/tough-times-on-the-road-to-starcraft)

[2] [http://www.codeofhonor.com/blog/the-starcraft-path-
finding-h...](http://www.codeofhonor.com/blog/the-starcraft-path-finding-hack)

------
zomgbbq
We once had a game demo that was crashing every time we tried to exit the
game. Inserted an exit(0); in the shutdown code and it never crashed again.

~~~
dbrower
+1. That should always work as an exmaple of "crash only" programming. It's
nice to get shutdown working for valgrind, but it should never be necessary.

------
probablyfiction
Some of these are dirty, but I think the majority are smart hacks in the best
sense of the word, especially the final story about memory allocation

------
GotAnyMegadeth
These seem to come from here [0] which has more and some other general tips.

[0] [http://www.dodgycoder.net/2012/02/coding-tricks-of-game-
deve...](http://www.dodgycoder.net/2012/02/coding-tricks-of-game-
developers.html)

~~~
Lewton
It's the other way around, the gamasutra article is from 2009

------
_mikz
(2009)

~~~
AceJohnny2
Yeah, I was wondering about that. I had certainly read it before, but was
confused about the "Copyright 2015" at the bottom of the page. If you follow
the link to the non-print version of the article you get the real date.

~~~
eterm
Ah ha, I was wondering this too since I've seen it do the rounds before.

The print version is so much more readable with a wider body and no comment
clutter!

------
donatj
I find th CRC collision story rather unbelievable.

~~~
dietrichepp
Most people find this kind of thing unbelievable, which is why they call it a
paradox (the "birthday paradox"). Assuming a perfect 64-bit hash, and "tens of
thousands of files" meaning 20,000 files, the chance of collision is one in 46
billion.

However, if they reuse filenames, then the chance of collision is much higher.
For example, assuming 1000 distinct filenames chosen at random, the chance of
collision rises to about 1 in 10,000.

~~~
FLUX-YOU
You see, shortly after leaving his boss's office and learning about the
hidden-allocated 2MB, that guy implemented his own CRC that would throw the
same hash just before release.

