Optimal Item Price Layout

Discussion in 'Spigot Plugin Development' started by Hunky524, Jun 15, 2016.

  1. I wanted to get some opinions on how I can save a large quantity of price data for my server. What I am trying to get your opinion on is how I can/should save and load ItemStack price data. The reason I don't want to just simply store materials is because I want to be able to adjust prices based on enchantments, durability, and custom attributes (don't really worry about the custom attributes, I'm more focused on getting enchantments and durability working at the moment). I know how to serialize items and I've made my own serializers in the past. I'm wondering if that is still the best option or if some kind of database structure would work much better for this. I've never worked with databases before, but I'm hoping if someone who has worked with both storing data in configs and databases might be able to give me their opinion on how they would store this kind of data.

    If anything is unclear I can rephrase.
     
  2. Save the item under a specific item name then add an extra thing so when you do config.getItemStack(section) you can also do config.getInt(section + ".price"); then you'll have an itemstack and price, I'm not sure how "Efficient" this is but I know it's a good way to do it, then on startup just store all the itemstacks into a hashmap, if you have a double item just skip it and don't put it into the map.

    I think that would be your best bet.
     
  3. I would take a slightly different approach. Assigning prices for every variant of item in the game is way too tedious. I would make the different variations apply a variation function to the base price of the material. Then just store the base prices for a material (or material data) and apply the appropriate functions from there.

    The way I would handle durability is if the item has 100% durability it costs the full price. Half durability -> half the price. (I would also bypass the check if the item has the unbreakable flag so that it is always charged full price). The enchantments I would store as functions affecting the original price. For example the unbreaking enchantment price modifier is something like
    Code (Text):
    1 + (0.2 * lvl)
    which would make something that cost 10$ cost 12$ with unbreaking 1, 14$ with unbreaking 2 etc. The expression I gave is just an example. This way your users can define functions in a config (there are very many simple expression parsers out there) and you can just apply the functions to the base item cost.
     
  4. That's what I have setup at the moment. It seems to work fine. I'll keep waiting for responses to see other ideas.
     
  5. what if you want different names, and lores to have different prices? That would change your algorithm a lot, and making a database of items which you load on startup is a good way to do it, just take your time loading in each item and don't let people log in until all the items have been successfully saved into a nice big hashmap, or you could make a nice long algorithm for each enchant / name color / etc whatever you need based on the base item price and an algorithm set by the enchant level etc.
     

  6. I'm not going to assign prices for each durability loss on an item or else I would use a function like you suggested. However, I did think of using a function for the enchantments which would save a lot on saving and loading, but then I thought I might want enchantments to be worth more on different items, ie, protection is worth more on a chestplate than it is on boots.
     
  7. if you'd like it like that then saving / loading through hashmaps would be your best bet.
     
  8. Ok, TY for the feedback :)
     
  9. or setup a nice long table as to what the item is, then based on that have the enchant level and cost then for that have a name cost then for that have a lore type cost etc
     
  10. Interesting, I haven't thought of setting up something like that.
     
  11. If you are looking to store information for long periods of time instead of in memory, here is what I suggest.

    I personally would much rather store it on a database. Searching it up, saving data, loading data, adding and removing data altogether would be a bit less intensive on your MC server then storing a massive config file for every itemstack and storing it by price etc. It would be even easier to handle over multiple servers. That is one of many uses for databases. I am however, unsure of the speed it will be. If you host a local or non-local and quick SQL server, speeds should be fine, however if your SQL server has problems executing simple tasks or it takes a while to connect to the server, then I would stick with a config. Also, speeds may vary for larger amounts of information.
     
  12. You could put in an enum of each material, then 10 or so integers for each price then having it like, "ShopMaterial.matchItem(Material).getExactPrice(ItemStack);" then it would factor in each enchant based on the enchant level so say we're adding protection we could setup, "DIAMOND_CHEST(Material.DIAMOND_CHESTPLATE, 100, 20, 40, 60);" first integer will be the base price then the 3rd 4th and 5th integers would be the level prices which would be saved in memory then when you access it it basically breaks the enchants down and reads it as 100 + enchant level cost and that would work how you'd like.
     
  13. If a chestplate is more expensive than a pair of boots this effect is built in as we are multiplying the base cost. If our protection enchantment function is
    Code (Text):
    1 + (0.2 * lvl)
    and a chesplate costs 20$, a prot I chestplate costs 24$. A pair of boots that costs 10$ would then cost 12$. The cost of the protection enchantment then costs 4$ on a chestplate and 2$ on boots.
     
  14. yes except he may want it to vary differently in the algorithm say he wants each extra enchant on a chestplate to be 50% and 20% on boots
     
  15. Then build it in to the functions! A couple more functions or variables are still a better option then a massive database of prices that can be calculated rather than saved. Not to mention it is much easier to adjust a price function rather than go through every piece of armor because you want to raise the price a bit. You could make an "enchant_mod" variable that you can set for various base items that can be then used in the calculation.

    Just because in the example I gave doesn't account for a specific cases doesn't mean it can't be done. I gave a simple example to give the OP and idea of how I would handle it. It is not an extensive example. The function doesn't have to be linear either.
     
  16. or he could make an enum table
     
  17. I feel like I might just go with a version of what @MrBlobman said. I can just store Materials to a base price which is really easy to do. Then whenever I need to pull the price for an item, I can just run it through a formula based on enchantment type, enchantment level, durability, armor type, etc. Time to spend the next days looking at numbers. I might report back after to see what you all think.
     
  18. That would make a lot more sense than saving individual prices for different combinations.

    In chestshop, if you do /iteminfo with a special item like with display names and whatnot, it generates a unique identifier for that item if one doesn't already exist and then you can set up shops using the unique identifier it gives you. That is a rather nice way of handling it as well.
     
  19. or you could to have it where you could save certain unique items to a price but if it's not saved it would run through either the formula or the base price with addon. That would be a nice way of doing it.
     
  20. I actually thought of doing that. I would only use it if I ever had a very unique item like an apple that gave some sort of AOE rejuvenation. In the lore it would have some kind of special lore, but there is no way to have a formula to calculate the price so I would just have to manually set it and put that price when needed.