News for hackers. Stuff that matters.
Re:Super Mario 64 – 1996 Developer Interviews by dmbaggett on Thursday September 22, 2016 @02:21PM (#12558925)
>The N64 hardware has something called a Z-Buffer, and thanks to that, we were able to design the terrain and visuals however we wanted.

This was a huge advantage for them. In contrast, for Crash Bandicoot -- which came out for the PS1 at the same time -- we had to use over an hour of pre-computation distributed across a dozen SGI workstations for each level to get a high poly count on hardware lacking a Z-buffer.

A Z-buffer is critical, because sorting polygons is O(n^2), not O(n lg n). This is because cyclic overlap breaks the transitive property required for an N lg N sorting algorithm.

The PS2 got Sony to parity; at that point both Nintendo and Sony had shipped hardware with Z-buffers.

Re:Super Mario 64 – 1996 Developer Interviews by xigency on Thursday September 22, 2016 @03:46PM (#12559723)
Learning this is like when I learned that the Sony PSP couldn't clip triangles that were larger than the view frustum when rendering. I was making a hack-and-slash dungeon game for a homebrew contest when I figured that out and had to find software clipping code fast, so that big pieces of the walls and floor wouldn't disappear when you got too close. It ended up slowing my game down, and if I knew about that limitation I would have engineered around it from the start. I ended up breaking up large triangles and keeping everything stored in an octree.

After that, I started noticing subtle clipping issues in a few games including Daxter.

I would have never guessed that any 3D video game console didn't have a Z-Buffer, including a relic like the PSX.

Re:Super Mario 64 – 1996 Developer Interviews by gambiting on Friday September 23, 2016 @04:29AM (#12563129)
Slightly off topic - I used to participate in several PSP homebrew programming contests too, have you by chance participated in QJ.net or NeoFlash competitions in years 2006-2009? I'm asking because it would be cool to find someone else who took part :D My entries were: PSPSnake, Shoot4Fun, Mandelbrot Fractal Generator, and BlowUp! in the final year.
Re:Super Mario 64 – 1996 Developer Interviews by xigency on Friday September 23, 2016 @09:02AM (#12564231)
Yes, I did. I made "Quak Arena" [1] for the 2006 NeoFlash competition and the game I mentioned was Chronicles [2] for the dash hacks competition in 2009.

[1] https://www.neoflash.com/forum/index.php/topic,3035.0.html

[2] http://forums.dashhacks.com/psp-programming-development/2399...

Re:Super Mario 64 – 1996 Developer Interviews by coldpie on Friday September 23, 2016 @08:55AM (#12564176)
I did :) I made Dyox in 2006 and won a prize: https://www.neoflash.com/forum/index.php?topic=2876 I no longer have a PSP, but reportedly it still works on modern CFW and you can run it in PPSSPP: http://brightnightgames.com/games.php?game=dyox

My email's in my profile if you want to chat

Re:Super Mario 64 – 1996 Developer Interviews by Retric on Thursday September 22, 2016 @03:55PM (#12559801)
You can bound polygon sorting by looking at the closest and furthest points from the camera for each polygon. This get's tricky if the polygon is perpendicular to the camera, but avoiding O(n^2) in the general case is huge.

Z-Buffer's are still a major advantage.

Re:Super Mario 64 – 1996 Developer Interviews by dmbaggett on Thursday September 22, 2016 @04:01PM (#12559855)
That's an excellent point, and something that I've never actually thought of or read. Cool!
Re:Super Mario 64 – 1996 Developer Interviews by oxide on Thursday September 22, 2016 @05:23PM (#12560484)
you should go implement this in Crash Bandicoot and make a youtube video of it.
Re:Super Mario 64 – 1996 Developer Interviews by CamperBob2 on Friday September 23, 2016 @05:03AM (#12563251)
You can bound polygon sorting by looking at the closest and furthest points from the camera for each polygon

That still fails to resolve cycles.

Re:Super Mario 64 – 1996 Developer Interviews by Apes on Thursday September 22, 2016 @06:30PM (#12560871)
I have heard before that the Z-buffer was not actually usable on the N64 due to a design flaw. I forget the details, but one of the wikipedia pages about the N64 mentions this:

"The Z-buffer could not be used because it alone consumed the already constrained texture fill rate."

-- https://en.wikipedia.org/wiki/Nintendo_64_programming_charac...

I vaguely remember a technical analysis on the N64 that explained using the Z-Buffer had such a dramatic negative impact on performance, that only a very small handful of games actually used it. The general theme of the technical analysis was that the N64 had a lot of "features" that had a massive performance impact to use, so many of them went unused.

If I remember correctly -- most games implemented their own pseudo z-buffer in microcode, which is why a lot of games on the N64 have issues with textures popping through each other incorrectly -- Goldeneye's bullet hole textures stick out in my mind as a good example of this.

However, I'm trying to find the analysis, and I'm not having any luck. Maybe I'm just remembering things incorrectly.

Re:Super Mario 64 – 1996 Developer Interviews by modeless on Thursday September 22, 2016 @06:35PM (#12560899)
That quote is referring to a game that runs at a 640x480 resolution. According to a quick search, most N64 games including Mario 64 run at 320x240 which reduces the fill rate requirements by a factor of 4. That would leave plenty of room for using the Z-buffer along with texture sampling.
Re:Super Mario 64 – 1996 Developer Interviews by MBCook on Thursday September 22, 2016 @07:51PM (#12561326)
640x480 was only possible with the memory expansion pack IIRC.
Re:Super Mario 64 – 1996 Developer Interviews by corysama on Thursday September 22, 2016 @08:18PM (#12561431)
The N64 only had 4 megs of unified RAM. 640x480x3bytesx2buffers would be 1800k. It was technically possible to run that without the expansion pack. But, losing that 1350k compared to 320x240 really hurt. 4x fillrate cost hurt even more.

N64 had a form of antialiasing support https://www.google.com/patents/US6999100 That was the motivation for the "9-bit RAM". Worked well enough for the time and was cheap enough to use. Much cheaper than running at a higher rez.

Re:Super Mario 64 – 1996 Developer Interviews by Narann on Friday September 23, 2016 @05:14AM (#12563292)
Z-Buffer had huge bandwidth impact that's true, but you can deal with it depending on you game. A good example is SSB which use Z-Buffer only for characters, all the rest is build from bottom to top. Combine this with the fact it only use "one cycle" graphic computation (N64 allow to do another shading computation pass in a mode call "2 cycles"). This allow big framerate.

> most games implemented their own pseudo z-buffer in microcode.

Just two or three IIRC. Mainly Factor 5 games.

Goldeneye use Z-Buffer, bullet texture overlaps because the poly offset value used to apply bullet texture on walls is always the same.

> The general theme of the technical analysis was that the N64 had a lot of "features" that had a massive performance impact to use, so many of them went unused.

I wouldn't say that.

1) The N64 is a complex console. It still inherit the "all electric" tradition of 16/32 bits consoles but focusing on 3d computation and shading so it need skilled peoples and time to do interesting things with it (in its last days, N64 had very impressive games).

2) With that, Nintendo devs provides GBI (graphic binary interface) which was not such efficient on the vector computation side (but generic enough to allow peoples to use it).

3) N64 had a all-wired per pixel processing unite (a GPU named RDP), meaning it could provide high quality pixels like never before but this was costly.

4) Because texture had to be stored physically "inside" the RDP chip for efficient processing (remember, 3DFX didn't even exists at this time and the GPU word was a concept), memory cost (and, I suppose, size limitation) were important so they choosed to focus on pixel quality over texture definition (there is actually many hack to "visually" improve texture definition: http://imgur.com/2EeH5Yg).

Re:Super Mario 64 – 1996 Developer Interviews by sspiff on Friday September 23, 2016 @08:15AM (#12563973)
Interesting, I hadn't heard about that.

In the case of Mario 64 though, many of the models and polygons didn't have textures but used super-simple single-color flat shading. So texture fill rate wouldn't not have been a constraint.

Most games also didn't use a custom microcode, but used one of a handful of microcode libraries for the RCP that Nintendo provided. A notable exception to this is Factor 5, which did write their custom microcode to improve graphics performance, with great results.

Re:Super Mario 64 – 1996 Developer Interviews by agumonkey on Thursday September 22, 2016 @03:01PM (#12559286)
Man you should write a book. Or many, I'm sure you could fill them with all the details about your game development over the years. That would be a nice complement to Abrash Black Bible.
Re:Super Mario 64 – 1996 Developer Interviews by vvanders on Thursday September 22, 2016 @04:16PM (#12559987)
If you dig this stuff then Real-Time Collision Detection[1] is solid gold. It's basically data structures for 3D along with a practical appreciate of what makes real world algorithms fast(data layout).

[1] http://realtimecollisiondetection.net/books/rtcd/

Re:Super Mario 64 – 1996 Developer Interviews by agumonkey on Thursday September 22, 2016 @04:22PM (#12560039)
That's the second time I see this suggested, time to try. Still doesn't absolve Dev Baggett to bless us with his stories ;)
Re:Super Mario 64 – 1996 Developer Interviews by jimminy on Thursday September 22, 2016 @06:41PM (#12560943)
Andy Gavin wrote several extended articles on the making of the original Crash Bandicoot. IIRC correctly, Dave contributed to a few of the articles,, or at least his contributions are mentioned pretty heavily.

http://all-things-andy-gavin.com/2011/03/12/making-crash-ban...

Re:Super Mario 64 – 1996 Developer Interviews by agumonkey on Thursday September 22, 2016 @07:02PM (#12561065)
I remember these; but I don't remember them including what Dave Baggett just said, hence my delighted surprise and suggestion above.
Re:Super Mario 64 – 1996 Developer Interviews by epse on Friday September 23, 2016 @05:07AM (#12563261)
That is one expensive book! It's discounted on Google Play and still 75 euro
Re:Super Mario 64 – 1996 Developer Interviews by seanwilson on Thursday September 22, 2016 @03:07PM (#12559344)
> we had to use over an hour of pre-computation distributed across a dozen SGI workstations for each level to get a high poly count on hardware lacking a Z-buffer.

Did you consider any other alternatives? Curious if you had any other ideas that you sidelined as being too crazy.

Re:Super Mario 64 – 1996 Developer Interviews by dmbaggett on Thursday September 22, 2016 @03:15PM (#12559403)
No, that idea was crazy enough. :) The collision detection system and camera control code were also insane. Mark Cerny helped me make the collision code fast enough. Very clever assembly language tricks there, and we used 2K of "scratchpad" static RAM built in to the PS1 (for some reason) to make it fast enough.
Re:Super Mario 64 – 1996 Developer Interviews by seanwilson on Thursday September 22, 2016 @03:28PM (#12559540)
> No, that idea was crazy enough. :) The collision detection system and camera control code were also insane. Mark Cerny helped me make the collision code fast enough. Very clever assembly language tricks there, and we used 2K of "scratchpad" static RAM built in to the PS1 (for some reason) to make it fast enough.

Can you expand on how the precompute trick works further? So you're precomputing the order of the scenery/level polygons because of their predictable movement but how does that combine with objects with unpredictable movement (Crash, enemies etc.) when you render a frame? Did the limitations of this trick limit the gameplay you wanted?

Re:Super Mario 64 – 1996 Developer Interviews by dmbaggett on Thursday September 22, 2016 @03:40PM (#12559684)
I've been meaning to write a blog post about this, but here's a brief summary.

We wrote a software renderer for the SGI that exactly replicated how the PS1 hardware would render. I wrote an imperfect clone for Crash 1, then Stephen White wrote a pixel-accurate one for Crash 2. (This is why Crash 1 has "crispies", as Andy called them -- little pixel-sized glitches in the background -- and Crash 2 does not.)

When computing a level, we'd sample N points along the rail as we moved the camera forward through the level. At each point, we'd render the entire scene using the software renderer, then recover the rendered list of polygons, in sorted order, from the (software) Z buffer. We'd then store this sorted list of polygons for each of the N frames, using delta compression between frames to keep the size manageable. The pre-computation phase would choose N empirically, based on much change happened from frame to frame in any given section of the level; basically it would make N as large as it could be without blowing out the page allocation (which was in turn determined by how fast we could read from the CD).

This handled all the polygons in the background, which was completely static. For foreground objects like Crash, enemies, gems, etc, we'd bucket sort them in as we rendered the background. This required manual tuning in some cases, so we had an editor where we could manually adjust the "push-back" (i.e., bucket adjustment) for each object in real time while playing the game. These magic values were then stored with the associated objects as part of the level data. If we couldn't make an object sort in right via bucket adjustment, we'd change the background slightly until it worked. In other words, it was a massive hack. :)

In terms of gameplay, we took our inspiration primarily from Donkey Kong Country, which had linear gameplay. So the rail model actually worked really well for the gameplay we were trying to achieve. (DKC is still an awesome SNES game; check it out if you haven't played it recently.)

Re:Super Mario 64 – 1996 Developer Interviews by oppositelock on Thursday September 22, 2016 @05:53PM (#12560658)
Why did you have to simulate pixel level output to sort your polygons, out of curiosity?

I've also written rendering engines for hardware lacking Z-buffers, and our approach was to build a BSP tree of the level, which gets you part of the way to working around no Z buffer, since there's no Z overlap in static polygons after being partitioned, but the downside is you split triangles and increase the triangle count, so it reduces model complexity if the splitting blows your poly budget.

Once you have your BSP cells, you can precompute all the visible cells from any given cell - heh, we too did this on SGI's, but by rendering each cell is a unique color and seeing which colors were visible in an output frame.

Then, within each cell, we'd have six draw orders for triangles, picking whichever was closest to the eye vector. Not pretty, and sometimes this produces quite a bit of overdraw, but it works. I'm guessing your approach minimized overdraw as compared to a heavily pre-computed BSP approach.

Anyhow, thanks for the post, it's fun to read about the the hacks form the early days of graphics hardware.

Re:Super Mario 64 – 1996 Developer Interviews by dmbaggett on Thursday September 22, 2016 @08:00PM (#12561358)
>Why did you have to simulate pixel level output to sort your polygons ... ?

We essentially rendered every frame with a Z-buffer; it's just that the Z-buffer was running in software on the SGI ahead of time, as the level was processed.

We needed pixel accuracy so that the occlusion was perfect. The BSP tree technique was well understood by then, thanks to Carmack's work on Quake, but we didn't want to split polygons so we used this brute force method instead.

However, as a little bit of disinformation to other developers, we put a big file of random data on the Crash CD called BSPTREE.DAT. You still have to download this huge, pointless data file when you buy the game on PSN. I feel slightly guilty about that. :)

Re:Super Mario 64 – 1996 Developer Interviews by STRML on Thursday September 22, 2016 @08:37PM (#12561507)
That's hilarious. It was just a matter of empty space on the disk = let's misdirect competitors for a while?
Re:Super Mario 64 – 1996 Developer Interviews by dmbaggett on Thursday September 22, 2016 @09:39PM (#12561741)
Yup.
Re:Super Mario 64 – 1996 Developer Interviews by digi_owl on Friday September 23, 2016 @07:48PM (#12568714)
Oddly i could have sworn that there was a problem with fitting the game on a CD until some clever compression was applied.
Re:Super Mario 64 – 1996 Developer Interviews by dmbaggett on Saturday September 24, 2016 @10:13AM (#12570991)
You're thinking of fitting the levels into the maximum number of pages that could fit into memory. That was hard, but had nothing to do with the CD capacity.
Re:Super Mario 64 – 1996 Developer Interviews by seanwilson on Thursday September 22, 2016 @04:13PM (#12559953)
> This required manual tuning in some cases, so we had an editor where we could manually adjust the "push-back" (i.e., bucket adjustment) for each object in real time while playing the game.

Sounds like one of those hacks where you're simultaneously laughing and shocked at how "kludgy yet it works" it is but relieved you've actually solved the problem in a way that meets the limitations and deadlines you have. Thanks for the replies, great to know this background information on a classic game!

Re:Super Mario 64 – 1996 Developer Interviews by dmbaggett on Thursday September 22, 2016 @04:37PM (#12560161)
Exactly. I was actually very worried about how much data would need to be stored per frame for this to work until I tried it. Most frames required under 100 bytes, incredibly.
Re:Super Mario 64 – 1996 Developer Interviews by sthatipamala on Thursday September 22, 2016 @02:41PM (#12559090)
I just read the Making of Crash Bandicoot blog post series. This limitation is why Crash Bandicoot had a camera-on-rails to limit the number of polys on screen, right?
Re:Super Mario 64 – 1996 Developer Interviews by dmbaggett on Thursday September 22, 2016 @02:45PM (#12559131)
Not to limit the number of polygons on screen, but to make it feasible to precompute the exact order polygons would appear on the screen during each frame at render time. Pre-computation actually increased the effective polygon count because it also meant that the engine didn't need to render occluded polygons (i.e., the rock behind the tree you're looking at) at all.
Re:Super Mario 64 – 1996 Developer Interviews by wnevets on Thursday September 22, 2016 @04:45PM (#12560228)
is that similar to resident evil's prerendered graphics?
Re:Super Mario 64 – 1996 Developer Interviews by corysama on Thursday September 22, 2016 @04:54PM (#12560289)
Resident Evil largely baked their complex scene geometry down to large, flat textures on large, flat polygons in game. Crash kept the complex geometry of the scene in the game. What was baked was the exact set of polygons that needed to be loaded and displayed at any point along the track.
Re:Super Mario 64 – 1996 Developer Interviews by fuckyeah on Thursday September 22, 2016 @02:39PM (#12559070)
Had the ps1 a dedicated chipset for 3d graphics or was it a pre-written software renderer library kind of thing? Was writting a software renderer (with perspective correct texture mapping and a zbuffer, amongst other things) out of question?
Re:Super Mario 64 – 1996 Developer Interviews by zubat on Thursday September 22, 2016 @04:05PM (#12559885)
The PS1 can be characterized as "half-software" because the geometry transforms are done through a CPU coprocessor, then sent to a mostly-2D GPU capable of filling in the gaps with affine transformations. This unusual pipeline accounts for why the rendering artifacts have a system-defining character to them - information about the geometry is lost after leaving the CPU and the GPU operates at screenspace precision, making the biggest polygons onscreen the most visibly inaccurate.
Re:Super Mario 64 – 1996 Developer Interviews by JonnieCache on Thursday September 22, 2016 @04:52PM (#12560271)
Nice to have a proper explanation of why PS1 games look so weird.
Re:Super Mario 64 – 1996 Developer Interviews by rangibaby on Thursday September 22, 2016 @09:18PM (#12561658)
It's called affine swim, and is present in some PC games too. I first noticed it in Half Life when I was messing around with the software renderer.
Re:Super Mario 64 – 1996 Developer Interviews by damptowel on Friday September 23, 2016 @04:18AM (#12563091)
Might be wrong but I thought Quake's software renderer does proper perspective texture mapping? (Original Half-Life is based on Quake)
Re:Super Mario 64 – 1996 Developer Interviews by royjacobs on Friday September 23, 2016 @04:53AM (#12563215)
Quake perspective corrects only every 16 pixels and does linear interpolation in between. This is because the correction requires an expensive FPU divide.

While the FPU is busy doing that, the CPU can do the linear interpolation. Once the CPU is done with the 16 pixels, the FPU has also completed the divide and the CPU can do the next 16 pixels, and so on.

Looks pretty decent but is not 100% accurate.

Re:Super Mario 64 – 1996 Developer Interviews by rangibaby on Friday September 23, 2016 @05:02AM (#12563246)
It was so long ago that I honestly don't remember. It might have been something like HL model viewer or Milkshape 3D rendering things using a different software renderer. I did some research and there is also an option to set affine texture mapping in the HL OpenGL renderer. HL works on Macs so I will test that stuff out soon
Re:Super Mario 64 – 1996 Developer Interviews by digi_owl on Friday September 23, 2016 @07:50PM (#12568717)
I think by the time HL shipped, the engine had been so hacked to bits that very little was left over from Q1. Heck, i think they even ported over various bits from Q2.
Re:Super Mario 64 – 1996 Developer Interviews by dmbaggett on Thursday September 22, 2016 @02:45PM (#12559135)
Yes, a software renderer would have been far too slow. The PS1 had a 33Mhz MIPS processor.
Re:Super Mario 64 – 1996 Developer Interviews by jimmaswell on Thursday September 22, 2016 @02:59PM (#12559265)
How did Spyro end up getting past this limitation to have a free roaming camera with a good poly count?
Re:Super Mario 64 – 1996 Developer Interviews by dmbaggett on Thursday September 22, 2016 @03:13PM (#12559386)
The Hastings brothers (who were actually down the hall from us when we were writing Crash) are really awesome coders. Even so, however, I don't think Spyro for PS1 actually had anywhere near Crash's effective polygon count. Crash himself was over 750 polygons, which was not bad for an entire frame of a PS 1 game.
Re:Super Mario 64 – 1996 Developer Interviews by icebraining on Thursday September 22, 2016 @03:14PM (#12559399)
According to this great series on the making of Crash Bandicoot¹, Spyro used walls to reduce the number of polygons visible concurrently.

¹ http://all-things-andy-gavin.com/2011/02/02/making-crash-ban...

Re:Super Mario 64 – 1996 Developer Interviews by rangibaby on Thursday September 22, 2016 @09:14PM (#12561643)
Quake 1 did that too