Services API: Economy

Discussion in 'Plugin Development' started by sk89q, Apr 12, 2011.

Thread Status:
Not open for further replies.
  1. Offline


    Something Bukkit needs is an API for plugins to register "services" in order for interoperability between plugins to be maximized. For example, if your plugin needs to get a player's wallet (in cash or points) on hand (for economy), there should be an easy way to do it without querying for 20 different economy plugins. Therefore, here has to be as standard for various services that may be needed that is both complete and extendable. Because not all plugins may implement all features, the services system MUST also have an understanding of "capabilities" so that plugins can declare what is supported. This thread is for discussion of a services API for economy services.

    We can start off with this:
    • double getWallet(Player player)
    • void setWallet(Player player, double amt)

    (No name is final.)

    Suggest both methods and capabilities in this thread.
    zachoooo and Jadedwolf like this.
  2. Offline


    All for an API with economies.
  3. Offline


    I suggest a more general version of your two methods that accept a name, rather than a player as an argument.
    • double getWallet(String account)
    • void setWallet(String account, double amt)
    These allow for accounts that are associated not just to individual players, but to organizations, server services and a number of other things that someone more creative than me can come up with. These methods don't necessarily need to replace yours, but I feel they're important to have.
  4. Offline


    Can't this go into Persistence when it's finally finished? Like, an over-plugin property system?
    So the developer of an API can register a variable in this property system and it's purpose and this property is being accessible over a string. For example:
    Variant getProperty(String type, String argument);
    Then, the server checks if the type is already registered and returns the value for the argument. Variant is a variable datatype. Look at the Qt documentation for the QVariant Class.

    We have to do something with registering a type because otherwise, we'd had multiple types for the same thing soon, e.g. a wallet.

    When we standardise the types, the plugin devs have no more problems with all the different incompatible Economy-APIs
  5. Offline


    That could work.

    Though there would need to be something to differentiate between a player and some other account, because plugins would just simply give the name of the player in most cases I imagine.

    I don't believe in accessing data directly like that, first, because that prevents plugins from doing pre-processing on the raw data; second, because it would allow other plugins to meddle in the data of another plugin (not a terribly good idea); and third, because it assumes that it would be in persistence to begin with. Plugins are not going to all store data in the same way as well, so it would be silly to attempt to conform plugins to that.
  6. Offline


    I don't disagree, but what would the purpose of differentiating the two be?
  7. Offline


    Are you limiting this to economies, or is this something you want to expand? I've been thinking lately about a similar thing for warp plugins, because they're so inefficient. Would this service system type have a "Service: x, description: y" type thing? If so, I'm all for that.
  8. Offline


    A player's name could be the same as some other random account's name.
  9. Offline


    Perhaps this for setting up/removing an account for a player or group :
    void createWallet(String account, double startamt)
    void deleteWallet(String account)

    For interest rate(if it is added) :

    double getInterest()

    Will this be kept simple or is it going to be more complex ?
  10. Offline


    Incidentally, not every economy system out there restricts players to a single denomination of currency. It might be nice if we had something like:
    interface Wallet {
        double getCurrency(); // use default currency.
        double getCurrency(String currency);
        void setCurrency(double amount); // use default currency.
        void setCurrency(String currency, double amount);
    // Elsewhere.
    interface WalletProvider {
        Wallet getWallet(String context);
  11. Offline


    This will be applied to a host of things such as warps, homes, friends lists, etc. I'm just starting with economy for now. Types of services can be added at runtime if needed.

    I'll add those things.

    This can get pretty complex because plugins will be able to declare "capabilities," allowing for a gradient of support for more advanced features.

    Where do you suppose "currency" could come from? Would the user specify it?
  12. Offline


    my take on this:
    bukkit would provide the basic interface for the service provided (simple economy in this example)
    public interface Wallet {
      public long getAmount();
      public void setAmount();
    public interface WalletManager {
      public Wallet getWallet(Player player)
    currency systems could then implement these interfaces and add to it, e.g. calculating interest for each wallet at certain intervals.
    to make this accessible to other plugins regardless of the system used currency systems would inject a WalletManager into the server. If another plugin tries to insert a different WalletManager an error should be raised.

    a plugin that wants to use wallets can then ask the server for the WalletManager instance of this server and find the Wallet of a player and use the methods of the interface to store money.
    if a currency system provides more methods than the basic ones and a plugin might want to use them it should add the currency system as a dependency and cast to the specific class.
  13. Offline


    Someone would have to specify something, somehow. The currency parameter in the interface is really intended to be some sort of opaque identifier the implementation can use to determine which denomination of currency is intended.
  14. Offline


    This has already been done, please stop re-creating the wheel and use the search feature; No I am not lying, its in the WIP / Resources somewhere.
  15. Offline


    Do you mean APIHandler.

    A “type” label? So define well known types like “player”, “group” and plugin specific types.

  16. Offline


    I don't really like the idea of a "set" method when we're talking about money. There is no bank system out there working this way, it's just "add" and "remove".

    You could be calling "get" adding money then another action changes your amount and the plugin uses "set" and now the amount is wrong.

    The only reason to use a "set" would be to make an account 0 or to start up an account with an initial amount.
  17. Offline


    I like this. It makes sense in the context of its domain. I would, then, posit three methods: deposit, getBalance, and withdraw.
  18. Offline


    And a forth “setBalance”. I mean you could add a abstract class, which will only have one method left and let the others redirect to it. So if somebody need the interface it is possible to use this, and other developers could use the abstract class. But the plugin developer which uses the economy plugin should use the interface.

  19. Offline


    Setting can be one of those "capabilities" if you need it, but it can be something that not everything provides.

    I couldn't care less. This is something that needs to be a part of Bukkit, and it has been discussed long before any other plugin, back in December.
  20. Offline


    What you want is something like

    double credit(double amount)

    This would attempt to deposit amount and return how much was actually deposited.

    double debit(double amount)

    This would attempt to withdraw the amount and return how much was actually withdrawn.

    Also, there should be a method to transfer between two wallets.

    double transfer(Wallet target, double amount)

    All amounts are just requests. The back-end can decide to send less.

    It might be worth having an "atomic" flag. If this is set, either the transaction happens fully or fails completely.
  21. Offline


    You really think that an economy should be a part of the core server?
  22. Offline


    No, that's not the point of this. This isn't about economies. This is about services in general having a decent and useful API.
  23. Offline


    Jep it would be nice, if there is an general API for plugins which are for plugins. Okay Permissions should some time in the core, but such things as economy could easily done by plugins but it would be nice if Bukkit allows me to share the APIs easily.

    Also I think that a currency shouldn't store as a double. For me I hate the rounding errors and possible wrong comparisons. Because most currencies have a base currency (like Euro/Dollar…) and a divisor (Cents…). So for example store the actual balance as cents and divide by 100 so you could show the balance as Euro/Dollar etc. The int allows (2³¹-1)/100 = 21 474 836.5 €/$. And if this isn't enough a long should be big enough.

  24. Offline


    That's my point. If you want <insert-economy-or-something-here> plugins to all use X interface/API with X features, then convince all <insert-economy-or-something-here> developers to merge into a single plugin. If there's going to be a prescribed interface/API for things that aren't even part of the core server, then you might as well ditch the plugin architecture and have "approved" "plugins" built-in.
  25. Offline


    This wouldn't require the use of the interface, though. It would just make it easier to make, say, an economy plugin, which would be useless without another plugin taking advantage of it. Even if the economy plugin does use the standard functions (say, "getCurrentMoney()), it could still use its own as well. It would just make it easier to have any standard at all. I know don't want to deal with 20 different APIs. I just want to use one.
    Same with, say, home. I'll have a plugin that sets home to where I sleep. Then I have a plugin that has a command, say /tohome sk89q, that lets me warp to sk89q's home instead of my own. How would these two plugins interact? There are a dozen plugins that set homes. If a home is standardized, then it's doable. Until then, it's really not, unless you like dealing with and keeping up with a dozen different plugins that don't actually have anything to do with you.

    EDIT: Sorry I babbled a bit. I'm operating on no sleep today.
  26. Offline


    So ask the /home plugin developer to add a getHome() function so your toHome plugin can access it, or ask them add toHome() directly. If "a dozen plugins don't actually have anything to do with you", then what on Earth do you need them to have a standard API for, when they "don't have anything to do with you"?
  27. Offline


    Sorry, I was unclear. It's not that they have nothing to do with you, it's that you shouldn't even need to know they exist. As it currently stands, my 'tohome' plugin would need to have information about every single home plugin in order to be fully functional. With this services api, my tohome plugin would be able to just query the system, see what plugin has home, and use the standard (because of the api) getHome() function.
    GatsbyTheGreat likes this.
  28. Offline


    @petteyg359: Maybe I get you wrong, but why shouldn't be this problem be solved with the bukkit team. So everybody could register interfaces like plugins and allow to share them easily. At the moment I only could support iConomy in my plugins. Now I could add support for the hundred others economy plugins, or hope that other economy plugin developer also write a second plugin, which implement a adapter and simulate to be iConomy. Or I support only iConomy. But there are users with other economy systems so the system at the moment is awfully incompatible.

    Mostly the plugin developers only need to get an account and change their balance. And maybe a “format” function. If now a developer support more than this and another plugins need this special abilities this plugin can work like now, but if you only need basic capabilities a basic API should do it.

    Also who is deciding which is supported and which not? I mean the developer of iConomy could change all method calls and every plugin depending/simulating it has to change the calls.


    PS: I haven't followed the progress of Raphfrk's pull request, but he already suggested a interface system like I described in the first paragraph.
  29. Offline


    As posted earlier, we already have such functionality in a plugin (APIHandler). You just need to get somebody to update and maintain it, and convince people to use it.
  30. Offline


    Alright, there's that API. Now I'm going to make my own API handler and xZise here is going to make his own as well. Now it's like with economy: which do you support? Why? Oh, wait, one of them doesn't support Permissions. However, that's the only one that has, say, warp support. Oh darn.
    It's so much easier to have a standard. The standard doesn't have to be followed, but it would be easier for everyone if it were. If a standard exists, there will be no "convincing people to use it". People just will, and people will end up gravitating toward those plugins which do. What about a standard API would actually be bad?
Thread Status:
Not open for further replies.

Share This Page