# Is hacky code allowed in industry?

This topic is 1535 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I find myself doing something like this alot. Basically setting a condition to false to avoid the if block from running more than once.

If I do not turn it off, the mushroom will keep appearing.

The hacky code is isHit = false;

Given a update method that constantly get executed from the game loop in this pseudo code.

[code]
public class Mario{

public void collide()
{
Block.setHit(true)
}

}
[/code]

[code]
public class Block
{
public void setHit(boolean hit)
{
this.hit = hit;
}

public void update(long milliseconds)
{
if(isHit)
{
// hacky code
isHit = false;
Mushroom mushroom = new Mushroom(50,50);
}

}
}


So my question is: is hacky code allowed in the industry?

Do industry professionals or game developers use hacky code in their game code?

I always found hacky code to fix all the bugs in my game and let me progress faster in my game development process.

Edited by warnexus

##### Share on other sites

There are kludges in any industry, though with varying degrees of frequency. The question isn't whether or not they exist but why they happen. I've only done games as a hobby, so I can't comment much on patterns for that industry, but my experience with them is that a kludge happens when deadlines loom, developers gloom, and project managers give out ultimatums of doom. In general, a kludge is a sign that either your design isn't working, you don't understand how to work with your design, or you're in a very funky context. The last one being rather uncommon.

Given that Mario.collide is calling a method on Block, is there some reason you can't have Block.createMushroom or Block.collide(thingHittingMe)? Does it need to be in update for some reason? An event makes more sense to me than an update loop for a context like this--the collision happens once at one moment and really only needs to fire off, "Hey, I've hit something!" to the interested parties (usually those involved in the collision). It's a lot cheaper than every few milliseconds, "Am I hit? Am I hit? Am I hit? I'm hit! Am I hit? Am I hit?"

##### Share on other sites
I interned at Microsoft and before I could commit my code to the master code repository other people had to review it and they would point out anything I did poorly. They would sometimes suggest alternatives but other times I had to fix it up myself. I realized that many times I would to a hacky solution more because I didn't want to take the time to find a better solution but in the long run you save time by making good design decisions for more elegant solutions. Hacky solutions usually are parts of more bugs later on. If it is allowed will depend on where you work but as I a rule of thumb I think it is good to avoid the hacky solutions, with the possible exception of if you are working on a prototype that you will throw away later.

##### Share on other sites

It depends how close you are to a deadline

If the game has two months of work left before it's finished, but the publisher wants to see a working/finished version of the game in two-weeks, then all sorts of horrible looking "duct tape" code starts appearing, which may work for now, but is barely managing to hold itself together!

##### Share on other sites

Hacky code is frowned on and there are code reviews and code style guidelines to try and prevent it.  However hacky code still gets through.  In the games industry you are likely to find a lot more hacky code than anywhere else though because most games code is throwaway code.

##### Share on other sites

Depends on where you work entirely, and the general stress level. Good programmers would rather fix stuff like that properly, but management and/or reality may disagree about that priority.

IMHO hacky code is OK if it's used as a stepping stone. Actually, many times I've found that adding a lot of hacky dependencies allows you to use the resulting code smells as a guide to find the architecture.

Agree on this one, if I can't immediately see a clean solution I may start out with a hacky one and then refactor it later once it becomes clear exactly how the related code meshes together. (Or I don't even start implementing it until analyzing it further. Starting to code when you don't know what you're doing is a major time waster.)

Edited by Petter Hansson

##### Share on other sites

Hacky code is not allowed, but when there are deadlines is tolerated. I think that sums it pretty much.

I'm actually working in a product for a client and from time to time he asks for some more functionalities. It happens that if I would go the safe route and take my time to design proper and clean code, my clients go hunting me constantly asking for progress and they go with a bad feeling about my services. If i do hacky code, I deliver much faster and they say ohh you are very productive, but its obviously a trap not only for them but for myself. What happens is that after two or three updates, code gets messy and difficult to modify and even understand after some time since its writing, you already know the story. What I do now is to clean an even rewrite those hacky lines of code only after delivering even when they dont expect a second release. Its more work for me but with this I get saved from the chaos, they get a free update and the code is ready for being upgraded with more functionality if the client requests it.

##### Share on other sites

If you’d taken all those times you ran away from proper design via hacks and instead took the time to do it right, the easy solution to the problem you suggested would be obvious to you by now. Every time you use hacky code you miss out on a chance to learn. Remember that.

I will bear in mind. Wow! Thanks for the truth about hacks.

##### Share on other sites
I have seen something similar to what you are referring to as a "hack" many times in the software development industry. I am not sure if this is the official name for it, but at my job we refer to it as a "latch". It is usually used to stop normal functionality when the form "IsLoading" or something of the sort.

##### Share on other sites

Where I work, hacky code appears:

- When the programmer is not experienced enough and/or does not care enough to write good code.

