Monday, August 30, 2021

What is the Strongest Wall in 41.53? (How the Code Calculates Wall Health)


Edit 2021-09-30:  In 41.55 it looks like they fixed the bug associated with walls, and adjusted the strengths as well.  While the code is almost the same as it was before, some of the numbers have changed.  Maybe I should write another post for the 41.55 version of walls.

With level 10 carpentry, I built 9 different walls from strongest to weakest (left to right).  As you can see, wall strength is a little more complicated than just the material used.  For now, I'm calling it "strength" even though you can also call it "hit points" or "health".

Here are the factors that influence wall strength:

  • Wall Type
  • Character Skill Level
  • Skill Level Required to Construct the Wall
  • Handy Trait (only for log walls)
  • If the Wall Has Been Upgraded
  • Sandbox Option: Player-Built Construction Strength

For the purposes of this entire post, let's assume the Sandbox Options are all set to default.

The strongest wall is:

Level 10 Carpentry.  Metal Frame.  Level 1 wooden wall, upgraded to Level 2, and then to Level 3.  Whether or not you are Handy doesn't matter.

And I think this has been the case since Build 40.  There have been a few changes since Build 40, so assume everything else you read from here on only applies to Build 41 until you get to the Build 40 section at the very end.

The walls in the picture are not all of the walls possible, and they were all built with a level 10 in carpentry and metalworking.  They were also built with the Handy trait, but that only matters with the log wall.  They are listed in order of descending strength:

#2 - Wood Frame.  Level 1 wooden wall, upgraded to Level 2, and then to Level 3.
#3 - Level 1 metal wall upgraded to Level 2
#4 - Level 1 metal wall
#5 - Log Wall
#6 - Level 2 metal wall
#7 - Level 2 wooden wall
#8 - (TIE) Level 1 wooden wall and Level 3 wooden wall 

Yes, if built at the same skill level:
A level 2 wooden wall is stronger than a level 3 wooden wall!
A level 1 metal wall is stronger than a level 2 metal wall!

What is the Strongest Wall I Can Build at My Level of Carpentry?

From level 0 - level 3 carpentry, log walls are the strongest.  Just four logs and some rippedsheets/twine/rope.

Between carpentry level 4 and 6, it depends.  
If you are using metal frames, build the L1 wood wall, and then upgrade it (5 planks, 10 nails).
If you aren't using metal frames and have handy, use the log walls (same 4 logs + binder).
If you aren't using metal frames and don't have handy, build wood walls.

At level 7 carpentry and beyond, the strongest wall is a new level 1 wood wall immediately upgraded to level 2, and then immediately upgraded to level 3 (6 planks, 14 nails).  At level 7, even upgrading only to level 2 is better than a log wall.

If your metalworking level is equal to your carpentry level, a fully upgraded metal wall is stronger until you hit level 9 carpentry.  And remember, at level 10 the fully upgraded wood wall is the strongest.

How Wall Health is Determined in the Code

Let's switch to calling it wall "health" instead of "strength", because that's basically what it is called in the code (calling this post "What is the Healthiest Wall?" sounded bad, so I decided to use "strength" in the introduction instead).

The code for wood (and log) walls starts in ISBuildMenu.lua.  Metal walls are handled in ISBlacksmithMenu.lua.  Metal walls are handled similarly to wood walls in lua, and use the same code when we get to the java, so we'll only look at the wood wall code here.

Once we get past determining the skills and materials required to build the wall, the stats for the wall frame gets set in onWoodenWallFrame:

ISBuildMenu.onWoodenWallFrame = function(worldobjects, sprite, player)
-- sprite, northSprite, corner
    local wall = ISWoodenWall:new(sprite.sprite, sprite.northSprite, sprite.corner, ISBuildMenu.isNailsBoxNeededOpening(2));
    wall.canBarricade = false
    wall.name = "WoodenWallFrame";
    -- set up the required material
    wall.modData["xp:Woodwork"] = 5;
    wall.modData["need:Base.Plank"] = "2";
    wall.modData["need:Base.Nails"] = "2";
    wall.health = 50;
    wall.player = player;
    getCell():setDrag(wall, player);
end

So the frame's health is 50.  

Wall frames are built in ISBuildMenu like a lot of constructions (stairs, crates, rain collectors).  But the actual walls are a little different because they can be upgraded.  You expect a level 3 wall to have more hit points than a level 2 wall (though one of my friends seems to be more concerned about the aesthetic).  They are handled in ISBuildMenu:

ISBuildMenu.onMultiStageBuild = function(worldobjects, stage, item, player)

The definitions of these are in the scripts, in multistagebuild.txt.

