[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)