[HN Gopher] Pokegb: A gameboy emulator that only plays Pokemon B... ___________________________________________________________________ Pokegb: A gameboy emulator that only plays Pokemon Blue, in 68 lines of C++ Author : brundolf Score : 320 points Date : 2021-06-04 18:31 UTC (4 hours ago) (HTM) web link (binji.github.io) (TXT) w3m dump (binji.github.io) | mettamage wrote: | You might want to add (obfuscated) to the title. The actual | source code, while small, is much larger [1]. (edit: at 589 lines | it's still impressive!) | | For people who like this kind of thing and/or for people who want | to be able to understand what is going on at all, you might like | the course NAND2Tetris [2]. It's a good prerequisite to | understanding this blog post if computer systems isn't a topic | that one has explored before. | | [1] | https://gist.github.com/binji/395669d45e9005950232043ab4378a... | -- the author notes this in the article. | | [2] https://www.nand2tetris.org/ | nighthawk454 wrote: | Still, the unbofuscated one is only 589 lines including | formatting, a copyright header, and what looks to be an 80-char | line limit. | | Seems sufficiently interesting either way | Aachen wrote: | See, the truth is just as impressive to me, but knowing it's | not a lie and a more than fair line length makes me | appreciate it. | smithza wrote: | 68 lines of code is pretty much arbitrary. It could have been | far less, he just put it all to fit his poke ball pattern. | ngokevin wrote: | The obfuscated one is awesome though, the code is in the shape | of pokeballs! | userbinator wrote: | I think instead of line count, either final binary size or | source code size in bytes should be more common in claims of | minimalism; the demoscene, for example, always uses binary | size. | Ekaros wrote: | Final binary size including all external dependencies is | probably fairest metric. With heavy use of libraries things | get messy. | binji wrote: | I got kinda dragged about this on reddit/twitter. Afterwards | I posted on r/tinycode with the size in bytes: | | https://www.reddit.com/r/tinycode/comments/nn5djb/pokegb_a_g. | .. | iampims wrote: | Don't let any of these comments take away from how great | this is, _especially_ with the in-depth blog post. | IgorPartola wrote: | Number of nodes in the AST or number of machine instructions | might be more meaningful. | deathanatos wrote: | That metric is game-able, too: you just implement a VM, and | only count the instructions to to VM. The rest is one big | binary blob of "data", occupying a single node in the AST | of the host language. | | Now, of course, that's basically cooking the books, but | there's a wide gulf between a full VM & smaller, domain | specific ones that might not _look_ like VMs. (All or most | of data-driven programming, really.) | [deleted] | vmception wrote: | "This is super impressive Binji we would love to have you on our | team, now that you've got our attention pass this leetcode | challenge with a random assortment of unrelated skills instead, | and faster than the people that only study this specific kind of | test" | tkiolp4 wrote: | Ha. This made my day. | binji wrote: | Ha, I guess we'll see when I go for my next gig :-) | andrewmcwatters wrote: | > When I started pokegb, I spent most of the first few days | implementing the CPU. Every time I hit an instruction that wasn't | implemented, I'd implement it and see if it would run any | further. | | If you've ever written a drop-in replacement for some existing | piece of software and filled the implementation with a bunch of | `notimplemented()` (example)[1], you know exactly how satisfying | this is. I love it. | | [1]: | https://github.com/Planimeter/lgf/blob/master/lua/framework/... | binji wrote: | It really is one of the best things about emulation | development. It's surprising how quickly you go from "nothing | works" to "I'm playing Super Mario Bros!" | missblit wrote: | I never did get very far with my NES emulator after getting an | actual job (it was plan B for if no one liked my resume), but I | do remember that being oddly satisfying [1] | | [1] | https://github.com/missblit/nesnes/blob/master/instructions_... | city41 wrote: | It's one of my favorite things about programming. For example | I made a Neo Geo tile viewer and decoding the format and | figuring out just what needs to be done to get it working | then suddenly BAM! tiles tiles everywhere! It's so | satisfying. | makapuf wrote: | I made a game console on an embedded system. The magic when | you actually bitbang pixels to a screen and you see that | first image is breathtaking. | tiddles wrote: | This x1000. I started implementing a JVM for shits and giggles | a while ago, and once I had laid out ~220 panics for each | opcode, it was incredibly satisfying to implement them one at a | time to work towards bootstrapping the standard library. | | Granted, most opcodes are implemented incorrectly as minor | things like method and field resolution aren't quite there | yet.. as soon as I've implemented enough opcodes to actually | run something and return/exit/throw, the correctness will be a | bugger to fix :^) | binji wrote: | JVM is a great choice! You might also want to check out | WebAssembly too (full disclosure: I used to work on wasm). | There aren't too many opcodes, and a lot of them are | relatively simple math operations. | | Once you get it working, you could run things like JSLinux! h | ttps://bellard.org/jslinux/vm.html?url=win2k.cfg&mem=192&gr.. | . | javajosh wrote: | Given your experience at this level of abstraction, do you | have any thoughts on what an ideal set of opcodes look | like? E.g. something like Knuth's MMIX. Do you prefer RISC | or CISC? What about RISC-V? How much do the designers of | real-world micro-architectures talk to folks like you? | | A bit of a tangent, I know, but it feels important. | binji wrote: | I'm probably the wrong person to ask, to be honest. I was | around for a lot of the design of Wasm, but wasn't really | involved at that level. | | That said, in my opinion the ideal set of opcodes really | depends on your goal. There were many goals For Wasm, but | I think there was a focus on keeping it small and simple. | Originally it was AST-based, but it was changed to a | stack machine to reduce size. It was also designed to be | AoT or JIT compiled, so the opcode layout is not | particularly friendly to hardware decoding or | interpreters (although people have made some very high | quality Wasm interpreters). | | And of course there were a lot of discussions and | disagreements about the best way forward: AST vs. | register VM vs. stack machine. Structured control flow | vs. goto. How to handle unreachable code. How to store | integer literals (LEB vs. prefix byte). What the text | format should look like (sexprs vs. ...?) etc. | skitter wrote: | I've just started the same, it's definitely fun. One thing | that surprised me about field resolution is that a class can | have multiple fields with the same name (if they have | different types). | binji wrote: | Hi all, I'm the author of this post! Happy to answer any | questions. :-) | shawntan wrote: | Does the MissingNo glitch work? | binji wrote: | Not sure, I think it should! Would be really cool if someone | tried it out. I'm a little worried I didn't implement some | necessary instructions/hardware features so the game isn't | actually winnable :-} | Andrex wrote: | I hope it's OK I blogged about your project! | | https://gameboy.blog/2021/06/04/good-read-pokegb-a-gameboy-e... | crowf wrote: | I may have missed it in the post, but how is blue different | than red? I realise that they have slightly different Pokemon, | but is that enough to make the emulator run only blue? | binji wrote: | Oops you're right, I should have mentioned that. Red works | too, I just didn't want to write Blue/Red everwhere :) | glhaynes wrote: | In the spirit of the project I'm surprised you didn't pick | "Red" because it's one fewer characters. :) | Y_Y wrote: | It probably needs less memory, since you only 8 bits to store | blue but red needs 3. | belthesar wrote: | This reminds me of the GB emulator that ran inside of Pokemon | Stadium. Folks found some tricks to make it work with other | cartridges, but it turned out the emulator was not complete. | https://n64today.com/2019/06/02/play-game-boy-games-on-n64/ | ReflectedImage wrote: | I wrote a GB emulator, the main issue was debugging it. Subtlely | wrong tends to lead to game crash very quickly. | | The trick I used was to take an existing GB emulator, add a | printf debugging statement to print out each current instruction | and the registers. Add the same printf statements on mine. Then | use diff on the outputs of both emulators. | | It does play Pokemon. The emulator is called FireGB. | progbits wrote: | Comparing to an existing, known-good emulator is probably the | most convenient way. This can be printf debugging like you | describe, or even trying to compare framebuffer contents etc. | | However I feel like that "spoils" a bit of the fun. A more | adventurous approach is to test with test ROMs [1] - they are | simpler to follow by hand and discover why they don't work than | real games. | | Of course if some game ROM is relying on some more obscure | hardware quirks this might not be enough. Just wanted to bring | it to attention for anyone interested in writing and debugging | their emulators. | | [1]: https://gbdev.gg8.se/wiki/articles/Test_ROMs ___________________________________________________________________ (page generated 2021-06-04 23:00 UTC)