Jump to content

An entropy-based solution to the hammer durability conundrum.


Streetwind

Recommended Posts

So I've read in the changelog that hammers had their durability increased not too long ago. And after I got into smithing, recently, I understood why. Smithing just destroys hammers. I was making metal sheets for lamps, and a brand-new, full durability copper hammer could not finish three of them before breaking. Not even six ingots worth of work. Now I don't claim to be the best smith, so maybe if you go super efficient and don't miss any strikes you can barely pull off six, I don't know. Either way, it's surprisingly little. I would expect to be able to do more, even with the worst quality hammer.

At the same time, the durability of hammers is already so much higher than other tools of the same metal that it begins to border on awkward. There is just no room to properly tune hammers for both smithing and non-smithing work at the same time.

...Or is there?

The first instinct might be to go 'why not a chance-based solution'? If only a set percentage of all smithing hits subtracted durability, then durability could be tuned for non-smithing use, and in a second step, the percentage would tuned to be able to process the intended number of ingots on an anvil. However, chance-based solutions have a big downside: streakiness. A proper random set means that you have no guarantee that your intended distribution of 'hits' and 'misses' actually happens reliably on a small scale. You could in fact very well have a scenario where the intended end result is perfectly achieved when viewed across all players, while at the same time not being achieved for even a single individual player. And we don't care about the large picture here. It needs to work for every player individually.

But there is a way to force a chance-based approach to work on the individual level, by intentionally sacrificing most of the randomness. Sounds counterintuitive? It isn't, trust me. This approach is called the entropy method. It is best understood with the help of a practical example, so here is one possible implementation method for an entropy-based smithing system:

  • Each kind of smithing hammer is given a value of how often it should take damage from a smithing strike. It's typically expressed as a percentage (let's say 20%), but under the hood, it's just the number itself. We'll call this number the "break chance" for simplicity, even though it technically speaking is not a chance.
  • When a work item is started by the player putting an ingot onto the anvil and selecting a pattern in the pop-up menu, a random number between 0 and 99 is generated. The result is stored in a counter attached to the work item, called the "entropy counter".
  • Every time the player performs a strike with a hammer on this work item, that hammer's break chance number is added to the work item's entropy counter.
  • As soon as the counter reaches or exceeds 100, the counter is reduced by 100, and the hammer takes one point of durability damage.
  • This continues until the work item is destroyed - either by re-smelting it into an ingot, or by finishing the pattern.

In this example, the hammer has a 1 in 5 "chance" to take damage - but the entropy counter ensures that it takes damage exactly 1 out of 5 times, every cycle, precisely on every fifth hit after the first damage instance. The starting value for the entropy counter is still random, so you will not know which hit will be the first one that causes damage. It also means that two otherwise identical work items with the identical number of steps performed on them might potentially cause different amounts of durability loss... but never more than one point of difference. A little bit of randomness, but not too much.

Because the entropy counter is attached to the work item, it persists as long as the work item lives. The counter will not reset if you take a break to reheat the work item in the forge while you go stab a drifter. The counter will not reset if your hammer breaks halfway through and you continue with another hammer. The counter will not reset if a different player takes over from you - or even if multiple players hammer the work item at the same time, potentially even with different hammers that have different break chances. Whichever hammer trips the counter over the 100 mark will take the durability loss. However, each time a new work item is started, that work item randomizes its own starting value.

It would also be possible, of course, to attach the entropy counter to the hammer itself. This approach means even less randomness, since each hammer only randomizes one starting value over its entire lifetime. In this case you might as well skip the random starting value entirely and just have a hardcoded "take damage every x strikes no matter what" effect. I personally think the entropy counter on work items is more interesting, though.

The advantage of the entropy method is that you can tune hammer durability for non-smithing work first, and have it match the other tools of the same metal. But by carefully choosing the break chance number, you can also tune it perfectly to last as long as you want it to last when working metal on an anvil, no matter what its durability actually is. And it will reliably give that intended result to each player individually, without random streaks throwing it off all the time.

And there is some interesting gameplay content you can implement with it as well. For example, what if ruins could drop an "masterwork smithing hammer" as loot? It would have the same stats as a normal hammer of its kind in every way, except that its break chance number would be much lower. So you could use this hammer for smithing, and it would last much longer for that specific purpose than any other comparable hammer - while still losing durability just the same if you used it to hit people or smash ore.

 

I hope this makes sense :) 

Edited by Streetwind
Link to comment
Share on other sites

While an interesting concept, I don't see a need for it to be used for hammers. A much simpler solution would be to just have the durability be higher and allow non-smithing actions to substract more than one point of durability. The extra durability could also be scaled down just on the tooltip by just dividing the values, so it doesn't seem higher than other tools, although it technically is.

