dance
Control a bot's movements to make it dance on Minecraft servers using specified duration and optional dance move names for automated in-game actions.
Instructions
Make the bot dance by moving and jumping
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Optional: Name of the dance move | |
| time | No | Duration to dance in seconds (default: 10) |
Implementation Reference
- The core handler function for the 'dance' tool. It validates parameters, checks cooldown using bot.lastDanceTime, performs random dance moves (arm swings, spins, jumps, crouching) in a loop for the specified duration, and emits observations.export const dance = async ( bot: Bot, params: ISkillParams, serviceParams: ISkillServiceParams, ): Promise<boolean> => { const skillName = 'dance'; 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 = { name: params.name ?? null, time: params.time ?? 10, signal: serviceParams.signal, }; const { name, signal } = unpackedParams; const DANCE_INTERVAL = 180000; // 3 minutes // Check if the bot is already dancing const time = Math.min(60, unpackedParams.time); // Ensure time is at most 60 seconds const start = bot.entity.position.clone(); if (bot.lastDanceTime && Date.now() - bot.lastDanceTime < DANCE_INTERVAL) { return bot.emit( 'alteraBotEndObservation', `You've danced recently and are too tired to dance right. You might want to comment on this.`, ); } bot.lastDanceTime = Date.now(); if (name) { // TODO: got to and look at the person were "dancing" with } const moves = [ // async () => { // console.log('Dancing: Walking back and forth with state'); // await bot.setControlState('back', true); // await new Promise(resolve => setTimeout(resolve, 1000)); // await bot.setControlState('forward', true); // await new Promise(resolve => setTimeout(resolve, 1000)); // await bot.setControlState('back', false); // await bot.setControlState('forward', false); // }, // async () => { // console.log('Dancing: Walking back and forth'); // // Walk back and forth x // await walk(bot, start.offset(-1, 0, 0)); // await walk(bot, start.offset(1, 0, 0)); // }, // async () => { // console.log('Dancing: Walking back and forth z'); // // Walk back and forth z // await walk(bot, start.offset(0, 0, -1)); // await walk(bot, start.offset(0, 0, 1)); // }, async () => { console.log('Dancing: Swinging arms'); // Wave hands (look up and down rapidly) for (let i = 0; i < 5; i++) { bot.swingArm(undefined); await bot.look(0, Math.PI / 2, false); bot.swingArm('left'); await bot.look(0, -Math.PI / 2, false); bot.swingArm('right'); bot.swingArm('left'); } await bot.look(0, 0, false); }, async () => { console.log('Dancing: spinning moon walk'); // Spin for (let i = 0; i < 4; i++) { await bot.look((Math.PI / 2) * i, 0, false); await bot.setControlState('back', true); bot.swingArm(undefined); await new Promise((resolve) => setTimeout(resolve, 200)); await bot.setControlState('back', false); bot.swingArm('left'); } }, async () => { console.log('Dancing: turning around'); // Turn around await bot.look(Math.PI, 0, false); }, async () => { // Jump console.log('Dancing: Jumping'); await bot.setControlState('jump', true); await new Promise((resolve) => setTimeout(resolve, 200)); await bot.setControlState('jump', false); }, async () => { // crouch console.log('Dancing: Crouching'); await bot.setControlState('sneak', true); await new Promise((resolve) => setTimeout(resolve, 200)); await bot.setControlState('sneak', false); await new Promise((resolve) => setTimeout(resolve, 300)); await bot.setControlState('sneak', true); await new Promise((resolve) => setTimeout(resolve, 200)); await bot.setControlState('sneak', false); await new Promise((resolve) => setTimeout(resolve, 300)); await bot.setControlState('sneak', true); await new Promise((resolve) => setTimeout(resolve, 200)); await bot.setControlState('sneak', false); }, async () => { // crouch 2 - timing variant console.log('Dancing: Crouching 2'); await bot.setControlState('sneak', true); await new Promise((resolve) => setTimeout(resolve, 300)); await bot.setControlState('sneak', false); await new Promise((resolve) => setTimeout(resolve, 100)); await bot.setControlState('sneak', true); await new Promise((resolve) => setTimeout(resolve, 300)); await bot.setControlState('sneak', false); await new Promise((resolve) => setTimeout(resolve, 100)); await bot.setControlState('sneak', true); await new Promise((resolve) => setTimeout(resolve, 300)); await bot.setControlState('sneak', false); }, ]; let dancing = true; const timer = setTimeout(() => { dancing = false; }, time * 1000); while (dancing) { if (typeof signal !== 'undefined' && signal?.aborted) { return bot.emit( 'alteraBotEndObservation', `You decided to do something else and stopped dancing.`, ); } const randomMove = moves[Math.floor(Math.random() * moves.length)]; await randomMove(); } return bot.emit( 'alteraBotEndObservation', `You finished dancing for ${time} seconds.`, ); };
- Input schema definition for the 'dance' tool, including parameters 'time' and 'name', no required params. Used to create the tool's inputSchema in SkillDefinition.dance: { description: "Make the bot dance by moving and jumping", params: { time: { type: "number", description: "Duration to dance in seconds (default: 10)" }, name: { type: "string", description: "Optional: Name of the dance move" } }, required: []
- mcp-server/src/skillRegistry.ts:350-367 (registration)Function that registers all skills, including 'dance', by creating SkillDefinition objects from SKILL_METADATA and dynamic executors that load the handler from skills/verified/dance.ts.export async function loadSkills(): Promise<SkillDefinition[]> { const skills: SkillDefinition[] = []; 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; }
- mcp-server/src/types.ts:38-38 (helper)Type extension for Bot interface adding lastDanceTime for dance cooldown tracking.lastDanceTime?: number;
- mcp-server/src/types.ts:81-81 (helper)Type extension for BotWithLogger interface adding lastDanceTime.lastDanceTime?: number;