Flame needs a more complete minimal physics engine
Problem to solve
There is no physics engine that available for Flame that has enough features to make implementing platformer physics easy.
Proposal
Flame needs a physics engine akin to bump.lua. That implements moving objects and performing [slide, cross, bounce, touch] reactions when moving an AABB from one spot to another. This is not available with Flame's built in collision detection and bringing in box2d is overkill and not good for many types of games (like platformers). FWIW I tried to leverage the existing collision detection system to implement slide and I came to the conclusion it would just be easier to implement my own physics.
Wishlist:
- slide collisions (like bump.lua's
movewith"slide") - rectangle casting (like bump.lua's
check)
More information
No response
Other
- [ ] Are you interested in working on a PR for this?
Here's the sort of thing I'd expect to be easy to do in Flame. This took only 30 minutes in Love2D + bump.lua but I struggled to make something similar with Flame's physics engine.
local bump = require('bump')
local class = require("30log")
local SPEED = 128;
local GRAVITY = 9;
local JUMP_POWER = 6;
local WORLD = bump.newWorld(16)
local Ninja = class("Ninja")
function Ninja:init()
self.x = 0
self.y = 0
self.width = 16;
self.height = 16;
self.dy = 0
self.onPlatform = false
WORLD:add(self, self.x, self.y, self.width, self.height)
end
function Ninja:update(dt)
local dx = 0
local dy = self.dy
self.dy = self.dy + GRAVITY * dt
if love.keyboard.isDown('left') then
dx = dx - dt * SPEED
end
if love.keyboard.isDown('right') then
dx = dx + dt * SPEED
end
if self.onPlatform and love.keyboard.isDown('up') then
self.dy = -JUMP_POWER
self.onPlatform = false
end
local actualX, actualY, cols, len = WORLD:move(self, self.x + dx, self.y + dy)
if len <= 0 then self.onPlatform = false end
for _, col in ipairs(cols) do
if col.itemRect.y + col.itemRect.h <= col.otherRect.y then
-- Hit your feet.
self.dy = 0
self.onPlatform = true
break
end
if col.itemRect.y >= col.otherRect.y + col.itemRect.h then
-- Hit your head.
self.dy = 0
end
end
self.x = actualX
self.y = actualY
end
function Ninja:draw(dt)
love.graphics.setColor(1, 0, 0)
love.graphics.rectangle("fill", self.x, self.y, self.width, self.height)
end
local Block = class("Block")
function Block:init(x, y)
assert(x ~= nil)
assert(y ~= nil)
self.x = x
self.y = y
WORLD:add(self, self.x, self.y, 16, 16)
end
function Block:update(dt) end
function Block:draw()
love.graphics.setColor(1, 1, 1)
love.graphics.rectangle("fill", self.x, self.y, 16, 16)
end
local NINJA = Ninja:new()
local BLOCKS = {}
function love.load()
for i = 14,16 do
for j = 0,20 do
table.insert(BLOCKS, Block:new(j * 16, i * 16))
end
end
table.insert(BLOCKS, Block:new(5*16, 7*16))
end
function love.draw()
for _, block in ipairs(BLOCKS) do
block:draw()
end
NINJA:draw()
end
function love.update(dt)
NINJA:update(dt)
end
Have you tried Leap which is an opinionated platformer package built on Flame? https://pub.dev/packages/leap
Thanks that definitely looks like it would solve my needs. When it gets to a good state we should consider mentioning it on https://docs.flame-engine.org/latest/flame/collision_detection.html
I know reading through lua code can be tiresome if you aren't familiar with it, but I want to make sure you get a chance to see how bump.lua works. I think there are some lessons from its design Flame can learn from. It's much more fundamental than Leap so different things can be implemented with it besides platformers. The other nice thing it is a self contained object that can be used directly as one wants, it doesn't rely on hidden life-cycle events or reflection. It also handles every interaction with tunneling, which eliminates a common pitfall for new users.
I think it's likely if someone were to invest a good chunk of time on making a platformer that they ship, one could really benefit from all the built-in features in Leap. However, bump.lua is much faster to get started, easier to understand and easier to use novelly. It would be nice to have an equivalent in the Flame ecosystem for people that just like to make small games quickly. Maybe that means expanding the built-in physics system or just making a whole separate thing.
and why can't this be achieved using forge2d?
and why can't this be achieved using forge2d?
Response from gemini:
In summary, while Box2D is excellent for games where realistic physics is the core mechanic (like Angry Birds), it often works against the goals of a platformer, which prioritizes player control and specific, non-realistic behaviors over simulation. Most developers recommend building a custom character controller for platformers to achieve the necessary level of precision and feel.
i love it how you start the answer with:
Response from gemini:
While I understand your point of view (and Gemini's), I also believe that if you want to use a physics engine, it's because you expect a certain "realistic" behavior, at least in terms of physics.
I think in this case it's a balance between a physics engine that solves collisions, gravity, movement, and other issues out of the box, and the freedom to create a 100% customized platformer. In that case, no physics engine would work for you because they all work by following the same principles (physics/realistic principles, although you can still modify the behavior at the code level of course).
If you want a simple but powerful physics system, Forge2D should solve all your problems. If you want something 100% customized, you'll probably have to implement it by hand.
Writing your own physics or using box2d is an option with love2d too, and yet bump.lua is a popular option. Look at the code above versus what the equivalent would be for forge2d. There is a space between forge2d and writing your own where nothing exists today and thats where a lot of hobbyists exist.
I think we're straying from the initial topic. The initial issue is:
Flame needs a more complete minimal physics engine.
and:
There is no physics engine that available for Flame that has enough features to make implementing platformer physics easy.
The answer was:
Flame does have a physics engine, called Forge2d (flame_forge2d), and it covers all the physics behaviors you'd expect from a 2D physics engine.
Clearly, it won't be 100% compatible with what other engines like Lua offer, but in general, it solves all the problems that all physics engines solve.
The question that remains to close the issue would be:
Is there anything that Forge2d doesn't cover (within its scope, of course) or something it's missing as a physics engine?
(From your example, I see that it's needed: collisions, gravity, and motion are all use cases that Forge covers.)
Is there anything that Forge2d doesn't cover (within its scope, of course) or something it's missing as a physics engine?
I think we are thinking about this differently. You are thinking about this solely in technical terms. I'm afraid I distracted from my point with my platformer example.
Imagine your kid tells you they'd like to learn to sail. You give them 2 options: 1) We can build our own sailing dingy and learn on that 2) We can rent a 20ft yacht and learn there. There is no option to just rent a sailing dingy and learn.
The reason this is an imperfect analogy though is because in our case, the middle option is actually versatile and can be used as the basis for creating more complicated systems. That's where the discussion of platformers comes in.