     @Wi = Math.floor(@W / g.cell_size)
     @Hi = Math.floor(@H / g.cell_size)
   
-  start: ->
-    @botx = 5
-    @boty = 5
-    @botdir = UP.theta
-
-    @program = new Program( [
-      'circle',
-      'circle',
-      'square',
-      'diamond',
-      'square',
-      'circle',
-      'diamond'
-      ])
-
-    @mapping = new Mapping( [
-      'circle',
-      'square'
-      'diamond'
-      'hex'
-      ])
-
-    @mapping.commands[0] = new MoveCommand(LEFT)
-    @mapping.commands[1] = new MoveCommand(UP)
-    #@mapping.commands[2] = new MoveCommand(DOWN)
-    @mapping.commands[3] = new MoveCommand(RIGHT)
-
-    @pc = 0
-    @execute()
-
+  start: (level) ->
+    @botx = level.startpos.x
+    @boty = level.startpos.y
+    @botdir = RIGHT.theta
+
+    @Wi = level.dims.w
+    @Hi = level.dims.h
+    @cnv.width  = @W = @Wi * g.cell_size
+    @cnv.height = @H = @Hi * g.cell_size
+    @ctx = @cnv.getContext('2d')
+
+    @level = []
+    for x in [0...@Wi]
+      @level[x] = []
+      for y in [0..@Hi]
+        @level[x][y] = {type: 'empty'}
+
+    @programs = []
+    for program in level.programs
+      id = @programs.length
+      @programs[id] = program
+
+      for {x:x, y:y} in parseRanges(program.loc)
+        @level[x][y] = {type: 'program', id: id}
+
+    @obstacles = []
+    for obstacle in level.obstacles
+      id = @obstacles.length
+      @obstacles[id] = obstacle
+
+      for {x:x, y:y} in parseRanges(obstacle)
+        @level[x][y] = {type: 'obstacle', id: id}
+
+    @available_mappings = level.available_mappings
+
+    @active_program = null
+    @mappings = []
+    
     @startRenderer()
     @startInput()
 


    bot.render(@ctx)

    @ctx.save()
    @ctx.translate(30,30)
    @program.render(@ctx)
    @ctx.restore()

    @ctx.save()
    @ctx.translate(230,30)
    @mapping.render(@ctx)
    @ctx.restore()

    @ctx.save()
    @ctx.translate(10.5,10.5)
    g.setStyle(@ctx, g.lined_style)
    g.renderNumber(@ctx, 1234567890)
    @ctx.restore()
    
    if not @stop_render
      requestAnimationFrame(@renderCB)


  renderCB: =>
    g.clear(@ctx, @W, @H)
    g.border(@ctx, @W, @H)


    for x in [0...@Wi]
      for y in [0...@Hi]
        switch @level[x][y].type
          when 'empty'
            true
          when 'program'
            @renderProgramCell(x, y)
          when 'obstacle'
            @renderObstacleCell(x, y)

    bot =
      showxi: @botx