- When the system has already been implemented (with nice, clean code) and the product managers decide to drastically change it close to a deadline.

- When a programmer leaves the company without documenting his systems and another programmer is told to make changes to the system close to a deadline.

##### Share on other sites

Sometimes you need hacky solutions for bugs that are out  of your control. Yesterday I fixed bug where new Apple A7 chip renderered pure black if there were shadow receivers but no casters with horrible kludge where I render small sub pixel size triangle to center of shadow map. This fixed nasty bug just before deadline.

##### Share on other sites

Your collision callbacks should be more robust. You should have OnCollideEnter, OnCollide, OnCollideExit. Enter and Exit will only ever be called once per collision with a given object. OnCollide would fire each frame. This way you can put your mushroom creation in the OnCollideEnter so it's only called once per collision.

Who cares if the industry allows hacky code. You should try to not make it hacky if possible. If you don't have control over your collision library and it doesn't support the enter/exit thing then you have to do what you have to do to make it work. It just so happens that you picked a path that is a little wasteful.

I always found hacky code to fix all the bugs in my game and let me progress faster in my game development process.

This is another way of saying you get lazy. It's not the end of the world. We all get lazy in different aspects of our lives (even football players who get paid millions sometimes "take plays off"), but it's important to know that's what you are doing (if it's a hobby project). Don't deny that fact or try to justify it in any way.

##### Share on other sites

When the programmer is not experienced enough and/or does not care enough to write good code.

No! I do not want to be that guy. Okay. I am def going to have to find a better way soon enough. This is the toughest part.

##### Share on other sites

The amount of hacky code in professional game code depends entirely on how strict the team's leaders are. I've been on teams where every bug I fix seemed to be the result of some hack, and I've been on teams that are very strict with code reviews and would not allow hacks at all. Generally the latter teams had better products commercially and critically than the others.

Deadlines and laziness generally are the main causes for hacks. On my current team, the only acceptable time for a hack is right before going into certification, and only if it's a localized targetted fix where the proper solution (which we also have prepared) would require extensive testing since the fix touches many game components. Generally the process there would be to send the hack (after testing) through certification and testing the proper fix extensively while waiting to hear back from first parties (Sony/Microsoft). If there are bugs preventing certification we would evaluate our testing on the proper fix and include it in the next submission. If the games are certified with the hack, then so be it.

##### Share on other sites

This is another way of saying you get lazy. It's not the end of the world. We all get lazy in different aspects of our lives (even football players who get paid millions sometimes "take plays off"), but it's important to know that's what you are doing (if it's a hobby project). Don't deny that fact or try to justify it in any way.

Interesting statement. I will come up with a better design to avoid hacky code or latch. Thanks.

##### Share on other sites

I wrote some hacky code back when I was prototyping the rendering part of my engine out - just trying to get stuff together and render some meshes on the screen..

well I forgot to go back and fix it..

3 months later certain types of meshes would scale and rotate what seemed in a random fashion - took 1 week to find my problem - took about 30 mins to rewrite the bad code...

so - I think most of the time it pays to take the 30 mins rather than the week

##### Share on other sites

Given that Mario.collide is calling a method on Block, is there some reason you can't have Block.createMushroom or Block.collide(thingHittingMe)? Does it need to be in update for some reason? An event makes more sense to me than an update loop for a context like this--the collision happens once at one moment and really only needs to fire off, "Hey, I've hit something!" to the interested parties (usually those involved in the collision). It's a lot cheaper than every few milliseconds, "Am I hit? Am I hit? Am I hit? I'm hit! Am I hit? Am I hit?"

I'm faulty of going that road too, very often. I have a post-it on my left screen (coding screen) that says exactly 'use events!' and it helps.

As for, is it acceptable in the industry: not really.

Does it happen?: All the time!

The thing is, no client (whether it be internal or external) will flat-out say that it's acceptable to code cheaply. They all want quality for cheap, but only some of them actually have realistic budgetary estimates.

Then you need to account for the quantity of change of direction during production, how late it happens, etc.

These tend to lead to hacky code appearing in the codebase. The technical debt increases, and through escalation of commitment, it gets more and more ignored (and not refactored).

As an 'indie developer', I give myself a guideline that goes as follows:

Code 5 days.

Refactor 1 day.

Take 1 day off.

During the 5 days I develop, I try to make things as 'fast' as possible.

During the refactor day, I take all the things I've done and consider how to make it more efficient, cleaner, etc. I break longer functions into smaller ones, fix my encapsulation usage of local vars, etc.

No later than yesterday, I've fixed a problem exactly like yours (occurring in an onEnterFrame loop and using a hacky Boolean to make sure it happens only once). It was taxing my loop unnecessarily and I switched that to an actual Event.

Whether it ends up being acceptable or not, I think you should aim at being able to avoid it, so that when given the time, you are able to code cleanly. The idea is that, if you're not rushed early in dev, you'll be able to do a clean codebase and keep relatively the same velocity over time.

