OpenGOAL: Port of Jak and Daxter, written in GOAL, a custom Lisp by Naughty Dog
github.com
github.com
https://www.youtube.com/watch?v=oSmqbnhHp1c&t=55s
Starting at around 10m into the talk, Liebgold says their DC language for TLOU (to get what they most needed from a DSL even if using C++ instead of GOAL) was implemented in Racket.
For anyone not familiar with TLOU, it was a critically-acclaimed game, and my personal all-time favorite game for storytelling that somehow grabbed me. (I dislike all zombie franchises, but at a key point towards the end of the nonlinear narrative and playing in the game, I was surprised how much I really wanted to protect the kid. Which I'll partly attribute to a Lispy DSL that helped them execute immersive storytelling in a zombie stealth shooter.)
https://en.wikipedia.org/wiki/The_Last_of_Us#Critical_respon...
This is one of the Racket success stories. They seem to happen because someone already knows they want a Lisp, they end up picking Racket without needing anyone else's permission, and the people using it are capable of designing and building whatever missing pieces they need.
https://en.wikipedia.org/wiki/Game_Oriented_Assembly_Lisp
https://all-things-andy-gavin.com/2011/03/12/making-crash-ba...
If someone hasn't seen it, his episode on Ars Technica's War Stories was awesome. He seems to be a hacker's hacker. It's a fascinating story because it's not really how I personally work (internally), so it's fun hearing someone describe just diving in like that.
https://www.youtube.com/watch?v=izxXGuVL21o
https://www.youtube.com/watch?v=pSHj5UKSylk
It was my understanding that Racket wasn't in use anymore at Naughty Dog. It would be cool if there was an update or someone who knows (I know Dan is no longer at Naughty Dog), because unfortunately the tale of Lisps in companies is normally that it eventually gets replaced or set aside (where new stuff is built in something else).
Any sufficiently advanced Common Lisp or Scheme program will eventually be rewritten in C++, Java, Python, or JavaScript.
Another possible factor: When I was at Google there was a similar phenomenon where any sufficiently complicated Python system seemed to get reimplemented in something with static types. A problem we had with Python (and I imagine this would be true of most Lisps -- yes, I know typed Racket exists) was that once a system got too big to keep in your head all at once, large-scale refactoring became almost impossible without the help of static types.
My personal opinion is that there aren't any huge barriers to making static and dynamic types meet more in the middle. There's the gradual typing approach like that in Racket and Typed Racket, but I feel that most of the times dynamic languages are really just dealing with fairly simple anonymous unions. Like a function make take a string or float and return some data structure or a boolean value.
I'd change that: `s/sufficiently advanced/sufficiently profitable/g`
The state of advancement is no indicator that something needs to be maintained, while the state of profitability is a reliable indicator that something will be maintained.
Wikipedia page on GOAL says exactly this happened.
"In all honesty, the biggest reason we're not using GOAL for next-gen development is because we're now part of Sony. I can only imagine Sony's shock when they purchased Naughty Dog a few years back, hoping to be able to leverage some of our technology across other Sony studios, and then realized that there was no way anyone else would be able to use any of our codebase."
https://guide.handmadehero.org/hmcon/2016/05/
My impression isn't that scheme is being passed out just because Sony doesn't like it, but also because the language has issues. On the other hand, it seems they're putting a lot of effort into getting the nice scheme features, like hot reloading, in their C++ environment.
Thank you to the authors for fulfilling a teenage dream. Please consider doing Last Of Us next —- I once downloaded it and tore it apart for any signs of lisp, but it was all compiled bytecode. That’s where I gave up, but it looks like you took it one millennium further by reverse engineering the bytecode from Jak and Dexter to make your own port that compiles to the same bytecode. If you have infinite time, you could theoretically do this for last of us too, and also last of us 2.
Edit: MzScheme
Although the engine is mostly C++, the bits that aren’t are usually the most interesting. And the most impactful. So it would be neat to analyze, if for no reason other than archaeology.
I distinctly remember EA pushing the Frostbite engine on bioware and thus ruining the franchises in production (MassEffect Andromeda/ Anthem).
Is this just another case of visible external costs (engine licensing) vs invisible internal costs (complete restructuring/retraining of existing pipelines/ engine rewrites)?
1. If you're pushing the platform, you need every part of the asset pipeline to be optimized for it, and probably lower level runtime optimizations too.
2. If you're doing something well within the constraints, your bottleneck is on implementing the specific types of assets that will make your game unique. As games get more featureful more and more micro-categories of assets show up - bits of UI text, custom behaviors, scene transitions, camera movements and so forth.
3. If you do 1, then 2 becomes more challenging because you made more optimizing assumptions, so the game production may fall off schedule due to lousy tooling making it hard to actually test anything in-game. If you focus on 2, you don't have as many reusable parts, and you're adding pressure to optimize near the end of the dev cycle, which can result in catastrophic bugs from changing assumptions in the asset-code mix, like "we tightened when we load in streaming assets. This broke a cutscene trigger because now it loads at the wrong time."
And then you add in an external tech group and you have another layer of communication to deal with, so the design or art teams can't just grab a coder and say "hey, this workflow sucks, give me a little support on this." Whether it's in the org or third-party, it's the same problem: you really need engine coders on staff to handle some things.
But the case can always be made: "if we have an internal engine group we can put all the smartest people in one place and have them develop the next-gen graphics." And once you have that group, it's politically necessary for the management to make its tech as widely deployed as possible, otherwise, why budget for them? The engine teams at large publishers who follow this kind of hard separation are known for having relatively cushy, high-profile gigs, while game teams are disposable bodies that churn out necessary but low-value features. Conflicts of interest and fiefdoms emerge from that. Some of them do enforce rotations and other protocols to lower the barriers.
I swear I remember a YouTube video from naughty dog about lisp, and that it was about one of their later engines. But at this point I think I just hallucinate parens wherever I go, so maybe not.
Bet it was the most extensible dialogue system ever though.
If I'm reading this right, the original Jak and Daxter was written in a Lisp, too? If so, that's pretty cool and I wouldn't have guessed.
But GOAL didn't have a GC, so it might not really count as Lisp.
Edit: I was just randomly watching this video (https://www.youtube.com/watch?v=cHkk9isDfg4), and Dave Baggett came up. When I searched his name, it does look like he was a co-founder of ITA after leaving Naughty Dog.
ITA's use of Lisp was driven by our co-founder and Chief Scientist, Carl de Marcken. He wrote the prototype in LispWorks, then the production code in Allegro, and then we finally ported everything to CMUCL when Franz essentially tried to extort us for a tax on our entire business. (We couldn't imagine this would become the norm for consumer "apps" five years later, but that's another topic entirely.)
Ultimately the MIT AI Lab circa 1993 was the source of the decisions to use lisp for both these commercial products. At the time, the lab's culture was still very much influenced by all the work done there and in spin-off companies in the late 80s commercializing lisp, e.g., at Symbolics (first registrant of a .com domain name!)
At INKY (my current startup) we use Python. By 2010, when I started the incubator that evolved into INKY, it was pretty clear that scaling a development team on a lisp stack was going to be really difficult.
> Ultimately the MIT AI Lab circa 1993 was the source of the decisions to use lisp for both these commercial products.
I suppose another example is iRobot, where there's a custom Lisp-like language used, at least in the earlier robots. My understanding is that it's not used as much anymore if at all.
> ITA's use of Lisp was driven by our co-founder and Chief Scientist, Carl de Marcken.
I chuckled at his website that states "I retired long ago and almost certainly do not find whatever commercial project you want help with interesting".
> At INKY (my current startup) we use Python. By 2010, when I started the incubator that evolved into INKY, it was pretty clear that scaling a development team on a lisp stack was going to be really difficult.
If you were to start it today, with the developments of languages like F#, Elixir, and Clojure, do you think you'd have a different decision or outcome? I'm just curious, as a hypothetical.
I've found that I like Fennel (and Janet as well, both created by the same author, though they have different maintainers) quite a bit. Turns out that having simple semantics and a very regular syntax makes for a language that makes writing basic code feel nice.
Next step is to make a cookbook of classical Game AI techniques (monte carlo tree search, goal oriented action planning) in GOAL. Then it becomes a package anyone can use, like PhysX and RAD tools ;)
I'll never understand why, compared to the other Naughty Dog franchises, it was basically dropped and forgotten. Or why Ratchet and Clank was favoured (comparitively bland and boring imo).
TL;DR for folks is that they left a lot of debug information in the build. The C code was compiled with no optimizations (and included debugging symbols), and GOAL uses a string-based table for global functions/variables/types, so they're starting with all those for free. Plus they don't think the GOAL compiler did too much tricky-to-undo optimization either.
That and I've always wanted to check out the language after Andy Gavin (ND founder) talked it up on here [0]
'Abuse' had a substantial lisp component.
I had no idea Andy Garvin was on hn, but makes sense :)! I had a vague memory that Super Mario 64 also used lisp and when I googled, I found him again [0].
You've likely seen this, but I recently watched and loved this extended interview with him about making Crash Bandicoot [1]. Really made me want to look more into making video games.
It also had great tutorials and documentation: http://www.aaronjamesrogers.com/misc/nworld/N-World-Intro.ht...
It's a shame that its successor Mirai https://en.wikipedia.org/wiki/Mirai_(software) just kind of vanished. Its main claim to fame is Gollum's face. Chronologically it's not that different from Blender, which also imploded around the same time in the early 2000s, but Blender was able to go open source and survive and have another 20 years of development to get where it's at today. I don't know that the world would look all that different if Mirai had been able to take a similar path, but at least there'd be a cool modern 3D modeling tool in Lisp.
Sadly not that uncommon in Lisp advocates for a number of different things even today... though I think that's been slowly changing as more Lispers either become aware of what's out there, or come with experience of what's out there and bring that knowledge with them to Lisp. The reverse direction seems to happen at least as slowly -- I've commented before that a JRebel setup is very close to bringing the still largely unique interactive development mode of Lisp over to the Java world, but it's also in important ways not fully there and may never be. Meanwhile many other languages don't even care about that development style at all.
> The “it’s easy to implement yourself because Lisp!” argument was laughable
I guess this would be kinda analogous to when Blender first added Python support, if they told everyone to just do expected things themselves. It may be true that such-and-such task is relatively easy to implement (if indeed it's possible to do at all without changing something about the application itself) but it's also just a terrible thing to focus sales on when the value seems like it'd mostly be measured by how useful the tool is to non-programmers.
I hadn't really looked much at the "Wide Open World" doc on the archive since it's not mentioned in the other docs except vaguely in like one spot I had to search for, but if a customer had heavy scripting needs to accomplish things not already provided or easily done with the graphical tools, now the customer's not only being sold on a graphics tool but also on learning to program in Lisp using their bundled xemacs. And as you note it's even worse when that work is already done in another tool that can't be integrated with. Though I see they provided an FFI so there could be a possibility of integrating C code the customer or others wrote. If a customer was expecting to have to do a bunch of new custom stuff regardless of tool maybe it'd have made more sense... But now at least I have an additional insight into why they weren't very successful.
I'm appreciating anew a lot of things the last products I worked on got right in terms of providing a good enough and frequently improving out of the box set of components and workflows while paying some attention to competitors to see what key things were lacking on either side, while streamlining development and deployment of custom components, and also providing a platform for customers to share their own custom work with each other either openly or by putting a price on it.
Not sure if they integrated a full Lisp or Scheme system, but since the rules were not arbitrary source code, nor doing unification, etc., they could have just hand rolled a custom reader, and written the rule engine itself in C...
https://en.wikipedia.org/wiki/MIT_Computer_Science_and_Artif...
https://en.wikipedia.org/wiki/Incompatible_Timesharing_Syste...
HN discussion: Zork source code, 1977 (github.com/mitddc)
https://news.ycombinator.com/item?id=23108626
https://github.com/MITDDC/zork
About MDL:
https://en.wikipedia.org/wiki/MDL_(programming_language)
>MDL (programming language)
>Paradigms: Multi-paradigm: functional, procedural, reflective, meta
>Family: Lisp
>Designed by: Gerald Sussman, Carl Hewitt, Chris Reeve, Bruce Daniels
>Developer MIT Project MAC
>First appeared: 1971; 51 years ago
>Final release: 105 / 1980; 42 years ago
>Typing discipline: Dynamic, strong
>Scope: Static, lexical
>Implementation language: MDL
>Platform: PDP-10, VAX, Apollo/Domain
>OS: ITS, TENEX, TOPS-20, BSD, AEGIS
>License: Open-source
>Influenced by: Lisp
>Influenced: ZIL, Planner, Scheme, Common Lisp, Java, Prolog, Smalltalk; actor model, interactive fiction
>MDL (Model Development Language, or colloquially also referred to as More Datatypes than Lisp: or MIT Design Language) is a programming language, a descendant of the language Lisp. Its initial purpose was to provide high level language support for the Dynamic Modeling Group at Massachusetts Institute of Technology's (MIT) Project MAC. It was initially developed in 1971 on a PDP-10 computer on a time-sharing operating system named Incompatible Timesharing System (ITS). It later ran on TENEX, TOPS-20, BSD, and AEGIS.
>The initial development team consisted of Gerald Sussman and Carl Hewitt of the Artificial Intelligence Lab, and Chris Reeve, Bruce Daniels, and David Cressey of the Dynamic Modeling Group. Later, Stu Galley, also of the Dynamic Modeling Group, wrote the MDL documentation.
>MDL was initially called Muddle. This style of self-deprecating humor was not widely understood or appreciated outside of Project MAC and a few other early citadels of information technology. So the name was sanitized to MDL.
>MDL provides several enhancements to classic Lisp. It supports several built-in data types, including lists, strings and arrays, and user-defined data types. It offers multithreaded expression evaluation and coroutines. Variables can carry both a local value within a scope, and a global value, for passing data between scopes. Advanced built-in functions supported interactive debugging of MDL programs, incremental development, and reconstruction of source programs from object programs.
>Although MDL is obsolete, some of its features have been incorporated in later versions of Lisp. Gerald Sussman went on to develop the Scheme language, in collaboration with Guy Steele, who later wrote the specifications for Common Lisp and Java. Carl Hewitt had already published the idea for the language Planner before the MDL project began, but his subsequent thinking on Planner reflected lessons learned from building MDL. Planner concepts influenced languages such as Prolog and Smalltalk. Smalltalk and Simula, in turn, influenced Hewitt's future work on the actor model.
>But the largest influence that MDL had was on the software genre of interactive fiction (IF). An IF game named Zork, sometimes called Dungeon, was first written in MDL. Later, Reeve, Daniels, Galley and other members of Dynamic Modeling went on to start Infocom, a company that produced many early commercial works of interactive fiction.
>In 1980 Marc Blank and Joel Berez adapted the MDL language to create a subset called ZIL (Zork Implementation Language) which was used extensively by Infocom to create their award winning games.
<DEFINE EXIT-TO (EXITS RMS)
#DECL ((EXITS) EXIT (RMS) <UVECTOR [REST ROOM]>)
<MAPF <>
<FUNCTION (E)
#DECL ((E) <OR DIRECTION ROOM CEXIT NEXIT DOOR>)
<COND (<TYPE? .E DIRECTION>)
(<AND <TYPE? .E ROOM> <MEMQ .E .RMS>>
<MAPLEAVE T>)
(<AND <TYPE? .E CEXIT> <MEMQ <2 .E> .RMS>>
<MAPLEAVE T>)
(<AND <TYPE? .E DOOR>
<OR <MEMQ <DROOM1 .E> .RMS>
<MEMQ <DROOM2 .E> .RMS>>>
<MAPLEAVE T>)>>
.EXITS>>
The MDL Programming Language Primer, Michael Dornbrook, Marc Blank:http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TR-29...
The MDL Programming Language, S. W. Galley and Greg Pfister:
http://ifarchive.org/if-archive/programming/mdl/manuals/MDL_...
The MDL Programming Environment, P. David Lebling:
http://ifarchive.org/if-archive/programming/mdl/manuals/MDL_...
There are some indie games done in Lisp, including at least one small Visual Novel released on Steam and another currently in development (2d platformer called "Kandria").
Several games, both indie and not, used Lisp as development tool - this includes games like "What Remains" (hn link: https://news.ycombinator.com/item?id=20930986 ) as well as numerous tools used IIRC at Nintendo.
[0] - https://www.reddit.com/r/programming/comments/6e6zwn/i_had_n...
I have seen a lot of claims of this but no real evidence? And I know Lisp quite well (having implemented my own versions of Lisp for fun). If Lisp truly is way more productive than other languages, why haven’t we seen lots of Lisp software out-competing software written in other languages? Surely a few Lisp guys could outcompete everybody else if Lisp is as super productive as claimed.
[1] http://www.codersnotes.com/notes/disassembling-jak/ (my old article this is based off)
On a related note, back when I was engine programmer for a PS2/Wii/Xbox engine I remember my boss always coming and saying "How do we get it to draw more in the distance. Just like Jak and Daxter!". It was a high bar to reach.
And out of this we get a free implementation of GOAL, long thought lost!
Certain kinds of techies were particularly enamoured with Jak & Daxter because, at a time when console devs rarely spoke much about the tech behind their stuff, and at a time when games were almost universally programmed in C/C++ with bits of assembly language, the developers of Jak & Daxter openly discussed how they had written the bulk of the game logic in a custom Lisp dialect they called GOAL, which itself was built with Common Lisp. If you don't know what Lisp is or understand why that's cool, well - Lisp is a very interesting programming language that pioneered a lot of incredible ideas in computer science and that certain hackers develop a real connection to, including one of the biggest names behind this site/Y Combinator, but has always struggled a bit in the market. Seeing it used in a AAA game production like this was, for those hackers, really exciting; maybe because it might be the beginning of an industry-wide move towards Lisp (which never happened), or maybe just because a Lisp success story like this was vindicating.
This appears to be a (work-in-progress) source port of the game and the GOAL language, produced with a lot of reverse engineering work. So it's neat to finally get to see first-hand this GOAL Lisp stuff that we've heard about for years, and if the project reaches completion it'd also make for a great way to play the game on modern hardware or mod it.
https://www.youtube.com/watch?v=5zGok-jEWO4&list=PLWx9T30aAT...
But fully fleshed out debug UIs are cool and useful in the large. There's a guy who's been integrating a bunch of C++ stuff including Dear ImGui into a Lisp engine, see: https://twitter.com/borodust/status/1443647135765962763 and https://twitter.com/borodust/status/1446569651236921346
In this case they were debugging the render, to fix problems that result in game’s own graphics being unusable. So they added their own system on top, so that they can inspect the data being sent to the gpu, turn on wireframes, etc. It’s a delightful look at what all of computing is going to look like in a thousand years, with layer upon layer of tooling as new generations of engineers adapt older programs to work on new systems. Remember “A Deepness in the Sky”?
I hope to return to https://github.com/NixOS/nixpkgs/pull/72366 at some point, so all arches can be built similarly!
https://github.com/water111/jak-project/tree/master/decompil...
Will be watching with intense interest, Jak & Daxter was my childhood.
This is the kind of project I wish I had the technical chops for.
I think Crash 2 was about the sweet spot and what they should aim for. Once you got good, you could sort of flow through the levels smoothly.