diff --git a/mosfet/bot.py b/mosfet/bot.py index 9e03cdf..ce56d8f 100644 --- a/mosfet/bot.py +++ b/mosfet/bot.py @@ -59,6 +59,23 @@ YAW_ANGLE_REF = vector.Vector3D((0, 1, 0)) YAW_LOOK_AHEAD = 4 +def missing_movement_chunks(g): + """Return chunks needed for local physics and the next path steps only.""" + position = g.get('pos') + if position is None or position is False: + return [(None, None)] + points = [position] + points.extend(g.path[:2]) + required = set() + for point in points: + if hasattr(point, 'x'): + x, z = point.x, point.z + else: + x, z = point[0], point[2] + required.add((floor(x / 16), floor(z / 16))) + return sorted((x, z) for x, z in required + if g.chunks.get_chunk(x, z) is None) + def tick(global_state): g = global_state @@ -66,10 +83,10 @@ def tick(global_state): target = None - # make sure current chunks are loaded for physics - required_distance = getattr(g, 'physics_render_distance', - g.info.render_distance) - if not g.chunks.check_loaded(required_distance): + # Require only chunks touched by local physics and the next path steps. + # A few unrelated holes in the wider view cache must not stall jobs. + missing_chunks = missing_movement_chunks(g) + if missing_chunks: if g.get('movement_status') != 'waiting_for_chunks': print('[movement] status=waiting_for_chunks near {}'.format( utils.pint(p)), flush=True) @@ -80,22 +97,10 @@ def tick(global_state): now = time.time() if now - g.get('chunk_wait_report_at', 0) >= 5: center = g.chunks.center - if center is None: - missing = 'cache center not received' - else: - cx, cz = center - missing = [ - (x, z) - for x in range(cx - required_distance, - cx + required_distance + 1) - for z in range(cz - required_distance, - cz + required_distance + 1) - if (x, z) not in g.chunks.chunks - ] print('\n[movement] chunk wait: pos={}, center={}, ' - 'radius={}, loaded={}, missing={}'.format( - utils.pint(p), center, g.chunks.radius, - len(g.chunks.chunks), missing), flush=True) + 'loaded={}, missing_required={}'.format( + utils.pint(p), g.chunks.center, + len(g.chunks.chunks), missing_chunks), flush=True) g.chunk_wait_report_at = now from minecraft.networking.modern import ( ClientTickEnd, PlayerPositionRotation, @@ -392,9 +397,8 @@ def start_automation(global_state): g.yaw = float(g.get('yaw', 0.0) or 0.0) g.pitch = float(g.get('pitch', 0.0) or 0.0) g.chunks.loading = False - # Local navigation only needs nearby chunks; waiting for the entire view - # radius can stall on servers that stream chunks gradually. - g.physics_render_distance = 2 + # Readiness below is based on the bot's own chunk and the next two path + # steps, never on unrelated holes elsewhere in the view cache. g.movement_paused = False g.movement_status = 'idle' g.movement_error = None @@ -420,7 +424,7 @@ def start_automation(global_state): started = time.monotonic() now = time.monotonic() if not initial_world_ready: - if g.chunks.check_loaded(g.physics_render_distance): + if not bot.missing_movement_chunks(g): if loaded_since is None: loaded_since = now elif now - loaded_since >= 0.5: