What is LÖVE? (Lua don't hurt me)

by on under dsp2017
10 minute read

looove Almost everybody has dreamt of creating a video game at some point in time. LÖVE isn’t a game engine - it’s an open source Lua framework aiming at creating 2D games. It’s also cross-platform (supports Windows, Mac OS X, Linux, Android and iOS).

Why LÖVE?

Good for beginners - LÖVE works out of box, doesn’t require learning whole complex IDE, thousands of keybindings or anything like that. Moreover, community provides a lot of tutorials, code examples and libraries that let us start our game in no time.

Extensive documentation - The LÖVE wiki is a good place to start. Documentation is very comprehensive and conveniently divided into modules, what makes searching for information easy and simple.

Friendly community - if you are stuck, you can ask for help on the LÖVE forums or their IRC channel

Let’s dive in!

Installation

It’s very simple - just download proper package from the website. Under Windows you don’t need to install it - just extract the archive and you’re ready for making awesome games! And if you are using Arch Linux, it’s even simplier - LÖVE is available in AUR.

Ready? So let’s run love and see what will happen! toast Yeah, we need a game.

Preparations

LÖVE doesn’t have any sort of official IDE or anything like that, so you are free to use you favourite editor like Atom, Sublime Text, Vim, Emacs, nano, edlin… everything will work, but I recommend something with support with Lua language support, it makes our work a lot easier.

Okay, so first we need to create main.lua file in our game root directory. To check if everything works correctly, put some code into it…

  function love.draw()
      love.graphics.print("Yay, it works!", 400, 300)
  end

…and run our “game”:

Windows: "C:\Program Files\LOVE\love.exe" "C:\path\to\game"

Linux: love /path/to/game

You should get something like this: hello world Congratulations, you are a professional gamedev now.

First game

Okay, we are now set to make real games. I’ll show you how to make a very (veeery) simple platformer. First, let’s initialize some objects, specifically our player and some ground for him to stands on.

  function love.load()

    love.physics.setMeter(64) 
    world = love.physics.newWorld(5, 9.81*64, true) --create a world for the bodies to exist in with horizontal gravity of 0 and vertical gravity of 9.81

    objects = {} -- table to hold all our physical objects

    objects.ground = {}
      objects.ground.body = love.physics.newBody(world, 650/2, 650-50/2)
      objects.ground.shape = love.physics.newRectangleShape(650, 50) 
      objects.ground.fixture = love.physics.newFixture(objects.ground.body, objects.ground.shape); 

    objects.player = {}
      objects.player.body = love.physics.newBody(world, 650/2, 650/2, "dynamic")
      objects.player.shape = love.physics.newRectangleShape(64, 64)
      objects.player.fixture = love.physics.newFixture(objects.ball.body, objects.ball.shape, 1) 

    --initial graphics setup
    love.graphics.setBackgroundColor(23, 3, 18) 
    love.window.setMode(650, 650)
  end

Awesome, but we also need to draw these objects.

  function love.draw()
    love.graphics.setColor(0,255,255,255)

    love.graphics.setColor(151, 216, 178)
    love.graphics.polygon("fill", objects.ground.body:getWorldPoints(objects.ground.shape:getPoints())) 

    love.graphics.setColor(160, 172, 173) 
    love.graphics.polygon("fill", objects.player.body:getWorldPoints(objects.ball.shape:getPoints()))
  end

At this point your game should look like this: love1 Nice, but it’s a bit empty, isn’t it? We can add some blocks, in the same way as before:

  function love.load ()
    objects.block1 = {}
      objects.block1.body = love.physics.newBody(world, 200, 550, "dynamic")
      objects.block1.shape = love.physics.newRectangleShape(0, 0, 50, 100)
      objects.block1.fixture = love.physics.newFixture(objects.block1.body, objects.block1.shape, 5) 
    
    objects.block2 = {}
      objects.block2.body = love.physics.newBody(world, 200, 400, "dynamic")
      objects.block2.shape = love.physics.newRectangleShape(0, 0, 100, 50)
      objects.block2.fixture = love.physics.newFixture(objects.block2.body, objects.block2.shape, 2)
    
    objects.block3 = {}
        objects.block3.body = love.physics.newBody(world, 400, 500, "static")
        objects.block3.shape = love.physics.newRectangleShape(0, 0, 200, 25)
        objects.block3.fixture = love.physics.newFixture(objects.block3.body, objects.block3.shape, 2)
    
    objects.block4 = {}
        objects.block4.body = love.physics.newBody(world, 250, 420, "static")
        objects.block4.shape = love.physics.newRectangleShape(0, 0, 150, 30)
        objects.block4.fixture = love.physics.newFixture(objects.block4.body, objects.block4.shape, 2)
    
    objects.block5 = {}
        objects.block5.body = love.physics.newBody(world, 380, 300, "static")
        objects.block5.shape = love.physics.newRectangleShape(0, 0, 100, 40)
        objects.block5.fixture = love.physics.newFixture(objects.block5.body, objects.block5.shape, 2)
    
    objects.block6 = {}
        objects.block6.body = love.physics.newBody(world, 200, 200, "static")
        objects.block6.shape = love.physics.newRectangleShape(0, 0, 150, 25)
        objects.block6.fixture = love.physics.newFixture(objects.block6.body, objects.block6.shape, 2)
  end

  function love.draw()
    love.graphics.setColor(83, 18, 83) 
      love.graphics.polygon("fill", objects.block1.body:getWorldPoints(objects.block1.shape:getPoints()))
      love.graphics.polygon("fill", objects.block2.body:getWorldPoints(objects.block2.shape:getPoints()))
    
    love.graphics.setColor(83, 18, 83) 
      love.graphics.polygon("fill", objects.block3.body:getWorldPoints(objects.block3.shape:getPoints()))
      love.graphics.polygon("fill", objects.block5.body:getWorldPoints(objects.block5.shape:getPoints()))
    
    
    love.graphics.setColor(51, 3, 47)
      love.graphics.polygon("fill", objects.block4.body:getWorldPoints(objects.block4.shape:getPoints()))
      love.graphics.polygon("fill", objects.block6.body:getWorldPoints(objects.block6.shape:getPoints()))
  end

No we have six blocks - purple, that will become our platforms and two, blue, pushable blocks to mess around with. love2 We are almost done - last thing we need to do is to put our world into motion!

  function love.update(dt)
    world:update(dt) 
      --here we are going to create some keyboard events
      if love.keyboard.isDown("right") then 
        objects.player.body:applyForce(400, 0)
      elseif love.keyboard.isDown("left") then 
        objects.player.body:applyForce(-400, 0)
      elseif love.keyboard.isDown("up") then 
        objects.player.body:applyForce(0, -400)
        objects.player.body:setLinearVelocity(0, -350) 
    end
  end

love.update(dt) function is where all math required to run our game takes place. dt stands for delta time and is the amount of seconds since the last time this function was called. The rest of code should be rather self-explanatory: when we push the button, we apply the force on the corresponding object. Line world:update(dt) activates gravity force defined in love.load() function. love3

Ta-dah!

dsp2017, gamedev, love, lua