[Mod] Player Effects [1.2.0] [playereffects]

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

[Mod] Player Effects [1.2.0] [playereffects]

by Wuzzy » Sun Jul 06, 2014 22:55

Player Effects is a modding framework for assigning temporary status effects to players.

Version: 1.2.0 (This is a SemVer.)
For: Minetest 0.4.10 or later
License of everything: MIT License
Download: download/file.php?mode=view&id=7980
Project page with README file: http://repo.or.cz/w/minetest_playereffects.git

List of known mods which use Player Effects:

This is a framework for other mods to depend on. It provides means to define, apply and remove temporary status effects to players in a (hopefully) unobstrusive way.
A status effect is an effect for a player which changes some property of the player. This property can be practically everything. Currently, the framework supports one kind of effect, which I call “exclusive effects”. For each property (speed, gravity, whatver), there can be only one effect in place at the same time.
  • high walking speed (speed property)
  • high jump height (jump property)
  • low player gravity (gravity property)
  • high player gravity (gravity property)
  • having the X privilege granted (binary “do I have the property?” property) (yes, this is weird, but it works!)

The framework aims to provide means to define effect types and to apply and cancel effects to players. The framework aims to be a stable foundation stone. This means it needs a lot of testing.

This is what the mod had achieved for now:
  • Showing all active effects in the HUD (with timer)
  • Letting you define your own status effect types
  • Letting you define effect groups to automatically eliminate effect conflicts (fast vs slow, low vs high gravity, etc.)
  • Letting you apply effects to player
  • Letting you remove effects to player
  • Doing a lot of important “plumbing” and “behind-the-stages” work:
    • Remembering effects when a player leaves and freeze the timer
    • Restoring them when the player is back
    • Remembering all effects when the server shuts down
    • Restoring them as frozen effects when the server is back
    • Cancelling all active player’s effects when he/she/it dies

The HUD shows a list of active effects and looks like this:
Image

Many things have been achiveved, but I do not guarantee a stable API yet. Until version 1.0, I intend this thread to be a discussion thread for comments, ideas, test reports, and whatever.


List of important goals for later versions:
  • Additive effects: A whole new class of effects which is different from the exclusive effects. They too use effect groups, but they do not cancel each other out. Instead, they add to each other. Let’s say you take 2 potion of speed, maybe both are not of the same strength. Under exclusive effects, the old effect is simply gone. But under additive effects, the speed of both potions would add up. It is also planned to add optional limits, so a player could not jack up a property towards absurdly high values.

The mod comes with several example effect types for testing; they are enabled by default and I hope they should be helpful for modders as well. As soon as I think this mod is stable, I disable the examples by default, simply to avoid cluttering the modspace. ;-)
The examples are simply chatcommands available to everyone (effect groups are in brackets)
* /fast: You become faster (speed)
* /slow: You become slower (speed)
* /highjump: You can jump a bit higher (jump)
* /fly: You get the fly privilege temporarily (fly)

Try /fast and /slow quickly after each other. There should be no overlap at all. Using status effects to handle privileges sounds weird and it IS weird. But it is also funny somehow. If you really want to manipulate privileges with this mods, just make sure nobody messes around with the affected privileges manually.

The relevant stuff for modders:

To use this framework, do this:
  • create a mod
  • make it depend on playereffects
  • register effect types
  • decide when to apply said effect types and apply them

The important functions:
Register a new effect type:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
playereffects.register_effect_type(internal_name, description, groups, apply, cancel)

Where:
internal_name is the name which is internally used by the mod. Please use only alphanumeric ASCII characters.
description is the text which is exposed to the GUI and visible to the player.
groups is a table of strings to which the effect type is assigned to. I explain the concept of effect groups later.
apply is a function which takes a player object. It is the player object to which the effect is applied to. This function isused by the framework to start the effect; it should only contain the gameplay-relevant stuff, the framework does the rest for you.
cancel is a function which takes an effect table. It is the effect which is to be cancelled. This function is called by the framework when the effect expires or is explicitly cancelled by other means.

Apply an existing effect type to a player:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
playereffects.apply_effect_type(internal_name, duration, player)

This applies the effect type with the internal name internal_name for duration seconds to player.
Attachments
playereffects1.2.0.zip
(13.1 KiB) Downloaded 244 times
Last edited by Wuzzy on Thu Jan 05, 2017 16:34, edited 19 times in total.
 

prestidigitator
Member
 
Posts: 632
Joined: Thu Feb 21, 2013 23:54

