minetest / minetest

Luanti (formerly Minetest) is an open source voxel game-creation platform with easy modding and game creation
https://www.minetest.net/
Other
10.77k stars 2.03k forks source link

Add support for basic physics (gravity and friction) for inanimate objects #9446

Open ryvnf opened 4 years ago

ryvnf commented 4 years ago

Problem

Mods should be able to do physics on non-living entities. Like pushing them in a direction. The most logical way to do this is to set their velocity. But that doesn't behave very well in the current version of Minetest as illustrated in this video. The example shows a dropped item which should be pushed in a direction by a tnt explosion. Because the speed of non-living entities (liked dropped items) remains constant they will slide endlessly which is very unrealistic.

One way for mods to solve this is the set the pushing velocity for a specific amount of time (like 2 seconds). But that looks very weird and unrealistic. What is really needed is a way to specify that an entity should be affected by friction of blocks. This means that when it is on top of a block, it's velocity should be decrease according to the friction of the block below.

Solutions

I found that the game already has some implementation of friction. As the player slides more on ice compared to other land nodes.

My proposed solution is to add one more property to entity definitions registered using the minetest.register_entity function. It can be called frictional and be a boolean value. This only has affect if the entity is also physical. When this is true the entity will be affected by friction, in the same way as the player.

I think this would make it a lot easier to add cool effects to items and benefit modding greatly. It might also improve the base game, as dropped items can behave more realistically when dropped at a velocity. And while issue #8967 is a bug and can probably be fixed otherwise, such weird behavior would probably be avoided by having realistic friction in the game.

Alternatives

The value might not have to be a boolean value. It can also be a scalar value which determines how much it is affected by friction. Like dropped ice being less affected by friction than stones for example. This allows mods more flexibility when defining items.

paramat commented 4 years ago

~Adding some kind of basic friction seems fine, but i am not convinced there should be an added object property, as it seems all objects should be affected, and it seems not being affected by friction should be decided by the node the object is on. Friction is a rather specialist aspect, object properties need a lot of justification.~

sfan5 commented 4 years ago

I don't understand that criticism here. The engine providing basic physics for objects is absolutely not specialist and there is no issue with enabling this only if selected by a property either.

TheTermos commented 4 years ago

I'm fine with implementing friction in lua, but I guess It also wouldn't hurt if it was supported by engine. It just isn't a good idea for it to be a boolean, different objects should have different friction coefficients, a number with default of 0.0 would work better.

One problem is currently the engine doesn't do a great job of detecting if an object is resting on ground, the result can be off by up to 15 world centimeters (the fix is ready and waiting for after 5.2 release, after that the best solution imo would be just exposing touching_ground and standing_on_object to lua)

paramat commented 4 years ago

~MT has been fine until now with no friction, so it is not really fundamental or essential physics, that is what i mean by 'specialist', poor choice of word i admit, sorry for that. Why is an object property essential or useful? No-one in this thread, including the issue author, has explained why, it has just been assumed. The node the object is on seems more important as the decider. Because new object properties need significant justification (they are complex to add and are sent over the network), there needs to be a reason for them. 'There is no issue with enabling this only if selected by a property' is not a justification. I am happy to be convinced, just pointing out the lack of a usecase for an object property.~

LoneWolfHT commented 4 years ago

MT has been fine until now with no friction

I'd actually argue that it hasn't been fine, it's just been possible to work around without too many hacks. My grenades mod could really use this. I'm not too good with physics yet

(I see you've crossed that out, just posting to show support for this issue)

paramat commented 4 years ago

Sorry, i completely misunderstood this, the first post talked about dropped items and i misunderstood this to be a feature for the builtin item entity only. Please ignore my previous comments. So now to address this properly ...

Mods should be able to do physics on [...] entities

They can already.

The most logical way to do this is to set their velocity. But that doesn't behave very well [..] Because the speed of non-living entities (liked dropped items) remains constant they will slide endlessly which is very unrealistic.

The actual problem here is not coding the laws of motion properly, setting velocity is not enough, you need to code gravity and friction too. Entities come completely clean with absolutely no laws of motion.

One way for mods to solve this is the set the pushing velocity for a specific amount of time (like 2 seconds). But that looks very weird and unrealistic.

Yes, because that is poorly coded laws of motion, the problem here lies with the modder, not MT.

What is really needed is a way to specify that an entity should be affected by friction of blocks.

You can do this already in the Lua code controlling the entity.

It might also improve the base game, as dropped items can behave more realistically when dropped at a velocity.

Conventional dropped items are controlled by the 'builtin item entity' code here https://github.com/minetest/minetest/blob/master/builtin/game/item_entity.lua the laws of motion are already coded and friction is already implemented, although it may have some bugs and could perhaps be improved.

///////

So now i am not misunderstanding, i can see that this feature would actually be a very bad decision in practice.

Entities come clean with no hardcoded laws of motion, this is right as they are meant to be completely flexible and should make no assumptions. All the laws of motion, including friction, are coded in Lua. Even gravity is not assumed and hardcoded, and friction is a less fundamental aspect than gravity (but i am not suggesting hardcoding gravity).

Consider that out of all entities in mods, it is likely that the majority are mobs, vehicles, and various other entities that should not be subject to friction or do not need it.

Most importantly, because currently entities come clean with no hardcoded laws of motion, if we add some hardcoded laws of motion like gravity and friction, the laws of motion will then be located in 2 different places which is a very bad idea. Laws of motion are all interedependent so need to be in one place, in the mod.

I have coded several vehicle mods, including one using fairly realistic physics-modelling (i am a qualified physicist). The friction code is an integral part of the coded laws of motion and cannot be separated into a different place.

Summarising:

:-1:

paramat commented 4 years ago

MT has been fine until now with no friction

That was a silly comment of mine, as MT has always had friction, it is coded in the laws of motion of the entity.

it's just been possible to work around without too many hacks. [...] I'm not too good with physics yet

Then, again, the problem actually lies with the modder =) There must be good examples of coded friction somewhere to learn from.