Link to comment
Share on other sites

Hmmm... no, I don't think that's a viable alternative. As I kept collecting my thoughts on why exactly, it just got longer and longer. In the end I decided to put it into a spoiler so it doesn't look like I'm beating you over the head with a wall of text for merely stating your opinion. That's not how it's meant. I just wanted to show how much extra work it would be to implement that deceptively simple workaround, and how many problems it potentially might create down the line for both new core features and for mod support.

 

Spoiler

When determining how much durability is removed in tool-assisted crafting, it is not the tool that makes the call - it's the recipe. So you would have to change every single recipe that includes the hammer as its component. That alone is potentially as much work as implementing entropy already, if not more. My C# is a little rusty, and I've never seen VS' source code, but theoretically, entropy would need... one extra integer field in the work item object, together with its get and set methods (autogenerated by the editor); one extra line of code when instantiating the object; one extra integer field and autogenerated get method in the hammer object; one extra line of code in the smithing logic; and an extra one-line IF clause encapsulating the damage code that's called when smithing.

By comparison, how many hammer crafting recipes are there that would need to be manually changed? I don't actually know, off the top of my head. But I bet that it's more than four or five. And then, you get to the brick crafting recipes, in which you put both a hammer and a chisel into the crafting grid. What happens if you make this recipe do more damage to the tools? Can you set the hammer's damage and the chisel's damage separately? I don't know. But if you cannot, then you have a problem on your hands, because now your chisel dies way too fast. You now have to apply the same hack you applied to the hammer to the chisel as well. That means not only changing the tool itself in all of its variants, but also - again - checking all of the recipes it appears in.

When you're done with that, then as a next step, you have to tackle in-world use. A tool in VS takes damage whenever an entity is struck with it, and whenever anything (blocks, plants, etc) is broken by it. So you have to find all of these instances in the code where it happens, and implement extra logic to catch and handle the special case where a hammer or chisel is used for these things, so that additional damage can be applied.

Finally, you have to implement the special logic in the mouseover tooltip that artificially disguises the durability value of hammers and chisels so that it looks no different from other tools.

Once you've successfully done that, you're left with a working implementation that faces two problems you can do nothing about: future proofing, and modding.

From this day forward, everyone working on this project needs to remember that hammers and chisels are special. Whenever a new recipe is built that includes one of the two, the person doing so needs to remember that these tools are supposed to do more damage. Additionally, you can never pair a hammer or chisel with any other tool in the crafting grid anymore - and everyone working on the project needs to remember that, as well. When you forget that, bugs crop up in which hammers and chisels suddenly report decimal places in their durability, or a certain recipe suddenly kills your saw way faster than intended, and so on. Furthermore, when new features are implemented, this needs to be kept in mind as well. Tool repairing, for instance, is an often requested/suggested feature. Should that ever be implemented, then whatever shape it would have, someone would have to remember to include special logic for these special tools, making the feature more work-intensive to develop and test, and more prone to bugs and oversights.

Then, modding. The same problem with adding new recipes, again - but this time by people who don't know that the hammer's durability has been hacked behind the scenes, because it is deliberately hidden from the player. I mean, they might spot the special handling logic now present all over the place, but they won't understand why it exists without reverse-engineering the whole process. And perhaps the modder wants to implement a new tool, which can also be used for smithing, among other things. Multitool mods have a long, long history in Minecraft, for example, so this is not just a theoretical exercise. How does the modder make sure their new multitool doesn't disintegrate while smithing? They can't, because the only way to do so is to give it extra-high durability. But in contrast to VS's own hammers, all the special logic that was implemented to deal with and obfuscate that high durability will not work for the new tool. Not unless the modder goes and hacks into core functions that are probably never intended to be accessible to modding.

With the entropy system, though? As long as your new modded tool has the required break chance number that the smithing logic expects to be able to get, and you register it as a valid hammer for working on the anvil, you just swing it at a work item, and it just works. No extra effort involved. And neither is there any need for the VS developer team to pay attention to special cases in the future, nor to train new people joining the project to do the same.

 

Link to comment
Share on other sites

You underestimate the work required to implement your suggestion quite a bit. It would not be terribly hard, but just changing some recipes is always done in a matter of minutes. However, I've looked a bit deeper into it and how the recipes are setup and just changing a number on them isn't possible, because the durability consumption for tools is hardcoded in the api to 1.

For removing durability from Tools, Collectible.DamageItem() is used, which thankfully has an optional argument for the amount of durability to damage an item. The method gets called when Grid-Crafting with a tool by the method Collectible.OnConsumeByCrafting() and in the code for the BEAnvil.OnUseOver() for smithing. A simple solution would just be to add an exception when grid crafting with a hammer by simply adding something like:

if (stackInSlot.Itemstack.Collectible.Tool == EnumTool.Hammer) {
stackInSlot.Itemstack.Collectible.DamageItem(byPlayer.Entity.World, byPlayer.Entity, stackInSlot, 100);
} else {
stackInSlot.Itemstack.Collectible.DamageItem(byPlayer.Entity.World, byPlayer.Entity, stackInSlot);
}

replacing line 558. It would obviously not be an elegant implementation, but recipes would not need to be changed, including modded recipes. Replacing to tooltip would just be a visual thing that would indeed be a bit harder to do and is not exactly required. However making a special case for the hammer in the tool code is not something I would like to see.

To be entirely honest, the best and simplest way to fix the problem is by modifying the smithing code rather than the item code, like you suggest. However, instead of involving chance and storing data on the hammer, but by having the "entropy counter" stored on the anvil and always changing it by a set amount. So every hit the counter gets decreased by one and the hammer only uses durability when the value reaches 0, which also resets the counter back to a hardcoded value describing how many hits it takes to lose one durability. To avoid exploits, the counter is set to 1 after the anvil has been placed, to always have the first hit cost durability. A similar thing is already in the game when it comes to clay consumption by clayforming where AvailableVoxels is used as the counter.

  • Like 1
Link to comment
Share on other sites

If the anvil counting the hits works, then that is an option too, yeah. I thought it might have to be the work item or the hammer, since those two are directly involved - but you clearly know more about the game's internals than I do.

That solution wouldn't allow for fun things like special hammers for loot. But ultimately, it's about finding a way to separate smithing durability loss from non-smithing durability loss, and that would be achieved. If it's the fastest and least involved way or the developers, might as well go with that!

Link to comment
Share on other sites

Spoiler
23 hours ago, Erik said:

You underestimate the work required to implement your suggestion quite a bit. It would not be terribly hard, but just changing some recipes is always done in a matter of minutes. However, I've looked a bit deeper into it and how the recipes are setup and just changing a number on them isn't possible, because the durability consumption for tools is hardcoded in the api to 1.

For removing durability from Tools, Collectible.DamageItem() is used, which thankfully has an optional argument for the amount of durability to damage an item. The method gets called when Grid-Crafting with a tool by the method Collectible.OnConsumeByCrafting() and in the code for the BEAnvil.OnUseOver() for smithing. A simple solution would just be to add an exception when grid crafting with a hammer by simply adding something like:

if (stackInSlot.Itemstack.Collectible.Tool == EnumTool.Hammer) {
stackInSlot.Itemstack.Collectible.DamageItem(byPlayer.Entity.World, byPlayer.Entity, stackInSlot, 100);
} else {
stackInSlot.Itemstack.Collectible.DamageItem(byPlayer.Entity.World, byPlayer.Entity, stackInSlot);
}

replacing line 558. It would obviously not be an elegant implementation, but recipes would not need to be changed, including modded recipes. Replacing to tooltip would just be a visual thing that would indeed be a bit harder to do and is not exactly required. However making a special case for the hammer in the tool code is not something I would like to see.

To be entirely honest, the best and simplest way to fix the problem is by modifying the smithing code rather than the item code, like you suggest. However, instead of involving chance and storing data on the hammer, but by having the "entropy counter" stored on the anvil and always changing it by a set amount. So every hit the counter gets decreased by one and the hammer only uses durability when the value reaches 0, which also resets the counter back to a hardcoded value describing how many hits it takes to lose one durability. To avoid exploits, the counter is set to 1 after the anvil has been placed, to always have the first hit cost durability. A similar thing is already in the game when it comes to clay consumption by clayforming where AvailableVoxels is used as the counter.

 

This is a fantastic, well thought-out response. Seriously, thankyou for spending the time researching and posting this. I agree that if we did want an entropy-based solution to smithing, then applying the counter to the anvil would probably be the best solution. In theory, this could be gamed (multiple people, using hammers made of a different material for the suspected last hit), but not by any drastic amount, and it is certainly better than other options :) +1

Link to comment
Share on other sites

  • 2 weeks later...

I think a solution that runs alongside the 'cellar' system might work here.  We can create a 'Smithy'.  Inside the 'Smithy' the Blacksmiths metal working tools (Currently just the Hammer) lose durability at reduced rate, also Charcoal burns for longer in the Forges.  The pre-requisites for the 'Smithy' are a minimum of 1 forge, an anvil, Stone floors (Not Cobble), Stone Walls and a roof.

Down the line when Steel becomes a thing can we add a forge that requires bellows (Wooden planks, sticks & Leather) that increases the temperature of the forge in order to melt the steel?

 

Link to comment
Share on other sites

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.