Get Started - Learn How To Make Your Bot!GuidesCode SnippetsGet methodsPost methodsWeb APIUseful linksList of all currently Free ItemsList of EmotesHighrise Bot SDK Changelog
Concept
Do you ever wondered how to make your bot follow you? Well, now you can do that with simple commands and this way you can get your own private Butler Bot!
To do that we will use the π¬ Command Handler, note that this use is optional, you can implement this function directly on your main code or directly on your on_chat method.
Methods/Functions used:
Required Libraries
- highrise-bot-sdk
- asyncio
Code
First of all, letβs create a new file called follow.py inside of our functions folder:
Hereβs what we will need to import into our follow.py file:
from highrise import * from highrise.models import * import asyncio
Letβs proceed to our functions definitions, since weβre using the command handler for this example, your function name will be the command that you will use in the chat to call it, I will name mines as follow and stop.
Since we want that the bot continuously follows us, this function has to be an loop and be asynchronously executed. For that, we will be using the buit-in Highrise taskgroup, and we will make a function called following_loop to be inserted in this taskgroup
from highrise import * from highrise.models import * import asyncio async def follow(self: BaseBot, user: User, message: str) -> None: async def following_loop(self: BaseBot, user: User, message: str) -> None: pass pass async def stop(self: BaseBot, user: User, message: str) -> None: pass
Finally, letβs implement the functions and after it you will see a detailed step by step guide on how the code works:
from highrise import * from highrise.models import * import asyncio from asyncio import Task async def follow(self: BaseBot, user: User, message: str) -> None: async def following_loop(self: BaseBot, user: User, message: str) -> None: if message.startswith("/following_loop"): await self.highrise.chat("Invalid command, please use /follow") return while True: #gets the user position room_users = (await self.highrise.get_room_users()).content for room_user, position in room_users: if room_user.id == user.id: user_position = position break print(user_position) if type(user_position) != AnchorPosition: await self.highrise.walk_to(Position(user_position.x + 1, user_position.y, user_position.z)) await asyncio.sleep(0.5) taskgroup = self.highrise.tg task_list = list(taskgroup._tasks) for task in task_list: if task.get_name() == "following_loop": await self.highrise.chat("Already following someone") return #checks if this function is already in the Highrise class tg (task group). taskgroup.create_task(coro=following_loop(self, user, message)) task_list : list[Task] = list(taskgroup._tasks) # Sets the name of the task who has the following_loop function to "following_loop" for task in task_list: if task.get_coro().__name__ == "following_loop": task.set_name("following_loop") await self.highrise.chat(f"Following {user.username}") async def stop(self: BaseBot, user: User, message: str) -> None: taskgroup = self.highrise.tg task_list = list(taskgroup._tasks) for task in task_list: if task.get_name() == "following_loop": task.cancel() await self.highrise.chat(f"Stopping following {user.username}") return await self.highrise.chat("Not following anyone") return
Now letβs understand how the code works:
from highrise import *
andfrom highrise.models import *
:- These lines import the necessary modules and classes required for interacting with the game's API.
async def follow(self: BaseBot, user: User, message: str) -> None:
:- This is an asynchronous function called
follow
. - It takes four parameters:
self
(a reference to the instance of the class this method belongs to),user
(an object representing the user to follow), andmessage
(a string representing the chat message sent by the user).
taskgroup = self.highrise.tg
andtask_list = list(taskgroup._tasks)
:- The code fetches the task group (
tg
) fromself.highrise
and creates a list of tasks (task_list
) in that task group.
for task in task_list: if task.get_name() == "following_loop": await self.highrise.chat("Already following someone") return
:- The code checks if there is already a task named "following_loop" in the task group.
- If such a task is found, it means the bot is already following someone.
- In that case, the function sends a message to the chat using
self.highrise.chat()
to inform the user that the bot is already following someone, and then returns, ending the function.
taskgroup.create_task(coro=following_loop(self, user, message), name="following_loop")
:- If the bot is not already following someone, the code creates a new task named "following_loop" in the task group (
taskgroup
). - It uses
following_loop(self, user, message)
as the coroutine to execute for the task.
await self.highrise.chat(f"Following {user.username}")
:- After creating the "following_loop" task, the function sends a message to the chat using
self.highrise.chat()
to inform the user that the bot is now following the specifieduser
.
async def stop(self: BaseBot, user: User, message: str) -> None:
:- This is an asynchronous function called
stop
. - It takes four parameters:
self
(a reference to the instance of the class this method belongs to),user
(an object representing the user the bot is following), andmessage
(a string representing the chat message sent by the user).
- The
stop
function has similar initial code as thefollow
function to get the task group and task list.
for task in task_list: if task.get_name() == "following_loop": task.cancel() await self.highrise.chat(f"Stopping following {user.username}") return
:- The code checks if there is a task named "following_loop" in the task group (
taskgroup
). - If such a task is found, it means the bot is following someone, and it cancels the task using
task.cancel()
. - The function then sends a message to the chat using
self.highrise.chat()
to inform the user that the bot is stopping following the specifieduser
, and then returns, ending the function.
await self.highrise.chat("Not following anyone") return
:- If the bot is not following anyone (no "following_loop" task found), the function sends a message to the chat to inform the user that the bot is not following anyone, and then returns, ending the function.
async def following_loop(self: BaseBot, user: User, message: str) -> None:
:- This is an asynchronous function called
following_loop
. - It takes four parameters:
self
(a reference to the instance of the class this method belongs to),user
(an object representing the user the bot is following), andmessage
(a string representing the chat message sent by the user).
if message.startswith("/following_loop"): await self.highrise.chat("Invalid command, please use /follow") return
:- The code checks if the
message
starts with "/following_loop". If it does, it means the user entered an invalid command directly for thefollowing_loop
function. - The function sends a message to the chat using
self.highrise.chat()
to inform the user that they should use "/follow" instead of "/following_loop", and then returns, ending the function.
while True:
:- The code enters an infinite loop to keep the bot following the user indefinitely until the task is canceled.
(await self.highrise.get_room_users()).content
:- The code calls an asynchronous method
get_room_users()
onself.highrise
to fetch a list of users in the room where this chat event occurred. - The result is awaited using
await
. - The method seems to return some kind of response object, and
content
appears to be the actual list of room users.
- The code then iterates through the room users and their corresponding positions to find the
user_position
of the specifieduser
.
if type(user_position) != AnchorPosition: await self.highrise.walk_to(Position(user_position.x + 1, user_position.y, user_position.z))
:- The code checks if the
user_position
is not anAnchorPosition
type. - If it is not, it means the user is not anchored (in a fixed position) and can be moved.
- The bot then calls
self.highrise.walk_to(Position(...))
to move the bot to the right of the user by increasing thex
coordinate by 1 (it follows the user from the right side). - The
walk_to
method seems to be used for moving the bot in the game.
await asyncio.sleep(0.5)
:- After following the user, the function awaits for 0.5 seconds using
asyncio.sleep(0.5)
before the next iteration of the loop. - This is to avoid unnecessary CPU load and to give some time between bot movements.