Post-0.10.0 feature wishlist

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
spill
Prole
Posts: 27
Joined: Thu May 07, 2015 1:53 am
Contact:

Re: Post-0.10.0 feature wishlist

Post by spill »

slime wrote:• Mobile-specific APIs for in-app-purchases and ads, as optional extensions (e.g. through require). I don't do any Android development, so if I were to implement part of this I still couldn't do all of it.
Yes please!
slime wrote:• Better APIs for mobile accelerometers and gyroscopes. The current "accelerometer-as-joystick" deal in 0.10.0 is a bit of a hack, and doesn't expose the device's gyroscope (rotation rate sensor) at all. Ideally I'd implement new APIs in SDL2 for this, and then use the new SDL APIs in LÖVE.
This would be cool. It would also be especially nice if the axes used would adjust when the screen orientation changes so that I don't have to write special code to convert accelerometer coords to on-screen coords.
slime wrote:• Improved handling of high-dpi / retina (issue #1122). The way it is right now, it's hard to figure out how to handle it properly without doing some testing on devices that support it. I'm sure LÖVE could be made to handle some of the annoying bits itself, but I have to figure out what the best way to do that is without adding too many surprising corner cases.
I definitely ran into a few hiccups with this when I started dev on a retina iPhone. My main suggestion would be that the default behavior should be for everything to appear the same size whether or highdpi is enabled or disabled (i.e. dimensionless "point" coordinates). It's a hassle to have to scan through your entire codebase for any references to dimensions just to get everything to not look super tiny.
slime wrote:• API changes to reduce the number of (accidental) graphics performance problems people might encounter (issue #1106), and as a secondary goal to make it easier to have a fancier graphics backend and make it use newer APIs like Metal and Vulkan (not that that's a high priority).[...]
Seems solid. I ran into some performance problems with my iOS game Unshuffle and had to do a lot of fine tuning to get it to the point where my iPhone was no longer heating up after a few minutes.
slime wrote:• Reducing the global state in love.graphics (see this thread for some discussion) – but without making the graphics APIs less simple to learn and use. A lot of experimentation will probably have to be done for this.
In my codebase, I've been using some helper functions that mimic Python's context managers. It really went a long way towards making my code more readable and less error-prone. If these were implemented as method calls, I think it would be a step in the right direction. Here's what my code looks like for canvases (and I have a similar setup for shaders):

Code: Select all

function love.graphics.drawOn(canvas, drawFn)
    local oldCanvas = love.graphics.getCanvas()
    love.graphics.setCanvas(canvas)
    drawFn()
    love.graphics.setCanvas(oldCanvas)
end
...
function love.draw()
    love.graphics.drawOn(tmpCanvas, function()
        love.graphics.drawOn(tmpCanvas2, function()
            love.graphics.rectangle(0,0,10,10)
        end)
        love.graphics.draw(tmpCanvas2)
    end)
    love.graphics.draw(tmpCanvas)
end
If it were implemented as methods on canvases/shaders, it could look something like this:

Code: Select all

function love.draw()
    tmpCanvas:drawOn(function()
        love.graphics.rectangle(0,0,10,10)
        love.graphics.screen:drawOn(function()
            love.graphics.circle('fill',10,10,10) -- Draw to screen directly
        end)
    end)
    love.graphics.draw(tmpCanvas)
end
The same logic could probably be applied to love.graphics.push()/love.graphics.pop() calls by creating a "context" object like this:

Code: Select all

function love.draw()
    local context = love.graphics.newContext()
    context:scale(2,2)
    context:translate(100,33)
    context:render(function()
    	love.graphics.circle('fill',100,100,100)
    end)
end
I realize this is not as purely functional as passing more arguments to all the functions, but I think it's a nice balance between reflecting the underlying implementation (OpenGL uses global state heavily) and being user-friendly (with this implementation it's impossible to have a mismatched push()/pop() or a mismatched setCanvas(canvas)/setCanvas()). That way, users are encouraged to follow practices that are good for OpenGL performance, like lumping draws to the same canvas together, but they're still protected from most of the nastiness of the global state.
slime wrote:• Support for different Image and ImageData pixel formats, including floating-point formats (e.g. storing arbitrary number values in pixels). This can be useful for advanced rendering techniques and similar things, but said formats aren't always supported by all of the graphics hardware that LÖVE supports. Also, LÖVE's APIs are all designed for "byte" color components that are in the range of [0, 255], so it's a bit awkward to add things that require different value ranges now.
I would find this useful. And I would definitely be happy if LÖVE used [0.0,1.0] colors. I don't think it sacrifices much for noob-friendliness, because 0-1 is fairly intuitive (50% brightness red is (.50,0,0) instead of (127.5,0,0), 30% is (.30,0,0) instead of (76.5,0,0), etc.), and it makes shaders easier to learn if the rest of LÖVE uses the same color representation. It's also pretty awkward that LÖVE nominally supports the canvas format rgba16f and other floating point formats, but you can't actually set the draw color to negative numbers or anything outside the 0-255 range.
slime wrote:• Microphone input (issue #1). Ideally I'd want a microphone API that's actually useful/usable for real world use cases, which I have no experience with.
That would be great. I'd also really like to have camera input on mobile devices.


On a much bigger scale, I think it would be really cool if LÖVE used 2d vectors instead of x/y coordinates everywhere. All my code uses the HUMP vector module and I think it's really good practice to use vector math. I could go on endlessly about the benefits, but I understand that converting everything would be a huge undertaking, so I know it's really only wishful thinking.

Overall, great work on 0.10.0! LÖVE is definitely moving in a great direction and I'm already excited for the next release and happy to be a guinea pig for new features.
User avatar
slime
Solid Snayke
Posts: 3166
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Post-0.10.0 feature wishlist

Post by slime »

Thanks for the feedback!
spill wrote:
slime wrote:• Better APIs for mobile accelerometers and gyroscopes.
This would be cool. It would also be especially nice if the axes used would adjust when the screen orientation changes so that I don't have to write special code to convert accelerometer coords to on-screen coords.
I'll look into it, no promises though – I don't want LÖVE to do too many internal changes to sensor values that might be unexpected, and I'm not sure to what degree the underlying Android/iOS APIs support that kind of thing.
spill wrote: I definitely ran into a few hiccups with this when I started dev on a retina iPhone. My main suggestion would be that the default behavior should be for everything to appear the same size whether or highdpi is enabled or disabled (i.e. dimensionless "point" coordinates). It's a hassle to have to scan through your entire codebase for any references to dimensions just to get everything to not look super tiny.
That's the plan – I have a preliminary test implementation partially completed right now.
spill wrote:I ran into some performance problems with my iOS game Unshuffle and had to do a lot of fine tuning to get it to the point where my iPhone was no longer heating up after a few minutes.
Can you elaborate on what was causing problems specifically? Maybe I can reduce some of that at the API level.
spill wrote:If it were implemented as methods on canvases/shaders, it could look something like this:

Code: Select all

function love.draw()
    tmpCanvas:drawOn(function()
        love.graphics.rectangle(0,0,10,10)
        love.graphics.screen:drawOn(function()
            love.graphics.circle('fill',10,10,10) -- Draw to screen directly
        end)
    end)
    love.graphics.draw(tmpCanvas)
end
[wiki]Canvas:renderTo[/wiki] does exist right now (and does the same thing as that). :)

One issue is that it doesn't really work with MRTs / multi-canvas rendering (i.e. love.graphics.setCanvas(c1, c2, c3, ...)).
Also, it doesn't necessarily encourage the most efficient use of render target switching under the hood.
spill wrote:The same logic could probably be applied to love.graphics.push()/love.graphics.pop() calls by creating a "context" object like this:

Code: Select all

function love.draw()
    local context = love.graphics.newContext()
    context:scale(2,2)
    context:translate(100,33)
    context:render(function()
    	love.graphics.circle('fill',100,100,100)
    end)
end
Yeah, something like that is one possibility. I haven't yet found out whether that's the best possible compromise between global state reduction, (lack of) boilerplate, API friendliness, and performance, though.
spill wrote:And I would definitely be happy if LÖVE used [0.0,1.0] colors.
Yeah – the next major version of LÖVE will, I think. It might've happened for 0.10.0 but it was already relatively close to release by the time I decided it was a good idea, and I didn't want to rush a major breaking change like that.

spill wrote:it would be really cool if LÖVE used 2d vectors instead of x/y coordinates everywhere.
The main problem with LÖVE's APIs using vector objects is that in Lua, vector objects tend to create a lot of garbage if used heavily. So having them required for using LÖVE functions prevents optimal performance. Some engines go to extreme lengths to try to work around that: https://www.youtube.com/watch?v=wTjyM7d7_YA#t=23m6s

I don't want to make vector-specific function variants either, as that would make the API a lot messier.
spill wrote:Overall, great work on 0.10.0! LÖVE is definitely moving in a great direction and I'm already excited for the next release and happy to be a guinea pig for new features.
Thanks! :)

