LÖVE: a framework to make 2D games in Lua
love2d.org
love2d.org
We had a devblog, doesn't exist anymore unfortunately. The thing I enjoyed the most was the flexibility of Lua, and the whole framework seemed to adopt that mindset. It gave you all the core pieces you need it (audio, input, physics, rendering), and then got out of your way.
The drawback to the full flexibility is having to spend time thinking about what design & workflow your wanted (but, really, wasn't a drawback, that's what I wanted, just took more time). We ended up designing a really flexible engine that allowed us to pivot from a 2D puzzle platformer with a story (Concerned Joe) to the action packed fast multiplayer game that Move or Die became.
If you don't just want to distribute a .love file (e.g. you do not want your user to get the Löve runtime themselves) this was basically unsupported and you had to come up with your own solutions..
I still think if the Löve community could improve this part it would help the most.
If it's supported, or not, documentation is king!
I didn't want to rely on whatever-version-of-löve-this-distro-has-packaged because Löve at the time would break API compat quite frivolously. You can probably use an AppImage these days but I think this goes against the intent and spirit of Löve. It should be trivial to build entirely self-contained binaries; and in case of Windows/Mac, it was indeed the case (modulo code signing).
which still seems to be up: https://thoseawesomeguys.com/party-mode-4-polish-score-scree...
I see a few snapshots of it on the web archive: https://web.archive.org/web/20200101000000*/https://thoseawe...
a few reasons why I love it
-Both the IDE and the framework are lightweight enough to run comfortably even on an RPI.
-The single best documentation I've ever used for any piece of development tool. Lots of examples, concise and made for max velocity.
-Excellent forum with friendly people. It has taken a bit of a backseat to project Discord, which I find a bit sad. But everyone is helpful there too.
-Great ecosystem of just about any library you can ask for.
It has kind of spoiled software development for me. I tried getting the hang of similar technologies many times without success. Atleast now I understand the people who still go on about how great their QuickBASIC / TurboPascal workflow was back in the days.
That being said there ARE a few areas in LÖVE that leave things to be desired:
- I feel like the devs are a bit too trigger happy to make API changes. Though fixing a big chunk of these are a matter of a few search + replaces.
- The rendering can feel oddly slow?? Especially on Android I kept bumping into weird scenarios where I felt like it should hit 60 FPS no problem, even with the Lua JIT inactive.
- There aren't many resources about how to make good use of threading features to speed up common performance problems. There is definetly room for a "LÖVE2D Performance Necronomicon" to be written by someone who is more knowledgeable in CompSci fundamentals than me. :^)
https://gitlab.com/alexjgriffith/min-love2d-fennel shows a basic setup that enables the repl too.
The only drawback is that it is a little bit too minimalistic for situations like shorter game jams where people with more kitchen-sink engines like Godot will have a much easier time. For example there is no native way to support multiple resolutions/fullscreen as well as lack of accessibility features. These things can be easily implemented or you can find libraries but it is definitely a concern.
On the other hand, learning Love2d first, paid huge dividends in my game dev journey because I learned how to actually program instead of relying on cobbling together engine features. And for the right project, especially those where a predefined engine structure does not not fit, it can still be the most productive choice.
Right on. While interning at an oil refinery, I developed an application in LÖVE that processes and displays data from spectrometers. In hindsight it may not have been the wisest choice, but hand rolling all the GUI elements I couldnt force out of the Nuklear[0] bindings for LÖVE gave me a strange sense of satisfaction.
If you're looking in that realm I also have to mention RAYLIB [1]. It might remind you of the XNA days, except it runs on many platforms and it actually works! (sic.) It's a Borland C style one-file include with some serious power. It's also a ton of fun until you segfault 3 mins into gameplay and you have no idea why. But then you can only blame yourself!
Final plug is of course PICO8. Very different style once again but so much fun[2]! Simple, cheat-sheet style programming, with all batteries included (pixel/spritesheet editor, mini DAW). And the productivity might surprise you, as you don't agonise for days on your third redesign this month.
All of these have vibrant, helpful, communities. You can't go wrong for fun.
Raylib has a ton of language bindings. I've been using it with Zig, the integration was seamless and have not encountered these types of bugs yet.
Both Raylib and Zig include all dependencies too, so I was able to build a single 700kb .exe from Linux, copy that to my Windows machine, and it just worked immediately without any issues. Pretty amazing.
At the top of your build.zig, import the raylib build.zig inside raylib's /src folder (exact path will depend where you've cloned raylib)
const raySdk = @import("raylib/src/build.zig");
Use the imported addRaylib() function to build raylib, then link to the exe and add include path var raylib = raySdk.addRaylib(b, target, optimize, .{});
exe.addIncludePath(.{ .path = "raylib/src" });
exe.linkLibrary(raylib);
After that, you should be fine to just use @cImport to use raylib within your project const ray = @cImport({
@cInclude("raylib.h");
});
pub fn main() void {
ray.InitWindow(800, 450, "raylib [core] example - basic window");
...Cannot not mention a Tic80. It is a FOSS alternative to PICO8.
Main differences are: 16:9 aspect ratio, no cpu limits and many languages to tinker with: lua, js, moonscript, ruby, squirrel, wren, fennel, janet, wasm, ... and just recently - a Python support was added.
- https://github.com/kitao/pyxel (Python)
- https://github.com/minigdx/tiny (Lua)
https://github.com/picolove/picolove (Love2D)
https://pixelvision8.github.io/Website/ (Lua)
https://hallucino.itch.io/px8 (Lua/Python)
https://liko-12.github.io/ (Lua)
https://github.com/antirez/load81 (Lua)
https://wasm4.org/ (WASM)
No idea if it will ever see the light of day, but it's been a very therapeutic hobby project.
I love open source: my two books are open source, I work in open source, and almost all of my hobby projects are open source.
But after spending all day coordinating with users and combing through the issue tracker, there's something very relaxing to me to have a little project where I don't feel "on stage" whenn working on it. It's good for me to get a social break.
Also do not expect Desktop 3D to have first priority although mouse and keyboard is supported.
I feel somehow unclean or dirty using Godot and Unreal and the like since they force you to work on their editors. The editors are basically immediately off limits for anyone who wants to mod the base game rapidly for their own enjoyment. A concept like http://sauerbraten.org/ is interesting, but seems to not have taken off for various reasons. Lesson learned I guess is that being able to customize is not everything.
Using LÖVE on Android was also pretty effortless. I could fire up a mobile text editor and fix Lua bugs or tweak animation constants. Every desktop feature worked the same on the phone. I could even tweak the audio framework to get optimal latency values. I would never get the chance to tweak under the hood had I chosen some closed source engine.
Since then I've "graduated" to 3D with LÖVR. It is completely different code with the same philosophy of surface simplicity and ample room for growth.
shame, i was very excited to try it!
The next step would be to try LÖVE's official interpreter [1] and see that it runs. That app & the docs are actually all you need to develop a full application right on your mobile phone. You could fetch Hexpress's source code and put it on the /sdcard/lovegame and the official LÖVE interpreter should run it fine, just with more latency.
If you'd like to pursue this further, please reach out on GitHub issues.
[1] https://play.google.com/store/apps/details?id=org.love2d.and...
The Play Store says "This app isn’t available for your device because it was made for an older version of Android". I'm on Android 13.
But I'll always gladly suffer through it in exchange for an easy and clean and secure embedding API.
So yeah, I totally understand why LOVE is made like that, but I don't think I'll use it.
On the other hand, JS was very similar to Lua. It wasn't object-oriented, but we could pretend it was, just like Lua. However, people started to use it for things that it wasn't meant to do when it was created, and it was extended with more features. Lua still have the same purpose, keeping its simple syntax.
Some years ago, the creator of Lua was invited to my university. He told us about some of the decisions that were made in Lua. For example:
- about it being indexed by 1: at the time, arrays indexed by 0 wasn't as popular as today. Lua was created in 1993, it is older than Java, JS and many other languages that we use today that are 0-based. A decision had to be made, and they chose to start at 1, as it was easier for non-programmers to write formulae
- about it using -- as comments: it was inspired by Haskell
- about it not having a ++ operator: that would increase the complexity of the syntax, and a -- operator wouldn't be possible due to that decision above
LÖVE 11.0 released - https://news.ycombinator.com/item?id=16731397 - April 2018 (2 comments)
How to make a game from scratch using Lua and Löve - https://news.ycombinator.com/item?id=16404230 - Feb 2018 (102 comments)
LÖVE 0.10 released with iOS and Android support - https://news.ycombinator.com/item?id=10780579 - Dec 2015 (91 comments)
Create 2D games in Lua and LÖVE. - https://news.ycombinator.com/item?id=3745631 - March 2012 (18 comments)
Löve 0.7.1 (lua game framework) is released - https://news.ycombinator.com/item?id=2262808 - Feb 2011 (14 comments)
LÖVE 0.6.0 (lua game library) is released - https://news.ycombinator.com/item?id=1019682 - Dec 2009 (15 comments)
LÖVE - a 2D game engine for rapid game development in Lua - https://news.ycombinator.com/item?id=457129 - Jan 2009 (12 comments)
Edit: This brings back so many memories
Let's say, you want to do UI, then there are 4-5 options ahead of you and you will no know how well these libraries are maintained till you use them. Very likely you wil find yourself mucking about the code of these libraries to fix weird bugs or adding a feature your game needs.
So, great for prototyping and learning about game dev. But not something I recommend for actual projects with dates.
Overall IMO, the closest to Unity alternative I can recommend are;
1. Godot 2. Defold 3. Gdevelop (HTML based. No-code development, which can make people love or hate it) 4. CTjs
If you are ok with paying for the gamedev - Gamemaker is another solid choice.
Each of these have their pros and cans, but are full fledged engines with huge communities and helpful resources to go with them.
And if an editor free engine is what you are looking for , Raylib would be highly recommended.
My personal requirements would be;
* 2d focused * huge community with tutorials & documentation for everything * libraries & extensions for all the usual gamedev stuff like camera, lighting etc. * asset protection baked in * console & mobile export targets. * Steam integration
Personally, I am personally leaning heavily towards Raylib using zig bindings - with Gdevelop/CTjs for quick prototyping of ideas.
I have tried Rust engines like Bevy, but the Rust tax was too heavy for me and I personally could not proceed beyond simple projects. your mileage may vary. Fyrox is good too, but there are pretty much no tutorials out there.
Another dark horse you can consider is the Flame engine on Flutter. Its very feature complete and you get all the mobile niceties for free. it has a nice community but examples, documentation tutorials etc are non existent.
Finally, if wishes come true, i'd really like a native version of the Phaser engine which will allow me to code in typescript, have all the existing Phaser features/apis, let me leverage its huge tutorials/resources, generate native binaries, enable baking in assets etc- but we don't have anything like that yet -_-
Sure, there is Monogame, Silk.NET, Stride, however they don't tick all the boxes that Unity offers.
So any engine whose game code isn't C# is a deal break for existing Unity users, as the only thing remaining are the assets.
"Unity like" refers to a Editor driven approach, not to a language
Unity became popular with its moonscript language (javascript like), they then ditched it to focus on C#, but what propelled unity to what it is today is the Editor driven approach, not c#, not DOTS (most AAA companies still fall back to lua in unity https://github.com/Tencent/xLua)
They are forced to transpile C# to C++ via IL2CPP as a result to target consoles/mobiles
C# is a disease when it comes to console/mobile support
It's a substantial dependency, quite heavy
And you are not free of unity like fuck ups, it's a microsoft language after all:
https://github.com/dotnet/sdk/issues/22247
And let's not forget when they changed the license of their debugger overnight to prevent people from using it in their products (jetbrains for example)
And them deprecating open source tooling to a proprietary/closed one for vscode (c# devkit)
Let's be careful, and let's not recommend evil as an alternative to evil ;)
Then again, you're certainly not Unity's target market.
I’d love to start making games with my son now he’s getting older, but I always used to hit a roadblock with the artwork. In this age of AI, can anyone recommend free/cheap ways of acquiring good animated sprites for hobby projects?
https://kenney.itch.io/kenney-game-assets
(no affiliation, it's just good stuff)
I’ve bought many nice asset bundles here for a very reasonable price.
I ended up moving to https://github.com/libktx/ktx for that little project.
> a = {}
> a[1] = "x"
> a[2] = "y"
> a[3] = "z"
> #a
3 -- okay
> a[2] = nil
> #a
1 -- wat
> a[4] = "w"
> #a
4 -- wat
> a[2] = nil
> #a
4 -- okay (I guess)
> a[4] = nil
> #a
1 -- wat
You can't just print a table, it will only display its memory address – you'll have to write that function yourself. Considering that tables are the fundamental non-scalar datastructure in Lua, and Lua is supposed to be a scripting language with a REPL, this is mind-boggling.Oh, and a table doesn't keep track of the number of its elements, you have to manually iterate over all elements and count them because of ... reasons?
Your complaints sound a little bit like you wish Lua was a little bit more, but it kind of has a design goal of being simple language you can embed. You are meant to bring your own batteries.
But why conflate the two? There's no benefit to this, only drawbacks.
> The # operator works on the array part simply starts counting from the first index and stops counting when it reaches nil.
That's obviously not the case, as can be seen from #a returning 4 after setting a[4] = "w", even though a[2] == nil. There's no simple logic behind the # operator's behavior, it's an unintuitive mess.
> Your complaints sound a little bit like you wish Lua was a little bit more, but it kind of has a design goal of being simple language you can embed.
No, a simple language doesn't have to be inconsistent.
Sorry I meant to say minimal and I was referring to the lack of certain features , not necessarily simple which is something else.
> That's obviously not the case, as can be seen from #a returning 4 after setting a[4] = "w", even though a[2] == nil. There's no simple logic behind the # operator's behavior, it's an unintuitive mess.
Oh, so perhaps it's a combination of being an "unintuitive mess" and/or it's been changed and/or I don't even remember.
Running the code you provided in the Lua online demo (which is lua 5.4.6) yields 3,3,4,4,3 so I guess you were running an older version.
I don't think this is a big problem in practice if you are just aware of this. It's a bit like 1 vs 0 based indexing. It may have been a problem in the beginning but it's been too long since I first started using Lua. And here you'd have a point.
> But why conflate the two? There's no benefit to this, only drawbacks.
I honestly don't know. I'm actually more on your side when it comes to distinguishing arrays and tables. I just don't think it's as big of a deal as you make it out to be.
-
As I alluded to earlier, you can just change Lua to fit your needs. It's meant as a language you embed in your own framework and was never really meant as a fully standalone language as far as I understand. Its position of being standalone is kinda weak in my opinion.
You even mentioned previously that "Lua is supposed to be a scripting language with a REPL" but the REPL included is the bare minimum.
By far my own biggest "complaint" about Lua is that it's dynamic. However Lua with types would be a different language entirely.
you can also swap and pop using the magic of multi assignment to preserve index order if you don't care about maintaining value order:
a[1], a[#a] = a[#a], nil
If you do care about value order there's table.sort
Just because you don't like the raw behavior doesn't mean it's incorrect. You can make the same argument about other languages in a practical use case
I'm a PHP dev and I would never rely on setting an array index to null or calling unset() on a collection if I'm deleting an element. Both lead to bugs. In the former case, null is treated as a set value so the count is inaccurate. In the latter case, the count is correct but the indices aren't continuous any more. JS has the same behavior with null and delete. Both PHP and JS have functions for manipulating arrays just as lua does.
You wouldn't. You'd set it to 0 or "" or whatever.
LuaJIT can also have unpredictable performance characteristics, if it matters.
I quite like Lua although it took some getting used to.
You would have to be fairly disciplined to work on a big game with multiple programmers. The c# of Unity means you can be fairly lazy rely on the IDE to help you work out what is going on. I imagine you could make a real mess with Lua.
It's much better than Godot and Love is a really solid foundation to build your game on.
Nobody likes to put down such a great looking open source project, but I decided it was not for me.
EDIT: looks correct albeit choppy on LÖVE 11.3, Ubuntu 20.04, i3-4160 integrated. Nice job btw.
Further, the source is entirely reversible and thus can be stolen. Conversely, we couldn't get LOVE to build on its own (from sources). Perhaps that's improved since ~4 years ago.
We ultimately had to ditch LOVE, but it was fun and cute while it lasted. For simpler or more straightforward projects, I'd consider picking it up again.
Is it okay to use OpenAL (unmodified) on a "closed" platform like iOS, or Nintendo Switch as long as it is dynamically linked? From what I've gathered so far, this is still okay with LGPLv2 since v2 does not have a tivoization clause. LGPL v3 does have the tivoization clause, which demands that the end-user has access to the necessary tooling to unpack, re-link, repack the binary for the used platform. Is this correct?
Using LGPLv2 might be fine though, many consoles are using Webkit (which contains LGPLv2 code) themselves.
Still, I am extremely grateful for all the work Ryan is putting into projects like this.
https://github.com/icculus/mojoAL/blob/1adfdf5cd5447c68e11b0...
I overall have a good experience with mojoAL.
It says "AL_PITCH support in MojoAL should still be considered experimental!" though.
There was this amazing fan game made to mimic an episode of this tv show called Community. The show is about a group of community college students getting into all sorts of hijinks and one episode had all of them go into this video 8 bit video game world....so LÖVE was used to recreate the game exactly as you see in the show.
Unfortunately it is running on a very old version at this point and I hear due to how the framework has changed upgrading is not straightforward. It interesting to see how software changes and grows over time. Fortunately the last version released still seems to work fine on modern machines. (at least it runs on my M1 Mac)
[1]: https://www.youtube.com/watch?v=PzhuvOqfmC4
[2]: http://projecthawkthorne.com/
[3]: gameplay footage: https://www.youtube.com/watch?v=Imv6J8dqLyE
What blew me away 10 years ago was the complexity of the game that you could produce in LÖVE. its astounding!
I wonder if anyone has ported Hanappe, which is a GUI framework on top of MOAI, to LOVE yet ...
https://github.com/makotok/Hanappe
Maybe its time to revive MOAI and bring some heat to these frameworks ..
I was able to look at the source code for a steam demo that should no longer be playable, modify it to make it playable, and then make a new exe.
Just something to be aware of.
I have not done gamedev in a while, finding the time is difficult with a growing family. But it still makes me happy when someone pings me about one of my libraries.
A similar library would be raylib, that I’ve been using lately.
These libraries are simple enough so you can keep everything in your head, and they are powerful enough so you can immediately put stuff on the screen with zero ceremony. This combination makes it extremely productive.
It’s the perfect abstraction layer for amateurs and people who are drawn to simplicity.
works great. used this on a large project. works great with Love/LuaJIT too.
The engine layer can be extremely thin, which is why Löve (or its peers, like SDL, Allegro, Pygame...) work great for small or "outside the box" games, but you use different tools for different jobs. If you're building a cookie-cutter game, writing your own engine is a waste of your most precious resource: time and effort. But it's an entirely reasonable choice if you're building something like Factorio (which runs on top of Allegro), where an existing engine would just get in your way.
Every evening I would start a new project. Some were random game ideas, some were to study certain aspects of math (like fractals), some were just meant to be nice to look at. This is where I learned a lot about game design, and also a lot of the harder aspects of programming (after that, my college CS degree ended up being a breeze).
I was working alongside an internet friend on these. Sometimes we would collaborate on something exciting, sometimes we would work alone on something and share lots of progress updates between each other. It was a really fun time. I think LÖVE having no GUI really helped our minds to run free while we learned how powerful computers could be.
Some of my LÖVE projects I remember the most fondly:
- A gravity simulation / art canvas where ships would fly around planets and paint a trail behind them [1].
- An online multiplayer platformer roguelike with full rollback netcode that handles 150ms+ ping (this was a real challenge!) - never completed.
- An online pseudo-rhythm game where you only have one button to use and you have to work with your friends to input in the correct order while a timer keeps ticking down [2].
The last one still lives rent free in my mind. This one still gets downloads today, it's the most popular project I've been a part of. But I suspect most players don't get past the step of needing to forward ports and find 3 friends to play a short 5 minute indie game. I'm proud of the idea behind it, but I don't have a good way to turn it into a full game without ruining the core idea.
LÖVE was my tool of choice for many gamejams, it was a breeze to put together a prototype once I had gotten comfortable. Today I think I have more perspective and wish I could go back in time to see more of my 100+ prototypes to completion, instead of always finding a reason something was imperfect and not worth pursuing. Now I just don't have the same amount of energy when I get home from my software day job, I often need the time just to unwind. Lately I'm trying to push through and make gamedev a habit even if it's hard, to get back some of the joy during the days I was in love with LÖVE.
Edit: Formatting
I worked on something similar in high school(also never finished). Implementing good netcode on a novel multiplayer game can be very hard to get right. Made me a lot more forgiving of games that didn't do it well. You pretty much need to design your game with multiplayer in mind.
- Möan.lua - A messagebox system with multiple-choices and more (renamed to Talkies)
- Gspöt - GUI library for Love
...
Looking at https://steamdb.info/tech/Engine/Love2D/, there's only two games on that list that (based on steamspy numbers) that would actually be affected by the recent pricing changes.
If you're objecting to Unity on moral grounds for it's new DRM philosophies, or it's CEO, well those were just as valid almost 10 years ago.
The only open source project that remotely resembles Unity is Godot.
It was not completely open source, but it is now (if I didn't read it wrong).
For those who missed it like me, Unity raised prices: https://news.ycombinator.com/item?id=37481344
https://blog.unity.com/news/plan-pricing-and-packaging-updat...
Yes Unicode is cool, I'm glad we have it, I'm glad increasingly more things support it. I don't know the key combination for any character modifier off-hand, I usually copy these sorts of characters from google when I need them. It seems like it makes this framework unnecessarily harder to find.
Ö is not O, but Ö can be Ø
I'd much rather see projects named in leet or aLtCaPs, which are way cooler