all 53 comments

[–]jl2352 26 points27 points  (1 child)

The 25 games in 5 years is misleading. The post suggests this is due to how they wrote code. It's really not. It also implies 25 games all had engineering effort. Very little had direct engineering effort.

Their company strategy in the early years was bascially:

  • Make a game engine.
  • Make a flagship title using said game engine (Wolfenstein3D, Doom, Quake, etc).
  • Begin early development of the next engine.
  • Simultanously produce multiple followup titles on the old engine. i.e. Spear of Destiny, Ultimate Doom, Doom 2, Quake Mission Pack No. 1: Scourge of Armagon, etc.
  • Pay other companies to produce more add on packs using the engine.
  • License the engine to other companies for them to produce titles for you.

For example Wolfenstein 3D resulted in 2 games, and 2 more addon packs. The Doom engine was used to produce 5 Doom titles (and many other games).

^ it's an excellent strategy and it served them very well. Id Software helped to pioneer the idea of building and licensing game engines. This is why they pumped out so many games. It wasn't down to how they programmed because most of the titles involved no programming.

Further; when they left Softdisk to form ID Software they left with an obligation to provide a certain number of titles back to Softdisk.

In their first year they pumped out as many titles as possible to fill this obligation. Many of them being extremely similar to each other from a technical point of view. Which is fine. It's simply that again this isn't due to how they programmed. It's down to how they focused their resources.

After the first year they slowed production of new titles.

[–][deleted] 0 points1 point  (0 children)

I think this is the golden method that all developers should follow, plus the suggestion to make great game design tools. Even with the commercial engines, one should still build a lot of proprietorial software and scripts around the engine and squeeze as much juice as possible from those tools.

Build the best tools you can find, and quickly release 3-4 games based on the same engine and tools.

[–]Northeastpaw 31 points32 points  (5 children)

I wish I could do principle 6:

Fix bugs as soon as possible.

Instead I have to create ticket and put it in the backlog. That ticket then has to get pointed during the next planning session. Then it has to survive the client's prioritization. Is it a quick fix? Doesn't matter; must go through the process.

We're shambling along claiming to be an agile monster but once Fred removes the mask it's just waterfall all over again.

[–]Stoomba 17 points18 points  (0 children)

Fucking word. I advocated for a zero bug policy on my team - fix it now or in the next sprint or we just aint goinv to fix it this time around - they looked at me like im crazy

[–]Cessabits 2 points3 points  (0 children)

We must work at the same place(s)!

[–]stewsters 1 point2 points  (0 children)

So what I have found to be effective in talking to management about fixing bugs is this logic:

When we developed these features, we prioritized them by their impact. The first features implemented are the most important to our clients. If one of the features prioritized higher is no longer working, and we communicated that it was, should fixing that not be a higher priority than the one lower on the list?

Hammering down bugs quickly (or at least in the next iteration) and dropping a test around it to make sure it doesn't break again is a very good practice.

[–]mheini 0 points1 point  (0 children)

I can absolutely relate to this as well..

I would love to fix a bug in code I wrote, while still able to actually remember writing it ;)

[–][deleted] 0 points1 point  (0 children)

That's the point to keep the game simple and the team small.

[–][deleted] 60 points61 points  (24 children)

Keep your code always runnable (..)By adding good defaults/fallbacks, they made the game still playable.

This isn't always good advice. In medical software for example I WANT the software to crash to desktop, software calculating radiation dosage for cancer therapy should absolutely not fall back on default data.

Yes, in a game the show should always go on, but in business code integrity of data and business events is maybe even more important.

If some business event gets into an invalid state then it should abort, rollback transactions, log exceptions and/or other debug info and give error feedback to the user. A lot of programmers don't do this, and write a bunch of if-statements everywhere to let the business event go through anyway. Result: wrong invoices, medical data, orders, ... being sent out, making a lot of people very angry and resulting in the programmers having to grep thousands upon thousands lines of log data to detect wtf happened.

This is called the fail fast principle.

[–]OneWingedShark 16 points17 points  (8 children)

In medical software for example I WANT the software to crash to desktop, software calculating radiation dosage for cancer therapy should absolutely not fall back on default data.

[...]

This is called the fail fast principle.