##### Share on other sites

I recently was faced with a bug which was pretty annoying:

periodically, all the point-light sources would momentarily fail, causing the scene to periodically go into full darkness.

long story short, eventually figured out that it occurred whenever the shadow maps were being redrawn (basically redrawing the scene via FBOs and a cube-map), but would fix itself whenever the scene-visibility was re-evaluated (via occlusion queries).

spent a while trying to figure out just where/how the OpenGL state was getting messed up here, but couldn't locate the issue.

eventually, I just hacked it, so that the shadow-maps would always be redrawn prior to re-evaluating visibility (rather than afterwards), which fixed the issue (even if the actual cause of the bug was not determined).

better still would have been to try to properly hunt down and eliminate the bug though.

##### Share on other sites

What's "hacky" about your code?   You seem to have a requirement that collisions with a block should power up a mushroom only once, and have implemented it as such.

Edited by Snovi

##### Share on other sites

The "hacky" part is that it's wasting cycles by checking an if statement on every update or a block. The more block objects he has in his level the more wasteful his code becomes. This situation in itself isn't the worse but if he does things like this all over the place it could add up. The better approach would be to have an OnCollisionEnter() for Mario which gets called once and only once per collision. Then inside this event create the mushroom. It's more efficient.

##### Share on other sites

I tend to think about implementation details in terms of the mechanics of the game. Your example suggests a mario clone sort of block triggering powerups. From that perspective, you need to first think about what the mechanism for triggering the blocks is going to be. Simply colliding with the blocks is too low level of a mechanism with which to trigger the spawning of the powerup. You want mario to trigger the powerup when he jumps upward into the block and collides, and also if the game has the power drop thing that allows you to smash down from a jump with it. Because the triggering of the blocks should be dependent on the type of action that is being performed, it would make more sense to generalize these activities within the state inside the Mario object class, such that when you jump up into something, or smash down onto something, you are calling functions that provide that context, and the objects being hit can respond accordingly.

Some example pseudocode

enum HitFeedback
{
FEEDBACK_NOHIT,
FEEDBACK_HIT,
};

class Mario : public GameObject
{
void collide( collisionevent )
{
HitFeedback hit = FEEDBACK_HIT;

// assuming -z is down
if ( collisionevent.normal.z < 0.5 ) // did we jump up into the object?
else if ( collisionevent.normal.z > 0.5  && IsSmashingDown()  ) // did we fall down into the object in the smash down state?
hit = collisionevent.otherObject.SmashDown( this );

if ( hit == FEEDBACK_HIT )
// handle landing on slopes or ground to change state to walking, etc
if ( hit == FEEDBACK_NOHIT )
// allow the character to continue its current physics state, if flying, keep flying, if smashing, keep smashing
}
}

// Then your various other game objects can easily implement responses to the game mechanics available by your player

class BreakableBlock : public GameObject
{
void HeadSmashed( Mario & player )
{
Break();
return FEEDBACK_HIT;
}
void SmashDown( Mario & player )
{
return FEEDBACK_NOHIT; // so that mario can continue smashing down a column of breakable blocks
}
}

class PowerupBlock : public GameObject
{
void HeadSmashed( Mario & player )
{
// implemented via a state as it likely involves playing an animation and isnt just an immediate spawning of the powerup
ChangeState( SPAWN_POWERUP );
return FEEDBACK_HIT;
}
void SmashDown( Mario & player )
{
ChangeState( SPAWN_POWERUP );
return FEEDBACK_HIT;
}
}
class CoinBlock : public GameObject
{
void HeadSmashed( Mario & player )
{
if ( mCoinsRemaining > 0 )
{
--mCoinsRemaining;
if ( mCoinsRemaining <= 0 )
ChangeState( DEACTIVATED ); // animate, disable callbacks, etc
}
return FEEDBACK_HIT;
}
void SmashDown( Mario & player )
{
}
}

class Turtle : public GameObject
{
void HeadSmashed( Mario & player )
{
// hitting a turle from below is damaging, and should probably be treated as solid
return FEEDBACK_HIT;
}
void SmashDown( Mario & player )
{
ChangeState( FLIPPED_OVER );
// add some small velocity so the turle gets knocked to the side a bit from where mario smashed down
return FEEDBACK_NOHIT; // so that mario can continue smashing down to the ground
}
}



Implement things with respect to game mechanics, and not so much the low level functionality of collision, physics, sound. Those low level systems will often be intricately tied to the function of certain mechanics. In marios case there will be some degree of complexity in interpreting the physics and collision information into a way that gets the actual game mechanics working as you want, but most of those details would ideally be encapsulated into the objects where it matters, such as your Mario class in a simple implementation. The game objects can provide some amount of hit information back from its callbacks such as in this case, so that the type of object can propagate back and effect