Skip to main content
Glama

runAway

Escape threats in Minecraft by specifying the threat type, name, and run distance. Integrates with the MCP Server to enable AI-controlled character movement for survival scenarios.

Instructions

Run away from a threat

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
runDistanceNoDistance to run away (default: 20)
targetNameNoOptional: Specific name of the threat
targetTypeYesType of threat: 'player', 'mob', or 'animal'

Implementation Reference

  • The core handler function implementing the 'runAway' tool logic. Detects nearby hostile mobs or specified targets, computes a weighted escape vector, and uses pathfinder to move to a safe distance.
    export const runAway = async ( bot: Bot, params: ISkillParams, serviceParams: ISkillServiceParams, ): Promise<boolean> => { const skillName = 'runAway'; const requiredParams: string[] = []; const isParamsValid = validateSkillParams( params, requiredParams, skillName, ); if (!isParamsValid) { serviceParams.cancelExecution?.(); bot.emit( 'alteraBotEndObservation', `Mistake: You didn't provide all of the required parameters ${requiredParams.join(', ')} for the ${skillName} skill.`, ); return false; } const unpackedParams = { targetType: params.targetType ?? 'mob', targetName: params.targetName ?? '', runDistance: params.runDistance ?? 10, signal: serviceParams.signal, }; let { targetType, targetName, runDistance, signal } = unpackedParams; // Define the radius within which you want to detect mobs const NEARBY_ENTITY_RADIUS = bot.nearbyEntityRadius; const MIN_DISTANCE = 0.01; // Minimum distance to avoid extremely small values targetName = targetName ?? ''; const targetStr = targetName ? targetName : targetType; targetName = targetName.replace(/\s/g, '_'); // Replace spaces in name with _ if (targetType == 'mob') { targetType = 'hostile'; } // Check if entities are available if (!bot.entities) return; const allEntities = Object.values(bot.entities); // Filter function to identify mobs within the specified radius const isNearbyEntity = (entity: Entity) => { return ( entity.position.distanceTo(bot.entity.position) < NEARBY_ENTITY_RADIUS ); }; // Filter for nearby hostile mobs const hostileMobs = allEntities.filter((entity) => { const version = parseInt(bot.version.split('.')[1]); const NBT_HEALTH = version < 10 ? 6 : version < 14 ? 7 : version < 17 ? 8 : 9; if (targetName) { if (targetType === 'player') { const closestPlayer = findClosestPlayerByName(bot, { name: targetName }); return ( isNearbyEntity(entity) && entity.username !== bot.entity.username && entity.username == closestPlayer.username ); } else { return ( isNearbyEntity(entity) && entity.name.toLowerCase() === targetName.toLowerCase() ); } } return ( isNearbyEntity(entity) && entity.type === targetType && entity.metadata[NBT_HEALTH] && entity.username !== bot.entity.username ); }); // Check if there are no hostile mobs if (hostileMobs.length === 0) { return bot.emit( 'alteraBotEndObservation', `There are no ${targetType}s to run away from.`, ); } // Calculate the weighted vector direction to run away const runVector = { x: 0, y: 0, z: 0 }; hostileMobs.forEach((mob) => { const vector = { x: bot.entity.position.x - mob.position.x, y: bot.entity.position.y - mob.position.y, z: bot.entity.position.z - mob.position.z, }; const distance = Math.sqrt(vector.x ** 2 + vector.y ** 2 + vector.z ** 2); const weight = 1 / Math.max(distance, MIN_DISTANCE); // Avoid division by extremely small values runVector.x += vector.x * weight; runVector.y += vector.y * weight; runVector.z += vector.z * weight; }); // Normalize the resulting vector const vectorLength = Math.sqrt( runVector.x ** 2 + runVector.y ** 2 + runVector.z ** 2, ); if (vectorLength > 0) { runVector.x /= vectorLength; runVector.y /= vectorLength; runVector.z /= vectorLength; } // Determine the destination position const runDestination = new Vec3( bot.entity.position.x + runVector.x * runDistance, bot.entity.position.y + runVector.y * runDistance, bot.entity.position.z + runVector.z * runDistance, ); if (bot.pathfinder.isMoving()) await bot.pathfinder.stop(); await bot.waitForTicks(1); // give the pathfinder some time to stop // Make the bot move to the destination position const goal = new GoalXZ(runDestination.x, runDestination.z); // execute a cancelable move to the destination const result = await cancelableMove(bot, { goal, signal }); // check signal 1st if (isSignalAborted(signal)) { return bot.emit( 'alteraBotEndObservation', `You decided to do something else and stop running away.`, ); } if (result.error) { return bot.emit( 'alteraBotEndObservation', `You couldn't finish running away, but did your best.`, ); } // Print out the list of all nearby hostile mobs // const hostileMobNames = hostileMobs.map(entity => entity.name); // const uniqueHostileMobTypes = [...new Set(hostileMobNames)]; // console.log(`Nearby hostile mobs: ${hostileMobNames.join(', ')}`); return bot.emit('alteraBotEndObservation', `You have finished running away!`); };
  • Input schema and metadata definition for the 'runAway' tool used during registration, specifying parameters like targetType (required), targetName, and runDistance.
    runAway: { description: "Run away from a threat", params: { targetType: { type: "string", description: "Type of threat: 'player', 'mob', or 'animal'" }, targetName: { type: "string", description: "Optional: Specific name of the threat" }, runDistance: { type: "number", description: "Distance to run away (default: 20)" } }, required: ["targetType"] },
  • Generic registration logic in loadSkills() that registers all skills including 'runAway' from SKILL_METADATA by creating SkillDefinition objects with schema and dynamic executor.
    for (const [skillName, metadata] of Object.entries(SKILL_METADATA)) { skills.push({ name: skillName, description: metadata.description, inputSchema: { type: "object", properties: metadata.params, required: metadata.required }, execute: createSkillExecutor(skillName) }); } return skills; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/leo4life2/minecraft-mcp-http'

If you have feedback or need assistance with the MCP directory API, please join our Discord server