Re: [Mod] Player effects [0.1] [playereffects]

by prestidigitator » Mon Jul 07, 2014 03:07

Interesting. It would conceivably be possible to layer multiple effects that each affect the same property, by using a Decorator pattern. Something like:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
--- Parent class for effects that can decorate each other.
 --
 -- Fields:
 --    parent
 --       - Parent effect, for removal.
 --    child
 --       - Child effect from which to derive this one.
 --    done
 --       True if effect has been removed.
 --    cleanup(self, root)
 --       Callback method to call (once) when effect is removed.  Passed the
 --       "parent-most" effect left in the list after removing self (possibly
 --       nil).
 --
Effect =
{
   new = function(class, child)
      local self = setmetatable({ child = child }, { __index = class });
      if child then child.parent = self; end
      return self;
   end,

   --- Calculates this effect's value.
   getValue = function(self)
      return nil;
   end,

   --- Removes this effect from the list, calling self:cleanup(root) and also
    -- returning root, where root is the "parent-most" effect left after the
    -- removal (possibly nil).
   remove = function(self)
      if self.done then return nil; end

      local p, c = self.parent, self.child;
      if c then c.parent = p; end
      if p then
         p.child = c;
         while p.parent do
            p = p.parent;
         end
      end

      local root = p or c;

      if self.cleanup then
         self:cleanup(root);
         self.cleanup = nil;
      end

      return root;
   end
};
setmetatable(Effect, { __call = Effect.new });

--- Always returns a constant value.
 --
 -- Example:
 --
 --    local eff = ConstEffect(3.14);
 --    eff:getValue() -- 3.14
 --
ConstEffect =
{
   new = function(class, constValue, child)
      local self = Effect.new(class, child);
      self.constValue = constValue;
      return self;
   end,

   getValue = function(self)
      return self.constValue;
   end
};
setmetatable(ConstEffect, { __index = Effect, __call = ConstEffect.new });

--- Multiplies the value of its child by a factor.
 --
 -- Example:
 --
 --    local eff = MultiplierEffect(3, ConstEffect(7));
 --    eff:getValue() -- 3 * 7
 --
MultiplierEffect =
{
   new = function(class, factor, child)
      local self = Effect.new(class, child);
      self.factor = factor;
      return self;
   end,

   getValue = function(self)
      if self.child then
         return self.factor * self.child:getValue();
      else
         return nil;
      end
   end
};
setmetatable(MultiplierEffect,
             { __index = Effect, __call = MultiplierEffect.new  });

--- Adds a constant to the value of its child.
 --
 -- Example:
 --
 --    local eff = AdderEffect(3, ConstEffect(7));
 --    eff:getValue() -- 3 + 7
 --
AdderEffect =
{
   new = function(class, addend, child)
      local self = Effect.new(class, child);
      self.addend = addend;
      return self;
   end,

   getValue = function(self)
      if self.child then
         return self.addend + self.child:getValue();
      else
         return nil;
      end
   end
};
setmetatable(AdderEffect, { __index = Effect, __call = AdderEffect.new  });


Here is an example of use of these classes:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local originalValue = ConstEffect(3.14);
print(originalValue:getValue()); -- 3.14
local me = MultiplierEffect(2, originalValue); -- me -> originalValue
print(me:getValue()); -- 6.28 = 2 * 3.14
local ae = AdderEffect(4, me); -- ae -> me -> originalValue
print(ae:getValue()); -- 10.28 = 4 + 2 * 3.14
me:remove(); -- ae -> originalValue
print(ae:getValue()); -- 7.14 = 4 + 3.14


And here is an example of how you could use it in a mod for, say, gravity:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local gravityEffects = {};

local function setGravity(player, g)
   player:set_physics_override({ gravity = g });
end

function addGravityEffect(player, effect, duration)
   local oldCallback = effect.cleanup;
   effect.cleanup =
      function(self, root)
         gravityEffects[player] = root;
         setGravity(player, (root and root:getValue()) or 1.0);

         if oldCallback then oldCallback(self, root); end
      end;

   effect.child = gravityEffects[player] or ConstEffect(1.0);
   gravityEffects[player] = effect;
   setGravity(player, effect:getValue());

   minetest.after(duration, effect.remove, effect);
end

minetest.register_on_leaveplayer(
   function(player)
      local effect = gravityEffects[player];
      while effect do
         effect = effect:remove();
      end
   end);


You could also call remove() on an effect before its time runs out (or after; it wouldn't hurt anything), and re-use the Effect classes for other types of effect (speed, jump, etc.).

(All code in this post is WTFPL.)
 

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

Re: [Mod] Player effects [0.1] [playereffects]

by Wuzzy » Mon Jul 07, 2014 06:23

Whoa! You put a lot of thought work into it. Thanks for taking your time here. I appreciate that. This looks like you have written almost a completely new mod just to make a point.

But I’m afraid I won’t use much or even anything at all of that. This is way too complicated for a relatively simple task.
I don’t like that a part of the complexity seems to leak out to the API, which is not what I want. I want the framework to do the plumbing. I don’t want to bother the modder with “cleanup” functions and children and parents and stuff like that. I am not even sure if I understood the term “‘parent-most’” correctly.

I think this could be done much much simpler. For “layering”, I might as well add all effect values together (with a start value maybe) each time an effect is applied or cancelled to get the value I have to set. ;-)
Same is true is I work with multipliers. Then I just multiply all values (again with a start value for when no effect is in place).
As long as I stick to one operation (addition, multiplication) per effect type, I see no reason to ditch the simpler approach. It seems weird to me to use so much fancyness just to do basic arithmetics. xD

What seems to be uniquely possible with that decorator pattern are multiple effect types where some effects add and some other effects multiply. But I just can’t think of any real use case for that.
I can see an use case for using only addition: Increasing something lineary, for examle the damage dealt (+2 damage points here, +4 damage points there, and so on. Or something like that).
And I can see an use case for using only multiplication: set_physics_override. Other operations wouln’t make sense here. (if you get 2 times double speed, the overall effect would be 2*2 = 4, a quadruple speed.)
But using addition and multiplication (and maybe even more operators?) for the same property? I have no idea for what that would be good for.
It’d probably even confusing for players and I also wonder how to expose this effect mess to the HUD without loss of information. Because it makes a difference if you get an “add 10” effect first, and an “multiply by 2” effect secondly or if you get these effects vice-versa. This is too much weirdness for me already and I fear when using effects with mixed operations, the results can be pretty unpredictable. So it would be hard to balance well. This feature would then end up in being not used.

So yeah, I think I rather do it my way. :P

Oh, the framework is already able to cancel effects, even before the timer runs out. :-)
 

prestidigitator
Member
 
Posts: 632
Joined: Thu Feb 21, 2013 23:54

Re: [Mod] Player effects [0.1] [playereffects]

by prestidigitator » Mon Jul 07, 2014 08:50

No worries. Writing class libraries is fun. The point was actually to make the external API really simple. Maybe I should've started with an example of how it could be used. Like:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
-- Multiply the player's gravity by 0.5 for 10 seconds (even if there are other gravity effects already)
local myEffect = MultiplierEffect(0.5);
addGravityEffect(player, myEffect, 10);

-- Now either forget about it and let it expire after 10 seconds...
-- ...or if you want to allow the effect to be cancelled by something...
myEffect:remove();


That's it. :-) But, anyway, I won't be offended if you don't use it or anything. It was just an idea for getting around that issue of allowing only one effect. Something to keep the fires burning.
 

prestidigitator
Member
 
Posts: 632
Joined: Thu Feb 21, 2013 23:54

Re: [Mod] Player effects [0.1] [playereffects]

by prestidigitator » Mon Jul 07, 2014 09:04

Wuzzy wrote:What seems to be uniquely possible with that decorator pattern are multiple effect types where some effects add and some other effects multiply. But I just can’t think of any real use case for that.
I can see an use case for using only addition: Increasing something lineary, for examle the damage dealt (+2 damage points here, +4 damage points there, and so on. Or something like that).
And I can see an use case for using only multiplication: set_physics_override. Other operations wouln’t make sense here. (if you get 2 times double speed, the overall effect would be 2*2 = 4, a quadruple speed.)
But using addition and multiplication (and maybe even more operators?) for the same property? I have no idea for what that would be good for.

You pretty much got it. The idea was that it allows things to be stacked and then parts removed again while keeping the rest intact. Classes could be generic enough to be reused between different properties (even though you may not necessarily want to use all possible combinations). But it certainly might be overkill! Your idea got me thinking of fantasy roleplaying systems and stuff, where one kind of item might say it, "adds ... to running speed," and some spell might say it, "doubles all movement." Such things DO often get a little ridiculous in terms of how every different case affects another. Maybe it's a bad idea to open that kind of door. LOL.
 

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

Version 0.2 released!

by Wuzzy » Sun Jul 13, 2014 23:22

