EPISODE 1651 [EPISODE] [0:00:00] ANNOUNCER: Portal is a 2007 game developed by Valve where the player encounter puzzles that must be solved using the portal gun, a device that can create inter-spatial portals between surfaces. Portal 64 is an open-source rewrite of Portal that can be run on original Nintendo 64 hardware. The game was developed by James Lambert and gained enormous praise as a technical and creative achievement. The project was ended in 2024 at the request of Valve. James joins the show to talk about the process of developing an N64 game, the toolchain for building Portal 64, its physics engine, the design of the N64 cartridge, and much more. Be sure to check out James's YouTube channel to see his work and get updates about his future projects. Joe Nash is a developer, educator, and award-winning community builder who has worked at companies including GitHub, Twilio, Unity, and PayPal. Joe got a start in software development by creating mods and running servers for Garry's Mod, and game development remains his favorite way to experience and explore new technologies and concepts. [INTERVIEW] [0:01:13] JN: Welcome to the show, James. How are you doing today? [0:01:15] JL: Thank you for having me. I'm doing very well. [0:01:17] JN: Awesome. So, we mentioned Portal 64 in the intro. We mentioned, of course, Nintendo 64, which might be a shock to some of our viewers, because that is a console that's a fair bit in the past for many of us. I want to know what is your journey to getting started developing for the Nintendo 64? And how did you come to start making a remake of Portal for Nintendo 64? [0:01:37] JL: Yes. I mean, I grew up playing Nintendo 64, and as a kid playing games on it, I wanted to make games. I got really excited about that idea. So, going back to make games on the N64 is always, it appealed to me. I just was on the Internet and noticed, like, “Hey, there's people who are developing tools that you need to make N64 for games, but using modern tools to run on the console now.” So, I wanted to give it a shot. I started tinkering around with the Modern SDK, which is taking Libultra, which is Nintendo's proprietary SDK, and running that using modern tools. So, you can just use Linux to build and create these ROMs. So, I started tinkering with that, and the first big project I did was a Gameboy emulator that runs on N64. That kind of got my feet wet. Then, they had a game jam, their first game jam for N64 games. So, I joined that and had a lot of fun making a game, Telocation: Gemini, if you want to find that one. That had a lot of fun making that game. Since then, I just been involved in making it N64 content, and every once in a while, I'd get an idea, like, “I wonder if this would –”. I would try things out. At one point, I'm like, “I wonder if I could do portals, right? The portal effect?” And I tried it out and it worked and got really excited. I'm going to see how far I can take this, and it just ended up going and getting a lot of momentum to the point where I was actually building out test chambers and building out the game to try to be as close as I can, but on N64 hardware. [0:03:12] JN: Perfect. Very cool. So, there's a couple of questions, I guess, I wanted to ask off the back of that. You mentioned along the way that you're using this modern take on Libultra, which is Nintendo’s SDK, and that you're doing that on Linux. What does your developer environment look like? What are you using in terms of text editor? What's the process of getting games into a ROM and I guess onto the N64? [0:03:37] JL: So, I just use the VS Code, and there's no real other – I mean, you could pretty much use any IDE. The person who's maintaining Modern SDK, they made it so you can just install it using APT if you're familiar with the Ubuntu or Vegas Debian-based system. So, you can just add that to his repository, and just APT install Modern SDK, which comes with some examples. It sets up a build environment where then you can just from a make file, say make, and it uses a version of GCC that targets the chipset or the architecture of the N64. So, it's able to compile the code to object files or in the L format, and then you get the final bundle of code. And then, you use a linker script to lay out the ROM layout. That usually comes with, at the beginning, you have to include headers for the N64. If you're familiar with the CIC chip, that's like their copy protection system. It adds headers for that, for the console to read. Then, after that comes the code segment that it lays it out, and the N64, when it boots, will copy the first megabyte of data from the cartridge into the RAM to run the code. Then, anything else after that, any assets you want to only be on the cartridge, and then you have to load those manually. There's a specific address space that you use when accessing. You say, “Okay, I want to copy from this memory range to this memory range.” The different parts of the columns are mapped to different memory ranges. So, the cartridge has a certain range. You say, “I want to copy that to memory, to RAM.” So, that's kind of how that works. [0:05:11] JN: Fascinating. Very cool. So, you mentioned getting involved in N64 because you had grown up with it, and you want to make games for it back then, and you found a way to do it as an adult. You mentioned these game jams. Where does portal come into it? Why did you decide to target portal for this? Was that a game jam idea that kind of grew? Or did it come from elsewhere? [0:05:30] JL: Let's see. I was experimenting with graphics techniques. So, a few of them are like doing real-time shadows and a technique, at least, I had never seen in the game. You typically see, the most advanced shadows you see on N64 games, they use shadow maps, where they render the character from the perspective of the light. Then, they just take that as an image and draw that image on the ground flat. So, it really only works well with flat surfaces. I wanted to try out a technique that's similar to shadow volumes, where you render the volume where, like the back of the volume of the shadow, and then you're able to render content that – I'm not describing it very well. But that was one thing I did. Then, another interesting graphics technique, trying to think of other ones I was tinkering with. But I had these ideas, and I just wanted to see if was possible to do the graphics, to the Portal effect at all. It was really like where it started out. I wasn't thinking I'd be making Portal. But then, as I was thinking about, “Well, what do I want to do to showcase the abilities?” Well, might as well make it look like Portal, because that's the most famous game that has, a Portal effect in it. It was after seeing how well it actually ran that I was thinking, “You might actually be able to make the full game out of this.” Because really, you think, okay, the Portal technique, it sounds like, “Oh, yes, that's really advanced. That's something N64 can't handle.” But really, it's kind of like doing split screen, but the split screens overlap. And N64 games do split-screen all the time. So, I figured I would just see how far I could take it. So, I grabbed the assets from the PC game in order to start porting them and downsizing them. This is a bit of a tangent, but in the process of compiling the game, I didn't want to have to like create low-res assets that I included with the project. I wanted it to be an automated process as much as possible. So, things like images and sounds. They're not part of the repo and said, if you want to build the game, you have to get these resources from Portal on PC. It can extract the sound effects, and then downsize them and re-compress them to the format that N64 needs, and that's all done as part of the build process. [0:07:36] JN: That's pretty cool. So, I saw that, when I went to play Portal 64, in the lead-up to this chat. I saw that you shipped it as a kind of install there, and you point it at your Portal installation, and I thought that was like a copyright hedge. Making sure that the person owns the portal assets, so you aren’t distributing them. But the fact so, it's actually taking the assets that exist on my PC, in this case, and converting them into the low-res format. That is very cool. What does that process look like? [0:08:02] JL: So, if you're familiar with make files, that's what I use. So, make file, what it does, it specifies an input file. In this case, like the bundle of resources from Portal, and then you say, “Take these input files”, and this generates that output file. Then you can now tell make, this output file that doesn't exist that's derived from these inputs, you just say make that file, and then underneath that, like dependency can declare the steps that computer needs to take to make that translation. Then, you can even chain them together. So, for example, Portal, the source files actually come in these pack files. They're a bundle of resources, and to make it easier to work with, I want to first extract all of those out into separate files. So, the first step is, well, I want to get all the sounds extracted from that pack, so I have a make step that says, to generate all these files, take the bundle, and then run this was an open-source project, somebody made that pick and extract the files and extract all the files app. Now, you have all the sound effects, but they're the full-quality sound effects that are uncompressed. So, then I have another make step that says, “Okay, now that I have that, I want to generate this specific file, and then it corresponds to that file in the Portal pack directory.” So, take that, run, I think it's using it's called SoX. It's an audio utility on Linux that can manipulate audio files. I use that to resample it down to a lower sample rate for memory reasons. Then, after that, I then use a tool that compresses the audio to the ADPCM format that N64 uses for its compressed audio. So, those are all separate steps that it runs in the make file, then it generates that output file of here's the audio. But then there's another step that will take all of the compressed audio files and then bundle them together into what's called a sound bank for the N64, which is just it has like a definition of here's all the sounds, but then the actual audio data, because it's so large, is actually streamed from the cartridge. It's not loaded into RAM ahead of time. So, just the description of the audio is in RAM, and then you say, “I want to play this sound with the sound effect. Here's where it lives in the cartridge.” And the audio system will stream it from the cartridge as it plays. [0:10:11] JN: Fascinating. Okay. I guess that brings me to a slightly tangential question. But like, what is in those cartridges like computing capacity-wise? Obviously, there's memory of some kind. But as Nintendo cartridges over the years have had various capabilities, actually, in the cartridge, what is it device-wise? [0:10:27] JL: Right. So, I don't know, great detail, but I will say what I do know. There is the CIC chip, which is their copy protection. The way that works is the CIC chip that N64 is able to communicate with that, and based on the content of the first megabyte of the ROM, it will go and read each byte, and then it will ask the CIC chip, “Okay, here's the data that is in the ROM”, and after feeding the data and doing this process, it's supposed to spit out a specific number at the end. That number is also saved with the cartridge. Then, N64 hardware also has like corresponding chips, so they do it in sync. So, when they get to the end of the process, it said, “Okay, does this number match?” If it doesn't match, then the N64 will actually do a hard reset and prevent the game from booting. So, you have to get that CIC to match. That's one piece of hardware, you have the ROM chip, and I know that in order to create aftermarket cartridges, they need to use an FPGA, which adds a little more complexity to just a basic ROM chip. Because most ROM chips, it just works where the console sends out, “Here's the address I want to read.” Then, the chip just spits out the data at that address. See, this is where I'm not certain. I think N64, they made proprietary ROM chips that weren't just so simple. I'm assuming those make it harder to create copies, is the assumption. So, that's there. These ROM chips that, there's probably something special about them. I don't know exactly what. So, you have that the CIC, the ROM chip. And then you also can have saved chips as well. You have EEPROM, SRAM, and Flash, and they're just different technologies for saving. Oddly enough, the EEPROM chip, if you use that, actually communicates the console communicates with the EEPROM chip, using the same bus that used to communicate with the controllers. Not sure why they made that decision. But just to send a command to the cartridge to save with EEPROM, you actually go to like the controller bus and say, “Okay, save as if I'm talking to a controller”, but instead it goes with the cartridge. I'm not sure why they do that. But the SRAM, SRAM is much simpler. It's just there's a specific address, that if you write to the address, it writes to the RAM, or if you read from that address, you're reading from that RAM, and that's battery backed. Then, Flash RAM, I think is similar, but it's not battery-backed, and there's different timing characteristics. You can't write nearly as fast to the Flash RAM as you can to the just SRAM. [0:13:01] JN: Very cool. You're breaking that down. Yes, I'm always – I think when I first realized in playing as a kid that like the same data was on the cartridge and not on the N64. I was like, “What is going on in here?” Obviously, having no idea about anything at that point. But yes, I've always been curious. So, you mentioned this point where you decided like, “Hey, I might as well just make Portal.” So, Portal 64, how much of Portal are we talking? How far did it get? [0:13:22] JL: So, they took it down. I did manage to get out a – I got Portal: First Slice done officially, which was the first 13 test chambers. Actually, you'll notice it's 13 test chambers. But when you get to the last test chamber, it says 12, that's because Portal, they start at test chamber zero, which I thought was a really clever joke because programmers like to start our arrays at zero. So, having GLaDOS, have test chamber zero be the first was just really fitting. But yes, the first 13 test chambers, which is right after you get the full portal gun. You get the full portal gun on test chamber 11. Then, in 12, you then get to do your first puzzle with both – where you have control over both portals. Then, after that, the demo ends. I did manage before I took the project down, I already had made progress on test chambers 13 and 14, and they're in an incomplete state, didn't look great, and there were a few little details like I wanted to fix. But at that point, I got the takedowns. I'm like, “I'm just going to release what I have.” So, if you're able to get the hold of the latest ROM, I think, the version 14, that will have those two test chambers as well with some missing details in them, but that's as far as I got. But within those test chambers though, I was able to get, trying to think of the list of features. I was sure to add like details like the security cameras and you can knock them off the wall, and if you do, GLaDOS has dialogue lines that she gives. I wanted to have like little indicator lights on the floor. So, when you push a button, they light up and show you, “This is connected to that.” I was getting to the point where I was at trying to add small details and getting – instead of just having the game be functionally there to actually start to feel like Portal and even be playable to somebody who's never played it before. Because I was realized, with those indicator lights, do I put them in? At least, early on, I wasn't sure if I was going to get there. But then I realized, well, if this is your first experience with Portal, Valve, I know they're really heavy with play testing. So, all of these little details they added and things that they've done in these test chambers, I'm sure we're there for very specific playtesting reasons. I was trying to match as close as I could, so that way, I would get the benefits that they discovered in doing that process, when they were making the game. [0:15:37] JN: Makes sense. When you say you matched as close as you could, I guess a useful thing for our listeners at this point is to emphasize like, what Portal 64 actually was. Because it's not a port in the sense that you were able to take existing code and put it on there. This is your writing. You had those source engines. This was a complete from-scratch rewrite. Right? [0:15:53] JL: Right. Yes. That is correct. I think being able to do as a complete rewrite meant that I was able to simplify a lot of the code in ways, so it could run on N64. I'm trying to think of like what – well, for example, I did have to rebuild the levels from scratch. I wasn't able to take their level format and translate it automatically. So, that actually was in the repo, which copies of low poly versions of the levels. But I had to cut details from some of the levels, or I had to do it in a way that was more efficient for the N64. If you're familiar with Hammer, which is their level editor, if you load up Portal in Hammer, you'll notice it's built out of a bunch of pieces. You'll have like, this is a wall section, and then you can combine it with other wall sections. The level itself is built up of lots of little wall sections that are all pieced together. And instead of doing that, I just had like, well, this is an entire wall. That's one piece. So, it meant I had to do a lot more manual work of just building out the levels exactly what they look like in the final game. But I'd imagine that the reason why that they had it as modular pieces is a lot easier for their level designers to iterate on ideas. Because they have this set of tools or pieces, they could piece together at the test chamber. And if they don't like something, they could go change it by adjusting and reusing pieces. So, in the iteration process, that's super valuable. But for me, when I was just targeting a specific final product, I could just look at the test chamber and say, “That's what it looks like”, and build it out exactly what it looks like as the final result, and I was able to be more slim and precise, and more efficient with my level creation, so that it could actually run on N64 for hardware. [0:17:33] JN: Awesome. Yes, I think you're right with that theory about Hammer. Actually, there was like a big Twitter discourse going on recently about how like no-level editors and even the big engines have replicated Hammer’s ease of iteration because of that kind of like object or, like brush-based methodology. I think the iteration speed is notable. So, obviously the other big thing about Portal as a game is the physics engine. And so, I wanted to ask, first of all, I had an N64 but I was quite young. I was looking back through my memory of, when I think of physics-based gameplay, I think the earliest game, I really think of something like that, is another Valve game. It's Half-Life 2. I can't think of any game on the N64 that really depended on a physics engine in the way that like a Portal or other Valve games, of that era did. Was there a physics engine comparable to what you've built on the N64 in its time? [0:18:17] JL: I don't know of any. Yes. If it’s a physics engine, there was an open-source project, I can't remember what it was called out. I want to give him credit that I based my implementation on. [0:18:28] JN: It was a physics engine for N64? [0:18:29] JL: It wasn't for N64. It was just an open-source physics engine for PC. It was, I want to say something Box. I don't think it's Box3D. And Box2D is a 2D physics engine. [0:18:40] JN: If you figure it out, we’ll put it in the show notes. If you're listening to this, check the show notes for that physics engine. [0:18:44] JL: Yes. So, I based mine on that. Actually, the code for, it’s called contact resolution is pretty close. Just their code, I just ported it to see. So, collision response, was just the – I guess, just a quick overview of how like a physics process works. You have a bunch of movable objects. I only implemented rigid bodies. A rigid body is simulated as like a single point. That one point has mass, and it has velocity, and angular velocity, and moment of inertia, which is kind of like mass, but for rotation. So, you have all those attributes on just single point, and that's pretty easy to simulate on its own if you're only applying forces and velocity to that. You have a pretty basic parabola trajectory for movement, for gravity. Like every step, you just say, “Okay, you have your velocity.” Add to the position, the velocity times time, and then do the same with velocity to acceleration, and then you're able to get the motion pretty easily. That's pretty simple to do. But then the difficult thing is you actually wanted to interact with things. And to do that, you have to do collision detection. So that, I wrote pretty much myself from scratch. And collision detection, I have a video that goes in greater detail, but there is a technique called GGAK or NEPA, and those are just acronyms based on the names of the people who wrote these papers, who –not a super memorable name. But they basically describe a method of, you take two convex shapes and quickly being able to find if they overlap. If they do, what vector can you use to separate them the fastest? Which way? Which direction you should push them apart, basically. So, those are very clever algorithms and very efficient actually for N64, because it's able to do what it does, in very small amount of code and memory. So, that's really efficient for the cache on the N64, which is very important. Because the N64’s RAM is slow. You have that part. I use that to do what's called context generation. You have the point mass as rigid bodies. You put a shape around them, a convex shape, and then with that, you're able to collide it with other shapes to generate contact points. Then, you take those contact points, and you pass them into the contact resolver. The contact resolver is the part that I didn't really write much myself from scratch. I based my implementation very heavily on that physics engine. But with all that, together, you're able to simulate the physics system. Because what the contact resolution does, is it takes that point rigid body, and it says, “Okay, you have this rigid body, but it's touching an object over here, and they overlap this much. What force do I need to push on that object to get it to spin or move, in a way that they separate?” That's the basic gist of it. My system, I only generate one contact per frame, at most one contact per frame per collision. And then I just keep the contacts around until I can tell that they've separated apart. That single point generation per frame was what, let me kind of get away with getting this to run on N64, more complicated solutions that try to generate multiple contacts at once. The physics engine is more stable and it works better, but it's more computation per frame. [0:22:03] JN: Yes, thinking back to, I mean, especially that you implemented. But first of all, in general, the physics objects that are moving aside from the player is mostly the Companion Cube, right? That’s not oddball things. It's a single virtual body that's contacting with surface geometry, most of the time. [0:22:19] JL: Yes, exactly. So, it was actually, there's not a lot going on. Even though you have realistic physics, there's not a lot of objects doing those physics. Two other shortcuts I take, one's a common shortcut for offices and physics engines, which is, if an object stops moving for a short period of time, you just put it in sleep mode, where it no longer is updating the contact resolution every frame. So, you're able to save a lot of time. Or say, “Well, this is not moving. I only wake it up if it hits something new, something that's already awake.” So, if two objects are sleeping, you can just ignore contacts between those two objects. That's one optimization, but that's fairly common. One that is not common, is I actually don't calculate moment of inertia correctly. Moment of inertia, I tried to represent it accurately, physics engines use a three-by-three matrix of data. The reason, you can imagine, if you have a really long metal rod, if you take that metal rod and you try to swing it, it's harder to swing side to side than it is if you take that rod and spin it in your hand. There's some axes in which it's easier to spin it than others. So, that's a moment of inertia. That's why I use a matrix, so that matrix could represent the attribute, that it's harder to spin in one axis than the other. But most objects in Portal, at least the most common one, the cube, you can actually get away with moment of inertia just being a single number for a cube. Because there's no axes at which it's – I mean, that’s not entirely true. If you spin it from corner to corner. A sphere, definitely. A sphere, it’s the same. But that treating moment of inertia as a single number, instead of a matrix. I just said, I'm going to try that and see how well the physics works in it. I mean, it's not noticeable. Nobody pointed out, “Hey, you're not using a matrix for moment of inertia.” So, it really would only show for longer objects, clearly. [0:24:14] JN: That brings me, I guess, to like, one of the things I was really curious about, which is different physics engines from game to game. Obviously, physics interactions are extremely finicky. I think everyone has had a Bethesda title do some weird specific stuff to them or whatever. When these are physics-based puzzles, I imagined – well, I want to know, I guess, whether getting the physics field exactly right was like important for making any of the puzzles work, or whether you had to like – you're implementing physics, but there are particular properties of the source physics engine. Were you trying to chase any of those at any point? [0:24:45] JL: So, for the most part, just using the correct value for gravity, and then trying to match the same velocities as much as I could seem to work pretty well, then just adjusting numbers until it felt right. Not necessarily to what they were using. I know like at one point, I realized that in Portal, they actually add an invisible platform in front of portals that are on walls. So, so that way, if you go through a portal, you can kind of go out of the portal a little ways before you fall, and you make use of that in some test chambers. So, I had to implement that to get a certain gap in test chamber, I think it was 10, where portal appears on the wall, you put another one and you walk through it, and you're able to kind of clear small gap. And in order for me to do that without jumping, to match the original game, I had to add that ledge. Once that ledge was in it, it did work. So, for the most part, it really wasn't a lot of tweaking, because I think they followed regular path. I did do screen recordings of playing Portal, and they had the feature where you can turn on where it shows the position on the screen. I was able to take that data right down, like do a spreadsheet where I say, “Okay, here's the position that attract frame per frame”, and then get a trajectory. Then, I was like, “Okay, well, given this trajectory, this is how much acceleration it's getting.” I was able to kind of figure out, “Okay, I think then I have the correct values and matching that.” So, there was a little bit of that. But really, in terms of getting the physics to feel right, I mostly just, it's kind of winging it. Another thing I had to do is when a fast object like a cube, if it's moving really fast and hits a wall, or a button, actually in this case is where it's important. You want it to lose a lot of energy, because you don't want it bouncing off the button. You want it to fall, hit, and then just stay. There's actually two modes of collision detection in Portal 64. One is for fast-moving objects, and one is for objects that are already touching. Fast-moving objects, I use swept collision. So, imagine you take the shape of the object – see, you have the object where it started, and then we've ended up. Then, you draw a convex shape around both of those, and so now you have this long-stretched object, and you do collision with that object against level geometry. So, that way, it can't tunnel through walls. When I'm in that mode, after detecting a collision, I'm actually able to just say, “Okay, you hit here”, and then I adjust the velocity as well, when resolving that collision. When a box hits a button, I cut its velocity. So, it ideally will stay on the button and not bounce off. [0:27:24] JN: Yes. Not flying around. Interesting. I guess one, kind of like a little physics detour. So, on your YouTube channel, which is great, by the way. You do some really, really wonderful exciting videos. You did a little bit of an exploration in tackling like a question about Portal, because Portal One didn't have moving portals, right? And you want to resolve what happened in this case. Can you tell us briefly about that? [0:27:43] JL: Yes. So, I was on Reddit, there's a discussion about what happened with portals and moving portals, and I just thought it just surprised me how many people supported my thought was, at least to me, seemed like the wrong answer. So, I'm like, “This isn't right. I need to explain why moving portals would work the way they do.” I decided, “Well, I'm working on a Portal physics engine, let's just implement moving portals.” So, I did, as a kind of a way to show, look, this is how it would work. I mean, I did that video, and then another follow up video. I feel like I pretty clearly explained my case. But there's still people who disagree. Just as a side note, when talking with Valve about whether or not they'd let me continue the project. In that conversation, one of the guys who originally worked on Portal One, was just telling me that he really thought the game was really cool and he was really impressed with it. Then, he also chimed in and said, “Yes, the portal paradox. I tried to explain to people why they would shoot out.” I just want to point out, one of the guys who originally worked on Portal One physics engine, agrees that the cube would shoot out, instead of stay stationary after coming out the other side. [0:28:57] JN: – now for that video and put a big Valve stamp of approval. [0:28:59] JL: Yes. [0:29:01] JN: Awesome. So, we'll get to that conversation, on Valve, very shortly. But I guess before we move on to that, just while we're talking about technical stuff. We've spoken a lot about the physics, that method like a virus limitation and that. Were there any other technical challenges that were particularly hard to overcome, or that surprised you in going about this project? [0:29:17] JL: One challenge N64 is the resolution is so small, that the details just really get mangled. Especially, really small things. There are plenty of objects in Portal, like the radio antenna, for example. I had to make that thicker to get that to look right, and just generally the challenge of low resolution, I guess, both in terms of the screen size, but also depth buffer resolution. There's a lot of Z-fighting artifacts in Port 64. I was making improvements. I was making things better there. But that was just kind of a limitation of the system. That, and the fact that the graphics pipeline uses fixed-point numbers for its 3D calculations which limits the range quite a bit on what values you can use, and that was leading to some graphical issues in some of the larger test chambers with the portals. So, that was kind of a big constraint that I had. I always had to keep trying to adjust things to make it work within those constraints. [0:30:20] JN: Awesome. Yes, I guess the resolution must be particularly tricky as well, when you're looking at things that are also for portals that are even, like, tinier than otherwise, right? [0:30:27] JL: Yes. [0:30:29] JN: Cool. You mentioned a couple of times that Portal 64, you've had to take it down. You mentioned, you [inaudible 0:30:33] Valve. Can you run us briefly for that situation, which I'm saying, knowing that you have a very good YouTube video about this? Don't want make your entire video, but yes, a brief overview would be great. [0:30:43] JL: Yes. So, somebody from Portal reached, from Valve reached out and I got in conversation with him about the project. I asked him, what could I do to officially get your permission to finish this project? Because I wanted to have – I mean, I was going to keep going until I was told to stop. But ideally, I just have their permission, because then I wouldn’t have to worry about that anymore. Right? They could say, “Yes, I'm able to finish this project.” Because not knowing whether or not you'd finish, like, I don't want to put another year or two into the project and have it stopped right before it was done. So, I was talking with some of their lawyers, and they're asking me some questions about, “Okay. How has this rolled out? How do you distribute this to people?” Then they asked the question, “Is there anything that Nintendo wouldn't like, basically?” Unfortunately, the answer to that was, “Well, I'm using Libultra, which is their proprietary SDK.” When they heard that, they basically said, “Okay, yes, we can't support it.” I'm sure they have to cover their legal bases. If they had an internal conversation about whether or not they would let me continue this project, and they say, “Yes, sure. If Nintendo gets mad, then we'll shut it down.” I feel like that would be a record that could go to court if Nintendo decided they wanted to sue Valve, right? They look, they let this person continue this project using our proprietary SDK, and well, maybe I'm not big enough target for Nintendo, Valve, certainly is. So, to Valve, it's like, they're just not going to go there. So, I did a follow-up question and asked, “Okay. Well, if I could port it to Libdragon, which Libdragon is an open-source, non-proprietary SDK for N64, would you let me continue it? They discussed a little further. I'm not sure what was said there. But they came back and said that they don't really want to have to worry about monitoring this project, or I'm sure, basically, to them, it's a liability and a cost potentially, to track it, and there's not really much benefit to them. So, they're like, just to cover themselves, because Nintendo's involved, they just said, “No, we're not going to allow this project to continue.” So, I understand that. It was a long shot, but I figured, if this project were to be completed, it would require both Nintendo and Valve agreeing to it, which would be a harder sell than just a single one of those companies. [0:33:05] JN: Yes, absolutely. So, I guess, seeing that whole situation, and also seeing it's not an uncommon situation, particularly, Nintendo have a bit of a reputation for this kind of thing. Hearing mainly from you that these N64 jams are such a common thing. I guess, one thing I wanted to ask you as both an N64 hacker, but also someone who's in that community. How do you approach being creative, and being a developer on these consoles, with that kind of always looming threat that the work will last a little bit and then might have to disappear for whatever reason? [0:33:42] JL: Right. Well, I like getting the work done. I like people being able to play the ROMs and the things they make. That's definitely part of it. But I feel like just the process of creating is a lot of fun and sharing it with people, and then being able to see it is part of the fun. I mean, ideally, it'd be great to have a final product that I could distribute freely and not have to worry about that. But I think the process and the exploration is part of the fun, for sure. [0:34:08] JN: This, I imagine, is a bit of a tricky question to answer. But if there are people listening to this, we're like, I want to have a go at developing on the N64, but I am scared of someone coming after me. What are the obvious things that people can do to avoid falling foul trouble? I imagine, Libdragon is a good place to start rather than using Libultra. [0:34:25] JL: Exactly. If you want to make N64 games and have any chance at being able to be successful and maybe even potentially monetizing, like selling. Libdragon. You want to use Libdragon. That’s not Nintendo's proprietary code. Then, be sure that you're not using any Nintendo branding. It’s nice it would be to have the N64 logo pop up when you start a game, unless you want to try to lay low and just hope Nintendo doesn’t crush it, don't do that. Don't put Nintendo branding on any boxes or cartridges. Make sure it's free from any of that branding. Use Libultra and, I think, legal advice. I think those are just things you can do to best avoid Nintendo's ire. But because I know people have sold commercial games, aftermarket games for NES, and they've succeeded there. And I think it's just as long as you avoid the branding, I think, it'd be in the clear. So, yes, that'd be my advice there. [0:35:25] JN: GB Studio, the community around GB Studio making Gameboy games. There's only been commercial games for the Gameboy from GB Studio as well. So, there's definitely – yes, that's a very interesting example, because I think the Gameboy, they came up with a pretty clever way to protect against copies or unlicensed games, when which, when you put the game in, and you boot it, and that Gameboy logo that shows up, that's actually part of the copy protection. Because the way they have it set up is the Gameboys first run some code that's supposed to display the Gameboy logo, and it tries to check. If it's not the Gameboy logo, we won't boot the game. So, that was their copy protection. The idea is if you create an unlicensed game, well, you have to show the Gameboy trademark, so they'd be able to go after you legally, right? Because that was a requirement to get it to boot. Well, hackers have since figured out ways to get around that where you can show any or some other logo that's not Gameboy and still have it. That is their way to get around that. [0:36:19] JN: So, these methods are so ingenious, and so technically cool. It's just such a shame the category of like thing they are doing with that. That's really interesting. Cool. I think, again, heavily not legal advice, but knowing about there is a non-proprietary s SDK out there is super helpful. And you've mentioned some of the game jams that you've got your start in. Are there particular events, or like communities that you would point people to, to get started if they were looking to do that? [0:36:47] JL: Yes. There's an N64-brewed Discord server. That's where I jumped in to get started and a lot of great resources there, and that Discord server alone is going to have, it has a page where a bunch of links where you can get started, and people create like open source tools to like compile assets to run on N64. I think, really, that’s be a good place to start. [0:37:10] JN: Awesome. I guess, the last question I have for you, well, almost last, I've got a bit of personal curiosity as well. Are there any developers who are making N64 content or content creators that you'd recommend that folks check out? [0:37:23] JL: I mean, there's obviously, Case. If you’re familiar with me, you're probably familiar with Case. You're doing really cool stuff. Modding Mario 64. I don't know of anything that's like you could go see on YouTube. I mean, there's the Smash remix project, which they're adding new characters to Super Smash Brothers 64, which I'm wildly impressed with that project. That was really cool. [0:37:44] JN: A Super Smash community, like across the generations is unhinged and very impressive to me. The melee community, especially. I'm in awe in every level of Smash community. They’re so dedicated to that game. [0:37:55] JL: Oh, yes. That's a great project. And I know, on the Discord server, I'm seeing people, somebody's trying to remake Five Nights at Freddy's for N64. There's an occasion that you see people posting updates from their own personal projects, their own original games, and there's a few that are making some pretty cool progress on that deal. You'll see on the discord server. I don't know of any places to send you to actually test it or to see the project, but certainly if any of those projects do finish and they release, I'll probably give a shout-out on my channel to him because I mean, they're very impressive projects to be doing solo developer. [0:38:34] JN: Awesome. But in the meantime, the N64 brew Discord is the place to hear about them. [0:38:39] JL: Yes, so that, I would recommend. [0:38:40] JN: Awesome. Yes, my one bit of curiosity. I’m wondering this since watching your YouTube videos. What is the red console behind you? Is that a Ouija board or it’s not a modded Switch, right? [0:38:51] JL: Let me grab it. So, it’s actually an N64 portable. [0:38:59] JN: As it came towards the camera, somebody was like, “That is bigger than I thought it was.” [0:39:02] JL: Oh, it is. It’s been a while since I've fired it up. [0:39:06] JN: So, for folks listening, this is like, if you imagine a Steam Deck-sized device, well a Steam Deck-looking device, but it is an entire N64. [0:39:14] JL: Battery’s dead, so I won’t be able to fire it up. But I made this around the time I started getting the brew development which is the kind of janky, in a lot of ways. You'll notice that the body is made out of wood, because I didn't have a good 3D printer at the time. [0:39:29] JN: Yes. I think making it out of wood is awesome. That's like, bring back wooden handhelds. I realized, having seen you bring out a piece of hardware that you've been working on. I forgot to ask a very important question. Now, that Portal 64 four s offline. What are you working on next? [0:39:42] JL: Right. There's still a few ideas for just tinkering with N64 hardware that I'm working on. Right now, I am trying to get the Oculus DK1 to work on N64. So, you'll be able to play a virtual reality game on N64. I'll probably have a few other random ideas like that, but I am just starting a new game project. I still in the early phases of just making ideas and getting kind of the foundation set up. Since I'm using Libdragon, I'm going to have to rewrite a lot of engine code. I'm not just going to be able to have a good starting point like I do for my Libultra-based game projects. So, it's still maybe a few months before I even have like a really basic prototype to show. But yes, I'm starting a new game project there. [0:40:26] JN: Awesome. Cool. Well, James, thank you so much. I've definitely learned a lot and I'm sure our viewers and listeners have as well. Thank you so much for joining me today. [0:40:34] JL: Thank you. [END]