baritone icon indicating copy to clipboard operation
baritone copied to clipboard

Add clutches

Open Murat65536 opened this issue 6 months ago • 38 comments

Closes #3226 Closes #4548 (duplicate) Closes #92 Closes #2907 Closes #2975 Closes #4146 Closes #1698 Closes #1146 Closes #1018 Closes #3950 (duplicate) Closes #109 (Still can't reproduce. I think this issue is gone now) Closes #28 (Doesn't clutch if there's something like a torch in the way) Closes #2578

Just a few more clutches to Baritone.

  • [x] Ladders
  • [x] Hay Bales (Fall distance should definitely be lower on this one since it only blocks 80% of damage)
  • [x] Powdered snow
  • [x] Twisting vines
  • [x] Vines
  • [x] Slime Blocks (Usually they launch you back up in the air but this can be avoided by holding jump as you hit them)
  • [x] Cobweb (Hard to get out of. Makes me think that falling with different items should have different costs coming with them. Should we think of a way to fall at the edge so we get out faster or is breaking them just easier.)
  • [x] Lava (Check if the player has the right status effect)
  • [x] Scaffolding (Can only be placed on solid blocks and need to crouch while standing on it)
  • [x] Sweet Berries (Can only be placed on grass and dirt varients)
  • [x] Literally any block (It's 1 health point less of fall damage) (Also this could be the difference between taking and not taking fall damage so it's actually pretty useful)
  • [ ] Bed (Worse than Hay bale by 30% and has the different colors that all need to be included) (Also since this is 2 blocks wide you can't place in some orientations. You also need to look in the orientation you place in)
  • [ ] Some blocks with carpets on them (I don't think this applies to all clutchable blocks but some still negate fall damage when there's a carpet on top of them. This includes slime blocks and powdered snow)

~- [ ] Boat (An entity... might be difficult. A good thing about this is that you don't need to be directly under it, you just need the ability to right click on it) (Also has a bunch of variants) (Also has the chest boats)~ ~- [ ] Minecart (A little more complicated since you also need to place a rail if there isn't one already)~ ~- [ ] Horse (Same as boat but we need to check if it's tamed or not since untamed horses require you to have nothing in your hand to mount while tamed horses just don't care)~ ~- [ ] Strider (Would need to check if it has a saddle already on it. If it does, just mount. If it doesn't, check if we have a saddle and if we do, place the saddle then mount)~ ~- [ ] Donkey (Same has horse)~ ~- [ ] Mule (Same as horse)~ ~- [ ] Pig (Same as strider)~ ~- [ ] Items (Picking up a water bucket for example and then placing it)~

I might've missed a few things so let me know if there's anything else. I would say camels but they aren't in 1.19.4.

  • ~With water, we should be checking to make sure we aren't placing on something that wouldn't stop our fall and just waterlog the block. These include leaves, mangrove roots, top slabs, etc.~ -Done
  • ~Also also with ladders and vines, we should be checking if there is a block north, south, east, or west of the ladder or vine being placed since it won't place otherwise.~ -Done
  • ~Should we be adding a setting for every single new clutch? Baritone's settings are already impossible to navigate in-game (we desperately need a UI) so doing this won't exactly help with that issue.~ -No
  • ~If the item to clutch with is in the inventory instead of the hotbar, the bot just acts like it isn't there. Even when allowInventory is on.~ -Fixed
  • If we aren't able to do the clutch on the bottom block, we should still be able to place it off a wall and clutch there.
  • ~Maybe have a setting that breaks the block you clutched on after the clutch is done. Would need to adjust costs for this. This setting should also control picking up with a bucket.~ -New setting not needed since allowBreak
  • ~Even if the block is waterloggable, if we can still be inside that water (ex. half slab), it should be allowed. An even more complicated version of this would be clutching on the parts of stairs that are waterlogged. There would need to be air/other stairs facing the opposite direction/slabs around them so we can lose the 0.5 blocks to hit the water. This is too hard though so I'm not going to bother.~ -Done
  • ~Also I guess if we fall in water that's already there and we have a bucket, we shouldn't try to pick it back up again.~ -Done
  • Not all non-solid blocks are full blocks but the code treats them like they are. This is because it's such a small difference that it doesn't really matter.

Murat65536 avatar Jun 10 '25 15:06 Murat65536

Hey! Maybe I can get to work on a UI? I was working on a swarm feature for Baritone and I think I have a good understanding of the codebase. Or maybe if there are any other features you'd like help with first?

anishalle avatar Jun 11 '25 14:06 anishalle

@ItsAGamer214 If you want to contribute to the repository, open up an issue. From there you can create a draft PR, commit to it, open it for review, and get it merged. A UI isn't in the scope of this specific issue but if you want to make one, feel free to do so. If you want to work on another thing instead, we have like 800 issues open (some are just trolls and others make no sense but there are still good ones that could be worked on).

Murat65536 avatar Jun 11 '25 16:06 Murat65536

I changed the swapped slot from the 8th hotbar slot to the currently selected one but I don't know if this is okay. I guess if it's not we should at least have a setting for which slot to switch to.

Murat65536 avatar Jun 24 '25 20:06 Murat65536

Clutches that don't nullify fall damage only happen when the height multiplied by the percent of fall damage taken is equal to or below maxFallHeightNoClutch.

Murat65536 avatar Jun 27 '25 17:06 Murat65536

I'm going to say that this PR is ready for review even though a lot of the things (mostly entities) are not implemented. I don't really think entity clutches are common enough to be worth so much effort. Maybe some more items will be checked off while I'm waiting for reviews.

Murat65536 avatar Jun 30 '25 09:06 Murat65536

I'm going to need costs for all these or cobwebs are going to ruin everything. @leijurv help how do I calculate costs.

Murat65536 avatar Jul 02 '25 18:07 Murat65536

help how do I calculate costs

Costs are equal to how many ticks it takes to do the action.

You should measure how long it takes to fall through the cobweb, then break the cobweb. that should be the cost.

use the toolset code to calculate how long to break the cobweb given the tools you have

leijurv avatar Jul 04 '25 13:07 leijurv

@leijurv There's a problem with that. Blocks like cobwebs don't exactly set the player's speed. They just have a multiplier that slows them down.

Taken from WebBlock.java

@Override
public void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) {
    entity.makeStuckInBlock(state, new Vec3(0.25, 0.05F, 0.25));
}

So if the player falls from higher, they gain more velocity and fall through the cobweb faster.

But this gets complicated when the player is falling through a midair cobweb, since both the head and feet need to go through and their momentum gets decreased more.

Also with breaking: you break blocks slower when you're not on the ground (which is the case when in a cobweb), so that's not as simple either.

Last thing: right now I'm using command blocks to check how many ticks it takes to go through a cobweb, but this clearly won't work when I need something that resembles a graph. How could I more accurately predict how many ticks something takes?

Murat65536 avatar Jul 05 '25 21:07 Murat65536

It would be nice if Baritone had access transformers (called access wideners in fabric) so I wouldn't need to copy the code from VineBlock for canSupportAtFace. Forge docs: https://docs.minecraftforge.net/en/latest/advanced/accesstransformers/ Fabric docs: https://wiki.fabricmc.net/tutorial:accesswideners NeoForge docs: https://docs.neoforged.net/docs/advanced/accesstransformers/

Murat65536 avatar Jul 17 '25 19:07 Murat65536

@leijurv Looking at the code some more, it turns out that it isn't how it works (at least for cobwebs). I think since velocity is calculated on a tick basis for getting stuck on stuff (right? or maybe even that isn't true. IDK anymore but this page kinda hints at it...), Minecraft just lets you go through the cobweb until the next tick where the velocity updates. When that tick happens, your velocity is reset and you just start drifting towards the ground at 0.05x your normal speed. Except that I just altered my code to do exactly that and it STILL doesn't work... :'(

Murat65536 avatar Jul 19 '25 00:07 Murat65536

@leijurv Here's a few graphs of the formulas: For all of these graphs, the x-axis is the height and the y-axis is the amount of ticks it took. The blue is the predicted fall cost without a cobweb and red is with 1 cobweb at the very end of the fall. 0-1000: swappy-20250718-205850 0-100: swappy-20250718-210031

I never expected cobweb costs to be so chaotic...

Anyway, on to the actually important data: Red is predicted and blue is actual. The annoying thing is that these results follow a general trend which is more or less correct, but it's almost always off. The differences in the graph don't look too significant but those numbers are in the hundreds of ticks, but there is sometimes 2 seconds between what the real value is and what the estimation is. swappy-20250718-212148 It seems significant enough for me to care. Do I just live with it or is there something I'm missing?

Here's the Python code for the graph if you want to look at it for some reason:

import numpy as np  
import matplotlib.pyplot as plt

actual_values = np.array([0, 237, 220, 229, 169, 241, 83, 107, 116, 110, 89, 54, 19, 259, 196, 119, 29, 23, 180, 64])
plt.plot(actual_values)
for i in np.arange(0, 20, 1):
    if i == 0:
        plt.plot(i, 0, '-ro')
        continue
    tmp_dist = i
    tick_count = 0
    while True:
        if tmp_dist < 1:
            fall_dist = 0.08 * 0.05
        else:
            fall_dist = (0.98 ** tick_count - 1) * -3.92
        if tmp_dist <= fall_dist:
            plt.plot(i, tick_count + tmp_dist / fall_dist, '-ro')
            break
        tmp_dist -= fall_dist
        tick_count += 1
plt.show()

Murat65536 avatar Jul 19 '25 01:07 Murat65536

Liquid costs seemed too hard :/.

Murat65536 avatar Jul 20 '25 19:07 Murat65536

Update to formula: I came up with 2 things while trying to sleep at 2 AM and just had to fully wake up and write down everything. Here's the result of that.

if (this.stuckSpeedMultiplier.lengthSqr() > 1.0E-7) {
    pos = pos.multiply(this.stuckSpeedMultiplier);
    this.stuckSpeedMultiplier = Vec3.ZERO;
    this.setDeltaMovement(Vec3.ZERO);
 }

This code in Entity.move does one thing that my original formula doesn't account for. It sets the delta movement after multiplying the position. Which means that the first time a player hits a block like a cobweb or sweet berry bush, it calculates the velocity and multiplies it by stuckSpeedMultiplier AND INCLUDES THE DELTA MOVEMENT. This is because the delta movement is only reset after pos is calculated.

The second thing I forgot is multiplying the velocity when stuck in a block by 0.98. Why this needed to be done is obvious if you go back to the velocity calculation code:

static double velocity(int ticks, double multiplier, double startingVelocity) {
    double velocity = startingVelocity;
    for (int i = 0; i < ticks; i++) {
        velocity = 0.98 * (velocity + 0.08);
    }
    return velocity * multiplier;
}

My previous code was 0.08 * multiplier. But if I'm calculating for 1 tick, I still need to include the 0.98 at the beginning. Fixing this changed the code to 0.98 * 0.08 * multiplier, or 0.0784 * multiplier.

These 2 changes made the cost calculation PERFECT. Just to show how impactful it was, here's a side-by-side comparison of what it used to look like vs what it currently looks like (blue is what it should be, red is what it used to be, and green is what it is): swappy-20250723-094005

Murat65536 avatar Jul 23 '25 13:07 Murat65536

I could probably bring back FALL_N_BLOCKS_COST if I made it a Pair<Double, Double> so it calculated both ticks and velocity. idk @leijurv your call. Also the current implementation doesn't account for resistance ~and slow falling~.

Murat65536 avatar Jul 28 '25 02:07 Murat65536

Also would be really good if there was a way to act like the clutch block was there while doing cost calculations since without this there are issues. For example, clutching with a cobweb and then trying to ascend a block. When you place the cobweb, Baritone already started trying to ascend and it can't since it's stuck.

Murat65536 avatar Jul 29 '25 01:07 Murat65536

The bot sometimes pillars up a few blocks before jumping down. This is a result of the graph above, which shows that falling from higher heights onto a block like cobwebs (the change is more noticeable the more you get slowed) can actually make you pass through that block faster. However, what the bot doesn't account for is getting out of the block. Even if the bot hasn't hit the ground yet, it can still try to get out of the block but the bot doesn't factor this into its calculations.

Murat65536 avatar Aug 12 '25 17:08 Murat65536

The bot might want to decide whether to break the clutch block or just walk off/through it. Implementing this seems hard and costs are annoying (see above) so I might not bother.

Murat65536 avatar Aug 14 '25 18:08 Murat65536

@leijurv A review would be really nice :) (IDK if I want to wrap it up here or add a few more things. School is going to cut down on how much I can contribute drastically. No more 10 hour sessions ig)

