The PSX had no real 3D capability, you could just throw a list of triangles at it to draw. The problem here is that you have to sort the list of triangles yourself, since there is no such thing as a z-buffer.
For Crash Bandicoot, since the path is essentially linear, they were able to pre-sort most of the triangles at build time, which allowed them to achieve greater visual fidelity compared to contemporary titles that allowed for freer movement.
Another challenge was dealing with foreground objects: you have to somehow sort these into the pre-sorted background polygons. This mostly worked with bucket sorting but we had to use the gross hack of allowing each foreground object to have tunable “push-back” to fix sorting glitches. This required manual work for each level.
Finally, while precomputing the per-frame sort order for a game like Crash would be trivial now, in 1995 we had to build our own Beowulf cluster thingy and farm the level precompute out in pieces to the artists’ SGI workstations, and levels typically took an hour to process. The artists LOVED that. :)
Additionally, I have written my own PSX software as well as reviewed plenty of contemporaneous PSX software. While many have some bit of assembler, it's usually specifically around the graphics pipeline. About 90+% of all code is C. This is in line with interviews from developers at the time, as well.
The point wasn't that ASM wasn't used at all (in fact, I specifically acknowledged it in my original post), it was that the PSX was in an era passed the time when entire codebases were hand massaged/tuned assembler (e.g. "the 16-bit era" and before).
Even Naughty Dog went with their own LISP engine for optimization versus ASM.
And this thread comes full circle: Mark Cerny actually significantly improved the performance of my original version of the Crash collision detection R3000 code. His work on this code finally made it fast enough, so it’s a really good thing he was around to help out. Getting the collision detection code correct and fast enough took over 9 months —- it was very difficult on the PS1 hardware, and ended up requiring use of the weird 2K static RAM scratchpad Sony including in place of the (removed) floating point unit.
GOOL was mainly used for creature control logic and other stuff that didn’t have to be optimized so much to be feasible. Being able to use a lisp dialect for a bunch of the code in the game saved us a ton of time. The modern analogue would be writing most of the code in Python but incorporating C extensions when necessary for performance.
Andy made GOAL (the successor lisp to GOOL) much more low-level, and it indeed allowed coding essentially at the assembly level (albeit with lispy syntax). But GOOL wasn’t like this.
https://ifdb.org/viewgame?id=c896g2rtsope497w
Graham Nelson ported my port to his Inform language, and Inform is probably your best choice if what you actually want to do is write a (plain text) adventure game.
If you want to learn C programming, writing a text adventure in C would be a fun learning project! But aside from pedagogy there’s no real reason to write a text adventure in anything other than Inform, TADS, etc. Not only is it much easier to use one of these purpose-built languages, with Inform you get multi-platform compatibility going back to the 8-bit era for free!
Personally if I had any free time, I’d be more interested in looking at how to use a frontier LLM like llama as an integral part of a text adventure. There was something like this using GPT-2 circulating on here a while back, but it was pretty rough.
However, it’s clear that if you figured out how to precisely control the LLM so it didn’t produce crazy stuff, you could realize the dream of truly realistic NPCs in these games. Text adventures would seem to be a perfect laboratory for experimenting with this.
https://en.wikipedia.org/wiki/ATPCO
However, interpreting this data properly is decidedly nontrivial (>1M LoC).
Pricing does not imply booking is OK, though. And even circa 1999, Southwest hassled us (ITA Software) about even showing their fares, without us offering any way to book any flights on any carrier.
The packer was the final step after a level was pre-sorted and otherwise processed. It was quite fast, so it added only a little bit of extra time to the primary work of pre-rendering every frame of the level to recover the sort order (which typically took around an hour).
I did experiment with solver algorithms but they were so obviously going to be too slow that I abandoned the idea.