Duke Nukem 3D Code Review
alancronin writes "Similar to Fabien Sanglard's previous code reviews of other games such as the Quake and Doom line of games comes a review of the code base of Duke Nukem 3D (split out over 4 pages). This will be a very good read for anyone interested in understanding the mechanics of a highly addictive game or anyone that wants to learn more about game design."
duke nuken
For shame /.!!
Cone get sone!
My sausage tree didn't grow, does that make me a bad mommy?
And you can't get it right. Find a job more suited to your lack of ability already (though I admit it's going to be hard to find a job that requires less).
Most methods have "void" parameters and return "void". Everything goes via global variables.
Methods naming does not use camelCase or NAMESPACE prefix.
Somewhere, my CS professor just had a simultaneous heart attack/stroke.
What political party do you join when you don't like Bible-thumpers *or* hippies?
I'm more interested in a Duke Nukem Forever code review. Imagine how horrible it must be.
The method names are more preference. Libraries should use a namespace prefix sure, but it's less of a problem for an application. And case typing is entirely a user-preference.
But I agree with you on the voids/globals.
Resource Limit Is Reached
The website is temporarily unable to service your request as it exceeded resource limit. Please try again later.
Hmm, maybe there will be an update released any day now...
The difference is most CS prof's don't program for the real world and would get a F if they tried.
Those who can, do.
Those who cannot, teach
Those who can't teach, teach college!
I love professors like that- they never account for all the bad code that is already out there and never realize that sometimes you just have to deal with it.
Piece of cake!
those who can't teach become journalists
DN3D came out when I was in my late teens, about 18 months before I went off to university and got a net connection good enough for online gaming. At the time, it was DN3D, rather than Quake, that was the LAN multiplayer game of choice for my friends and I.
Partly that was because of the actual gameplay. While Quake was a better twitch-shooter, DN3D had a real, nasty, sneaky dimension to its multiplayer. You could use the pipebombs and holoduke in particular to make traps for opponents that were just like something out of Spy vs Spy. Much more potential for hilarity than a simple rocket to the face.
But it was also the ease of level creation. Once we were bored of the levels that came with the game, it was trivially easy to fire up the bundled level editor and make new maps. We'd been doing that before with Doom and, if anything, despite having "2.5d" levels (as opposed to Doom's straightforward "2d" levels), DN3D level creation was even easier due to the quality of the tool. By contrast, creating "3d" Quake levels was massively more difficult and time consuming.
Once I went to University, of course, it became much easier to download new maps from the internet and the superior network infrastructure underpinning Quakeworld, Quake 2 and eventually Half-Life multiplayer moved my gaming in that direction instead.
When I first created my account on /. I remember getting excited about the sequel that was going to be released soon.
Fuck Ajit Pai
The engine was written by an 18 year old. You've got to forgive the lack of college CS education and work experience, and marvel at the talent to actually make the best featured and performing 3D game engine of it's day.
Yes! I use to roll me eyes that they things they would spout off about.
Here in the real world using global variables gets you fired. Even worse are the PHP dunderheads who think that turning on register globals is a good idea.
When I used to look at Doom and Duke3D and try to imagine how the engine worked, portals was the concept I imagined. I was surprised and initially rather confused when I found out that Doom actually worked using Binary Space Partitioning.
I'm rather pleased to see that I was at least right in my theory with regards to DN33. Possibly I came up with the portals theory after seeing DN3D's windows and mirrors, and then imagined that Doom worked the same way.
Anyhow, the article was a great read.
ISTR it was well featured but not as fast as DOOM, on my old P60. Fast enough, though, and just way, way more variety in the artwork than DOOM.
My personal favourite was:
laser-tripmine just outside of a door beside a pile of pipebombs...
Door opens, breaks laser, explodes tripmine, explodes pipebombs. Bonus if you can leave a little breadcrumb trail of pipebombs.
Also fun to stick at the bottom of mineshafts, steps, etc.
Jetpacks. Tricksy holograms. Shrink-rays. I mean, there are entire games based on individual Duke features. Timed detonators! It’s like they had access to a different alphabet, and somewhere they are still hoarding those secret letters. Why are all of those ideas in the same game? It’s from 1996, and it still comes up in conversation. The Subway. The Bank. Virtually unlimited levels to play on, 20k or less in most cases. I shot Gabriel once with a shrink ray, and he used his jetpack to fly out the window like an insect. Fifteen years ago. Still talking about it, about scenarios that to this day no game has managed to top.
PHEM - party like it's 1997-2003!
Okay, sit down, grab a good embedded C board and write me an entire full featured RTOS without using a global, once you can do that you can slander global variables.
Which is not what 99% of code does.
I was speaking generally, and generally globals are a bad idea.
At my old job I was once writing a while loop and decided to use "i" as the name of a counter variable I was incrementing. After a while I noticed that I had not declared the i and was perplexed as to why there was no compile error. Then to my horror I discovered that someone was using a global variable named "i".
Embedded Code out numbers Non Embedded Code on about a 50 000:1 scale. Every single little micro-controller, power IC, control system and numerous other devices, to many to mention, all run Embedded Code. Desktop code really being the exception should follow Embedded Code.
Desktop code roughly teaches:
Global's are evil.
Goto is the most evil and hated statement ever.
Loops shouldn't run forever.
Pointers in general are evil.
Function pointers are to hard to understand because people are morons.
etc... etc... etc... Basically all the great features of a languages are considered evil because some dumb ass in the office who doesn't understand programming messed it up. Don't blame the guys who know how to program, blame the guys who don't. If desktop code was designed more like Embedded code you would have computers that run multiple times faster and more secure.
Ha, yeah right. We don't even have secure embedded devices. We have plenty of buggy, crashy, insecure ones though.
I am not sure what metric you are using, but most programmers are not employed writing embedded systems.
I never said most programmers were embedded programmers, I said embedded code out numbers non embedded code. If you take unit insecurity and compare the desktop to the embedded world then you'd easily find the desktop contain FAR more insecurity then the embedded world. Every door lock, finger lock, bio-meteoric lock runs embedded code. Most cars on the road run embedded code, most airplanes run embedded code. Most military drones run embedded code, all phones run embedded code, all desktop computers even run embedded code in the form of a Bios / UEFI. I can keep going but you should get the point. If you scale embedded code and desktop code to be equal I think you'd find that secure desktop programming is basically non existent.
There was a coder in our organization that did not understand what the 'var' keyword does in Javascript, and hence never used it for any of their variables, ever. That person is, shockingly, no longer employed here.
Every so often we come up against a problem as a result of this person's legacy, even a year later. We call such incidents [Name]Bombs. Just goes to show how a bad coder can have a severe negative effect on an organization.
Is the genesis of a source port that doesn't engage in a delusional modder's fantasy of sticking in Ted Turner and redundant real-world weapons.
I always love when people post this sort of nonsense. Good luck getting a job teaching if you can't do it first, sure it does happen, but portraying that as the status quo is just ignorance.
Teachers not only have to be able to do whatever it is, but they also have to be able to teach other people how to do it. The references I see in this thread are pretty much indicative of, we don't actually want to do it correctly, so we'll disparage the folks trying to make our lives easier by forcing the development of good habits. You see that in pretty much any specialty.
I actually miss goto and I'll admit it. It doesn't NECESSARILY produce spaghetti code, people! [ducking for cover]
What political party do you join when you don't like Bible-thumpers *or* hippies?
Had a similar problem; couldn't figure out why I kept getting surprising compiler errors in some of my perfectly legal loops. Even more surprisingly, I got similar errors in some basic expressions, despite identical expressions using different variables compiling just fine.
Surprise was no longer adequate, and I had to resort to astonishment when I found a colleague had #defined the letter "r" to a constant.
Why would anyone engrave "Elbereth"?
I think that would be for most number of devices, not necessarily lines of code written (or even # projects). Most code written today is not for embedded systems.
Even a small update to a micro-controller can cause millions and million of devices to requires updates. Embedded Systems far out number Desktop Systems, even a mobile system is an embedded system. So I would say that most development really is for embedded platforms.
The no globals thing comes from OO programming. Doesn't matter if it is embedded or desktop, on OO languages you use static class members. These are essentially globals, but they are confined to a namespace. In C you sometimes need globals, but if you are using globals to return the results of a function call, your doing it wrong. You made your API non-thread safe for no good reason.
Indeed, these Apple iOS programmers must be doing something wrong, with their OS X desktop code running on devices filled with viruses and malware.
It's not proper spaghetti until there is a jump across functions.
Well it wasn't true 3D; the Build engine was basically 2.5D -- the levels were still 2D, with an added height component -- using a lot of clever hacks to enable Z-axis levels and targeting. It worked well enough, and was a lot faster than the true-3D Quake on machines of the day. Quake needed a Pentium; if memory serves, Duke could run well on a 486.
I'd disagree that it was the best-featured engine of the day though. Bungie's Marathon engine was 2.5D with free-look and z-axis targeting, but also allowed for higher bit-depth textures, featured a basic physics engine for weapon effects, featured alt-fire modes for weapons, and more advanced networking. And it came out in 1994; Duke arrived in 1996. Ultimately, they're both innovative engines, but I'd give the nod to Marathon as being the best of the time.
Thanks for the pointer. Back then I was still on PCs, so I wasn't aware of Marathon. I see it's been ported to the iPad, so I'm downloading it for a look.
I imagine Macs of the day were better featured than the PCs. So that might account for some of it? Perhaps.
Did Marathon have angled floors? I remember being impressed with that in DN3D, having been used to Doom's limitations.
Oh yeah, destroyable walls, transparent windows and reflecting mirrors were also impressive aspects of DN3D, did Marathon have those?
The Marathon series has also been open-sourced by Bungie, and builds are available for Mac, Windows, and Linux. Probably a better experience than the iPad version (haven't played it), but YMMV. They're actually pretty good single-player games.
With regards to your questions, Macs of the day did have an edge on graphics as compared to PCs, so that could account for the higher resolutions and higher bit-depth textures. But most of it is just smart people making cool stuff. As for destructible stuff, you know, I don't really remember. I haven't really played through the Marathon games since the 90's -- I should probably download them myself! But yes, Marathon has angled floors, and also features liquids, with different physics for each type.
Bungie has open-sourced the Marathon series, with builds available for Windows, Mac, and Linux, so that may be a better experience than the iPad version.
You're right -- Macs of the day did have better graphics capabilities than equivalent PCs, so that may account for the higher resolutions and texture bit-depths. But I think most of the innovation just comes from smart people making cool stuff.
Yes, Marathon did have angled floors. Destructible stuff, I'm not sure -- the last time I played through the series was in the 90's. Guess I should download those games as well!
Bungie has open-sourced the Marathon series, with builds available for Windows, Mac, and Linux, so that may be a better experience than the iPad version.
You're right -- Macs of the day did have better graphics capabilities than equivalent PCs, so that may account for the higher resolutions and texture bit-depths. But I think most of the innovation just comes from smart people making cool stuff.
Yes, Marathon did have angled floors. Destructible stuff, I'm not sure -- the last time I played through the series was in the 90's. Guess I should download those games as well!
Duke Nukem was a great game - many hours played over the phone lines and single player. One fond memory I have is tinkering with the Duke Nukem game settings file. IIRC you change all sorts of things like bullet damage, explosion radius, health, etc.. I once set the radius high enough that you could kill all the enemies in the level with one RPG round aimed at the floor. Then walk around and witness the carnage. ;)
I want to cuss at monster and lend my attitude to the game environment. I want to put cash on hookers. I want to shoot my firearms in the city and in the game. The monster is stealing Earth's chicks and I'm still a virgin.... I'm gonna rip your head off and shit down your neck! You are going to pay for that!
Then there are those LARD ass COPS....
This game taugh everyone what Los Angeles was all about, built on one of the best fucking WWF wrestlers Roudy Roddy Piper, and it did what we wanted. It's like 3D Realms knows what's in my mind and our minds! Man, that's gotta curt if you were an inspiration for birth control.
This sucks that games gone FULL ENVIRONEMNTAL 3D not Fast 3D (2.5D as in Duke Nukem 3D).l
Wait a minute...I thought that game was made for me... It's like the game was written as I played it. You mean it was the same for everyone? ahhhhhhhh ;-( wait a second. You mean there are others that feel like I do? You mean I'm not alone? Fahck year! :-)
And a recursive call to main().
I ran Duke3D on P60 and it ran full speed all the times. (Of course the SVGA modes were another story, but that is understandable.)
I noticed in the article that he was working with a decompiled version of the a.c file.
A version of it reimplemented in C was released as detailed here.
MUCH easier to read.
That should help with his project updating the engine as well as anyone else wanting to study the code in depth.
Cwm, fjord-bank glyphs vext quiz
Most methods have "void" parameters and return "void". Everything goes via global variables. Methods naming does not use camelCase or NAMESPACE prefix.
Somewhere, my CS professor just had a simultaneous heart attack/stroke.
Yeah, C doesn't have methods, it has functions. Argh!
Really, part of the fault lies with javascript, though. I generally like javascript, but implicit globals - bad idea.
Just because you're paranoid doesn't mean there isn't an invisible demon about to eat your face
Which is not what 99% of code does.
Citation?
Here in the real world using global variables gets you fired. Even worse are the PHP dunderheads who think that turning on register globals is a good idea.
Global variables are everywhere. They're just hidden by factory methods that obscure what's going on. So instead of "GlobalConfiguration.debugEnabled = true", we have "GlobalConfiguration.getOnlyInstance().setDebugEnabled(true)".