I have a full-time job now though so I can't spend as much time working on LÖVE as I used to. I still intend to work on it as much as possible, but contributions from people who aren't me are more than welcome. ;)
Last edited by slime on Thu Jan 21, 2016 9:56 pm, edited 1 time in total.
User avatar
spill
Prole
Posts: 27
Joined: Thu May 07, 2015 1:53 am
Contact:

Re: Post-0.10.0 feature wishlist

Post by spill »

slime wrote:
spill wrote:I ran into some performance problems with my iOS game Unshuffle and had to do a lot of fine tuning to get it to the point where my iPhone was no longer heating up after a few minutes.
Can you elaborate on what was causing problems specifically? Maybe I can reduce some of that at the API level.
It's somewhat of a complicated performance problem, but basically, rendering my game involves drawing a bunch of circles and lines (maybe 20 circles and 40 lines), but it gets complicated because the circles and lines have drop shadows, so I use images for them, and the order of drawing is significant. While I'm doing this, I am also using a modified version of the bloom pixel shader you wrote (looking at it now, I think I might be switching between canvases too much). And I also have two custom pixel shaders that produce different visual effects (one does a rippling rainbow wave and the other does a wispy dissolve). In previous iterations of the game, I was using some temporary canvases and different blend modes to properly render different lines weaving in and out of each other. I realize that a lot of the issues were caused by the aesthetic requirements I placed on myself, but the fewer ways for me to shoot myself in the foot, the better. ;)
slime wrote:[wiki]Canvas:renderTo[/wiki] does exist right now (and does the same thing as that). :)
*facepalm* I did not realize that. Still, I'd like to see that pattern replicated for other things like Shaders and the old pattern depricated.
slime wrote:
spill wrote:it would be really cool if LÖVE used 2d vectors instead of x/y coordinates everywhere.
The main problem with LÖVE's APIs using vector objects is that in Lua, vector objects tend to create a lot of garbage if used heavily. So having them required for using LÖVE functions prevents optimal performance.
I think it would be possible to address those issues. One way to do it would be to have vectors be immutable objects and intern a certain number (or all) of them, like Lua does with strings, or Python does with numbers. And as it is, my games (and many other people's) are pretty much creating that garbage in the worst possible way anyways (HUMP uses lua tables instead of userdata), so even if the LÖVE API accepted vectors, it wouldn't really affect my game's performance. Like I said, though, converting LÖVE to use vectors is mostly just wishful thinking because I do understand the effort it would require and that it would break backwards compatibility in a major way. I have written an experimental vector library for myself though that does use immutable userdata vectors with hashing that would allow for interning. I haven't gotten around to performance testing yet though, so I can't say how it fares. If there's any interest, I'll put it up on BitBucket.
slime wrote:I don't want to make vector-specific function variants either, as that would make the API a lot messier.
Yeah, I agree. There should not be two APIs, and the way that the x,y components go first in most of the functions makes it too difficult to allow the function to take either x/y or vector arguments.
User avatar
zorg
Party member
Posts: 3468
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Post-0.10.0 feature wishlist

Post by zorg »

spill wrote:And as it is, my games (and many other people's) are pretty much creating that garbage in the worst possible way anyways (HUMP uses lua tables instead of userdata)
But, garbage should only be an issue if you'd be creating temporary tables every frame; Also, if you're only referring to HUMP's vector module, then vrld did make vector-light because of that. If you mean others as well, i can't say anything except for the gamestate module, that doesn't create any (temporary) intermediate tables.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
spill
Prole
Posts: 27
Joined: Thu May 07, 2015 1:53 am
Contact:

Re: Post-0.10.0 feature wishlist

Post by spill »

zorg wrote:
spill wrote:And as it is, my games (and many other people's) are pretty much creating that garbage in the worst possible way anyways (HUMP uses lua tables instead of userdata)
But, garbage should only be an issue if you'd be creating temporary tables every frame; Also, if you're only referring to HUMP's vector module, then vrld did make vector-light because of that. If you mean others as well, i can't say anything except for the gamestate module, that doesn't create any (temporary) intermediate tables.
vrld's vector-light module does solve the problem, but if you're using HUMP's regular vector library, basic math operations will tend to accumulate a lot of temporary tables. Consider this example:

Code: Select all

function love.update(dt)
    for _,obj in ipairs(objects) do
        obj.vel = obj.vel + dt*GRAVITY
        obj.pos = obj.pos + dt*obj.vel
    end
end
It's much more readable than vector-light's

Code: Select all

obj.velx,obj.vely = vector.add(obj.velx,obj.vely, vector.mul(dt, GRAVITY_X,GRAVITY_Y))
obj.x,obj.y = vector.add(obj.x,obj.y, vector.mul(dt, obj.velx,obj.vely))
but the first example will create a new table for every math operation, which means 4 new tables are instantiated per object, per frame. The same is true of any vector module that overrides __add and other math operations. Personally, I think the HUMP vector module is worth the performance cost because it makes the code a lot more readable and maintainable. The question of whether the LÖVE API should use vectors is a question of whether the code cleanliness benefits of a vector API is worth forcing everyone to make the same readability over performance tradeoff. Since I'm already paying the performance cost, I'd be happy if the API changed, but I can understand why people who don't use vectors would be unhappy.
User avatar
Nixola
Inner party member
Posts: 1949
Joined: Tue Dec 06, 2011 7:11 pm
Location: Italy

Re: Post-0.10.0 feature wishlist

Post by Nixola »

I wrote a quick vector library that tries to prevent the creation of intermediate tables in a weird way - vector1 + vector2 edits vector1 and returns it, so no new tables are created. The drawback is obvious, but I noticed that most of the time I don't mind it (and I've got an explicit vector:clone() method when I do).
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Post-0.10.0 feature wishlist

Post by bartbes »

But how would you implement the dt*obj.vel example from above? Or worse, the dt*GRAVITY? If you modify the vectors obj.vel or GRAVITY, you're changing something you shouldn't be, and if you're not, you're making useless tables. I don't think there's a clean solution here that "simply" involves operator overloading, because you'd kind of need a ternary operator.
User avatar
Nixola
Inner party member
Posts: 1949
Joined: Tue Dec 06, 2011 7:11 pm
Location: Italy

Re: Post-0.10.0 feature wishlist

Post by Nixola »

Actually, even though I can't remember the project exactly (it's been a while since I last seriously worked on this), I'm quite sure I handle things almost properly here.
Ok, I'm sure there are a lot of mistakes in my approach, but that's how I'm doing it.
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Post-0.10.0 feature wishlist

Post by bartbes »

Right:

Code: Select all

self.x = self.x + self.velocity.x*dt
self.y = self.y + self.velocity.y*dt
I suppose the "best" solution would be a method

Code: Select all

self.pos:scaledAdd(self.velocity, dt)
but it's not exactly as nice.
User avatar
Nixola
Inner party member
Posts: 1949
Joined: Tue Dec 06, 2011 7:11 pm
Location: Italy

Re: Post-0.10.0 feature wishlist

Post by Nixola »

I actually didn't remember that part, I was thinking about how I handle it in the enemies, but I guess that works too :3
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
Post Reply

Who is online

Users browsing this forum: No registered users and 7 guests