LoneWolfHT commented 4 years ago

Then, again, the problem actually lies with the modder =) There must be good examples of coded friction somewhere to learn from.

Not everyone is good with math/physics, or wants to have to go learn it to make their mod work. Wouldn't friction be faster if handled C++ side anyway?

sfan5 commented 4 years ago

Consider that out of all entities in mods, it is likely that the majority are mobs, vehicles, and various other entities that should not be subject to friction or do not need it.

If you take the example "sliding on ice" from the issue text: Should mobs have this? definitely Vehicles? possibly The builtin item entity? Also yes Other entities? Probably not, in which case it can be disabled

You can do this already in the Lua code controlling the entity.

And what is the justification that each modder should implement this stuff on their own instead of letting the engine (which already has an implementation) handle this?

Any hardcoded friction will inevitably make assumptions and therefore be inflexible and unusable in many cases.

I don't see an issue if it's useful in enough cases and can be disabled in the others.


As I understand it, the point of the physical property is to have an object that interacts with the world just like other physical objects (the player) do. But currently mods have to implement half of it themselves, leading to bugs like #8967. If this could be implemented in the engine instead, it would make entity physics significantly easier for modders and wouldn't be in the way for modders wishing exact control over their entities.

ryvnf commented 4 years ago

I don't think it is reasonable to expect each modder to find a way to do friction by themselves. I don't agree that the reason we don't have proper friction in mods yet is because of lazyness, but rather that a modder wants to focus on their mod idea instead not having the research how to code proper physics.

I also think it is important to get consistency across mods. If each modder is responsible for adding friction by themselves, that would still lead to situations where different mods handle friction differently. Their implementations might also be inconsistent with how friction is calculated for players by the engine:

https://github.com/minetest/minetest/blob/7dffd08c1a068e5e0748a046fd8a1e884947b597/src/client/localplayer.cpp#L1073-L1090

I think the main goal should be to introduce an easy way for modders to specify friction for entities, so everyone isn't responsible to do it themselves. But also to achieve consistency with the rest of the game. If this can be achieved in Lua I think that would be fine, maybe through an API exposed by the builtin Lua code (like fallings nodes and similar things). But if there is no easy way to do that, I think it should be handled by the engine instead. The engine already handles other physics for entities (through the physical property), which is why that was my initial implementation idea.

TheTermos commented 4 years ago

I've just recalled one reason why implementing friction in the engine isn't such a good idea afterall.

Friction property would do OK in case of inanimate objects, but anything that moves by itself mustn't be affected by friction all the time, only when it's inert, so that would require the hassle of turning the property on and off. Worse still are more physically complex entities, like vehicles, which should be affected by friction differently in different directions relative to entity's rotation.

Such an engine property would only come in the way. The best course of action imo would be exposing touching_ground and standing_on_objest to lua after collsion.cpp will have been fixed.

As I understand it, the point of the physical property is to have an object that interacts with the world just like other physical objects (the player) do.

The code says the sole purpose of the physical property is to enable collision detection, no more, no less. Players work very differently than entities as far as friction is concerned, their movement is determined by keypresses and they are not affected by friction whatsoever, entities just can't behave like that.

LoneWolfHT commented 4 years ago

obj:set_friction(3D vector, respects_rotation) obj:get_friction()

EDIT: Come to think of it a 6D vector might be better

LoneWolfHT commented 4 years ago

Anything that moves by itself mustn't be affected by friction all the time, only when it's inert, so that would require the hassle of turning the property on and off.

There'd be a hassle implementing it yourself too

The best course of action imo would be exposing touching_ground and standing_on_objest to lua after collsion.cpp will have been fixed.

Having that would be nice, not for this case but in general

and they are not affected by friction whatsoever

Ice

benrob0329 commented 4 years ago

