Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript
	
   - 1 -
	
  
	
  
	
  
http://nodered.org
	
  
An	...
CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript
	
   - 2 -
Technical	
  background:	
  For	
  this	
 ...
CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript
	
   - 3 -
3. Drag	
   and	
   drop	
   an	
   “injec...
CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript
	
   - 4 -
information	
  packages	
  arrive	
  in	
 ...
CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript
	
   - 5 -
2. Drag-­‐and-­‐drop	
  in	
  a	
  functio...
CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript
	
   - 6 -
6)	
  Exercise:	
  Retrieving	
  values	
 ...
CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript
	
   - 7 -
For	
  this,	
  we’re	
  going	
  to	
  ex...
CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript
	
   - 8 -
Optional	
   reading:	
   The	
   .trim	
 ...
CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript
	
   - 9 -
To	
  prevent	
  summing	
  up	
  of	
  el...
Upcoming SlideShare
Loading in …5
×

Node-RED and Minecraft - CamJam September 2015

2,108 views

Published on

This workshop uses the Node-RED framework as development tool for JavaScript. Building on functionality available for generic programming challenges, we’re going to use the communication standard TCP (Transmission Control Protocol) to interact with the Minecraft API (Application Programming Interface). The material is aimed at people who have had first experience with the Minecraft API on a Raspberry Pi (say, using Python), who now want to understand what's going on behind the scenes and what TCP, API and all those other acronyms mean. It also introduces flow-based programming concepts.

Published in: Education

