Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add possibility to easier override HP and breath engine logic by Lua. #14179

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

sfence
Copy link
Contributor

@sfence sfence commented Dec 28, 2023

To do

This PR is a Ready for Review

  • Get feedback
  • Apply feedback
  • Add documentation

How to test

Run devtest game and change the engine_mask value via the included item for properties change.

@lhofhansl
Copy link
Contributor

Wasn't there some discussion to move the entire logic to Lua?

@sfence
Copy link
Contributor Author

sfence commented Dec 28, 2023

Wasn't there some discussion to move the entire logic to Lua?

Yes, in #14125.
But this solution should target to allow full backward compatibility and moving logic to Lua as well.
I also think that the C++ solution has better performance than the Lua alternative. So, why not keep it where it is possible?

@Zughy
Copy link
Member

Zughy commented Dec 28, 2023

So, why not keep it where it is possible?

Because, contrary to HPs, it's not something the majority of games need. It should be eradicated from the engine imho, it's only a burden for core devs

@sfence
Copy link
Contributor Author

sfence commented Dec 28, 2023

Because, contrary to HPs, it's not something the majority of games need. It should be eradicated from the engine imho, it's only a burden for core devs

I understand.

But, before some time I created some mod that was doing something like breath in Lua. The problem with it was, that it did not work smoothly because of the non-constant time difference between steps.

So, I think that the use of C++ HP and breath engine whatever is possible will look better from the player's side as a result.

Copy link
Contributor