Version 0.2 released!

The following changes have been made:
  • You can add little icons (please only 16px×16px) for every effect type.
  • Effect types can now be hidden. Hidden effects will not be exposed to the player HUD.
  • New settings file: settings.lua. Be careful not to mess this file up for now but it should be safe if you follow the instructions and don’t delete the lines.
  • HUD list of effects can be completely disabled for all players via the settings.
  • The HUD list is now aligned to the right.
  • Autosave feature: The mod automatically saves the effect states in <WORLD PATH>/playereffects.mt every 10 seconds. Real usage has yet to show wheather this is a reasonable interval.
  • Autosave can be disabled and the autosave interval can be changed
  • New examples: /hfast (travel faster for 10s, hidden effect), /stresstest (see below)
  • The “fly” and “highjump” examples now have simple icons
  • After some stresstests (/stresstest <number of effects>), I found out that this mod seems to be safe to use with 100000 dummy effects in place without any notable performance drop. I had to tweak a bit to reach this performance. I don’t think real use will ever reach such extreme numbers, but seeing that playereffects copes well with that number is an important milestone.
  • For performance and network traffic reasons, the maximum number of effects shown in the HUD is now 20. Further effects are hidden.


You may have noticed that I forked the Magic Beans mod. Here’s the fork: magicbeans_w
It uses the Player Effects mod and I think this is an excellent demonstration of using this mod in a production environment. Magicbeans_w 1.2 is only compatible with Player Effects 0.1, I will soon update magicbeans_w to work with the Player Effects 0.2. (Edit: done!)

Here’s a screenshot of how the HUD could look now:
Image

The download link for Player Effects 0.2 lies in the attachment of the first post.

Edit: Interested developers who want to know how the Magic Beans mod was converted to use Player Effects can view this relevant commit diff. For the later addition of icons, see here.
 

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

Version 0.3.0 released!

by Wuzzy » Mon Jul 14, 2014 23:22

