love2d / love

LÖVE is an awesome 2D game framework for Lua.
https://love2d.org
Other
4.82k stars 388 forks source link

Proposal: Include love-nuklear as a Native GUI Framework #1243

Closed slime73 closed 4 years ago

slime73 commented 7 years ago

Original report by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


While I am aware that LOVE follows the general principles of Lua in that we don't want to bloat the API with cruft, I believe that one feature severely missing from LOVE is a native GUI module. There have been several attempts to make various GUI frameworks for love, all of which fall flat (including my own). I've been tinkering around with love-nuklear recently and it feels like a strong contender for something that could be included natively with LOVE. nuklear itself is an ANSI C header-only library and love-nuklear is a pretty decent Lua binding for it.

I really think LOVE could use a native GUI module, it would help round off all the major features in a framework that we already have, such as networking and physics. I'm not necessarily looking for a fast decision here, but perhaps we could discuss this?

slime73 commented 7 years ago

Original comment by buckle2000 (Bitbucket: buckle2000, GitHub: buckle2000).


That's great.

slime73 commented 7 years ago

Original comment by Jan W. (Bitbucket: [Jan Werder](https://bitbucket.org/Jan Werder), ).


I can only second that. Nuklear seems like a robust GUI.

slime73 commented 7 years ago

Original comment by lai weichih (Bitbucket: [lai weichih](https://bitbucket.org/lai weichih), ).


I think it can make LOVE more like a formal game framework, such as libgdx, unity, godot and game maker. Especially more and more gui library are stopping maintain and the rest are lack of complete feature. Of course if LOVE has stable graphic api then we can build our gui system from ground up. Before that happens, nuklear maybe a good alternative for the gui solution of LOVE. That can reduce a lot of effort for game developer.

BTW, throw these problem by plugin system may be a choice. (~ OwO )~

slime73 commented 7 years ago

Original comment by Andrew McWatters (Bitbucket: andrewmcwatters, GitHub: andrewmcwatters).


Please don't. I'd stop working with LÖVE if it decided to become more than the solid framework it has become. My team relies on LÖVE as a reliable Lua game framework, and we recently made the decision in Grid 8 to move away from our abstraction layers over LÖVE to using LÖVE directly in examples, so that people familiar with the ecosystem didn't have to learn another piece of software.

We originally used abstraction layers over LÖVE to provide a means of moving away from the framework in the event we wanted to pursue extending the engine to either have 3D capabilities (in the realm of LÖVR's design, sans the VR focus), or stop using LÖVE all together. By making changes like this, my team and I would have to revert our decision, and possibly start moving away from this framework.

In fact, our whole engine's tag line is "a game engine built on LÖVE" and in the past we've reported what issues with LÖVE we've stumbled on while building out parts of the engine.

The way I see LÖVE is that it's a game framework. It exposes to Lua routines related to window management, graphics, audio, image loading, and these low level concepts in a high level programming language. Planimeter's engine builds on this, and provides high level concepts like ui, client server architecture, maps, entities, pathfinding, and other engine-level implementations.

Unity is not a game framework, it's an engine.

slime73 commented 7 years ago

Original comment by Jan W. (Bitbucket: [Jan Werder](https://bitbucket.org/Jan Werder), ).


If find that logic hard to follow. Don't get me wrong, but from my point of view, you are essentially saying that Löve can't evolve in a direction you don't want it to evolve, because you use it in a certain way.

If we are quoting taglines here then, I want to quote Löve's tagline: It's a "[...] framework you can use to make 2D games in Lua". GUIs are an integral part of fully featured games, and one Löve doesn't provide a solution for. This led to the repitition and heterogeneous landscape that we find, when we're looking for a GUI solution for Löve. Grid, after all, is just one more repitition of that same problem.

From my point of view, it would be a good idea to solve that problem once and for all. That doesn't require anyone necessarily to use the "gui module". You could still roll your own, if you are not satisfied with what the Löve nuklear integration offers you, but at least it's an solution for people who want to make 2D games.

In conclusion I don't disagree with you, when you say it's only a framwork, but I would count a basic gui solution to the basics of a game framework, not the higher level problems like pathfinding, entities and client server architecture.

slime73 commented 7 years ago

Original comment by Andrew McWatters (Bitbucket: andrewmcwatters, GitHub: andrewmcwatters).


Well, yes, that's absolutely what I'm saying. People invest time in technologies, and when they uproot their foundations, it affects those who relied on it being what it used to be. Imagine if SDL became a game engine instead of a library to handle window creation and cross-platform issues.

What about XNA? That provided similar callback handlers back in its heyday, why not a GUI layer as well?

It's a shame LÖVE has this nice ecosystem, but no one has created a good enough GUI library for people to use. Maybe tackle this issue yourself, or contribute to one of the implementations available.

But to suggest an immediate mode GUI library as something to include by default? Are you asking for low FPS? I don't understand how a GUI system that isn't utilizing invalidation or canvases or anything to that effect as being suitable for the go to solution.

slime73 commented 7 years ago

Original comment by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


What? LOVE is not SDL, don't be silly. That's a very poor comparison. No one is asking for LOVE to become a fully fledged engine. a GUI is a very important part of all games and is something LOVE is severely lacking. As I said in my OP, many people have tried, and failed (including myself) to make a GUI module for LOVE. GUIs are hard. nuklear is very light weight, very robust, and would be great as a default option. But like every other module in LOVE, you can simply switch it off in conf.lua and never have to use it.

Also, immediate mode GUIs are not inherently bad at performance. Why not give love-nuklear a spin and see how it functions for you? The fact that it's so light weight yet so completely customizable is nothing short of impressive.

Edit: That love-panel lib you pointed out has some very bad design practices. Mainly that it infects a project with globals.

Edit2: Oh my god, that love-panel thing, the more I look at it, makes me cringe. Not only does it infect global state, it actively monkey patches both love and lua. That's really bad. I would never use that library.

slime73 commented 7 years ago

Original comment by Andrew McWatters (Bitbucket: andrewmcwatters, GitHub: andrewmcwatters).


Also, immediate mode GUIs are not inherently bad at performance.

Yes, they are. I've built an entire engine that's virtually the size of LÖVE itself and found that we couldn't use LoveFrames because the author didn't use optimized mouseover algorithms nor invalidation techniques to cut back on draw time. So we built our own subsystem that allowed us to develop more advanced usage. Vibrancy, and frames in worldspace were also goals and no one else had them but us.

slime73 commented 7 years ago

Original comment by Alex Szpakowski (Bitbucket: slime73, GitHub: slime73).


I strongly recommend not monkey-patching love like that. It makes any change in love's APIs drastically more likely to break more code than it would otherwise, if that code uses your library.

Keep in mind that an "immediate-mode GUI API" doesn't mean that batching and culling optimizations aren't possible, it just means the external API doesn't surface them.

If love were to get a built-in UI API, it would not require you to throw away your existing work since love.graphics isn't going away. (This isn't a statement about whether a UI API will or will not be included in love, though.)

slime73 commented 7 years ago

Original comment by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


loveframes is garbage, even the author admits that. loveframes is also not an immediate mode framework, so I don't see what your point here is.

Just because you write some code, doesn't mean it is good. Infecting global state is considered very bad practice in general, not just in Lua. Monkey patching is also considered to be a questionable practice. Predictability is very important for a codebase, and when one developer decides to break that predictability with their own code, it can cause a lot of havoc. This is why encapsulation can be a great thing: each bit of code runs in its own little sandbox.

An example: What if you decided to add a global string.split function to your module that took two arguments: string and delimiter. But another module also creates its own string.split that take sin delimiter and string. One of them is going to overwrite the other, and the overwritten module is going to break. However, if each module creates its own local string_split function, they can be used internally without affecting each other.

Edit: Your UI doesn't exactly look complex. It looks nice for sure, but I would hardly call it complex.

slime73 commented 7 years ago

Original comment by Andrew McWatters (Bitbucket: andrewmcwatters, GitHub: andrewmcwatters).


I strongly recommend not monkey-patching love like that.

I don't like monkey-patching things if I don't need to, but I can't think of a solution for most of the problems solved by these libraries that doesn't involve much more code and maintenance. At some point, you have to give up some ideological pureness for practical implementations.

Keep in mind that an "immediate-mode GUI API" doesn't mean that batching and culling optimizations aren't possible, it just means the external API doesn't surface them.

It certainly also means a lot of involved work to implement these basics. If the community couldn't write a GUI library, it sure isn't going to do these things, either.

slime73 commented 7 years ago

Original comment by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


Because the community couldn't create a solid GUI library is precisely why I suggest we include one natively. GUIs are generally very important for most games, and have an out of the box solution would be a huge improvement to love as a framework. If you don't want to use the built-in, you don't have to. Just like many people turn off love.physics and instead use bump.lua, you too could turn off love.gui and roll your own.

Not to mention nuklear is written in C89 with zero dependancies, it's just plain fast.

slime73 commented 7 years ago

Original comment by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


When someone uses my engine, they subscribe to my architecture. If you're developing against my codebase, and there's already a util function that exists with a name you wanted, pick another name. This argument is used consistently by developers, but when it comes down to a large platform you're using, it's all thrown out the window. If you're an individual library author, sure, don't do it. If you're a platform architect, who cares?

That is an extremely poor attitude to have. Why should your module take presidence over any other module? If I included love-panel in my project, why should I be forced to remove other modules I need because your module is so selfish?

slime73 commented 7 years ago

Original comment by Gabe Stilez (Bitbucket: z0r8, ).


I'd also mention that just like the default font included with Löve (which is small, and iirc lacks CJK), it's there so the framework can (mostly) function in that regard, having a font to print out text; if i want CJK or a fixed-width font, i'll have to include it myself.

Also, nuklear wouldn't be a GUI that one would end up using in a release build, but to start out with, and experiment; it might just be worth it, not to mention the fact that it's one header file.

@karai17 He made an engine, you probably wouldn't just include it in your project anyway.

slime73 commented 7 years ago

Original comment by Andrew McWatters (Bitbucket: andrewmcwatters, GitHub: andrewmcwatters).


I'd also mention that just like the default font included with Löve

I wish it wasn't, and the framework would just use a system font.

slime73 commented 7 years ago

Original comment by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


Pure Lua is NOT faster with LuaJIT. In an apples-to-apples comparison, C is going to be faster almost all of the time.

I suspect the vast majority of people would use the built-in GUI module, especially if it is nuklear, because it is actually good. Some people opting for their own is no reason to not include something for everyone else.

slime73 commented 7 years ago

Original comment by Andrew McWatters (Bitbucket: andrewmcwatters, GitHub: andrewmcwatters).


There is overhead in calling from Lua -> C -> Lua, that many times LuaJIT does not have when running equivalent functionality, or using FFI. C isn't faster almost all of the time, and it's why some authors choose to use FFI over the Lua C API.

slime73 commented 7 years ago

Original comment by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


I am well aware of the overhead. That doesn't mean LuaJIT is magically faster than C. While it may be able to contend in some cases, C is almost always going to come out on top.

slime73 commented 7 years ago

Original comment by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


It is also worth noting that LOVE officially supports platforms where JIT is not available (iOS, for example). Creating a cross platform game with mobile in mind is immediately going to cause you performance problems. You simply cannot rely on JIT when using LOVE in every case, so having a native gui module over a Lua module is going to be just that much faster.

And again, nuklear is completely fine. Immediate mode GUIs aren't inherently bad or even slow. For the vast majority of games that would be built in love, it is a perfectly acceptable and performant solution. I suspect it would even be fine for a menu-heavy RPG. If for whatever reason nuklear just wasn't working out for you, you could simply not use it. It's a single header file that compiles to about 200kb. If you were so worried about raw binary size, you could even compile your own binary when you release your game.

Not including a gui module in love simply because some people wouldn't use it, especially when gui's are about the number one pain point that crop up on the forums, is extremely short-sighted and selfish.

slime73 commented 7 years ago

Original comment by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


Pot, meet kettle.

slime73 commented 7 years ago

Original comment by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


I was more pointing out the whole "hobbyists who can already barely code as it is" bit in your statement. But yeah, also the proliferation of bad design is definitely something you seem to be doing.

slime73 commented 7 years ago

Original comment by Aatu Hieta (Bitbucket: AatuHieta, ).


I seriously don't think this is the place to get your fix of EgoBoost, mr "Award winning developer" (funny how you listed that on your resume, but not a single award...). I see that you argue about love-nuklear adding to binary size, and not justifying said addition by being unused, which is funny, because we already have things like love.physics, which are widely unused, yet you don't seem to care about their existence.

I personally think we need a solid, yet minimal(*) native GUI lib for löve. This would make development a lot easier, as people wouldn't have to care about choosing a GUI lib (which is pretty common topic. And as other löve features, these are optional, and can be disabled, and you can compile your own binary without it.

But I understand your point. I know why you are saying what you are saying. You feel threatened. You fear that people will stop using your shitty excuse-of-an-engine if love gets native GUI. You feel threatened, so you go running your mouth, spouting nonsense. Someone points your (horrible, if I may add) coding practices. I didn't know this was possible, but you get even more defensive. You begin quoting your own "award winning" work, while sadly, the code is out there, for all of us to see. Btw, did you know that the usage of module() is considered bad practice?

I suggest you remove your egoist nonsense, and let grown-ups discuss good design, as you clearly have no valuable input to this matter.

EDIT: I tried to make footnotes, but I failed. Anyway, nuklear is small AF

slime73 commented 7 years ago

Original comment by Aatu Hieta (Bitbucket: AatuHieta, ).


It's ok, you can stop trolling now. BTW flagged your comments. Here's some reading for you while you wait to get banned from this repo: http://lua-users.org/wiki/LuaModuleFunctionCritiqued

(Have some submit-button-discipline bro)

slime73 commented 7 years ago

Original comment by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


love is self-contained in a single namespace. there are some cases where you need globals, love being one of them. Throwing globals all over the place when you don't need to is very, very poor code design.

In my game code, I tend to have about 4 or 5 globals: love, gamestate, signals, preferences, and some flags. Now, preferences and flags don't need to be global, but they are self-contained tables that do not affect any other part of my code and it is very useful to be able to query _G.PREFERENCES to grab sfx volume, for instance. Gamestate is used as a callback instance mechanism and it needs to be controlled on a global level. love also has this attribute where it needs to carry state with it regardless of where you are using it.

Globals themselves are not explicitly bad, it's the rampant disregard for designing your code that is abhorrent. If you feel like you need to use globals to get a job done, you can almost always redesign your code to not require them. Same with monkey patching. It looks like your monkey patchig mostly adds caching to love. There is a self-contained module that already does that and does not require any patches to any monkeys. https://github.com/airstruck/knife/blob/master/knife/memoize.lua

Landon works on a project which uses monkey-patching as a prominent feature

No I don't? If you are referring to LOVE3D, the monkey-patching is an optional flag and was since removed (maybe not upstream) because it was awful and didn't even work well.

slime73 commented 7 years ago

Original comment by Aatu Hieta (Bitbucket: AatuHieta, ).


"linking me to a article on lua-users, which answers the question I asked, isn't answering the question I asked". Cool beans bro.

How about this. You quit using löve. You get your toxic, egoistic, uneducated ass out of this community. We don't need you. We don't want you. Feel free to rewrite your engine with something else. I think C++ would be perfect for you, just don't use anything too new :)

As for your listed "highlights", I don't get what you mean? No one is perfect, I know, but at least I stand by my words, and don't outright lie. You are clearly egoist (you lie to make yourself look better, which is not cool), and you are certainly not grown-up. You have brought next to none to this conversation about löve, yet about half of the text here is written by you.

This is not your personal playground, we are not your personal army. We are here to discuss future of löve, and you are not contributing. Please, leave.

EDIT: About reading your resume, yes, I did. You yourself quoted your work, so I had to check it out. I wish I hadn't.

slime73 commented 7 years ago

Original comment by Alex Szpakowski (Bitbucket: slime73, GitHub: slime73).


Hi all. Please chill – this issue tracker is about LÖVE's code and APIs, and this specific issue is about whether nuklear could be included in LÖVE. It is not for promoting or discussing other people's APIs built using LÖVE or otherwise, or anything that does not directly pertain to LÖVE's own code and APIs.


love is a global largely for legacy reasons. In 0.11.0, the third party modules included with LÖVE (enet, luasocket) will no longer export themselves as globals automatically when you require them.

slime73 commented 7 years ago

Original comment by Nicola Orlando (Bitbucket: Nixola, GitHub: Nixola).


If I may at least try to get this back on topic, I think adding a GUI to LÖVE would only be beneficial, having tried to code one myself as well, and I really don't think your reasons for not adding one are really valid - just don't use it. If you're concerned about binary size, build LÖVE on your own without the extra module[s], especially since you have to build it anyway for the only platforms where size matters if I recall correctly (although 200KB is pretty much nil).

slime73 commented 7 years ago

Original comment by Aatu Hieta (Bitbucket: AatuHieta, ).


So, for the record, I support both of these:

slime73 commented 7 years ago

Original comment by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


fwiw, I have 500 nuklear panels open right now running at 60fps (vsynced). Bumping up to 1000 drops me to 47fps. Seems performant enough.

throwing several ui elements inside each window (500 windows) brings me to 25fps.

50 windows with some ui elements gets me back up to 60fps (vsynced).

slime73 commented 7 years ago

Original comment by lai weichih (Bitbucket: [lai weichih](https://bitbucket.org/lai weichih), ).


performance look fine, but how many binary size spend on nuklear ?

slime73 commented 7 years ago

Original comment by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


An increase in about 200kb for the dll/so, possibly less if statically linked.

slime73 commented 7 years ago

Original comment by lai weichih (Bitbucket: [lai weichih](https://bitbucket.org/lai weichih), ).


I think spending 200kb for making gui design easier is quite fair, especially for games in beta version. Changing gui design already kill me inside, I do not to worry about choosing gui library any more. Besides, we will manually optimize ui before release anyway. To start out and experiment with gui is matter.

Edit: For one worry about binary bloat as me, comment unused module and re-compile love for release version could be helpful.

slime73 commented 7 years ago

Original comment by Jan W. (Bitbucket: [Jan Werder](https://bitbucket.org/Jan Werder), ).


To even the odds: One thing I found irretating is that the state of nuklear in its current form seems to be kind of final (https://github.com/vurtun/nuklear/issues/157) This is a shame, because in the case that our needs expand, it seems unlikely that the base nuklear is going to cover it, which might lead to a Löve specific fork. All in theory of course and I'm still for an inclusion, but I just wanted to throw that out there.

slime73 commented 7 years ago

Original comment by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


What are some things that nuklear is currently missing that may seem beneficial in the future? nuklear definitely has all the basics that the vast majority of lovers would be likely to use, so I wouldn't want to write it off because it doesn't include some obscure widget that, like, 5 people maybe really be interested in.

slime73 commented 7 years ago

Original comment by Jan W. (Bitbucket: [Jan Werder](https://bitbucket.org/Jan Werder), ).


My point isn't to write it off, because it doesn't have feature X, but that it might be hard to get feature X, IF we ever think we need it. For examples on what might be missing at the moment, the author himself names a few: "[...] not because there are no more things to fix (like better graph support) or add (tables, shortcuts, docking, more widgets, ...) "

slime73 commented 7 years ago

Original comment by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


It's something to consider. I definitely think that what nuklear currently offers is very close to what most lovers need. It's got your buttons, your labels, sliders, etc. Nearly every GUI that's popped up in the love community over the years generally only supplied those basic widgets. One of the biggest issues (besides performance and stability) has been stylability, and nuklear also provides a pretty decent theming/styling system.

slime73 commented 7 years ago

Original comment by Jan W. (Bitbucket: [Jan Werder](https://bitbucket.org/Jan Werder), ).


Sure, and if you wanted to extend nuklear for table capability (i.e.), you could always just spawn an empty nuklear window and do the rest yourself with Löve. The only thing we wouldn't be able to extend or improve are the built-in things, like graph handling, docking and so on. Still this would be a pretty solid solution though.

slime73 commented 7 years ago

Original comment by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


Yeah, there's nothing stopping a lover from making an in-love widget. And there's nothing really stopping love devs from patching the nuklear module (and even sending up stream) if it is deemed necessary.

slime73 commented 7 years ago

Original comment by Alex Szpakowski (Bitbucket: slime73, GitHub: slime73).


I don't want to have to maintain a dependency.

slime73 commented 7 years ago

Original comment by lai weichih (Bitbucket: [lai weichih](https://bitbucket.org/lai weichih), ).


I don't want to have to maintain a dependency.

I totally understand that maintain extra dependency is no use. But if we do not use other gui lubrary( nuklear, or even imgui ), will Löve has it own build-in gui module?

slime73 commented 7 years ago

Original comment by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


nuklear is still in active development. New features may not be common but bug fixes seem pretty constant and reliable. I don't think we would need to maintain nuklear.

slime73 commented 7 years ago

Original comment by lai weichih (Bitbucket: [lai weichih](https://bitbucket.org/lai weichih), ).


It is frustrating.

slime73 commented 7 years ago

Original comment by Clyybber (Bitbucket: Clyybber, GitHub: Clyybber).


Do you know if nuklear supports nine-patching, cause that would be a feature to consider especially when developing for mobile platforms

slime73 commented 7 years ago

Original comment by M D (Bitbucket: rootmars, GitHub: rootmars).


love-nuklear doesn't seem to support quads, only images.

slime73 commented 7 years ago

Original comment by Landon “Karai” Manning (Bitbucket: karai17, GitHub: karai17).


You could open an issue on the love-nuklear repo about that.

slime73 commented 7 years ago

Original comment by M D (Bitbucket: rootmars, GitHub: rootmars).


Sure, I'll get on it.

slime73 commented 5 years ago

Original comment by Joel Schumacher (Bitbucket: dudeguy, GitHub: dudeguy).


Since this was talked about in the Discord, I'll add my opinion which is, that nuklear may be a nice library, but it is barely of use for actual game UIs. And including a GUI library for prototyping and the occasional tool does too little good to warrant an inclusion (that requires continuous maintenance too).

slime73 commented 4 years ago

Original comment by Alex Szpakowski (Bitbucket: slime73, GitHub: slime73).


Nuklear is no longer being maintained by its author: https://twitter.com/MichaMettke/status/1206707558657994764

slime73 commented 4 years ago

Original comment by Gianmichele Mariani (Bitbucket: gianmichelemariani, GitHub: gianmichelemariani).


I think this is a perfect example where probably plug-in hooks for LÖVE would solve the debate elegantly.

Users could download the source + plugin and compile their own custom build and LÖVE could remain lean and minimalistic at the core.

Thoughts?

slime73 commented 4 years ago

Original comment by Alex Szpakowski (Bitbucket: slime73, GitHub: slime73).


Users could download the source + plugin and compile their own custom build and LÖVE could remain lean and minimalistic at the core.

What are the differences with that versus standard Lua C modules (which love-nuklear is one of)?