There is no problem here, it is modder laziness or poor coding.

Not everyone has a degree in physics, in fact I'd say that most of MTs community lacks a degree in physics, perhaps even a degree in general considering a good portion of modders and players and underage, not to mention those who use MT for education.

Don't need physics? Just turn it off and do stuff yourself like the current behavior. Want to make a mob walk and have friction? You'd probably need a way to specify (or just have it be the behavior) that entities acceleration comes from the bottom plane, that way friction helps when standing on something but hurts when rubbing against a wall.

TheTermos commented 4 years ago

Ice

Not quite. Player just stops instantly when a key is released, it actually requires special effort to keep them in motion when on ice, that's kind of a hack for gameplay reasons, there are no physical reasons they should be able to stop instantly in midair, but not on ice.

Entities work exactly the opposite, they will keep going unless there's something to stop them, and that's exactly what friction is about.

paramat commented 4 years ago

If (hypothetically) we add support for basic inanimate object physics, only attending to friction is not enough, gravity is more fundamental, the bare minimum is gravity and friction. Friction implies an object thrown onto the ground, a thrown object should follow a ballistic arc when thrown. Friction alone is useless.

Covering gravity and friction means that all the basic physics of an inanimate object can be handled by this new feature, which then avoids the problem of splitting the physics code into 2 places. Basic inanimate objects can then use this feature only, and objects with more complex motion can disable this feature and use Lua code only.

I am not supporting doing this in C++ using object properties, as requested, just stating that if it is done, this is how to do it properly. The issue title should probably be changed to something like "Add support for basic physics (gravity and friction) for inanimate objects"

The underlying issue here seems to me to be: How do we help modders code basic physics? I have no problem with helping modders somehow. The builtin item entity code is (or could be) a good example, but is far more complex than it needs to be for a basic inanimate object.

So i think it is best that mods help by providing good examples. Or, a 'inanimate object physics API' mod could be written where objects can be registered. Such an API might even eventually be added to builtin. In both cases, the physics code remains in Lua where i think it should be, and, this is not (initially) the responsibility of MTEngine.

raymoo commented 4 years ago

One problem with just having mods set the acceleration every frame is that you don't get any prediction for things like linear damping where the force is not relatively constant. You also get larger approximation errors (like a damping force reversing the movement of an object like in #9520 ) when the server step is increased or the server is lagging, which could be avoided with more well-behaved approximations (for damping you could apply a multiplier to the velocity, using exponentiation to adjust it to the time step).

A fully generalist solution allowing any kind of physics model would be to allow CSMs that provide movement prediction on the client (as in #8708) but that may be a lot of work and I don't think server-sent CSMs are a thing yet.

sorcerykid commented 4 years ago

I'm happy to report that with recent fixes to collision detection, my Interactive Physics mod is finally out of alpha and working as originally intended. I've already completed the integration with my Athletics, Thievery, and Mobs Lite mods, so I feel that the API covers most use-cases involving LuaEntitySAOs. Here I'm testing a "new and improved" soccer ball using the latest beta version.

https://vimeo.com/420764088

All of the basic physical properties are supported for both liquids and solids as well as air:

With the aid of the physics wand, it's also possible to override these physical properties in game, hence the name "Interactive" Physics. So cobble can be transformed to ice, or water into thick molasses :)

Admittedly, client-side prediction would be a nice bonus to have at some point. But after several days of benchmarking on my production server, I've found the mod performs very reasonably as is.

Wuzzy2 commented 2 years ago

A really huge problem with entity physics in my view is the fact that player physics are treated already by the engine, mostly, while for all other entities modders start at near-zero. Therefore, many physics features that player have have to be re-invented by modders for non-player entities somehow. This is really awkward and no matter how well you code your mod, you will probably always have awkward inconsistencies between players and other entities.

I don't understand why players and other entities don't truly share the same physics system. That is, at least the basic theoretical functionality.

To get a player-like entity, you have to awkwardly approximate player physics by hand. This is, frankly, just not a good design. Players have gravity, players slide on ice, players slow down in liquidlike nodes, players can swim in liquids, players don't fall at ladders, etc. etc. etc.

The most basic thing, gravity, is probably the easiest thing to replicate. But when you remember that liquid move physics exist, and you don't want your entities to fall down like a brick in water, that's when it already gets tricky. You have to re-invent the entire liquid physics from scratch at that point. And it'll never be perfect anyway.

It is such an awkward design that players and entities are so different physics-wise and that most of player physics are not available to entities. This even shows in builtin: Dropped items have to re-implement sliding on slippery nodes from scratch and don't share any code with player physics.

The reason why I think this is such a big deal is because of the way things are now, it essentially just generates a lot of redundancy and inconsistencies. Ideally, entities and players would share the physics-related code.

"Code your own entity physics" might be fine as long your entities are not supposed to be player-like but distinct from them. But if they are, it will get messy.