I have changed the version numbering scheme. From now on, Semantic Versioning (http://semver.org/) is used.

Version 0.3.0 is released!
This time I have made the documentation, an API cleanup and added some features.

List of changes:
  • Documentation. Yeah, finally! README.md is the file which contains a hopefully complete API and data type specification along with many explanations on how to use this mod as player, server operator and modder. If you have any problems with this file, please tell me.
  • Effect metadata. This is a measure to store additional, user-defined data when applying an effect. This effect metadata can be reused in the cancel callback again. For example, this can be used to store a HUD ID which you need again if you want to remove the HUD element again.
  • cancel_on_death = false: You now can define effect types which are not cancelled when the player dies.
  • Effects which are kept on death are shown in a light purple font in the HUD.
  • apply_effect_type now checks if the player argument is valid.
  • apply_effect_type returns the effect ID of the created effect on success. Use case: You can use this later if you want to cancel the effect manually with cancel_effect.
  • Experimental feature: The apply callback of an effect type can now “fail”. This can be used if for some reason you cannot apply the effect in this situation. This feature is experimental, buggy and may be removed again.
  • New example chat commands:
    • cancelall: Cancels all your active effects
    • blind: Makes the screen black for 5 seconds. Very experimental and messes around with the HUD, but demonstrates the usage of effect metadata.
    • null: A simply dummy effect which always fails when you try to apply it. This is there to demonstrate “failing” effects.
    • The “fly” example effect now is kept when you die.
    • The “effect apply” examples now write in your console the effect ID on success or that the effect failed.

Player Effects comes closer to version 1.0.0. The TODO list for it becomes smaller and smaller:

  • Ensuring the API functions actually help the modder and don’t get in the way
  • A lot of testing!
  • Disable examples by default

This version is still compatible to magicbeans_w 1.3.

The actual programming for this milestone is done. What is needed now are reviews and testing. I want to be sure that everything is stable before I declare version 1.0.0. I also want to stabilize the API to prevent breaking it all the time.
 

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

1.0.0 released

by Wuzzy » Fri Jul 18, 2014 05:54

I think all the goals of 1.0.0 are achieved now and I don’t see what I could add more for this branch.
So I release 1.0.0. See opening post for the download link.

Changes:
  • New API function to receive the remaining time of an effect: playereffects.get_remaining_effect_time
  • Performance optimizations, especially concerning the HUD
  • “cancel” callback now takes a player argument as well (for convenience)
  • disable examples by default. Use settings.lua to enable them
Read README.md to know how this all works.

Version 1.0.0 is fully backwards-compatible to 0.3.0.

My earlier stresstests were bogus; accidently I did not actually had 100000 effects, just 1000.
So I retried the stresstests. On my slow laptop, I can have a server with 10000 simutanous effects without problems; it starts to get laggy at 35000 effects. On 100000 effects, the server almost stops responding. However, I think already 10000 is a number which is large enough for real-life usage. I highly doubt that a single player ever needs more than 20 effects at once, but Player Effects could cope with that.
The performance optimizations were really needed, I think. The apply effect function was of complexity O(n), where n is the number of active effects. I managed to reduce it to O(1).

I also want you to inform you of a known bug in playereffects:
In singleplayer mode, the effect timers completely ignore any pause. So if you have effect X and there are 30 seconds left and you pause the game for 5 seconds, you have 25 seconds left when you unpause the game and not, what would be better, 30 seconds.
Sadly, this bug is currently unfixable with the current Lua API, so I released version 1.0.0 anyways.

The initial post for Player Effects is currently not accurate anymore. I hope I can update it later. The “official” documentation is in README.md now, take the initial post just as an overview.


From version 1.0.0 on, I plan to add two more major features which I already explained in the initial post: Additive effects and repeater functions. I can’t guarantee yet that this would be a backwards-compatible change. My guess would be that it would likely not backwards-compatible, sorry.
After that, I don’t plan any further features yet.
 

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

1.1.0 released

by Wuzzy » Sat Jul 19, 2014 13:38

Okay, here is version 1.1.0 (Zip archive in first post).

The new release has one new feature: Repeating effects! A repeating effect is an effect which is applied n times with a interval of t. A possible use case of this would be to create a “healing” effect which heals you 1 HP per second.
As always, this is documented in README.md and an example is included.

I also finally uploaded the Git repository. Here’s the project page: http://repo.or.cz/w/minetest_playereffects.git
 

User avatar
balthazariv
Member
 
Posts: 214
Joined: Mon Apr 07, 2014 15:48

Re: [Mod] Player Effects [1.1.0] [playereffects]

by balthazariv » Sun Oct 12, 2014 18:37

Hello,

I don't know what that backup "Autosaving mod data to playereffects.mt"

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
20:10:42: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:10:42: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.
20:10:47: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:10:47: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.
20:10:57: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:10:57: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.
20:11:07: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:11:07: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.
20:11:17: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:11:17: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.
20:11:27: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:11:27: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.
20:11:37: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:11:37: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.
20:11:47: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:11:47: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.
20:11:57: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:11:57: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.
20:12:07: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:12:07: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.
20:12:17: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:12:17: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.
20:12:27: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:12:27: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.
20:12:37: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:12:37: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.
20:12:47: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:12:47: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.
20:12:57: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:12:57: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.
20:13:07: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:13:07: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.
20:13:17: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:13:17: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.
20:13:27: ACTION[ServerThread]: [playereffects] Autosaving mod data to playereffects.mt ...
20:13:27: ACTION[ServerThread]: [playereffects] Wrote playereffects data into L:\Minetest\minetest-0.4.10\bin\..\worlds\TEST2/playereffects.mt.


In the file playereffects.mt i have just

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
return { ["inactive_effects"] = {  }, ["last_effect_id"] = 0 }


As against that prevents the loading of my mods

Thanks
 

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

Re: [Mod] Player Effects [1.1.0] [playereffects]

by Wuzzy » Sun Oct 12, 2014 18:46

This is not an error. And the particular file you have means you haven’t experienced any effects so far.
The mod uses the file to store all the active effects. It is saved regularly so all the effects can be restored with a precision of 10 seconds even if the server crashes.

But maybe I should try to reduce the number of times this mod autosaves the effect data. Especially if nothing actually changes. Do you want such a change or isn’t it important enough for you?

Or is the only thing you care about just that the log file is flooded with these messages?

As against that prevents the loading of my mods

I do not understand this.
 

User avatar
LanceJZ
New member
 
Posts: 5
Joined: Thu Sep 11, 2014 08:54
GitHub: Lancejz
In-game: Purple

Re: [Mod] Player Effects [1.1.0] [playereffects]

by LanceJZ » Sun Jan 11, 2015 07:56

Hey, I could use something like this for my RPG mod I've started working on. Are you still working on this mod, because I hope you are.
 

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

Re: [Mod] Player Effects [1.1.0] [playereffects]

by Wuzzy » Sun Jan 11, 2015 19:03

I will continue working on this whenever I feel like it. :P
Currently, I do not feel like it.
 

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

Patch Release: 1.1.1

by Wuzzy » Sun Feb 08, 2015 00:07

Hi! I just made a patch release, the new version is now 1.1.1.

This fixes a bug leaking a variable into global space which caused an error message in the chatlog in the recent Minetest version. That's all, bye!
 

TeTpaAka
Member
 
Posts: 131
Joined: Sat Dec 28, 2013 21:54

Re: [Mod] Player Effects [1.1.1] [playereffects]

by TeTpaAka » Thu Apr 02, 2015 10:59

Hi Wuzzy,

Is there a way to give priorities to effects?
What I means is, right now, when an effect is applied, every other effect of the same group is disabled. Would it be possible to give the effects a priority, so that the effect with the higher priority continues? Or is there another way to achieve this?
That would make some effects of my Magic mod more powerful.
 

User avatar
davidthecreator
Member
 
Posts: 179
Joined: Mon Aug 18, 2014 19:48
In-game: DavidDoesMinetest

Re: [Mod] Player Effects [1.1.1] [playereffects]

by davidthecreator » Sat May 30, 2015 11:50

Can i make nodes or entities give player effects when touched?
 

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

Re: [Mod] Player Effects [1.1.1] [playereffects]

by Wuzzy » Sat May 30, 2015 16:16

@davidthecreator: No, the player effects stricly apply to players only.

@TeTpaAka: No. Unless I update this mod, of course (sorry for late answer). But I am not sure what exactly you want here.
 

TeTpaAka
Member
 
Posts: 131
Joined: Sat Dec 28, 2013 21:54

Re: [Mod] Player Effects [1.1.1] [playereffects]

by TeTpaAka » Sat May 30, 2015 16:32

Wuzzy wrote:@TeTpaAka: No. Unless I update this mod, of course (sorry for late answer). But I am not sure what exactly you want here.


For example:
  1. A player gets hit by a spell that makes him blind for 20 seconds.
  2. After 5 seconds, he gets hit again, this time with a spell that blinds him for 5 seconds. This spell overrides the previous one although it is less powerful. This way, you can heal yourself by hurting yourself with a weaker attack.

Another example:
  1. A player gains temporarily the ability to fly.
  2. He gets hit with a spell that temporarily disables flight.
  3. When he gets hit by another spell that grants flight, the seconds point gets invalid, since it gets overridden by this.
 

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

Re: [Mod] Player Effects [1.1.1] [playereffects]

by Wuzzy » Sat May 30, 2015 16:55

TeTpaAka, thanks for your remarks. Yes, these are all correct and in the current version, stuff like this can not be prevented. :-(
It turns out this mod really needs these additive effects or some sort of “effect stacks” to properly handle this stuff. I also need to put some thought into how the effect timers are treated.

I am just too lazy to do this work right now, sorry. xD
 

User avatar
davidthecreator
Member
 
Posts: 179
Joined: Mon Aug 18, 2014 19:48
In-game: DavidDoesMinetest

Re: [Mod] Player Effects [1.1.1] [playereffects]

by davidthecreator » Sat May 30, 2015 21:54

I ment are nodes or entities able to give the efects to players not players to entities or nodes for lets say: some one makes "poisoned" debuff that can be given to player using a command or drinking a potion from your potions mod but the maker of this debuff makes a poisoned spyke node and he wants it to give the debuff to a player as soon as it touches it is that possible
 

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

Re: [Mod] Player Effects [1.1.1] [playereffects]

by Wuzzy » Sat May 30, 2015 22:24

Yes, this is certainly possible. Nodes and entities can use their own code to cause a player effect. In fact, I have already demonstrated this possibility in my (still very WIP) subgame Weird. If you get into the frost biome, there is one ice/stone monster which throws ice balls, if it hits you, you get frozen for 5 seconds. Being frozen is a player effect and the ice ball is an entity. :-)
Basically everything which has code and is able to call the Player Effects functions should be able to apply player effects to any player. Node callbacks, entitiy functions, your own mod, whatever. It does not matter.

However, detecting when a player *touches* a certain node is quite tricky right now, but this has nothing to do with this mod. One could theoretically detect when a player is near a certain node. Maybe you want to look into the code of the pressure code of Mesecons, here the node just regularily checks if a player stands above the node.
 

User avatar
davidthecreator
Member
 
Posts: 179
Joined: Mon Aug 18, 2014 19:48
In-game: DavidDoesMinetest

Re: [Mod] Player Effects [1.1.1] [playereffects]

by davidthecreator » Sat May 30, 2015 22:29

If you say its possible i say: aaaaaaaaaawwwwwwwwwwyyyyyyyyyeeeeeeeeeeaaaaaaaa!!!!
And also: i guess after a little play arround with mobs that mihght poison player or so i should also dont forget to make an antidote couse armor wont help in this case
 

User avatar
MineYoshi
Member
 
Posts: 4267
Joined: Wed Jul 08, 2015 13:20
GitHub: MineYosh
IRC: MineYoshi
In-game: Kirby_Retro

Re: [Mod] Player Effects [1.1.1] [playereffects]

by MineYoshi » Wed Sep 09, 2015 16:43

wuzzy add a new mod in the list of mod that uses your mod is my Retroblocks mod please here is the link:
https://forum.minetest.net/viewtopic.php?f=9&t=13118&p=188502#p188502
People talk about freedom of speech, so i'll say that God exists.
Open your eyes!! See The big unicorn conspiracy.!! :D The government has been lying to us about unicorns!!
"I've learned there are three things you don't discuss with people: religion, politics and the Great Pumpkin" - Linus Van Pelt
I'm the Officially 1st ABJist in the world ( ͡° ͜ʖ ͡°)
 

Byakuren
Member
 
Posts: 441
Joined: Tue Apr 14, 2015 01:59
GitHub: raymoo
IRC: Hijiri

Re: [Mod] Player Effects [1.1.1] [playereffects]

by Byakuren » Wed Dec 30, 2015 06:47

A simpler way to implement additive effect groups could be to have the effects be monoidal. What this means is that when you define additive effects, you don't define an "apply" function. Instead, you define for each effect type in the additive group a data value associated with the effect. This can be any value. Then for the entire effect group, you want to define:

  • A combination function: A function that will combine two data values. For example, if your effects give gravity multipliers, this function would just multiply them together.
  • An identity: A "default" value, to be used when no effect in the effect group is active. For gravity multipliers, this would be 1.
  • An application function: It takes a data value and applies the effects.

What you would do is keep track of all of the active effects for each effect group. Whenever this list of active effects changes, you calculate the current data value by using the combination function to combine the whole list, and then you apply it to the player using the application function. If there are no more effects, just apply the application function to the identity, which will give default behavior. If the identity value is truly an identity for the combination function, you can handle both empty and nonempty lists in the same case: you combine the identity with the contents of the list of active data. If it's empty, you get just the identity, and if it's not empty, the identity doesn't affect the result of combining the list. But for this to work, users of the library are obligated to make sure the identity is really an identity, so it might be better to handle them in separate cases anyway.

I think this is an elegant solution, and some common effect uses would be covered:

  • Anything involving numerical addition or multiplication - Combination function is addition or multiplication, and the identity is 0 or 1, respectively.
  • Stronger effects overriding only during their duration - Suppose you want a longer-lasting weak effect to remain even after a strong similar effect wears off. Then your combination function could just choose the maximum-strength effect. The identity isn't so obvious though. What you can do is make the identity nil, and when the application function is applied to nil, it just cancels the effects. To be a proper identity, the combination function should always pick a non-nil value as the maximum if it can. This method of using "nil" as the identity in fact works for any combination function, so you can do this when there is no natural-feeling identity.
  • Effects with explicit priorities - Similar to the above, but comparing their priorities rather than potency. The above one could be considered a special case of this.

One limitation I see already is that you wouldn't have a proper monoid if you mixed additions and multiplications. To cover these, you can weaken the requirements on the users of the library, so that the combination function doesn't have to be associative (which monoids require), but still require the identity be an identity. You as the library-writer would have to guarantee a certain application order though, like earliest-applied to latest-applied, so that users of the library know what to expect.

Another issue is that if you want an effect to affect multiple monoidal effect groups that have a different kind of effect data, there wouldn't be a way to handle it in this system. One way to work around that would be to instead have a table of effect data indexed by effect groups, similar to how tool capabilities have numbers associated with them. Then for each effect group, you would just use the provided value in the table.

An effect could affect both exclusive and monoidal effect groups, since the original apply function would not be used in the monoidal effect group, and the extra data for the monoidal effect groups would not affect the exclusive effect groups.

Another thing this method would be unable to do is cancel effects permanently, since the effects cannot remove other effects, and when they wear off, the other effects will remain. The most you could do is temporarily mask the effects. Arguably you would want to remove effects from outside the framework of monoidal effects, though.

EDIT:: Another possibly useful feature would be to have effect groups that are just tags, and don't cancel or add together or anything. Then, for example, you could cancel all effects in the group "magical", if you are dispelling magical effects.

EDIT2:: If additive effects are included, then it would make sense to allow infinite-duration effects as well, because then you can have permanent effects that stack with temporary ones nicely.
Last edited by Byakuren on Sun Jan 03, 2016 21:02, edited 1 time in total.
Every time a mod API is left undocumented, a koala dies.
 

Byakuren
Member
 
Posts: 441
Joined: Tue Apr 14, 2015 01:59
GitHub: raymoo
IRC: Hijiri

Re: [Mod] Player Effects [1.1.1] [playereffects]

by Byakuren » Sun Jan 03, 2016 06:15

I've started using playereffect in magical_realm.

Is there any reason you put effect cancellation into a minetest.after instead of doing it in the step function along with the HUD? You are already calculating the time left, so it would only be an extra comparison, except when you have to cancel effects (or apply repeating effects). I'm getting long delays in the cancellation of some effects, so that the HUD sometimes goes even to -60 seconds. minetest.after already uses globalstep, so I don't think it would be much less efficient.

Here is the effect in question: https://github.com/raymoo/magical_realm ... t.lua#L262
Every time a mod API is left undocumented, a koala dies.
 

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

Re: [Mod] Player Effects [1.1.1] [playereffects]

by Wuzzy » Mon Jan 04, 2016 00:25

I am currently not in the right mood to work on Player Effects. It does not mean I have quit Minetest altogether, but I have phases I go through … :D And currently, I am not in the Minetest phase.

But be assured I read your comments, they are interesting and I will probably consider them should I start to work on Minetest mods again.

And no, I don't know why I used minetest.after somewhere. xD Maybe I'll tell you later when I am in the right mood again.
I'm creating MineClone 2, a Minecraft clone for Minetest.
I made the Help modpack, adding in-game help to Minetest.
 

Byakuren
Member
 
Posts: 441
Joined: Tue Apr 14, 2015 01:59
GitHub: raymoo
IRC: Hijiri

Re: [Mod] Player Effects [1.1.1] [playereffects]

by Byakuren » Mon Jan 04, 2016 02:43

I'm sorry, I didn't even mention where minetest.after was used. It's used in apply_effect_type to schedule the cancellation of the effect, but the time left is also calculated when the HUD is updated. So I thought you might as well use that to cancel the effect also. Since minetest.after is already implemented using a globalstep callback, I don't think this would be less performant.

EDIT: I saw that the HUD only updates at intervals of 1 second, so maybe that's the reason it isn't used to also update the actual effects. I'm still not sure why I sometimes get very long delays on effect cancellation though.
Every time a mod API is left undocumented, a koala dies.
 

Byakuren
Member
 
Posts: 441
Joined: Tue Apr 14, 2015 01:59
GitHub: raymoo
IRC: Hijiri

Re: [Mod] Player Effects [1.1.1] [playereffects]

by Byakuren » Mon Mar 28, 2016 00:11

Hi again. A secondary reason I split to monoidal_effects was that playereffects used os.time for the HUD and minetest.after for actually updating effects. This often results in a discrepancy with the effect HUD elements (negative time remaining), and in extreme cases could result in effect cancellation delays of hundreds of seconds. It is a nice way to measure globalstep lag, but can break the balance of things such as physics override effects, which are simulated at the correct speed on the players' clients regardless of lag.

In monoidal_effects I used os.time both for effect cancellation and updating the display. The downside of this is that effect durations now only have a granularity of one second. What is your opinion on switching playereffects to using os.time for effect durations? It shouldn't be hard to make something like minetest.after that uses os.time instead, and after that it would just be search and replace.
Every time a mod API is left undocumented, a koala dies.
 

User avatar
xeranas
Member
 
Posts: 99
Joined: Fri Feb 05, 2016 11:06
GitHub: xeranas

Re: [Mod] Player Effects [1.1.1] [playereffects]

by xeranas » Mon May 09, 2016 05:27

Did not find license mention within source code / readme file (or I completelly missed?).
 

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

Re: [Mod] Player Effects [1.1.1] [playereffects]

by Wuzzy » Mon May 09, 2016 10:29

It's WTFPL, I wrote in in first post.
I'm creating MineClone 2, a Minecraft clone for Minetest.
I made the Help modpack, adding in-game help to Minetest.
 

Next

Return to Mod Releases

Who is online

Users browsing this forum: No registered users and 17 guests

cron