
Many games are held together by duct tape - misotaur
https://www.polygon.com/2020/1/13/21064100/vvvvvv-source-code-game-development-terry-cavanagh-release
======
rlayton2
Watching speed runners play through games is a great way to visualise not only
this aspect (that games are flimsy at best), but to visualise the same
practice in any software - if you don't code defensively, often a simple mis-
input breaks the game.

A common pattern in many speed runs is finding some glitch through a door, and
then the game logic kicks in and says "you are past this door, so you must
have got the key".

If you are curious, watch the five or so minutes of this speedrun:
[https://youtu.be/0Ct8n1CClUM?t=3072](https://youtu.be/0Ct8n1CClUM?t=3072)
First, the player jumps through a game world, getting to a race he shouldn't
be able to get to yet. Second, he glitches into the "solid" wall, which is
just a thin wall around the racetrack.

~~~
michaelbrooks
Thanks to Breath of the Wild, I've recently enjoyed watching a few speedruns
and it's amazing to see the number of glitches in BoTW. Check this out
[https://www.youtube.com/watch?v=JEtHpCfi_DE](https://www.youtube.com/watch?v=JEtHpCfi_DE)

I also don't understand how anyone can accept speedrunning through glitches as
a world record, but I guess if everyone does the same run with similar or the
same glitches then it's fair? Seems like it just becomes a race to know every
glitch in the game.

EDIT: I just want to say thank you to the replies that explains the mechanics
and categories of speedrunning.

~~~
huffmsa
Playing the meta is part of the game. If you're not loading in other code or
using 3rd party assistance, it's fair.

Understanding the buy strategy in CSGO doesn't make you a "cheater", in means
you understand how to stretch the game to it's limits.

Mike Vrabel taking penalties to burn the clock might seen unfair, but he was
just leveraging the rules as written to improve his chances of winning.

~~~
leetcrew
> Understanding the buy strategy in CSGO doesn't make you a "cheater", in
> means you understand how to stretch the game to it's limits.

the economy in cs is a core mechanic of the game. I don't know of any buy
strategies that are even close to considered "exploits".

a better example would be illegal boosts. in the old days, there were many OP
positions you could get into by boosting on top of other players (or even
throwables in midair). each competitive league would have its own lists of
illegal boost spots for each map. boosting on throwables was almost always
illegal. you could also do stuff like defuse through walls, which was always
illegal.

bunnyhopping was something of a grey area. some leagues allowed it, while
others didn't. it was eventually patched out of the default game settings
behind an svar.

allowing literally anything that didn't involve loading external code would
have severely broken cs:source. there were even ways of replacing assets that
would effectively give you wallhacks without injecting any code. these
decisions always comes down to "how much does this deviate from the balance
designed by the developer?" and most importantly "is the game still fun with
this behavior?"

~~~
retsibsi
All good points, but additionally: sometimes it's good to wait and see where a
glitch takes a game, rather than banning it straight away because it 'breaks'
the version of the game that everyone has been playing so far.

A classic example is the Quake series, where the movement mechanics that gave
the games lasting appeal were all originally accidental. (And Carmack even
briefly patched strafe-jumping out of Q3, before quickly reverting -- but only
because his fix caused other problems:
[https://www.rockpapershotgun.com/2014/09/02/quake-3-john-
car...](https://www.rockpapershotgun.com/2014/09/02/quake-3-john-carmack-
strafejumping/))

David Sirlin also writes well about this sort of thing (with more of a focus
on 'cheap' use of intended mechanics), though his tone could be offputting to
people who think hyper-competitive videogaming is a bit silly:
[http://www.sirlin.net/articles/playing-to-
win](http://www.sirlin.net/articles/playing-to-win)

~~~
leetcrew
I totally agree. "skiing" in tribes is another classic example. fun mechanics
take priority over everything. after all, it's a game!

as an aside, strafe jumping is pretty similar to bunnyhopping in cs, probably
because the source/goldsrc engine had its roots in quake code. I brought it up
as a grey area. it's a fun mechanic, but timing is really important on cs
maps, and it definitely breaks the balance on some of them. personally I think
it was a mistake for valve to patch it out of the vanilla game (leagues, 3rd
party servers, and matchmaking could have just disabled it through the svar),
but that's all history now.

my main point is that the mere fact that games take place in virtual
environments doesn't make whatever the client/server permits the ultimate law
of the land. just like in real life, the rules of the game are the
intersection of what's possible and what's fun.

------
kelvin0
Ex-Game dev here: shipped many titles on console (AAA and some zzz titles).

When comes time to shipping a game, the crunches, pressure and overall stress
is through the roof. Most everything goes at that point: duct tape, hot glue,
bobby pins and toad spit. And if you disagree with management over these 'not
so best practices' (in order to ship faster...) they will find someone to do
it and you could be out of a job.

That being said I would not trade my time in that industry for anything else.
It's basically the BUDs of programming (of course I'm biased)

Good times!

~~~
tartoran
What does BUDs stand for?

~~~
kelvin0
[https://en.wikipedia.org/wiki/United_States_Navy_SEAL_select...](https://en.wikipedia.org/wiki/United_States_Navy_SEAL_selection_and_training)

Basic Underwater Demolition/SEAL (BUD/S) Training

------
hopfog
I run a small MMORPG and I'm considering open-sourcing the whole thing but the
code is a complete mess. The source code of VVVVVV is a work of art in
comparison.

What holds me back are 1. I'm ashamed to reveal the monstrosity 2. I'm afraid
the code is too messy for anyone to be able to make contributions 3. it will
make it much easier for hackers to find exploits.

It's a shame because I think the game would be really cool as an open source
project.

~~~
nkrisc
Messy code that produces a valuable product is better than beautiful code that
does nothing.

~~~
dleslie
Or worse, the pursuit of beautiful, well-tested, aesthetically-pleasing code
that is never finished and never shipped.

------
angarg12
Anyone working in the industry knows that the fact that software works at all
is flabbergasting.

------
CoolGuySteve
As a counterpoint, the Quake -> Quake 2 -> Quake 3 original open source
releases are remarkably clean. Quake 2 in particular is very minimalist and
the game was developed in something like 10 months.

Granted, it's not really fair to compare anyone to the id software team of the
time. But the requirements of the Quake series, basically a BSP renderer that
is easy to modify and extend, probably forces it to be extensible and clean.

~~~
perseusmandate
The fast inverse square root algorithm Carmack invented for Quake 3's lighting
is the definition of elegant code

[https://en.wikipedia.org/wiki/Fast_inverse_square_root](https://en.wikipedia.org/wiki/Fast_inverse_square_root)

~~~
xsmasher
It's EFFICIENT, but it's the opposite of elegant. If you looked at the code
you would have no idea what it is doing or meant to do.

Elegant code should be simple, readable, and apply some leverage to make a
difficult problem more clear.

------
whytaka
A friend of mine in gaming though had an insight I found illuminating. The
difference with games though is that there’s often an element of “One and
Done” in that unlike much of web development, the starting from scratch for
the next generation is more of a given. There is less need for long term
support as games are expected to meet its twilight much sooner. With web
development however, it is a regular risk assessment and there must be a true
meeting of minds to decide that a rewrite is worth it.

~~~
rgoulter
> There is less need for long term support as games are expected to meet its
> twilight much sooner.

I think this is true for the majority of games.

But I wonder if it remains true for the most successful.

e.g. GTA V released in 2013. Apparently as of 2018 it saw $6B in revenue.
Though, surely a lot of this has to do with the new content they introduce to
incentivize microtransactions.

Fortnite was a paid early-access game in July 2017, but had a free-to-play
battle-royale mode by September 2017. Minecraft came out of beta in 2011.

I can agree with "just ship it, quality of code is not a concern" for an
initial release. I wonder how much bad code affects big and successful
products, though.

e.g. Ubisoft's Ghost Recon Breakpoint was very buggy, even though it looked
like an iteration on the Ghost Recon Wildlands game just two years earlier.

~~~
SmellyGeekBoy
I'm not sure about the others but Minecraft's code was notoriously bad for
years, but it didn't seem to hold it back.

~~~
mcphage
Honestly I think the bugs _helped_ Minecraft—bugs in the terrain generation
made for interesting scenery that was popular to share, and bugs in the
multiplayer code helped build the community as people shared how to get things
like minecart tracks to work.

------
phn
I think code quality is important, and big studios make a buck on having clean
and workable code they keep improving over time.

That being said, and especially on indie games like VVVVVV, hammering in a
cool little detail gives the final product much more value than having clean
code.

That's why big engines with mature coding patterns sometimes are not the way
to go to make a cool little thing. Making novel mechanics (e.g. time reversal
in Braid, or the super tight controls of Super Meat Boy) with an existing
engine, while possible, would probably be a PITA.

The "hackability" of the engine you use can allow you to be more creative,
even if a bit messy to maintain.

Back in the days of flash, I'd probably use a simple display list engine
(flixel comes to mind) to do the heavy lifting, and hack away with those basic
building blocks.

Nowadays, I was surprised by the relative hackability you get with godot[0],
while still being able to tap into what you can call a mature engine. If you
like to make small games, you owe it to yourself to check it out.

[0]: [https://godotengine.org/](https://godotengine.org/)

------
Cthulhu_
Writing hacky code can be liberating though. I really enjoyed hacking together
things in the pico-8 last year. Globals? Fine. Neat function names? Nah.
Variable names? 'a' will do.

------
seanalltogether
Wow a 3440 line switch statement for processing game state!

[https://github.com/TerryCavanagh/VVVVVV/blob/master/desktop_...](https://github.com/TerryCavanagh/VVVVVV/blob/master/desktop_version/src/Game.cpp#L605)

~~~
_the_inflator
And it works! I learned a lot about preventing magic with this here:
[https://gameprogrammingpatterns.com/state.html](https://gameprogrammingpatterns.com/state.html)

For me - and I mostly do frontend apps now - I always advise to go for state
pattern instead of complex if/thens. Thanks to the aforementioned article.

~~~
lzralbu
Does Redux help with things like this?

~~~
davidkpiano
If you have enough discipline, sure. Finite state machine tools like XState
are more strict about this.

------
_def
When you are making a game, priority number one is always that you are indeed
making a game, and not how.

(substitute "game" for anything you want to do)

I love elegant code, but in the end it's never _more_ important than the game
itself.

~~~
tartoran
Sure this goes if you're a one man team. But the more people share hacky code
it quickly can turn into a nightmare to work with.

------
cryptica
This is very true. I created an open source framework to help developers build
scalable real-time systems and I tried to focus on multiplayer games at one
point; I thought it would be a good idea to ride the wave of web-based
multiplayer .io games by targeting those developers but I ended up realizing
that they're better off just using raw WebSockets. My framework could only
help in terms of producing the initial prototype.

The profit margins on ad-sponsored web-based multiplayer games are paper thin.
They don't care about code structure or cleanliness at all. If someone can
make fugly code that performs 10% better, that can make the difference between
a profit or a loss or it can mean doubling profits/earnings from the game.

This is very different from most software businesses where even a solution
that performs 10x worse is still acceptable if it makes for cleaner code that
is easier to maintain and can handle changing requirements better.

Micro-optimizations and clean code are mutually exclusive IMO. Like for
example, people may be tempted to send JSON objects with nice descriptive
properties like 'direction', 'keyCode', etc... But in the end it's faster to
just send a raw string or binary packet without any property names; just pass
raw integers directly in a certain order and the receiver decodes the message
assuming a certain order. This is extremely inflexible at the protocol level
but it performs really well (I.e. you can't easily add new properties later or
make some of them optional without breaking the current protocol).

------
benologist
Games, websites, and everything else - both Apple [1] and Dropbox [2] got
passwords wrong in the last decade. I am in awe of the NASA programmers who
have virtually no bugs [3].

[1] [https://www.theguardian.com/technology/2017/nov/29/macos-
hig...](https://www.theguardian.com/technology/2017/nov/29/macos-high-sierra-
bug-apple-mac-unlock-blank-password-security-flaw)

[2] [https://www.cnet.com/news/dropbox-confirms-security-
glitch-n...](https://www.cnet.com/news/dropbox-confirms-security-glitch-no-
password-required/)

[3] [https://www.fastcompany.com/28121/they-write-right-
stuff](https://www.fastcompany.com/28121/they-write-right-stuff)

~~~
matthewbauer
I think you may not realize how many bugs NASA programmers are making. For
instance, see the fairly simple mistake made on Deep Impact spacecraft:

[https://en.wikipedia.org/wiki/Deep_Impact_(spacecraft)#Conta...](https://en.wikipedia.org/wiki/Deep_Impact_\(spacecraft\)#Contact_lost_and_end_of_mission)

There are no doubt more, that don't cause the loss of an entire spacecraft.

~~~
jlangemeier
Every time I see "Deep Impact" in the context of NASA I end up thinking of the
Climate Orbiter; where, due to an issue with unit conversion between metric
and SI they turned it into the most expensive lawn dart to ever leave the
solar system.

------
ChikkaChiChi
I'm sure there are oodles of creators out there who hold back their source
code because they don't want to deal with being shamed. We should be using
these opportunities to learn and grow together, and not as a soundboard to
feel good about how much better we are than someone else.

------
rglover
Someone posted this talk by Johnathan Blow on a story a week or two ago and it
seems worth sharing here:

[https://www.youtube.com/watch?v=pW-
SOdj4Kkk](https://www.youtube.com/watch?v=pW-SOdj4Kkk)

------
this_is_not_you
I've never thought about it but it makes a lot of sense. Just thinking about
the few times I had to write some hacky code to get something to work and
given the complexity of video games it is kind of expected.

------
huffmsa
This I what made the 1990s era games so full of non-critical bugs AKA
"glitches".

The ceiling of complexity was raised waaaay over that of the previous
generation of tech, but the techniques used by developers didn't advance
nearly as far.

So you have a lot of _if this value == this number, load this scene_ (OoT) or
_if this value is greater than this limit, cycle it back to the lowest
possible value of the range_ (Civ, Nuclear Ghandi)

Now, bugs in big games tend to be critical crashes because the tooling and
techniques have standardized and caught up to the complexity ceiling

------
rafaelvasco
It's interesting to see how duct taping a game inside out can result in
absolute success once you ship something valuable. It can be really thrilling
and you can get away with it specially if you're working alone, which for me
is the best work. It's another story entirely if you're on a team, coding
together a product that must be maintained and improved for years. I work on
both sides, and I can say that I only have real fun when I'm coding alone.
Though learning to work in team is a great skill as well. I'm specially
careful with code architecture and readability, but sometimes when you're on
the flow, the zone, the code just flows as well;

------
tluyben2
So is almost every other piece of software. I would like to see an analysis of
commercial closed source software on how many of then use good practices, have
clean code etc. Not the ones that filled in the [] we y use TDD in the CIO
monthly questionnaire. Maybe I meet the wrong companies I have to work or
integrate with, but in my experience it is not very far from 0% (but it is >0
luckily). I met one company last week who do everything right, but only for
projects over 500k where over 10% goes into those practices, otherwise there
is simply no money for the overhead...

------
uncle_j
The code sample they have there that is "messy" doesn't look that bad to me.
The reality is that almost all the code that runs lots of important things is
a complete spagetti.

------
ken
> “Games aren’t just an ordinary piece of software, they are a complex beast
> that require many different disciplines to successfully ship, and often on
> timelines that require sacrifices to be made,” said game developer ...

Is this any different from any other type of software? What is this "ordinary"
software that doesn't require different disciplines, or have timelines?

~~~
xsmasher
It's not the most complex or hardest kind of software, but it does have
special concerns.

Dates are huge; you have to have a good E3 demo, and you (often) have to ship
in time for Christmas. These dates can not slip.

There's also a lot more art / interfacing with artists / art tooling and
collaboration than a typical software project.

------
jayd16
The real differentiation to games from most other software is just how little
correctness actually matters. It arguably doesn't matter at all as long as it
doesn't produce feel bad moments lost items or lost progress.

------
hawski
If AIs of today make a heap of code (if you say it's data, I say data is code
is data) that is really a spaghetti of a code that happens to seemingly
achieve a goal, maybe game developers are already a bit like that ;)

------
cr0sh
VVVVVV's code is still better than the source code of Descent - holy hell, was
that codebase a mess in areas, and virtually no comments in the complex parts
of the 3D engine...

------
dang
Related from a few days ago:
[https://news.ycombinator.com/item?id=22011358](https://news.ycombinator.com/item?id=22011358)

------
mylons
change games to software

------
braythwayt
Nit:

I wish people wouldn’t mention programming and computer science in the same
essay, unless it’s something very technical such as discussing synchronization
algorithms.

Most programming isn’t science. Most programming isn’t even engineering. Most
programming is contracting or DIY tinkering.

We use ridiculous metaphors like constructing an airport, when most
programmers are tradespeople working on renovations.

Have you ever inspected the work of a tract house builder? It’s awful and
usually plays fast and loose with building codes.

When an indie teaches themselves to code, we get the same result as a
homeowner teaching themselves to renovate. That’s not a bad thing, but nobody
swapping ordinary outlets for outlets with USB-C ports is thinking about
Maxwell’s equations.

~~~
petermcneeley
Nit:

Actually most programmers I know are vastly intellectually overqualified for
their jobs. We are talking like science PhDs.

It's not "tradespeople working on renovations" it's more like rocket surgeons
making mud huts.

~~~
huffmsa
Sounds like they were mislead as to what their career prerequisites were.

Or we're just churning out too many Phds

~~~
AstralStorm
Specifically job requirements are incorrect. Which big companies have figured
out and are hiring for cheap in China and India.

~~~
petermcneeley
Is that really whats happening? The way I see it is the old guys without even
degrees worked on higher quality code than their younger counterparts with
increasing levels of education.

I think the issue is probably touched on by something like " bullshit jobs" by
David graeber

------
misotaur
To be fair,everybody in web development knows the same thing is true for the
internet.

~~~
joshstrange
s/web/software/

s/internet/everything/

I can't tell you how many times I have to reteach myself this lesson. I'm not
advocating for writing sloppy/bad code on purpose but I fall into the trap way
too often of trying to make my code a work of art or overly-clever. No one
cares, don't spend twice the time to try to abstract something within an inch
of its life. Write working code and move on. Once you've done something 4, 5,
10, 15 times then you can look for an abstraction.

Really I think I use refactoring or "stressing over the best way" really to
just be a way to procrastinate and tell myself I'm doing something useful or
dare I say noble. Of course in practice it's often neither.

~~~
cjfd
Sounds more like too little care rather than too much. Of course it also
depends on how much maintenance is going to occur on that code. I think in
production code one should already look for an abstraction if something is
done twice. The goal is not to create a work of art or an abstraction that
stands the test of time. It is just to remove some duplication, distribute
code a little better over functions, give things names that are somewhat
better and so on. If one does a bit of that every day one is never going to be
in a horrible mess. One problem is that people sometimes think that
refactoring is all or nothing. You either refactor nothing or you go all the
way to adhere exactly to design patterns. Neither of these two extremes
produces very good code. The middle way is where the good code is.

~~~
pure-awesome
I used to think that if something is done twice, it should be abstracted.

Now, I'm a bit more careful. There's a pretty famous quote by Sandi Mentz:
"Duplication is far cheaper than the wrong abstraction."

[https://www.sandimetz.com/blog/2016/1/20/the-wrong-
abstracti...](https://www.sandimetz.com/blog/2016/1/20/the-wrong-abstraction)

Make sure that you're picking the write way to think about the task at hand,
rather than blindly following DRY.

There are times when even a single instance of a code call would be made
clearer with abstraction, and there are times where having the same piece of
code duplicated multiple times (or duplicated with one piece changed) is far
clearer than trying to abstract it.

This Reddit Comment also has an interesting take:
[https://www.reddit.com/r/programming/comments/5txp5t/duplica...](https://www.reddit.com/r/programming/comments/5txp5t/duplication_is_far_cheaper_than_the_wrong/ddq5ykf)

> The main purpose of abstractions is not to remove or reduce duplication, and
> not even to make code "reusable"; it is to make semantic patterns and
> assumptions explicit and, if possible, first-class.

The further comments provide more discussion.

\---

I agree with the rest of your comment that refactoring and code-cleanup should
be done in pieces and that, as with everything, striking the right balance is
key.

~~~
cjfd
If there is any article that I absolutely hate it is 'Duplication is far
cheaper than the wrong abstraction'. A somewhat minimal abstraction has very
little chance of being wrong. And if it is wrong, is it really that difficult
to know? It has a chance of needing some improvement, but what code does not
have a chance of needing some improvement? If one goes the full monty and
introduces three design patterns every time that two lines are duplicated
sometimes one will certainly end up with, perhaps, not so much the wrong
abstraction as an overly convoluted one. This acticle is the excuse for
programmers everywhere not to fix their messes. It is 100% opposite to what
programmers need to hear.

~~~
mcphage
> It is 100% opposite to what programmers need to hear.

Maybe you know very different programmers than I have known, but if I had to
compare what has been a bigger source of problems—missed abstractions, or
abstractions that make things more difficult for no benefit, it's definitely
bad abstractions almost every time.

~~~
cjfd
Well, I worked for quite some time in a code base that was basically one big
ball of missed abstractions. Maybe I was traumatized a bit by that. I also
have seen wrong abstractions, but not because there should not be an
abstraction. If people had actually written abstractions that removed
duplication instead of the ones that they half-understood from the design
pattern book, they would have had come up with better ones. Duplication is in
fact the best way to find the correct abstraction. The article makes this
sound suspect but it really is not. The whole literature of design patterns is
basically unneeded. If one just follows the path of deduplication one will
discover all of them one by one and one will have applied the right one in the
right place. Maybe there is some value in noticing that one still has to keep
thinking and keep an eye on the likely future and not blindly do this but that
is no more than a small footnote to the main message which is that you will
find all the right abstractions by removing duplication. It is quite right
that in TDD the refactor step is often described as the removal of
duplication.

~~~
AstralStorm
You have not worked on bad enough code base.

Duplication is a problem as the different implementations inevitably drift and
get repeated bugs, but simple reduplication results in the rather known
problem of RavioliCode( _) of thousands low cohesion functions. Which ends up
unreadable thus bug prone and slow to develop.

Use of the right patterns or rather paradigms reduces amount of code in
general, thus reducing duplication.

Wrong patterns are hard to actually change especially on change averse
projects. The more widely used the wrong design is, the harder it is to change
as the hacks on it multiply. Even worse if the wrong patterns (not code) are
duplicated.

These require in depth rewrites to which bosses are usually allergic, which
are very hard to pull off on bigger teams too. Incredibly hard to coordinate.

\-- (_) [https://wiki.c2.com/?RavioliCode](https://wiki.c2.com/?RavioliCode)
\- can happen in functional and structural code too.

~~~
cjfd
'You have not worked on bad enough code base.'

You know, it is a bit pretentious to read a few sentences that someone wrote
and then conclude a lot about what they know or do not know.

And I actually do know what ravioli code is. I think ravioli code is mostly a
good thing. Also the people on the c2.com page are not uniformly negative
about it. Not all code should be ravioli code but in a project with complex
requirements there should be quite a bit of ravioli code. It is true that
ravioli code is not easy to understand if you are a newcomer to a project but
really if the context is 'a project with complex requirements' why would
anyone think that it is easy to get into, no matter how it is written?

Another thing is that ravioli code absolutely needs automated tests.

'This style maximizes maintainability by old hands at the expense of
comprehensibility by newcomers.' Maintainability is exactly what I want
maximized. It sounds a bit bad if there are no developers that are there for a
long time. But in that case you are cooked anyway, I would say.

~~~
AstralStorm
Main problem with the style is lack of overarching structure and cohesion.

Preferable state is high internal cohesion and low coupling. Most code is
opposite. Ravioli is when you trade high coupling without introducing
cohesion, which is structure. Typical state after dumb refactor rather than
rework.

Simple extraction of functions does not get you anything (if done well within
a module, maybe increases cohesion), while making them reusable modules trades
reduced cohesion for increased coupling, which is bad.

If you deduplicate too much you suddenly cannot change anything simply... As
every place that got deduped is now coupled to one implementation. Once you
need some special care, you get to replicate it again oftentimes.

Only true primitives are really worth it to not replicate and parts of code
that won't change. (Ask the crystal ball again.)

See if deduplicaton gets you any of useful high level designs, like MVC,
event-driven, reactive, message based. Without overarching design, you end up
with a mass of locally useful ones that together are incompatible thus
requiring lots of different, unique glue code.

The big mistake people do is to equate design patterns with code patterns.
Which is what the silly GoF book did a lot. For example "fire and forget
background parallel tasks" is a design pattern. Reactor (executes Strategies
to deal with Events) is one while Singleton or Context are not. Event also is
not. Etc. Generally anything that doesn't actually _structure_ anything is a
code pattern.

~~~
cjfd
It is quite possible to get an MVC by deduplicating things. Image we have two
tables that display some data by the same means, e.g., a web page. This will
be about the same code twice. For instance, both will iterate over rows and
columns. Removing that duplication will give you an M and a V. Then you may
also have to react to some events in about the same way. Remove that
duplication and you have a C.

------
ipython
“Perfect is the enemy of the good” applies to computer programs just as much
as anything else.

------
somesortofsystm
I recently found myself trying to describe modern software techniques to a
layman, who is a carpenter.

"Its like this - you're hired to build a house. First, you have to go get
someone motivated to harvest the raw materials for you - designs, logic, etc.
- which will then be turned into the 'raw wood' that holds up the walls and
keeps the roof on. Then, when that person is busy getting the materials cut,
you start building the tools you know you're going to need, to get the walls
up and strung together. You don't have these tools yet, because you left all
the previous ones you've worked with at a previous construction site. The
reason for this is that you are going to use the tools to put the walls up,
sure - but then you're going to glue all the tools in place to make sure the
walls stay up. That glue is the most powerful stuff in the universe, but it
will fail catastrophically if you don't put the tools at just the right angle
in the glueball .."

Basically, you glue all the new tools together, cover them in wood, and leave
them in place so that the thing doesn't fall over ...

~~~
jaywalk
For the sake of anyone who uses your software, I hope you're better at writing
code than coming up with metaphors.

~~~
somesortofsystm
Exactly. That's software development for you. :P

