Voyager
Voyager copied to clipboard
First person view is possible, at least with mc_port
In single player open to lan with cheats and survival, use the port for mc_port, once the bot joins. Then run /gamemode spectator
command in in-game text, from the player in single player, then run /spectate bot
command in in-game text.
This should work until the bot leaves and rejoins. Then you just need to rerun the /spectate bot
command. There is definitely a way to automate this with repeating command blocks and chains, but idk enough about command blocks to be able to figure it out right now.
Hi, thanks for pointing out this method! You're right that commands in games can help the player follow the first-person view of the bot. However, we still cannot see the bot's status bar in the game. Also, this needs some human intervention during the learning process. One possible solution could be using a command block to consistently execute the /spectate
command.
@TimeLordRaps @xieleo5 Tks all.When I try to run the code,I can't see the first view.I feel a little nervous.I told myself where's my bot, What's doing the bot in this moment.:)
@go-maple what code, the in-game commands?
The first in-game command: /gamemode spectator
puts your gamemode into spectator, which is just a way to spectate the world, without interacting with it. While in spectator gamemode you can go through walls and other things with standard movement controls.
The secondin-game command: /spectate bot
should immediately transport you into the body of the bot, as long as the bot is on the server and you are in the spectator gamemode.
To see your bot move, you can observe from the default first person perspective or to see from a 3rd person perspective: While inside the bot, or generally, press f5, then pressing f5 again will give a perspective looking straight at the character's face, then f5 for a third time will bring it back to first person perspective. All these things I am talking about occur from within an mc_port of the game. So a single player mc launcher version of the game. I have not experimented at all using the azure login.
To clarify, when the bot leaves the server, you no longer are spectating it, however you remain in spectator gamemode. Once the bot rejoins the server, you need to reuse the second in-game command: /spectate bot
to once again spectate from the bot's perspective(s).
I wrote a script to automate it a bit. It requires the following settings in the minecraft server:
root@mc-voyager:~/mc_server# grep rcon server.properties
broadcast-rcon-to-ops=false
enable-rcon=true
rcon.password=hunter2
rcon.port=25575
Then the following script, updating the variables where relevant. Make sure to pip install mcrcon
before running.
import time
from mcrcon import MCRcon
import math
import re
# Server RCON connection details
rcon_host = "localhost"
rcon_port = 25575
rcon_password = "hunter2"
# Time interval (in seconds) to check for player joining and teleport
check_interval = 0.1
# Dictionary to track the online status of the specified player and bot
spectator_username = "theblazehen"
player_status = {spectator_username: False, "bot": False}
previous_player_status = player_status.copy()
# Distance to move away from bot in the X and Z directions
distance = 3
# Height offset for the specified player above bot
height_offset = 1
def main():
global player_status, previous_player_status
while True:
with MCRcon(rcon_host, rcon_password, rcon_port) as mcr:
response = mcr.command("list")
players_string = response.strip().split(": ")[1]
# Handle the case when there are no players online
if players_string == "":
players_online = []
else:
players_online = players_string.split(", ")
# Update the online status of the specified player and bot
for player in player_status:
player_status[player] = player in players_online
# Check if the online status of either the specified player or bot has changed
if player_status != previous_player_status:
previous_player_status = player_status.copy()
# Check if both the specified player and bot are online
if player_status[spectator_username] and player_status["bot"]:
mcr.command(f"gamemode spectator {spectator_username}")
# Continuously teleport the specified player behind bot and face towards bot's back
if player_status[spectator_username] and player_status["bot"]:
response = mcr.command("data get entity bot Pos")
bot_position = [float(coord) for coord in re.findall(r"[-+]?\d*\.\d+|\d+", response)]
response = mcr.command("data get entity bot Rotation")
bot_rotation = [float(coord) for coord in re.findall(r"[-+]?\d*\.\d+|\d+", response)]
x, y, z = bot_position
yaw = bot_rotation[0]
# Calculate new position for the specified player
x_new = x - distance * math.sin(math.radians(yaw))
z_new = z - distance * math.cos(math.radians(yaw))
# Calculate pitch and yaw to face bot's back
dx, dy, dz = x - x_new, y - (y + height_offset), z - z_new
distance_2d = math.sqrt(dx * dx + dz * dz)
pitch = -math.degrees(math.atan2(dy, distance_2d))
dyaw = math.degrees(math.atan2(dx, dz))
yaw_to_face_bot = (dyaw + 180) % 360
# Teleport the specified player to the new position and face towards bot's back
mcr.command(f"tp {spectator_username} {x_new} {y + height_offset} {z_new} {yaw_to_face_bot} {pitch}")
time.sleep(check_interval)
if __name__ == "__main__":
main()
I wrote a script to automate it a bit. It requires the following settings in the minecraft server:
I haven't tested it yet, but why face the bot's back. Wouldn't you want the exact direction it's facing, and location to emulate "being" the bot, or is your intention to have a solid view of the bot, if so assuming this would run as does what it looks like it would do a pretty good job of it.
I do not know about the library you used, but I assume there's a way maybe to set the inventory and status of the player to the bot? Well, I guess that wouldn't really work for complete recording purposes because spectator mode doesn't show those things. So best case scenario I can imagine is 2 players, 1 used to record hotbar, health, and hunger, and the other recording the first-person view, then somehow having to combine the two recordings. Otherwise, I think you have more or less solved the general recording problem quite well. Unless someone wants to try to implement a solution for first-person with status, I think I'm going to close this.
In single player open to lan with cheats and survival, use the port for mc_port, once the bot joins. Then run
/gamemode spectator
command in in-game text, from the player in single player, then run/spectate bot
command in in-game text.This should work until the bot leaves and rejoins. Then you just need to rerun the
/spectate bot
command. There is definitely a way to automate this with repeating command blocks and chains, but idk enough about command blocks to be able to figure it out right now.
I can see the first person view and hear the sound of the game.
I wrote a script to automate it a bit. It requires the following settings in the minecraft server:
root@mc-voyager:~/mc_server# grep rcon server.properties broadcast-rcon-to-ops=false enable-rcon=true rcon.password=hunter2 rcon.port=25575
Then the following script, updating the variables where relevant. Make sure to
pip install mcrcon
before running.import time from mcrcon import MCRcon import math import re # Server RCON connection details rcon_host = "localhost" rcon_port = 25575 rcon_password = "hunter2" # Time interval (in seconds) to check for player joining and teleport check_interval = 0.1 # Dictionary to track the online status of the specified player and bot spectator_username = "theblazehen" player_status = {spectator_username: False, "bot": False} previous_player_status = player_status.copy() # Distance to move away from bot in the X and Z directions distance = 3 # Height offset for the specified player above bot height_offset = 1 def main(): global player_status, previous_player_status while True: with MCRcon(rcon_host, rcon_password, rcon_port) as mcr: response = mcr.command("list") players_string = response.strip().split(": ")[1] # Handle the case when there are no players online if players_string == "": players_online = [] else: players_online = players_string.split(", ") # Update the online status of the specified player and bot for player in player_status: player_status[player] = player in players_online # Check if the online status of either the specified player or bot has changed if player_status != previous_player_status: previous_player_status = player_status.copy() # Check if both the specified player and bot are online if player_status[spectator_username] and player_status["bot"]: mcr.command(f"gamemode spectator {spectator_username}") # Continuously teleport the specified player behind bot and face towards bot's back if player_status[spectator_username] and player_status["bot"]: response = mcr.command("data get entity bot Pos") bot_position = [float(coord) for coord in re.findall(r"[-+]?\d*\.\d+|\d+", response)] response = mcr.command("data get entity bot Rotation") bot_rotation = [float(coord) for coord in re.findall(r"[-+]?\d*\.\d+|\d+", response)] x, y, z = bot_position yaw = bot_rotation[0] # Calculate new position for the specified player x_new = x - distance * math.sin(math.radians(yaw)) z_new = z - distance * math.cos(math.radians(yaw)) # Calculate pitch and yaw to face bot's back dx, dy, dz = x - x_new, y - (y + height_offset), z - z_new distance_2d = math.sqrt(dx * dx + dz * dz) pitch = -math.degrees(math.atan2(dy, distance_2d)) dyaw = math.degrees(math.atan2(dx, dz)) yaw_to_face_bot = (dyaw + 180) % 360 # Teleport the specified player to the new position and face towards bot's back mcr.command(f"tp {spectator_username} {x_new} {y + height_offset} {z_new} {yaw_to_face_bot} {pitch}") time.sleep(check_interval) if __name__ == "__main__": main()
Cool. Did you manage to run the Voyager code with the MC server?
@theblazehen I tried to run your code by the following steps:
- Install
mcrcon
via pip - Create a folder call
mc_server
in$HOME
. - Add a file called
server.properties
and put the following content into it:
broadcast-rcon-to-ops=false
enable-rcon=true
rcon.password=hunter2
rcon.port=25575
- Run the Python script in the same directory.
But in step 4, I got the following issue:
raceback (most recent call last):
File "/Users/me/mc_server/mc_auto_spectate_bot.py", line 79, in <module>
main()
File "/Users/me/mc_server/mc_auto_spectate_bot.py", line 28, in main
with MCRcon(rcon_host, rcon_password, rcon_port) as mcr:
File "/Users/me/miniconda3/lib/python3.9/site-packages/mcrcon.py", line 57, in __enter__
self.connect()
File "/Users/me/miniconda3/lib/python3.9/site-packages/mcrcon.py", line 77, in connect
self.socket.connect((self.host, self.port))
ConnectionRefusedError: [Errno 61] Connection refused
Do you know why?
@GoingMyWay It requires you to be running a standalone minecraft server. As mentioned in #88 , will be writing the docs for that later today
@GoingMyWay It requires you to be running a standalone minecraft server. As mentioned in #88 , will be writing the docs for that later today
@theblazehen Cool. Thank you. I am looking forward to it.
@theblazehen Hi, thanks for your useful scripts.
After running your mcron script, I continuously get the following info: [15:55:08] [RCON Client /127.0.0.1 #999/INFO]: Thread RCON Client /127.0.0.1 shutting down [15:55:08] [RCON Listener #1/INFO]: Thread RCON Client /127.0.0.1 started
However, the view in my minecraft doesn't move. Do you have any suggestions on it?
Ps: I have a gui, so I just link to the local server in "multiple players".
This issue is stale because it has been open for 30 days with no activity.
This issue was closed because it has been inactive for 14 days since being marked as stale.