@appgurueu appgurueu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this PR is overkill for de-hardcoding breath; all you need for that would be a simple (player-only) flag that tells the engine to stop managing breath so that the modder can take over. (In fact, this PR goes a bit in the opposite direction of #14125 even IMO: It adds breath to entities, and complicates it by adding more features such as controllable intervals.)

I would suggest splitting this up into a PR which lets you disable engine breath handling for players, which will basically fix #8042 and half of #14125 and should be rather uncontroversial, and another PR for all the features, esp. adding node damage to entities etc. (which I'm frankly not sure belongs into the engine).

So, I think that the use of C++ HP and breath engine whatever is possible will look better from the player's side as a result.

I'm not so sure about this. If I see this correctly, this PR is entirely serverside and uses no server features not available to Lua, so why would it have clientside prediction advantages over a Lua-only solution, which would be entirely serverside as well?
(By the way, I think breath was moved to the server to combat cheating a rather long while ago?)

src/object_properties.cpp Outdated Show resolved Hide resolved
src/object_properties.h Outdated Show resolved Hide resolved
src/script/cpp_api/s_player.cpp Outdated Show resolved Hide resolved
src/server/player_sao.cpp Outdated Show resolved Hide resolved
@sfence
Copy link
Contributor Author

sfence commented Dec 29, 2023

So, it looks like the idea of using a mask to add the ability to partially disable SAO damage/breath logic in combination with Lua callback does not sound interesting for Minetest developers.

So, this idea is probably a step aside.

So, the best way is probably to abandon this idea of a solution. Am I right?

@lhofhansl
Copy link
Contributor

lhofhansl commented Dec 29, 2023

So, the best way is probably to abandon this idea of a solution. Am I right?

Not the idea I like that.
Maybe a bit simpler... I really like @appgurueu suggestion above. Add a flag to disable engine's breath management, and separate for the Lua API.
I think for now we can leave the C++ logic in place, and perhaps remove it later.

Please do not be discouraged, we like contributions that make modding easier/possible.

@Zughy Zughy added Action / change needed Code still needs changes (PR) / more information requested (Issues) Feature ✨ PRs that add or enhance a feature Concept approved Approved by a core dev: PRs welcomed! labels Jan 22, 2024
Copy link
Member

@grorp grorp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR still contains the change to add node damage to entities. That doesn't belong in this PR and breaks backwards compatibility if enabled by default. Please remove it.

src/script/cpp_api/s_player.cpp Outdated Show resolved Hide resolved
@sfence
Copy link
Contributor Author

sfence commented Feb 5, 2024

This PR still contains the change to add node damage to entities. That doesn't belong in this PR and breaks backwards compatibility if enabled by default. Please remove it.

It is related to bug #9372. But yes, it breaks back compatibility. Will it be satisfying to disable it by default?
So backward compatibility will not be broken and #9372 will be also fixed with this PR.

@grorp grorp self-requested a review February 14, 2024 15:19
@Zughy Zughy removed the Action / change needed Code still needs changes (PR) / more information requested (Issues) label Feb 14, 2024
@grorp
Copy link
Member

grorp commented Mar 31, 2024

Well, actually I'd be fine with adding node damage to entities as long as it's disabled by default. It would save modders from having to write their own node damage reimplementations in case they just want entities to behave the same as players. However, this seems to be a controversial idea considering the comments in #9372. Maybe it would be better to keep this PR simple and uncontroversial by just including the "allow disabling hardcoded engine features" change.

doc/lua_api.md Outdated Show resolved Hide resolved
@grorp grorp self-assigned this Mar 31, 2024
@grorp grorp added the Action / change needed Code still needs changes (PR) / more information requested (Issues) label Mar 31, 2024
@Zughy
Copy link
Member

Zughy commented Apr 28, 2024

@sfence reminder

@Zughy Zughy removed the Action / change needed Code still needs changes (PR) / more information requested (Issues) label May 6, 2024
@grorp grorp self-requested a review May 6, 2024 17:53
Copy link
Member

@grorp grorp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new table-based form for engine_mask isn't documented. Also, is there a reason for exposing the underlying bitmask to the Lua API by allowing to specify engine_mask as a number?

I again suggest the https://dev.minetest.net/Code_style_guidelines, for example this:

When breaking conditionals, indent following lines of the conditional with two tabs and the statement body with one tab.

src/script/common/c_content.cpp Outdated Show resolved Hide resolved
src/script/common/c_content.cpp Outdated Show resolved Hide resolved
src/script/common/c_content.cpp Outdated Show resolved Hide resolved
src/script/common/c_content.cpp Outdated Show resolved Hide resolved
src/object_properties.h Outdated Show resolved Hide resolved
@grorp grorp added the Action / change needed Code still needs changes (PR) / more information requested (Issues) label May 7, 2024
@Zughy Zughy removed the Action / change needed Code still needs changes (PR) / more information requested (Issues) label May 7, 2024
Copy link
Member

@grorp grorp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about the naming, but I currently have no better naming proposal.

Tested. The default value behavior didn't match my expectations. When not specifying engine_mask, all flags default to true. When specifying engine_mask as {breathing = false}, the other flags default to false, not to true as I would expect. Defaulting to true in this case would also result in better forward-compatibility if more flags are added in the future.

src/script/common/c_content.cpp Outdated Show resolved Hide resolved
doc/lua_api.md Outdated Show resolved Hide resolved
src/script/common/c_content.cpp Outdated Show resolved Hide resolved
@grorp grorp added the Action / change needed Code still needs changes (PR) / more information requested (Issues) label May 8, 2024
@grorp
Copy link
Member

grorp commented May 8, 2024

Tested. The default value behavior didn't match my expectations. When not specifying engine_mask, all flags default to true. When specifying engine_mask as {breathing = false}, the other flags default to false, not to true as I would expect. Defaulting to true in this case would also result in better forward-compatibility if more flags are added in the future.

Since you replied to everything else, I'm repeating this in case you missed it.

@sfence
Copy link
Contributor Author

sfence commented May 9, 2024

Tested. The default value behavior didn't match my expectations. When not specifying engine_mask, all flags default to true. When specifying engine_mask as {breathing = false}, the other flags default to false, not to true as I would expect. Defaulting to true in this case would also result in better forward-compatibility if more flags are added in the future.

In Lua nil and false are commonly expected to have similar/same effect. So it can be confusing to replace nil with true.
Maybe I can change the logic of the engine_mask table not to enable part of engine logic, but to disable part of engine logic.

engine_logic = {
  no_breathing = true,
   ...
}

Does it sound better?

@sfence
Copy link
Contributor Author

sfence commented May 9, 2024

Ok, nil is used with no change meaning in other parts of the Lua API tool. So it should be understandable. The previous version of read_engine_mask was also potentially buggy, so it should be better now.

Copy link
Member

@grorp grorp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works as expected now.

I think defaulting to the old values makes sense because that's how top-level object properties work too.

@grorp grorp added One approval ✅ ◻️ and removed Action / change needed Code still needs changes (PR) / more information requested (Issues) labels May 9, 2024
@SmallJoker
Copy link
Member

I like this PR and was about to submit my review when I got an idea. Wouldn't it be more helpful to control these damage ticks with floats for each? That would allow arbitrary delays, or also disabling it with values < 0.

@sfence
Copy link
Contributor Author

sfence commented May 29, 2024

I like this PR and was about to submit my review when I got an idea. Wouldn't it be more helpful to control these damage ticks with floats for each? That would allow arbitrary delays, or also disabling it with values < 0.

This possibility was included but rejected. So I removed it.

After this PR, I want to create PR for the player on_step callback. It will add the possibility to implement custom delays, breath/damage, and similar logic in the player on_step Lua callback.

Copy link
Contributor

@appgurueu appgurueu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested, works:

  • enabling/disabling drowning works
  • enabling/disabling breathing works
  • enabling/disabling node damage works

I believe it would be cleaner for this to be a player-SAO field rather than an object property. I've sent you a pull request to refactor this appropriately (sfence#3). I'd also like to hear what @grorp thinks.

Besides this, I only have minor comments.

(There's an edge case I consider slightly odd, but which I don't think needs to be addressed (in particular because modders can just turn off the system entirely if they are unhappy with it): When you disable breathing and enable drowning, you only lose health while you are actively drowning. When you "stop drowning" - but stay at zero air - you do not lose health. Intuitively, this doesn't really make sense to me: When you have no air, shouldn't you continue to lose health?)

doc/lua_api.md Outdated Show resolved Hide resolved
doc/lua_api.md Outdated Show resolved Hide resolved
doc/lua_api.md Outdated Show resolved Hide resolved
src/object_properties.cpp Outdated Show resolved Hide resolved
src/object_properties.h Outdated Show resolved Hide resolved
src/script/common/c_content.cpp Outdated Show resolved Hide resolved
src/script/common/c_content.cpp Outdated Show resolved Hide resolved
src/script/common/c_content.cpp Outdated Show resolved Hide resolved
@@ -156,7 +158,10 @@ void PlayerSAO::getStaticData(std::string * result) const

void PlayerSAO::step(float dtime, bool send_recommended)
{
if (!isImmortal() && m_drowning_interval.step(dtime, 2.0f)) {
bool not_immortal = !isImmortal();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about mortal? :)

@sfence
Copy link
Contributor Author

sfence commented Jun 10, 2024

@appgurueu

I believe it would be cleaner for this to be a player-SAO field rather than an object property. I've sent you a pull request to refactor this appropriately (sfence#3). I'd also like to hear what @grorp thinks.

I am planning to use the same field for fix #9372. In that case, is it better to have two separate SAO fields in player-SAO and entity-SAO?

@appgurueu
Copy link
Contributor

I am planning to use the same field for fix #9372. In that case, is it better to have two separate SAO fields in player-SAO and entity-SAO?

Commented. I do not support #9372. I'd like to wait for other opinions on it so we can make a decision.

Breathing & drowning is exclusive (and I would say should be exclusive to) players; if modders want similar mechanics for their entities, they can and should implement them themselves. The breathing & drowning flags at least should be player-only. Entities having but not using them is hacky.

Even if it was decided that we support #9372, this would, unless client-side prediction is added (which it probably won't and shouldn't be), still make more sense as a SAO-only property. It does not belong in object properties. It's better not to bloat object properties unnecessarily.

Refactor (from object property to PlayerSAO flags)
@sfence
Copy link
Contributor Author

sfence commented Jun 19, 2024

@grorp I take @appgurueu ideas into this PR. So please recheck your approval.

@appgurueu appgurueu added this to the 5.10.0 milestone Jun 19, 2024
@appgurueu
Copy link
Contributor

I'm happy with this now; it has my approval. grorp can mark this as "two approvals" if he's happy too. Since we're in feature freeze, I've put this on the 5.10 milestone.

@grorp
Copy link
Member

grorp commented Jun 23, 2024

Looks alright.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Concept approved Approved by a core dev: PRs welcomed! Feature ✨ PRs that add or enhance a feature @ Script API >= Two approvals ✅ ✅
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants