Join the list

Berglet / learn

Learn.

Most first programs print a sentence on a screen. Yours moves a ship on a console in your hand, and you can show it to somebody on the bus.

a One idea at a time

Every idea arrives as something on the screen.

A value
ship.x = 140
Change the number, the ship is somewhere else. That is a variable.
A condition
if held(buttons.left): ship.x -= 2
It only moves while you hold the button.
A function
def update():
What happens sixty times a second. You wrote the heartbeat.
A list
rocks = []
One rock was easy. Now there are forty and you need a loop.
Time
every(1, tick)
A countdown. Something that happens later. Events.
Memory
saved.best = score
Still there after the console is switched off. Why?
The network
web.get(address, tell_joke)
The answer comes back later, and the game doesn't stop to wait.
Other machines
nearby.send({ x = me.x, y = me.y })
Two consoles on two desks, and a message that might get lost.

Every line above comes from the example games in the editor.

b Made for beginners

Small things that make a big difference

  • No setup lesson. Scan a code. That's the installation.
  • Nothing to remember by spelling. Colours, buttons, pictures and sounds are chosen from lists the editor shows, not typed as words in quotes.
  • Errors in sentences. “There is no picture called shipp. Did you mean images.ship?”
  • A mistake doesn't stop the game. Save something broken and the old game keeps running, with the line marked.
  • No magic. Sprites don't move by themselves. If it falls, it's because of three lines the student can point at.
  • Real languages. It's plain Lua and plain Python. What you learn here works everywhere, and the questions get better: what is a frame? Where does saved go?
Python / Lua
# A joke from the internet each time you press A.
# Nothing here waits: the game goes on while the answer is on its way,
# and it still plays (with a joke of its own) when there is no Wi-Fi.
top, bottom = "Press A for a joke", ""
asking = None

def punchline(words):
    global bottom
    bottom = words
    play(sounds.coin)

def tell_joke(reply):
    global top, bottom
    joke = reply.json()
    if reply.ok and joke:
        top = joke["setup"]
        after(2, lambda: punchline(joke["punchline"]))
    else:
        # reply.error says why there was no answer at all; otherwise the
        # address answered, but not with a joke (reply.status says how)
        top = "No joke from the internet (" + (reply.error or "answer " + str(reply.status)) + "). Here is mine:"
        bottom = "Why did the game cross the road? To get to the other slide."

def another():
    global top, bottom, asking
    if asking and not asking.done:
        return  # one at a time
    top, bottom = "Asking the internet...", ""
    asking = web.get("https://official-joke-api.appspot.com/random_joke", tell_joke)

def update():
    if pressed(buttons.a):
        another()

    # then the picture
    clear(colors.navy)
    text(top, 20, 50, width=240)
    text(bottom, 20, 130, colour=colors.yellow, width=240)
    text("A: another joke", 20, 220, size=sizes.small)
-- Two consoles near each other, each running this game, see each other.
me = sprite(images.player, 140, 120)
friends = {}                           -- a ghost for each console heard from, by its id
together = nearby.shared("together")   -- a table every console sees the same

-- Where I am, ten times a second (a message may get lost: the next one is soon)
every(0.1, function()
  nearby.send({ x = math.floor(me.x), y = math.floor(me.y) })
end)

nearby.on_message(function(place, from)
  if not friends[from] then friends[from] = sprite(images.ghost) end
  friends[from].x = place.x
  friends[from].y = place.y
end)

-- Who is still around, once a second. Whoever left goes out of the list,
-- and with that is no longer drawn.
every(1, function()
  local names = {}
  for _, player in ipairs(nearby.players()) do names[player.id] = player.name end
  for id, ghost in pairs(friends) do
    if names[id] then
      ghost.name = names[id]           -- a value of our own on the sprite
    else
      friends[id] = nil
    end
  end
end)

function update()
  if held(buttons.left) then me.x = me.x - 2 end
  if held(buttons.right) then me.x = me.x + 2 end
  if held(buttons.up) then me.y = me.y - 2 end
  if held(buttons.down) then me.y = me.y + 2 end
  me.x = clamp(me.x, 8, 272)
  me.y = clamp(me.y, 8, 232)
  -- A waves: everyone's count goes up, on every console
  if pressed(buttons.a) then together.waves = (together.waves or 0) + 1 end

  -- then the picture
  clear(colors.grass)
  for _, ghost in pairs(friends) do
    ghost:draw()
    text(ghost.name or "", ghost.x, ghost.y - 22, { align = sides.center, size = sizes.small })
  end
  me:draw()
  text("Friends here: " .. #nearby.players() .. "   Waves: " .. (together.waves or 0), 6, 220)
end
Two examples from the editor, a little further along: a joke from the internet, and a game where consoles in the same room see each other.

c Teachers

Thinking of using it in class?

Every student gets a game they made and can hold. Nothing to install on school computers: the editor runs in any browser on the same network.

We'd love to hear what would make Berglet work in your room. Tell us, and we'll let you know as plans for schools take shape.

In the editor
A step-by-step first game, a full reference and 38 “How do I…” recipes, in Lua and Python.
To take apart
Eleven example games, from a game of catch to a 3D landscape.
Works with
Laptops, tablets and Chromebooks. Anything with a modern browser.
Good to know
Editing works over your local network and is switched on from the console. On a school network, talk to your IT team first.