Node-RED and Minecraft - CamJam September 2015

  1. 1. CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript   - 1 -       http://nodered.org   An  introduction  to  flow-­based   programming  using  Node-­RED     ! Node-­RED   is   a   visual   tool   for   wiring   the   Internet   of   Things   (IoT).   Node-­‐RED   is   platform-­‐independent,   but   has   been   developed   with   small   computers   such   as   the   Raspberry  Pi  in  mind.     ! Traditional   IoT   development   can   be   very   technical:   Access   to   the   GPIO   and   other   hardware  requires  skills  in  C  or  assembler,  output  of  data  to  web  services  or  sending   tweets   and   emails   requires   the   use   of   complex   APIs.   Node-­RED   takes   care   of   the   technicalities  and  lets  you  concentrate  on  the  logic  of  your  workflow     ! While   most   programming   in   Node-­‐RED   is   done   visually   using   pre-­‐defined   functions   (“nodes”),  any  additional  functionality  can  be  added  in  JavaScript.     ! Node-­RED  is  a  multi-­purpose  survival  tool  –  use  it  for  any  prototyping!       WORKSHOP  CONTENT:  In  this  workshop,  we’re  going  to  use  Node-­‐RED  as  a  development   tool   for   JavaScript.   Building   on   functionality   available   for   generic   programming   challenges,   we’re   going   to   use   the   communication   standard   TCP   (Transmission   Control   Protocol)   to   interact  with  the  Minecraft  API  (Application  Programming  Interface).  
  2. 2. CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript   - 2 - Technical  background:  For  this  workshop,  you  will  find  a  Raspberry  Pi  with  Node-­‐RED  already  installed.  While  the  installation  of  Node-­‐RED   software  is  relatively  easy,  it  would  be  difficult  to  include  this  step  within  the  time  constraints  of  the  exercise.  On  a  fresh  and  up-­‐to-­‐date   Raspian  installation  we  added:  node.js,  npm  and  Node-­‐RED  as  per:   http://nodered.org/docs/hardware/raspberrypi.html   Note:  On  your  own  system,  to  leverage  the  power  of  Node-­‐RED,  consider  installing  the  node  for  GPIO  access  as  well.     1)  Exercise:  Starting  Node-­RED  as  Raspberry  Pi  user   Node-­‐RED  can  be  installed  as  a  service  on  the  Raspberry  Pi,  i.e.  as  a  program  that’s  always   executed  when  your  Pi  is  running.  However,  this  is  only  useful  if  you  want  to  commit  your  Pi   for   this   particular   use   as   it   can   consume   considerable   resources.   For   everyone   else,   it’s   recommended  to  start  Node-­‐RED  only  when  needed:   1. Open  the  LXTerminal    to  see  a  console  that  allows  you  to  enter  Linux  commands.   2. Start  Node-­‐RED  by  issuing  “node-­red”.     You  should  now  see  Node-­‐RED  starting  up  –  that  may  take  a  few  seconds:     Congratulations.  You’re  now  ready  for  the  exercises.   Node-­‐RED  represents  a  server  on  the  basis  of  node.js  and  interacts  with  the  user  through  a   graphical   user   interface.   It   can   be   reached   on   port   1880.   To   use   Node-­RED,   open   a   web   browser  and  direct  it  to  http://localhost:1880   It’s  useful  to  remember  that  Node-­‐RED  acts  as  a  server  in  your  entire  network.  That  is,  if  your  Raspberry  Pi’s  internal  IP  address  is  something   like  192.x.x.x,  every  computer  in  your  network  can  open  the  Node-­‐RED  GUI  through  http://192.x.x.x:1880.  You  can  make  your  system  more   restricted/secure  by  following  the  configuration  advice  on  http://nodered.org/docs/security.html.     2)  Exercise:  Your  first  flow  –  this  is  a  recap  for  those  who  attended  the  last  course(s)   The  best  way  to  explain  “a  flow”  is  by  creating  one.  In  this  mini  flow,  we’re  going  to  inject  a   value  into  our  debug  window  (refer  to  page  1  for  what  the  GUI  elements  are  called).   1. Open  the  Epiphany  Web  Browser.  (It  supports  JavaScript  better  than  Midori).   2. In  the  address  line,  enter  localhost:1880.  You  will  then  see  the  Node-­‐RED  GUI.  
  3. 3. CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript   - 3 - 3. Drag   and   drop   an   “inject”   node   from   the   nodes   library   into   the   flow   editor   (once   you’ve   chosen   the   inject   node,   you   should   see   some   general   explanation   about   its   functionality  in  the  info  pane  –  no  need  to  read  that  now).   4. Drag  and  drop  a  “debug”  node  from  the  nodes  library  into  the  flow  editor.   5. Create  a  pipe  between  the  inject  and  debug  nodes  by  drawing  a  connection  between   their  small  grey  rounded  rectangles.   6. Change  from  the  info  pane  to  the  debug  pane  (upper  right).   7. Deploy  (=start)  your  flow.   8. Once  deployed,  press  the  left  blue  rectangle  that’s  attached  to  the  inject  node.  Check   what’s  happening  in  the  debug  pane.  (Yes,  that’s  a  Unix  time  stamp).     3)  Exercise:  Finding  the  Minecraft  API    and  understanding  the  protocol   1. Open   another   LXTerminal   and   change   to   your   Minecraft   installation   by   issuing   “cd   /opt/minecraft-­pi”.   2. In  the  API  directory  (“cd  api”),  get  a  list  of  available  files  and  directories  (“ls”).   Those   with   previous   programming   experience   may   recognise   the   python   sub-­‐directory.   Inside  you  would  find  the  files  that  expose  the  Minecraft  functionality  of  the  mcpi  package   to  Python.  It’s  important  to  note  that  the  Application  Programmers  Interface  (API)  –  be   it   for   a   locally   installed   application   like   Minecraft   or   a   web   server   that   listens   to   your   commands  over  the  Internet  –  is  just  a  convention  on  which  interface  (local  socket  or  IP   address,  port)  an  application  is  listening  to  other  programs  (like  yours),  which  commands   are  available  and  what  parameters  in  which  formats  are  expected.   The   mcpi   package   encapsulates   these   concepts   (connection,   commands)   in   easy-­‐to-­‐use   Python  commands.  Sometimes  the  underlying  specification  is  not  communicated  and  as  a   programmer  you’re  stuck  with  the  functions  available  in  the  higher-­‐level  library.  However,   the  Minecraft  API  is  rather  transparent  and  if  you…   3. Change  into  the  spec  directory  (“cd  spec”),  you  are  going  to  find  mcpi_protocol_spec.txt  –   a  humble  text  file  with  the  information  that  you  require.   4. Open  the  file  in  an  editor  (“nano  mcpi_protocol_spec.txt”)  and  have  a  look  around.   Most  modern  web  services  (including  Twitter  or  the  BBC)  provide  APIs  for  programmatic  retrieval  of  information.  If  you’re  interested  how  to   use   APIs   over   the   Internet   in   Node-­‐RED,   I’ve   put   up   a   guide   on   accessing   IoT   platforms   that   can   serve   as   an   entry   point:   http://www.slideshare.net/BorisAdryan/node-­red-­iotplatformtest     The  specification  states  that  the  Minecraft  binary  listens  to  incoming  messages  at  “TCP  port   4711”   and   expects   character   strings   that   are   terminated   with   a   “n”   (Unix   linefeed).   A   following  schematic  of  the  Open  Systems  Interconnection  (OSI)  Model  helps  to  digest  this:     In  a  nutshell,  once  a  physical  connection  is  established  between  two  devices  (Level  1)  and   they  can  exchange  signals  (Levels  2+3),  Level  4  in  the  OSI  Model  takes  care  of  housekeeping   jobs:   Is   there   an   error   in   the   communication?   Can   we   recover   from   small   errors?   Do  
  4. 4. CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript   - 4 - information  packages  arrive  in  the  right  order?  While  some  protocols  like  UDP  optimise  for   high  throughput  (little  error  checking,  little  redundancy),  others  are  slower  but  more  secure   in  terms  of  data  integrity  (like  TCP).       http://programmerhelp404.blogspot.co.uk/2014/01/iso-­osi-­layer-­model-­tcpip-­model.html   It’s  important  to  understand  that  these  communication  routes  exist  on  the  Internet,  but  at  the   same  time  localhost  (IP:  127.0.0.1)  offers  the  same  functionalities  on  your  local  computer.  One   can  imagine  the  communication  via  the  Internet  Protocol  (IP,  Level  3)  like  a  motorway,  but   there  are  65536  (216)  different  lanes,  commonly  referred  to  as  port.     4)  Exercise:    “Hello  World”  in  Minecraft,  Node-­RED  style   Please   start   Minecraft   and   open   a   new   world.   You   may   want   to   arrange   the   console   windows,  the  browser  and  Minecraft  to  your  liking…  …yes,  there’s  always  too  little  space  on   that  screen  and  Model  1  Raspberry  Pis  are  not  the  fastest  machines  to  do  this.   In  Node-­RED,   1. Double-­‐click   your   input   node,   and   once   the   associated   dialog   opens,   change   the   Payload  to  type  string  and  write  “Hello  World”  in  the  empty  text  field  below.  
  5. 5. CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript   - 5 - 2. Drag-­‐and-­‐drop  in  a  function  node.  This  is  the  node  type  that  allows  you  to  directly   interact   with   Node-­‐RED   messages   (by   default   having   a   ‘payload’   and   a   ‘topic’)   in   JavaScript.   3. In  your  function  node,  write  “msg.payload  =  "chat.post("+msg.payload+")n";”  before   return  msg;   This  line  is  going  to  take  the  incoming  msg.payload  (“Hello  World”),  and  assigns  new   content   “chat.post(Hello   World)n”   to   the   variable.   chat.post   is   a   command   we’ve   learned   from   the   mcpi_protocol_spec.txt,   and   Minecraft   is   going   to   assert   it   as   such   when  it’s  followed  by  a  line  break  (Unix  definition:  n).   4. Drag-­‐and-­‐drop   a   TCP   node   from   the   output   panel.   Set   it   up   with   the   following   parameters:     5. Connect  the  nodes  like  this:     6. Deploy.  Test  your  flow  by  triggering  the  inject  node.  Do  you  see  what  you  expected?     5)  Exercise:  Move  Steve  around  -­  and  build  stuff   You’ve  been  there  before,  but  probably  in  Python.  Now  try  it  with  raw  ASCII  strings.   1. Have  a  look  around  the  protocol  specification  and  look  for  the  command  that  sets  the   player  to  a  new  coordinate.   2. Set  a  wooden  block  directly  in  front  of  you.  (Hint:  blockTypeID  for  wood  is  17;  and   hard-­‐code  the  coordinate  for  now).  
  6. 6. CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript   - 6 - 6)  Exercise:  Retrieving  values  from  Minecraft   So   far   our   interaction   with   Minecraft   was   rather   one-­‐directional.   We   just   sent   command   strings  that  had  an  effect  on  the  Minecraft  world.  Now  we’re  going  to  modify  our  flow  so  we   can  query  values  like  our  own  position  via  the  API.   The  overall  anatomy  of  our  flow  is  going  to  look  like  this:     1. Use  an  inject  node  (here  named  trigger)  to  start  the  flow.   2. In  the  appropriate  function  node,  set  “msg.payload  =  "player.getPos()n";”   3. Instead  of  a  TCP  out  node,  we’re  now  going  to  use  a  TCP  request  node  that  allows  for   bi-­‐directional  communication.  Configure  the  node  like  this:     Just   as   we   indicated   the   end   of   our   message   to   the   server   with   a   “n”   character,   Minecraft  terminates  its  return  messages  with  the  same  character.   4. By   default   the   TCP   request   node   returns   a   buffer,   and   we   need   to   convert   the   information   from   Node-­‐RED   using   “msg.payload   =   msg.payload.toString();”   in   a   function  node.   5. The  flow  concludes  with  a  debug  node.  If  you’re  having  trouble  with  the  flow,  consider   sending  output  to  debug  panel  and  console.   6. Deploy.   Have   a   walk   around   Minecraft   and   trigger   your   flow.   Do   you   see   what   you   expected?     7)  Exercise:  Event-­driven  programming  and  loops   By  now  you  may  have  realised  that  our  Node-­‐RED  flows  were  linear  series  of  commands.  Once   triggered,  we  sent  a  command,  retrieved  information  and  displayed  it.  But,  for  example,  how   can   we   iterate   over   a   set   of   coordinates   and   execute   world.getBlock(x,y,z)   for   Steve’s   immediate  neighbourhood?  
  7. 7. CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript   - 7 - For  this,  we’re  going  to  extend  our  flow  a  little  bit.  First,  look  at  the  overall  anatomy  of  our   flow.  It’s  a  bit  of  a  mouth  full:     First,  we  translate  Steve’s  position  into  a  series  of  (x/y/z)  coordinates,  more  specifically,  a   cube  that  this  directly  underneath  Steve’s  feet.  Then,  we’re  going  to  query  each  block  in  the   Minecraft  world  for  its  content.  Next,  we  tabulate  the  elements  we’ve  found  and  provide  a   summary  in  the  debug  panel.  The  tutorial  is  going  to  guide  you  through  the  necessary  changes   bit  by  bit.   1. Change  the  .toString()  function  node.  I’ve  renamed  it  to  position  to  “()”  string  to  better   reflect  its  new  functionality:    
  8. 8. CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript   - 8 - Optional   reading:   The   .trim   function   removes   the   invisible   trailing   “n”   from   the   player’s  position,  and  with  .split(“,”)  we  separate  out  the  x,  y  and  z  component  of  the   coordinate   into   an   array   called   pos.   Due   to   the   way   Minecraft   considers   player   positions  as  floating  point  numbers,  but  places  elements  in  discrete  blocks,  we  need  to   round  our  position  with  the  Math.round  function.  JavaScript  can  occasionally  act  a  bit   funny,  so  to  about  any  problems,  we  specifically  tell  it  to  interpret  the  character  strings   in  the  pos  array  as  floating  point  numbers  with  parseFloat.  Ultimately,  we  are  going  to   define  an  array  called  coordinates,  and  each  element  inside  coordinates  is  a  payload   with  a  string  in  parenthesis,  featuring  a  coordinate  of  the  cube  below  Steve.   Obligatory  reading:  By  returning  [coordinates]  at  the  end  of  the  function  (line  30,  note   the  [  ]),  we’re  going  to  tell  Node-­‐RED  to  trigger  the  next  node  for  reach  element  in  the   array.   2. Add   a   function   node   and   add   “msg.payload   =   "world.getBlock"+msg.payload+"n";”    -­‐  this  simply  makes  the   overall   code   more   readable.   It   complements   each   (x,y,z)   triplet  with  the  world.getBlock  command,  followed  by  “n”;   3. Add  another  TCP  request  node  and  configure  it  exactly  like   the  one  before.   4. The   material   .toString()   function   node   adds   exactly   this   functionality:  “msg.payload  =  msg.payload.toString();”  –  add  a   debug  node  if  you  want  to  check  your  results.  A  table  with   common   elements   is   shown   in   the   figure,   from   http://minecraft.gamepedia.com/Data_values_(Pocket_Edition)   5. The   function   node   tabulation   counts   how   many   times   each   element  of  the  Minecraft  world  was  seen  in  the  5x5x5  =  125   blocks  underneath  Steve’s  feet.  Because  tabulation  is  invoked   every  time  a  new  element  is  detected,  we  need  to  make  use  of   a   Node-­‐RED   trick:   The   context   variable   remembers   its   state   between  iterations.    
  9. 9. CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript   - 9 - To  prevent  summing  up  of  elements  of  different  trigger  events,  we  modify  the  inject   node   with   a   topic   called   “trigger”.   If   the   tabulation   node   is   invoked   from   the   inject   button   (note   the   new   connection!),   we   delete   the   variable   by   assigning   it   the   value   undefined.  However,  if  we  invoke  the  function  from  the  material  .toString()  node,  we   make  sure  we  interpret  the  code  as  String.  If  our  table  is  still  undefined,  we  create  it  as   array,  otherwise  we  use  the  existing  one  (line  8).  If  the  ID  has  been  seen  before,  we   take  its  current  count,  otherwise  we  assign  0  (line  9).  Then  we  increase  the  count  for   this  observation  (this  event  only)  of  seeing  the  ID  (line  10).  Ultimately,  we  return  our   table  as  message.   6. To  prevent  the  printing  of  our  table  while  it  is  still  being  generated  (remember,  the   tabulation   method   gets   invoked   125   times!),   we   make   use   of   the   trigger   node.   Configure  it  with  the  following  settings:     The  node  remembers  the  first  time  it  was  triggered,  and  only  if  it  hasn’t  received  any   new  messages  for  250  milliseconds,  passes  the  information  on  to  the  final  debug  node.   7. Deploy  and  take  Steve  for  a  walk.  Trigger  the  inject  node.  Wait  patiently.  Check  the   console  and/or  debug  panel  for  output.  Does  the  output  make  sense  to  you?       Conclusions   Node-­‐RED  is  an  incredibly  powerful  framework  that  allows  you  to  do  things  in  very  little  time.   The  official  directory  of  flows  donated  to  the  community  is  here  http://flows.nodered.org   and  they  can  easily  be  imported  by  copying  &  pasting  the  JSON-­‐formatted  code.   Given   the   availability   of   a   convenient   input   node,   try   to   display   tweets   with   a   particular   hashtag  in  Minecraft.  You’re  going  to  be  surprised  how  simple  it  is!     There’s  a  bunch  of  other  Node-­RED  tutorials  at  http://www.slideshare.net/BorisAdryan  and   occasional  Node-­‐RED  tips  at  @BorisAdryan.    

×