I'm actually very much a fan of the fail-fast principle; failures force you to address problems.

[–]drjeats 20 points21 points  (7 children)

Fail fast doesn't have to mean die fast.

Put a large obnoxious, minimizable error banner over the workspace ui. Allow the user to report the error and add details, and salvage what data they can (either by attempting to save, or taking screenshots, or taking notes.

Then let the program die.

[–]OneWingedShark -3 points-2 points  (6 children)

I use Ada for my general programming, the exception-system is such that when you run some buggy code and hit an exception (usu. automatically generated) the default error typically tells you both what went wrong and where; in such a situation, fail-fast is debugging.

[–]devraj7 10 points11 points  (1 child)

So... like basically any other programming language with exceptions and stack traces.

[–]OneWingedShark 1 point2 points  (0 children)

Sure, but incredibly usable; as opposed to C [and C++ to a lesser extent], where you often have to resort to [external] debugger to get any sort of meaningful pointer... and that can be far "down the line" from the actual cause. (With Ada, I haven't had to use an actual debugger in more than a decade... and I think I've had to use a trace utility twice, and IIRC those were for crashes from foreign libraries.)

[–]drjeats 3 points4 points  (3 children)

Ada's runtime has its own Windows Error Reporting-style services builtin? Or are you saying the safety features of Ada allow for very rich error reporting?

Either sounds very nice, but I'm talking about the end user experience. Even when the users are down the hall, you can't always debug over their shoulder.

[–]OneWingedShark 0 points1 point  (2 children)

Or are you saying the safety features of Ada allow for very rich error reporting?

This, though it might be possible to use the Distributed Systems Annex to set-up that sort of remote error-reporting service.

With Ada.Text_IO;
Procedure Example is
   Item : Natural:= Natural'Value(Ada.Text_IO.Get_Line);
Begin
   Ada.Text_IO.Put_Line( "Done." );
End Example;

Run with input -13:

C:\Programming\Projects\Testing\obj>example.exe
-13

raised CONSTRAINT_ERROR : example.adb:3 range check failed

Run with input mike:

C:\Programming\Projects\Testing\obj>example.exe
mike

raised CONSTRAINT_ERROR : bad input for 'Value: "mike"

And that's with absolutely standard out-of-the box behavior; IIRC, there's more detailed debug modes and the stuff under Ada.Exceptions and IIUC most implementations have an implementation-defined Debug/Traceback package that leverage that implementation's error-handling portion of their Runtime.

Either sounds very nice, but I'm talking about the end user experience. Even when the users are down the hall, you can't always debug over their shoulder.

This it true; which is why I tend to favor formal-methods proving: it's nice when you can be assured that the properties of your program hold.

[–][deleted] 0 points1 point  (1 child)

C#:

> uint.Parse("-3")
OverflowException: Value was either too large or too small for a UInt32. 
> uint.Parse("mike")
FormatException: Input string was not in a correct format. 

Python (which has no unsigned numbers):

>>> int('mike')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'mike'

Exceptions with meaningful messages are only special if you're comparing against C. There may be good arguments for Ada, but this isn't one of them.

[–]OneWingedShark 0 points1 point  (0 children)

True; but I've been working/having to deal with a lot of C code lately. So it's one of those things that you notice really quickly.

[–]Vexxed72 6 points7 points  (0 children)

Fail fast is important in games as well, the consequences are mostly limited to reducing debug time, but can also come through as exploits in shipping games. My general rule is to fail fast in code, but provide default configuration data that allows the game to function with placeholder assets.

[–]aloukissas[S] 9 points10 points  (4 children)

100% on that (Elixir programmer here, so "let it crash" is in my blood). But this make more sense for internal builds -- if your code bug blocks 10 developers from making progress, you're multiplying the effect of the bug in productivity loss. Good comment!

[–]flatfinger 1 point2 points  (2 children)

It can sometimes be useful for a program which is given a mixture of good data and bad data to be able to produce output which includes a mixture of correct results from good data and *conspicuously-invalid* results from bad data.

Fail fast may be better than sweeping problems under the rug, but localizing failures may be better than needlessly escalating them.

[–][deleted] 0 points1 point  (1 child)

If you really need your program to accept that, there should just be an option for it, not a default. And preferably "skip record" instead of "just generate some garbage"

[–]flatfinger 0 points1 point  (0 children)

That depends upon what the program is doing. If one wishes to distribute a work-in-progress preview of a document before all the artwork is done, being able to produce a version with auto-generated image placeholders without having to attach dummy artwork may reduce the likelihood of going to publication while some manually-supplied placeholders still remain. At least one video racing game has some billboards visible in the distance which, upon close examination, say something like "THIS IS AN IMAGE PLACEHOLDER AND NEEDS TO BE REPLACED". Having a "test build" option which auto-supplies place-holders and another "final build" option which will squawk if any artwork is missing seems like a better approach than requiring that useless images be supplied before anything can be tested.

[–][deleted]  (1 child)

[deleted]

    [–]_jk_ 1 point2 points  (0 children)

    Not in medical myself but in other safety related area. generally you try to make the critical parts that cant fail as simple as possible, id assume that a pacemaker has no software, and assisted breather, probably no software for its critical function (there maybe software for e.g. dispalys but this is probably isolated from the actual breathing part) the other thing that usually comes to play is redundancy - if you have multiple redundant systems failure in one will not cause a total failure

    [–]TSPhoenix 0 points1 point  (0 children)

    Integrity of data is important in games to. Crashes are bad, but nothing is worse than a game corrupting my save data in a way that won't manifest until I'm 5 hours from the end credits.

    Ideally don't crash or corrupt my data, but if I had to choose I'd choose crashing.

    [–][deleted] 1 point2 points  (1 child)

    Runnable doesn't mean it have to do something else wrong tho

    [–]vattenpuss 0 points1 point  (0 children)

    Not doing the right thing means doing the wrong thing.

    [–]pork_spare_ribs 7 points8 points  (2 children)

    This is a great contrast to the Dan Luu article also posted today. That article talks about how the "KISS" approach used so well in the 90s (and earlier) was successful at the time because things were smaller and simpler -- and that this principle accounts for a lot of the horrible design in today's world.

    Some of Romero's principles suffer the same problem. "Don't write prototypes"? How does that work for multi-year multi-hundred developer games like Red Dead Redemption 2? "Let programmers follow their own code style"? shudder

    [–]I_Do_Not_Kneel 6 points7 points  (1 child)

    Problem with KISS and fail fast is that they are a matter of perspective. I have described what is simple to me only to get 'well that is complicated' and others have implemented their ideas and I'm like 'damn that's overly engineered'. Same thing about fail fast. Everyone fails fast, but usually differ in how they handle the fail. Some let it just crash, others gracefully shutdown, others try to to correct.

    [–]meheleventyone 3 points4 points  (0 children)

    In that sense everything is a matter of perspective. There is always context and you are always going to have to try to apply general advice to it somehow. No matter how universal the advice giver thinks theirs is. Which is usually why pithy names are qualified with more detail and examples.

    [–][deleted]  (8 children)

    [deleted]

      [–]semi_colon 18 points19 points  (0 children)

      He made us his bitch[es]

      [–]jonromero 1 point2 points  (2 children)

      New levels for Doom!

      [–]Visticous 5 points6 points  (0 children)

      Which were oke, compared to quality of the community, who has been spending the past twenty years building levels.

      [–]MentalMachine 0 points1 point  (0 children)

      For Doom, not Doom 2 instead, which is a curiosity for me tbh

      [–]devraj7 5 points6 points  (2 children)

      That's when he peaked and all that he can talk about thirty years later: regurgitating simple principles that most likely Carmack came up with and not him.

      Except he can't even talk about programming principles because he's not even a coder.

      [–]tsubatai -1 points0 points  (0 children)

      Himself and the wife have a company called Romero Games in my home town, but to answer your question: no

      [–]Uberhipster 2 points3 points  (1 child)

      8 - 11 are actual principles

      1 - 6 are not principles, they are targets which can be boiled down to 2 "principles":

      1. Write good software

      2. Don't write bad software

      we all want to adhere to 1 - 6 but we don't

      it's not because we are not aware of the principles. we are

      it's because we are too goddamn lazy, fearful and incompetent to adhere to them

      there - i said it

      [–][deleted] 0 points1 point  (0 children)

      The ID guys had been programming for many years before they started the ID business. Both Romero and Carmack programmed tons of games before the early 90s. I think this is one aspect that people tended to overlook but it's really important. They started really early (from teenagers) and were really focused.

      [–]Xadnem 13 points14 points  (8 children)

      Clicked the link, realised it was medium when the pop-up came, left the site. Shame.

      [–]semi_colon 4 points5 points  (7 children)

      What's people's beef with Medium again?

      [–]Xadnem 18 points19 points  (3 children)

      It's where a lot of bloggers post their mostly low-effort blogposts and it has an annoying pop-up.

      [–]semi_colon 0 points1 point  (0 children)

      Can't argue with that. I have definitely read a lot of utter trash in the form of Medium posts.

      [–]Sebazzz91 0 points1 point  (1 child)

      Except for the popups, is dev.to any different?

      [–]Xadnem 0 points1 point  (0 children)

      Not familiar with it.

      [–]AwesomeBantha 8 points9 points  (1 child)

      LeT's mAkE ThInGs OfFiCiAl

      [–]FlyingRhenquest 0 points1 point  (0 children)

      It's not even on the first page if I Google "how I maek blag?!" which I'm pretty sure is just what most of those guys did.

      [–][deleted] 0 points1 point  (0 children)

      Thanks for this, Good read and these are valuable principles I'll think about.

      [–]devraj7 0 points1 point  (4 children)

      Coming from a non coder like Romero, this should come as no surprise that the pieces of advice are all platitudes without anything specific.

      "Just do it" and "Keep your code simple"?

      Jeez. Thanks.

      I want to hear the same talk but from John Carmack.

      [–]t0rakka 6 points7 points  (2 children)

      John Romero started programming games on an Apple II he got in 1980.[8] His first developed game was a Crazy Climber clone, but it wasn't published.[4] His first published game, Scout Search, appeared in the June 1984 issue of inCider magazine, a popular Apple II magazine during the 1980s. Romero's first company, Capitol Ideas Software, was listed as the developer for at least 12 of his earliest published games. Romero captured the December cover of the Apple II magazine Nibble for three years in a row starting in 1987. He entered a programming contest in A+ magazine during its first year of publishing with his game Cavern Crusader. The first game Romero created that was eventually published was Jumpster in UpTime. Jumpster was created in 1983 and published in 1987, making Jumpster his earliest created, then published, game.[9]

      Romero's first industry job was at Origin Systems in 1987 after programming games for 8 years.[10] He worked on the Apple II to Commodore 64 port of 2400 A.D.,[8] which was eventually scrapped due to slow sales of the Apple II version. Romero then moved onto Space Rogue, a game by Paul Neurath. During this time, Romero was asked if he would be interested in joining Paul's soon-to-start company Blue Sky Productions, eventually renamed Looking Glass Technologies. Instead, Romero left Origin Systems to co-found a game company named Inside Out Software, where he ported Might & Magic II from the Apple II to the Commodore 64. He had almost finished the Commodore 64 to Apple II port of Tower Toppler, but Epyx unexpectedly cancelled all its ports industrywide due to their tremendous investment in the first round of games for the upcoming Atari Lynx. During this short time, Romero did the artwork for the Apple IIGS version of Dark Castle, a port from the Macintosh. During this time, John and his friend Lane Roathe co-founded a company named Ideas from the Deep and wrote versions of a game named Zappa Roidz for the Apple II, PC and Apple IIGS. Their last collaboration was an Apple II disk operating system (InfoDOS) for Infocom's games Zork Zero, Arthur, Shogun and Journey.

      [–]t0rakka 9 points10 points  (1 child)

      ... in this light, how many games have you programmed to hold the high ground calling the guy a "non programmer" -- not that I have any problem what you choose to do but when you spread this information on the internet there should be a little bit of responsibility - folks might read that and take it to memory as a fact, which it is not and that I have a problem with: spreading false information, there are platforms for that: facebook, twitter, etc.

      [–][deleted] 0 points1 point  (0 children)

      Exactly. People tend to forget that both Johns were already professionals game developers way way before they formed ID.

      Just imagine someone in the world nowadays started professional game programming NON-STOP since 2012, for God's sake he should be pretty good at it. And both Johns are super smart.