Murat65536 avatar Aug 24 '25 00:08 Murat65536

can i see a screen recording?

leijurv avatar Sep 11 '25 02:09 leijurv

https://github.com/user-attachments/assets/459f7d86-76e5-44bc-99be-fa26b7c7b4ff

https://github.com/user-attachments/assets/45894790-722a-4d61-9192-360231da8439

Sorry for low quality. Ran these through a compressor at least twice for them to fit in 10mb limit.

Murat65536 avatar Sep 12 '25 00:09 Murat65536

That looks... alright. It shouldn't recompute the path upon landing though? And maybe I'm being biased by the view snapping, but, the falling looks less controlled than before? Although, it doesn't look like you touched that part of the code...

If you put lava around the column you're falling in, meaning you walk off a ledge and fall through a 1 block column with lava on all 3 sides, does it fall straight through without catching fire? Like if it bounces on a slime block is that bounce controlled enough to not hit the walls?

leijurv avatar Sep 12 '25 01:09 leijurv

It might just be the resolution. I found no issues with it missing the target in any of my testing or even developing.

https://github.com/user-attachments/assets/8f348642-c279-4734-b740-1f2596cef806

Murat65536 avatar Sep 12 '25 01:09 Murat65536

It shouldn't recompute the path upon landing though?

No idea why it's doing that but it isn't something I changed. (I think)

Looking at the video, it only does that once. The only thing I would be able to think of is that it wasn't on the ground when it calculated but that can't be true since I added in a check to prevent that. I guess its current path just didn't work out?

Murat65536 avatar Sep 12 '25 01:09 Murat65536

@leijurv Only other thing I can think of is that the code doesn't like that it's in the twisting vines? I don't know how to check this though. It also doesn't recalculate every time it does a twisting vine clutch so idrk.

Murat65536 avatar Sep 12 '25 20:09 Murat65536

@ZacSharp Does this look good to you?

Murat65536 avatar Sep 13 '25 12:09 Murat65536

@leijurv I can't reproduce the path recalculation anymore, so that might be gone. The bot is still trying to break cobwebs instead of just going through them which is kinda annoying. IDK how to fix that though. Any ideas?

Murat65536 avatar Oct 05 '25 18:10 Murat65536

never mind, it's still there.

Murat65536 avatar Oct 16 '25 15:10 Murat65536

Still being a little weird. I'll work out all the issues soon enough but for now I'll change this to a draft.

Murat65536 avatar Oct 16 '25 21:10 Murat65536

https://github.com/user-attachments/assets/d6213a5e-a514-4c18-9671-686b8cf59b50

I've been stuck on this for a while and honestly have no idea what's going on. Maybe it's correlated to y-level? The bot lands. It sets the MovementStatus to SUCCESS. But it DOES NOT MOVE ON. Why?! Help @leijurv

Murat65536 avatar Nov 02 '25 02:11 Murat65536

After looking a bit more, dest's y pos seems to be 1 above where it should be when this happens. Still trying to fix

Murat65536 avatar Nov 03 '25 21:11 Murat65536