Thanks for the interest in our shared video gaming past. I had a lot of fun making that video. The PS1 was a fun machine as it was capable, complex enough that you felt it had secrets, but not so bizarre or byzantine that you felt learning them was a waste of time. And you were pretty much the only one in there as the libraries were just libraries, not really an OS. Still true of the PS2 although that was a complex beast, but by the PS3 there was more of a real OS presence. If you want some more, slightly different, slightly overlapping info on the PS1 or making Crash, I have a mess of articles on my blog on the topic: https://all-things-andy-gavin.com/video-games/making-crash/
HN user
agavin
Novelist. Polymath. Entrepreneur. Foodie. Collector. Co-Founder of video game developer Naughty Dog, Inc. and co-creator of Crash Bandicoot and Jak & Daxter.
Probably focus on something simple with very addictive gameplay.
This was the first American title that was heavily produced by Japan. Before us, Tetris was the only external game that had sold really well. Across all consoles/machines!
I've been on HN for over a year :-)
Starting out is hard now in console gaming, except "maybe" x-box live or something. You'd have to start on iPhone, Android or the like where the costs are lower.
Well pause in video games is actually kinda complicated. By the jak period I had a pause mask (64 bits) that could pause all sorts of independant parts of the game separately. Particles, Camera movement, texture cycling, light changes, enemies, etc.
Sometimes you just want to free the characters in place (and usually enemies and the like) but don't want the whole screen going motionless. For example in Crash, when Aku came out, I wouldn't want to pause the fruit from flying to the score. That would look odd. The Aku pause is to give the player a breather, not just to pause.
Also, the real pause brings up the pause menu, which you certainly don't want with Aku.
Haha. Ken Kutaragi complained of Crash in the very early days that the "trees should wave their branches at you, giving the nostalgia of childhood." Or something like that. At the time we found it merely puzzling.
I'll have to check that out. Although my advice will be free :-) But I'm sure that many many other good debuggers have developed the same basic techniques independently. Still, the vast majority of programmers could use some improvement in this area. "Quit thinking and look" is exactly what I mean by "don't assume." People tend to get wrapped up their own view of things and forget that empiricism really wins the day. There is often even fundamental denial, as in "what bug? I haven't seen it." Clearly if someone saw it, unless they were hitting the crack pipe, it's real.
You can't have no assumptions. But half the time I help someone debug something they begin with, "it can't be in this part of the code" which is often unfounded. Now if you PROVE that it isn't, that's a different matter.
Good debugging is key, and as anyone who ever worked with me will note, I'm a fantastic debugger (in no small part because I'm cold, rational, and rarely get upset). I keep meaning to write up a post for my blog with "Andy's rulez of debugging." There are really very simple, but very effective.
Like: "don't assume" and "divide and conquer" (they do require a bit of explanation)
There is such a difference in coding output. Having had perhaps 50 work for me over the years (and being one myself), the top guys do perhaps 10x the output of the merely "very good" guys. And near infinite with the mediocre ones who on tough projects actually suck more time than they contribute.
The good guys also come in and contribute right off the bat. Like Christophe Balestra, who now is co-president of Naughty Dog. When he arrived on Jak 2 he was pounding out real working stuff the first or second day. By the end of the game (one year later) it was clear he was so kick ass that we promoted him across like 15 others guys to be co-lead with me on Jak 3. And he continues to kick ass to this day. I just site him, but I had the pleasure to work with around half a dozen other totally awesome guys too. Still, the "good" guys will take a system and do a great job with it over weeks. The great guys will knock it out in like 24-48 hours.
Lots of articles on this kind of stuff at my site too:
I'm not a LISP hater, far from it, I love the language.
In 2006 I wrote a complex multi-threaded socket and web server that talked to MySQL. I wrote it first in ACL, ported it to CMCL, then to Ruby, and then parts of it (with another programmer) to C (ultra high performance after that). So I got a head to head comparison for the same task.
As to libraries in 2006 (and Ruby libs are only better now). It was easy in Ruby to find libs to talk to third party APIs like Twitter, Facebook, Photobucket, etc. None of this existed in CL. They might be quirky, but they were there.
In ACL/CMCL "core" libraries like sockets and database access tended to be missing a lot of "fringe" (not really that fringe) features like transactions, multiple database support, enums, bigints, etc. But worse than that they tended to mysteriously hang under moderate volume. I found this true on both ACL and CMCL, different libs.
The equivalent Ruby libs, like ActiveRecord, had some SERIOUS quirks, and were missing some of those "fringe" features (I added a lot of them like multi-db, enums, and bigints). But fundamentally, they were more modern in design and reliable. ActiveRecord almost never crashed or hung. Yeah, it did some crazy and stupid things, and performance was a problem. But it didn't hang. When writing real production code mysterious hang/crash/corruption bugs are just a deal killer.
I need to check it out -- been busy :-)
The GOAL compiler, yes. The GOAL runtime no. GOAL itself produced high performance code without arbitrary GC, with simple (semi-static) runtime type checking etc. It was designed for console runtimes. I didn't write Jak & Daxter in CL, but in this Scheme dialect language (the compiler was written in CL/CLOS).
For nearly two decades I was a diehard LISP advocate. I even forced all my programers to code three Crash Bandicoot and four Jak & Daxter games in custom LISP dialects that I wrote the compilers for (an article on one here http://all-things-andy-gavin.com/2011/03/12/making-crash-ban...). But by the mid 2000s I started doing the kind of programming I used to do in LISP in Ruby. It's not that Ruby is a better language, but mostly it was the momentum factor and the availability of modern libraries for interfacing with the vast array of services out there. Using the crappy unreliable or outdated LISP libraries -- if they worked at all -- was tedious. Plus the LISP implementations were so outmoded. It was very hard to get other programers (except a couple enthusiasts) to work that way. Ruby struct a decent compromise. And it's type system and object model are better than CL anyway. The syntax is more inconsistent, and the macro model nowhere near as good. But it turns out. Libraries and implementation matter a lot. Still, you can feel lots and lots of LISP influence in all the new runtime typed languages (Ruby, Python, etc). And 30 years later, listeners still rule!
Anyway I bundled up some of my thoughts on this on my blog: http://all-things-andy-gavin.com/2011/10/25/lispings-ala-joh...
I compiled some of these posts and some other thoughts on LISP (far far from completely formed, but perhaps amusing) into a blog post:
http://all-things-andy-gavin.com/2011/10/25/lispings-ala-joh...
CLOS is perhaps more powerful, but the whole generic function thing is more awkward than object based dispatching. It is perhaps more powerful as it allows arbitrary overloading, but it was a pain. And I wrote a really big CLOS program: The GOAL compiler.
I keep meaning to check it out. But my pile of "keep meaning too" (which includes bills, taxes, and other boring things) is very large.
Thanks for all fan love :-)
One of the interesting things about LISP is that it's actually a pretty easy language to parse, interpret, and compile. This isn't actually an accident as the S-expression syntax I'm sure was initially chosen for it's machine regularity (in those early days of underpowered machines). Newer languages are syntactically much more complicated. Ironically most normal programmers, being human, seem to find the more complicated syntax easier and the "simple" S-expression syntax confusing (being backward much of the time to normal human convention). I always found it unambiguous, but go figure. It's also precisely this regularity that makes the awesome macrology of LISP possible. In Ruby you can manually build up strings and feed them into the interpreter, which is equivalent to simple backquote. But you can't do the kind of cool nested constructions that are trivial in LISP.
Well it certainly shows you how BAD/OLD the CMCL and ACL Garbage Collection code/algo's were (at least when I last used them in 2006). In ACL you could get these LispMachine-like multi-hour GCs. Now we use tons of GC based systems everyday (like browsers) without having to reboot too frequently.
For nearly two decades I was a diehard LISP advocate. I even forced all my programers to code three Crash Bandicoot and four Jak & Daxter games in custom LISP dialects that I wrote the compilers for (an article on one here http://all-things-andy-gavin.com/2011/03/12/making-crash-ban...).
But by the mid 2000s I started doing the kind of programming I used to do in LISP in Ruby. It's not that Ruby is a better language, but mostly it was the momentum factor and the availability of modern libraries for interfacing with the vast array of services out there. Using the crappy unreliable or outdated LISP libraries -- if they worked at all -- was tedious. Plus the LISP implementations were so outmoded. It was very hard to get other programers (except a couple enthusiasts) to work that way.
Ruby struct a decent compromise. And it's type system and object model are better than CL anyway. The syntax is more inconsistent, and the macro model nowhere near as good. But it turns out. Libraries and implementation matter a lot. Still, you can feel lots and lots of LISP influence in all the new runtime typed languages (Ruby, Python, etc). And 30 years later, listeners still rule!
A number of factors. Games were much smaller then and a competitive game could be done in 1-2 years by 2-4 people. The budgets were usually in the 5 digits. This made it much easier to do if you knew how. On the flip side, far fewer people had any programming expertise.
Now, it's possible to do something similar on the web, or with a cheap mobile game, but in console gaming (PS3, 360 etc) the games all run in the 8 digits (over $10,000,000!) and involve big teams, often over 100 people.
I and my partner started Naught Dog, Inc. from scratch (some various articles I've written on this here http://all-things-andy-gavin.com/video-games/). We went from 2 (us) to well over 100 employees. Building from bigger and bigger game one at a time. But we started in a much easier era (the 80s).
I just put my "place" on top of my todo list, or leave the editor up there.
If you are truly banging your head against a wall getting some distance can help. I'm just a stubborn mofo and can't relax if I have series ongoing bugs. They haunt and torture me -- so I prefer to terminate them before moving on to something else.
There are no magic bullets here. Becoming a great programmer takes a LOT of time and effort. It's fun and rewarding, but not exactly easy. :-)
I posted a comment complaining about his intellectual property theft (of my work) and he deletes it. LOL
Uh yeah. This is the original author, and Tech Talks shouldn't be posting my entire copyrighted text (even if I give it away -- which I do) without permission. I have no problem if someone does a little introduction or comment, and then a couple lifted paragraphs, then links to the original, but to copy it wholesale with no/little attribution is plagiarism.
and a part 3: http://news.ycombinator.com/item?id=2941688
and a part 4: http://news.ycombinator.com/item?id=2950413
I posted a part 2 -- except I actually made it a prequel -- but it's new nonetheless.