Baruco 2014: How I Built My Own Twitch-Plays-Pokémon

Baruco 2014: How I Built My Own Twitch-Plays-Pokémon

As the slides don't really say much, the content of the talk is going to be published as a series of blogposts.
http://ajipirijou.com/talks/how-i-built-my-own-tpp-part-1

This talk was given at Baruco 2014.
It explains the story of How I built my own TPP.

570a76d7545a0ae4b693ffee5435717e?s=128

José Tomás Albornoz

September 12, 2014
Tweet

Transcript

  1. When was the last time you worked on a non

    productive project, just for the fun of it?
  2. February 14th 2014

  3. Twitch Plays Pokémon

  4. None
  5. None
  6. None
  7. OMG

  8. OMG I need to make my own

  9. by @eljojo How I built my own Twitch Plays Pokémon

  10. by @eljojo How I built my own Twitch Plays Pokémon

  11. Saturday Morning

  12. None
  13. None
  14. None
  15. Ingredients List • 1 GameBoy Emulator • 1 screen-streaming app

    • 1 internet control for emulator
  16. Ingredients List • 1 GameBoy Emulator • 1 screen-streaming app

    • 1 internet control for emulator
  17. Ingredients List • 1 GameBoy Emulator • 1 screen-streaming app

    • 1 internet control for emulator
  18. Ingredients List • 1 GameBoy Emulator • 1 screen-streaming app

    • 1 internet control for emulator
  19. How do I control an emulator with Ruby?

  20. “How do I send keystrokes from a ruby app?”

  21. None
  22. None
  23. None
  24. None
  25. Problems with the Windows solution • WINDOWS!!!!!111! • I have

    no Windows machine • I want to run this on a server with no desktop environment
  26. None
  27. None
  28. require 'sinatra' mappings = { "a" => java.awt.event::KeyEvent::VK_Z, "b" =>

    java.awt.event::KeyEvent::VK_X, "up" => java.awt.event::KeyEvent::VK_UP, "down" => java.awt.event::KeyEvent::VK_DOWN, } robot = java.awt.Robot.new get '/:key' do |key| if key_code = mappings[key.downcase] robot.keyPress(key_code) robot.delay(100) robot.keyRelease(key_code) end end
  29. None
  30. None
  31. Problems

  32. Problems • Simulating Keystrokes • Requires desktop environment • Latency!

  33. The perfect emulator • requires no desktop environment • streams

    the video online • has an API that allows to send button presses
  34. None
  35. None
  36. None
  37. What’s an emulator?

  38. None
  39. None
  40. None
  41. $ ./emulator pokemon_red.gb

  42. None
  43. None
  44. $ ls lib cpu.rb gpu.rb ram.rb

  45. None
  46. None
  47. @ram = [] rom = File.binread('pokemon.gb') @ram += rom.unpack('C*')

  48. None
  49. None
  50. address operation 0x00 nop 0x04 inc_b 0x80 add_a_b 0xA0 and_b

    0xC0 jp_nn CPU Instruction Table
  51. address operation 0x00 nop 0x04 inc_b 0x80 add_a_b 0xA0 and_b

    0xC0 jp_nn CPU Instruction Table class CPU OPS = [ :nop, … … :inc_b, … :add_a_b, … :and_b, … :jp_nn, ]
  52. “the” loop class Emulator def step next_byte = @ram[@program_counter] next_instruction

    = OPS[next_byte] @cpu.send(next_instruction) @program_counter += 1 end end
  53. “the” loop class Emulator def step next_byte = @ram[@program_counter] #

    => 0xC0 next_instruction = OPS[next_byte] @cpu.send(next_instruction) @program_counter += 1 end end
  54. “the” loop class Emulator def step next_byte = @ram[@program_counter] #

    => 0xC0 next_instruction = OPS[next_byte] # => :jp_nn @cpu.send(next_instruction) @program_counter += 1 end end
  55. “the” loop class Emulator def step next_byte = @ram[@program_counter] #

    => 0xC0 next_instruction = OPS[next_byte] # => :jp_nn @cpu.send(next_instruction) @program_counter += 1 end end
  56. “the” loop class Emulator def step next_byte = @ram[@program_counter] #

    => 0xC0 next_instruction = OPS[next_byte] # => :jp_nn @cpu.send(next_instruction) @program_counter += 1 end end
  57. “the” loop class Emulator def step next_byte = @ram[@program_counter] #

    => 0xC0 next_instruction = OPS[next_byte] # => :jp_nn @cpu.send(next_instruction) @program_counter += 1 end end
  58. Why do we care?

  59. we’ll write our own!

  60. Advantages • No need for keypresses

  61. Advantages • No need for keypresses • We can run

    on a headless server
  62. Advantages • No need for keypresses • We can run

    on a headless server • We can stream closer to real-time
  63. Advantages • No need for keypresses • We can run

    on a headless server • We can stream closer to real-time • We control the memory!
  64. Advantages • version controlling of gameplays • rewind game sessions

  65. Advantages • version controlling of gameplays • rewind game sessions

    • forking and branching
  66. Advantages • version controlling of gameplays • rewind game sessions

    • forking and branching • machine learning
  67. tom7.org/mario

  68. Advantages • No need for keypresses • We can run

    on a headless server • We can stream closer to real-time • We control the memory!
  69. None
  70. None
  71. None
  72. None
  73. if you want to succeed at conferences you should totally

    promise stuff you have no idea about that’s p good
  74. Taking over Mimey

  75. Jano González… … loves GameBoy … loves Pokémon … loves

    Ruby
  76. Mimey • GameBoy emulator • written in Ruby

  77. Mimey • GameBoy emulator • written in Ruby • only

    10% done
  78. None
  79. How to draw an owl

  80. How to draw an owl draw some circles

  81. How to draw an owl draw some circles add the

    rest of the owl
  82. bits and bytes

  83. None
  84. None
  85. None
  86. I had no real reason to know what that means

  87. I was forced to learn

  88. Sven Fuchs • he knows about computers

  89. Sven Fuchs • he knows a lot about computers

  90. “ugh, I learned that 20 years ago”

  91. I never learned it because I didn’t have to.

  92. Irresponsible Ruby

  93. Steve Klabnik • also knows a lot about computers •

    gave talk in EuRuKo last year
  94. “Ruby code that you wouldn't deploy at your day job

    because it's just too interesting or creative” - Steve Klabnik
  95. Irresponsible Ruby • Neat Hacks • Weird metaprogramming • Unusual

    techniques • No Unit-Tests
  96. “If you worry too much about being clean and tidy,

    you can’t push the boundaries” - _why
  97. testing irresponsibly

  98. CPU Steps Step Operation A B C D E F

    1 nop 0 15 232 22 19 10 2 dec_d 0 15 232 21 19 10 3 inc_b 0 16 232 21 19 10
  99. The specification of how the original GameBoy works was feature-frozen

    before I was born.
  100. None
  101. None
  102. Rendering the first image

  103. Patience

  104. Patience

  105. Patience

  106. None
  107. None
  108. None
  109. None
  110. The memory was the same!

  111. None
  112. None
  113. None
  114. None
  115. None
  116. None
  117. None
  118. None
  119. “It uses ruby everywhere!” - DHH

  120. None
  121. gameboy emulator

  122. None
  123. None
  124. None
  125. None
  126. None
  127. None
  128. None
  129. None
  130. None
  131. None
  132. The Realization

  133. I learned tons of things that I would have never

    learned by my own
  134. I got out of my comfort zone

  135. It was fun!

  136. I can apply some of this to my work

  137. Conference Driven Development

  138. sometimes you need the right push

  139. None
  140. wear the hacker hat

  141. write irresponsible ruby

  142. get back the passion that got you into programming

  143. thanks! @eljojo

  144. github.com/eljojo/mimey