Here is the definition of a level 1 wall:

    multistagebuild CreateWoodenWall_1
    {
        PreviousStage:WoodenWallFrame;MetalWallFrame,
        Name:WoodenWallLvl1,
        TimeNeeded:250,
        BonusHealth:400,
        SkillRequired:Woodwork=2,
        ItemsRequired:Base.Plank=2;Base.Nails=4,
        ItemsToKeep:Base.Hammer,
        Sprite:walls_exterior_wooden_01_44,
        NorthSprite:walls_exterior_wooden_01_45,
        CraftingSound:Hammering,
        ID:Create Wooden Wall Lvl 1,
        XP:Woodwork=10,
    }

It's pretty clear what most of the items in this definition means.  BonusHealth is what is important for this discussion.

You can look at multistagebuild.txt if you want to see all the values, but here are the health values for the walls and upgrades:

Bonus Health

Level 1 Wall: 400
Level 2 Wall: 500
Level 3 Wall: 600
Level 1 Metal Wall: 650
Level 2 Metal Wall: 750

Upgrade from L1 Wall to L2 Wall: +100
Upgrade from L1 Wall to L3 Wall: +200
Upgrade from L2 Wall to L3 Wall: +100
Upgrade from L1 Metal Wall to L2 Metal Wall: +100

The code that handles setting the stats of these walls isn't in the lua, it is in the java.  It is in the MultiStageBuilding class.  This is used for both wood and metal walls:

        public void doStage(IsoGameCharacter isoGameCharacter, IsoThumpable isoThumpable, boolean bl) {
            int n = isoThumpable.getHealth();
            int n2 = isoThumpable.getMaxHealth();
            String string = this.sprite;
            if (isoThumpable.north) {
                string = this.northSprite;
            }
            IsoThumpable isoThumpable2 = new IsoThumpable(IsoWorld.instance.getCell(), isoThumpable.square, string, isoThumpable.north, isoThumpable.getTable());
            isoThumpable2.setCanBePlastered(this.canBePlastered);
            if ("doorframe".equals(this.wallType)) {
                isoThumpable2.setIsDoorFrame(true);
                isoThumpable2.setCanPassThrough(true);
                isoThumpable2.setIsThumpable(isoThumpable.isThumpable());
            }
            int n3 = this.bonusHealth;
            switch (SandboxOptions.instance.ConstructionBonusPoints.getValue()) {
            // code edited out by Ed for brevity because we are assuming default values
            }
            Iterator<String> iterator = this.perks.keySet().iterator();
            int n4 = 40;
            switch (SandboxOptions.instance.ConstructionBonusPoints.getValue()) {
            // code edited out by Ed for brevity because we are assuming default values
            }
            while (iterator.hasNext()) {
                String string2 = iterator.next();
                n3 += (isoGameCharacter.getPerkLevel(PerkFactory.Perks.FromString(string2)) - this.perks.get(string2)) * n4;
            }
            isoThumpable2.setMaxHealth(n2 + n3);
            isoThumpable2.setHealth(n + n3);

When you build a level 1 wood wall from a wood frame here are the steps for setting the health:

  • Get the health of the wood frame (this includes any damage taken)
  • Get the maximum health of the wood frame (we know this is 50)
  • Get the Bonus Health value of the level 1 wall (we know this is 400)

Then we look at the "perks" which is basically the skills required to build this wall.  In this case, it is carpentry.  We take the character's level, subtract the carpentry level required to build this wall, multiply that by 40, then add that to the Bonus Health value we had before.  And that number gets added to the original (frame's) health and max health to set the values for the new Level 1 wall.

So this part of the calculation is causing a bug.  A level 10 carpenter has stronger level 2 walls than level 3 walls.

Basically, all that code can be summed up in this formula:

Old Wall (Frame) Health + Bonus Health of New Wall + (40 * (Carpentry Level - Required Level))

L2 Wall: 50 + 500 + (40 * (10 - 4)) = 550 + (40 * 6) = 790

L3 Wall: 50 + 600 + (40 * (10 - 7)) = 650 + (40 * 3) = 770

The difference between the base Bonus Health of a L2 and L3 wall is only 100, and the skill difference between them is 3 (7-4)  and (40 * 3 = 120) so L2 walls are 20 health stronger than L3 walls constructed at the same carpentry level.

When you include upgrading level 1 walls to better walls, this becomes even more pronounced, because you are getting the level multiplier over and over again.

Let's take a look at the difference between creating a level 3 wall and upgrading a level 1 wall to become a level 3 wall, if you are at carpentry level 10 for all of the building and upgrades:

L3 Wall: 50 + 600 + (40 * (10 - 7)) = 650 + 120 = 770
L1 Wall: 50 + 400 + (40 * (10 - 2)) = 450 + 320 = 770
L1 Wall Upgraded to L2 Wall: 770 + 100 + (40 * (10 - 4)) = 870 + 240 = 1110
L2 Wall Upgraded to L3 Wall: 1110 + 100 + (40 * (10 - 7)) = 1210 + 120 = 1330

1330 is quite a bit stronger than 770, at a cost of 2 additional planks and 8 additional nails.

I could argue that, because of the additional materials used, a level 1 wall upgraded to a level 2 wall should be stronger than an original level 2 wall (I don't think it is a strong argument).  Additionally, most people build the best wall they can when they can, so when you want to upgrade your level 1 wall, it is because you built that wall when your carpentry skill was lower.  So you could try arguing this only happens in unrealistic circumstances.

But considering that an unupgraded L2 wall is always stronger than an unupgraded L3 wall with the same carpentry level, it seems evident that the system needs some adjusting.

What About Metal Walls and Log Walls?

Although metal walls get their start in the ISBlacksmithMenu.lua code, they also end up in the MultiStageBuilding class so they have the same problem, with different numbers.  Actually, worse, because you can't build a L2 metal wall until L8 metalworking, while you can build a L1 metal wall at L2 metalworking.  This means that while the Bonus Health difference is still 100, the skill bonus difference amounts to 240, giving a net advantage of 140 health to the L1 metal wall.  At level 10, with a metal frame, the L1 metal wall has 1090 health, while the L2 metal wall has only 950 health.

By the way, metal frames have a health of 120 compared to the wood frame health of 50.  And you can build wood walls over metal frames.  So if you want to strongest wall, start with the strongest frame.

Log walls fall under what appears to be the old system of calculating health.  Much of the code for the old system of constructing wood walls is still there, just unreachable because of comments.  When we want to calculate a log wall's health:

-- return the health of the new wall, it's 200 + 100 per carpentry lvl
function ISWoodenWall:getHealth()
    if self.sprite == "carpentry_02_80" then -- log walls are stronger
	    return 400 + buildUtil.getWoodHealth(self);
    else
        return 200 + buildUtil.getWoodHealth(self);
    end
end

The comment there is in the 41.53 file, and is wrong.

-- give the health of the item, depending on you're carpentry level + if you're a construction worker
buildUtil.getWoodHealth = function(ISItem)
	if not ISItem or not ISItem.player then
		return 100;
	end
	local playerObj = getSpecificPlayer(ISItem.player)
	local health = (playerObj:getPerkLevel(Perks.Woodwork) * 50);
	if playerObj:HasTrait("Handy") then
		health = health + 100;
	end
	return health;
end

We can see here that for the log walls, 50 per carpentry level gets added to the health, with an additional 100 if the character is handy.  So a handy character with level 10 carpentry makes 1000 health log walls.  That's a little better than a L2 metal wall, but not quite as good as a L1 metal wall (at Level 10 metalworking).  At every level, a L2 metal wall is better than a log wall.  If you have handy, a log wall is better than a L2 metal wall, but only if you have handy.

Although handy isn't currently being used to calculate wall health, I'd bet that when they fix the wall health calculations they'll add handy back in.

What About Build 40?

I took a quick look at the Build 40 code.  I'm not sure (because it was a *quick* look), but it is basically the same with these notes:

  • Wooden walls have 200 lower health
  • Metal walls have 200 lower health
  • Log walls have the same health
  • Upgrading metal walls from L1 to L2 gives 420 bonus health, not just 100

This makes metal walls upgraded to L2 much stronger.

Fully upgraded L3 wood walls (completely built at level 10 carpentry) still have more health than log walls, but not by as much.  And unupgraded L2 wood walls are still stronger than unupgraded L3 wood walls.

For Build 40, log walls without handy are strongest until carpentry level 7.  Log walls with handy are strongest until level 8.  At level 9 and 10, fully upgraded wood walls are strongest.

New Mod:  How Strong Is That Wall?


After writing the bulk of this post, I decided to create a mod that allows players to see how much health walls have.  Look at the mod through this link!

Takeaways

Until they fix the system:

  • Never build a level 3 wood wall unless you are upgrading
  • Never build a level 2 metal wall unless you are upgrading

And when they fix the system, it is VERY likely it will only affect walls built from that time forward.  I don't think they'll try having the system modify the walls in your existing saved game.  The health of your existing walls should remain what they were before the fix.  I'll make sure to post and update with the details when it happens.


Thanks for reading!  If you see any mistakes I made, or if you have any questions you'd like me to answer by looking at the code, please let me know!

No comments:

Post a Comment

Do Gloves Protect You From Broken Glass?

Yes, gloves protect you from handling broken glass - any pair of gloves.  But gloves are not needed when removing broken glass from a smashe...