玩家狀態與生存
死亡與重生、維度切換、經驗、能力、出生點,以及床、釣魚和書這幾項生存交互。觀察環境為 BDS 1.26.51.1(protocol 2193)與 bedrock-protocol 3.60.1。
重生握手
- 影響:
bot.respawn()、respawn選項、isAlive、death/respawn/spawn事件。 - Java: 死亡 =
update_health≤ 0;client_command(執行重生)→ 服務器respawn包 →update_health→spawn。 - Bedrock: 死亡 = 玩家自己的
entity_event death_animation+minecraft:health屬性為 0(沒有set_health0),隨後在 死亡位置收到respawnstate 0(搜索中)。重生是一個三步握手:客戶端respawnstate 2(client_ready;若在服務器的 state 0 之前發送,BDS 會忽略)→ 服務器respawnstate 0 + state 1(就緒,眼睛高度的出生位置)→ 客戶端player_action respawn→ 服務器entity_event respawn+set_health 20。重生到另一維度時(在下界死亡、在主世界出生),客戶端 state 2 與服務器 state 1 之間會插入一個不帶 loading_screen_id 的change_dimension;若用serverbound_loading_screen回應它,客戶端會被 斷開(unexpected_packet)。 - bedboo: API 和事件順序與上游相同(
health→death;respawn在服務器的 state 1 時觸發,對應 Java 的 respawn 包; 服務器的生命值更新表明玩家存活後,由生命週期模塊觸發spawn)。bot.respawn()每次死亡只發送一次 state 2(必要時等待服務器的 state 0);respawn: false選項讓機器人停留在死亡界面。對於不帶 loading_screen_id 的change_dimension,生命週期模塊不發送 加載界面確認,並且在重生過程中完成維度切換而不觸發額外的spawn:每次死亡只有一次respawn和一次spawn,跨維度也是如此。 加入時和末地出口的 respawn 包不算死亡。重生到另一維度後spawn時的位置見出生搜索高度。
創造模式玩家不會死亡
- 影響: 對創造模式的機器人使用
/kill(或任何傷害);為已死亡的機器人設置遊戲模式。 - Java:
/kill能殺死創造模式玩家。 - Bedrock: "Players cannot be killed while they are in Creative mode"(
/damage和虛空也不行),並且不能對已死亡的玩家 設置遊戲模式("No targets matched selector")。 - bedboo: 庫中無需修改。殺死機器人之前先把它切換到生存或冒險模式;非默認的遊戲模式(例如冒險)在重生後會保留。
維度切換、末地製作人員名單
- 影響:
bot.game.dimension、維度切換時的respawn/game/spawn事件、末地出口傳送門。 - Java: 一個帶有另一維度的
respawn包(製作人員名單另有game_state_change win_game,用client_command跳過)。 - Bedrock:
change_dimension(/execute in … tp時為腳部位置;經傳送門時是一個無效位置,隨後由move_player重置)→ 客戶端player_action dimension_change_ack→ 服務器dimension_change_ack→ 客戶端帶 loading_screen_id 的serverbound_loading_screen1 / 2。經出口傳送門離開末地:BDS 先發送show_credits {status: 0}(僅在玩家第一次離開末地時), 並一直等待客戶端的show_credits {status: 1}(不等到就永遠不繼續),然後才發送前往主世界的change_dimension(respawn: true)。 - bedboo: 與上游一致:切換時先
game再respawn(isAlive 為 false),新維度加載完成後spawn(isAlive 為 true); 製作人員名單立即跳過(show_creditsstatus 1),與上游的client_command一致。站在portal(下界傳送門,Bedrock 的名字; 生存模式玩家約需 4 s,創造模式約 1.5 s)和end_portal方塊中即可通過傳送門旅行。世界如何重置、適用哪些高度: 見維度。
跨維度切換等待 tick
- 影響: 在循環中用
await bot.waitForTicks(1)走進傳送門的代碼。 - Java: 重生到另一維度期間,物理 tick 仍在繼續。
- Bedrock: 玩家切換維度期間(
change_dimension→ 維度切換確認 →player_spawn;末地出口還會顯示製作人員名單),bedboo 會暫停物理。 - bedboo:
bot.waitForTicks(1)會一直等到切換結束,並在 5 s 後以 "Timeout waiting for 1 ticks" 拒絕,即使機器人已經到達。 走進傳送門時,應等待下一個 tick,或game(維度已切換)、spawn、respawn、death事件中最先發生的一個,並在新維度中通過spawn等待到達(bedboo agent 的util.tick(bot)就是這樣做的,且從不拒絕)。
經驗值
- 影響:
bot.experience.points。 - Java: 服務器發送總經驗值。
- Bedrock: 只有
update_attributes中的minecraft:player.level和minecraft:player.experience(經驗條進度)。 - bedboo: points = 達到當前等級所需的經驗 + 進度 × 下一級所需經驗(Bedrock 與 Java 共用同一條曲線;
/xp 10→ 1 級 + 3/9 → 10 點)。無法區分附魔花掉的經驗。
能力
- 影響:
bot.abilities、abilities事件。 - Java: 加入時以及每次遊戲模式變化時發送帶標誌位的
abilities包。 - Bedrock: 加入時以及權限變化時發送帶能力層的
update_abilities(base、spectator、commands、editor、loading screen: allowed / enabled 集合、飛行 / 行走速度)。執行/gamemode時,客戶端自行推導該遊戲模式的能力;BDS 只在飛行狀態變化時發送update_abilities。BDS 在回應request_ability時,以及在改變飛行狀態的遊戲模式變化之後(飛行中 → 生存,進入 / 離開旁觀), 會發送兩次update_abilities,重複機器人已有的值(在 BDS 1.26.51.1 上測得)。在旁觀模式下,BDS 的能力層會清除mayFly, 而flying仍保持開啟。 - bedboo: 合併各能力層(每層決定它所允許的標誌;後面的層覆蓋前面的層)。遊戲模式變化時,能力按 Java 服務器的
GameType.updatePlayerAbilities設置(創造:mayFly、instantBuild、invulnerable;旁觀:再加 flying,沒有 instantBuild; 生存 / 冒險:無),並像 Java 一樣只觸發一次abilities。沒有任何變化的update_abilities不觸發abilities,並保持bot.abilities對象不變(加入時的第一次總會上報)。bot.abilities是唯一的飛行狀態來源:物理引擎跟隨它,不會回發request_ability(飛行)。
出生點
- 影響:
bot.spawnPoint。 - Java:
spawn_position= 世界出生點(指南針目標),帶真實高度。 - Bedrock:
start_game.spawn_position(世界出生點;高度未確定時 y = 32767:有人在那裡出生時服務器會搜索最高的安全方塊), 以及spawn_type為world(/setworldspawn)或player(床、重生錨、/spawnpoint;Java 從不發送)的set_spawn_position。 - bedboo:
bot.spawnPoint= 世界出生點(來自 start_game,之後是world更新 +game);玩家自己的重生點不會改變它。 32767 的高度會在出生點區塊列加載後解析:見出生搜索高度。
床、睡覺與 spawnReset
- 影響:
bot.sleep、bot.wake、sleep/wake事件、bot.isABed、bot.parseBedMetadata、spawnReset。 - Java: 16 種顏色的床方塊,帶朝向 / 部位 / 佔用狀態;睡覺 = 使用床;
entity_action leave_bed起床;睡眠狀態是玩家的姿態 元數據;game_state_change no_respawn_block_available。 - Bedrock:
- 只有一個
bed方塊(顏色在方塊實體中;另有straw_bed),帶direction(0 南、1 西、2 北、3 東)、head_piece_bit、occupied_bit。名字以 "bed" 結尾的第一個物品是straw_bed,而不是床。 - 睡覺 = 對床進行物品使用
click_block。服務器回應set_entity_data的player_flags第 1 位 +player_bed_position(床頭),用一次correct_player_move_prediction把玩家移到床上(腳在床頂面下方約 0.7,位於床頭方塊中心),並標記床頭的occupied_bit;創造模式玩家也能睡覺。player_action stop_sleeping讓玩家起床(animate wake_up+player_flags0, 並修正到床旁邊)。若沒有人叫醒玩家,BDS 會在 100 tick 後自行結束睡眠(doDaylightCycle開啟時跳過夜晚;時鐘跳到早晨)。 - 用
/setblock放床總是放置整張床:給定位置成為床頭,床尾在其後方(head_piece_bit被忽略;例如/setblock <head> bed ["direction"=0]);移除一半會破壞另一半。 - 當重生用的床 / 重生錨已不存在時,會以
tile.bed.notValid/tile.respawn_anchor.notValid消息通知;若回退位置就是床出生點 本身的位置,則不會有任何通知。
- 只有一個
- bedboo:
isABed匹配bed和*_bed;parseBedMetadata根據 Bedrock 狀態返回與上游相同結構的結果;收到上述消息時觸發spawnReset。sleep()按上游的順序、使用上游的消息執行上游的檢查(時間 / 雷暴、已在睡覺、不是床、已被佔用、半張床、canDigBlock觸及範圍、點擊距離、敵對生物);會等待activateBlock完成(Bedrock 上它是異步的);3 s 後報 'bot is not sleeping'。wake()發送player_action stop_sleeping並立即返回,與上游一致。
剛放下的床是"半張床"
- 影響: 在
bot.placeBlock放下床之後立即調用bot.sleep(bed)。 - Java: 服務器為兩半各發送一次方塊變化;客戶端在能點擊之前就能看到兩半。
- Bedrock: 床尾和床頭作為兩個獨立的
update_block到達(在 BDS 1.26.51.1 上觀察到)。 - bedboo: 在被點擊的格子剛出現床時就調用
bot.sleep(),會以上游的 "there's only half bed" 被拒絕(另一半的bot.isABed仍為 false),一個 tick 之後就可以成功。應等待(≤ 20 tick)兩個格子都是床,並在這種拒絕後再試一次sleep。之後的睡眠行為見 床。
釣魚
- 影響:
bot.fish()。 - Java: 用 use_item 拋竿 / 收竿;浮漂是一個
fishing_bobberspawn_entity;咬鉤表現為浮漂旁邊的 6 個fishing/bubble粒子(world_particles),上游據此檢測。 - Bedrock: 拋竿 / 收竿 = 手持釣竿進行物品使用
click_air。浮漂是add_entity minecraft:fishing_hook,其owner_eid元數據是拋竿者的 unique id。等待期間,魚鉤先發送entity_event fish_hook_tease(附近有魚),然後是帶fish_x/fish_z元數據的fish_hook_position(一條魚游過來,約 1–3 s);咬鉤是魚鉤上的entity_event fish_hook_hook。隨後收竿時,漁獲作為一個 飛向玩家的add_item_entity掉落(通過take_item_entity拾取),外加經驗球,並移除魚鉤(remove_entity)。- 實測等待時間(拋竿 →
fish_hook_hook,開闊水域,用/enchant設置等級):Lure 0 晴天 6.3–32.3 s(均值 20.7,n=10); Lure 0 雨天 6.0–20.9 s(12.1,n=8);Lure III 晴天 2.5–12.7 s(5.9,n=8);Lure III 雨天 1.9–12.2 s(5.7,n=14)。 基礎窗口與 Java 的 100–600 tick(+ 魚游過來的時間)相符,因此fishingBiteDelayMaxTicks: 600(特性表)成立;與 Java 一樣,每級 Lure 縮短約 5 s。 - Bedrock 的
/give不能攜帶附魔,/enchant的 Lure 上限為 III(/give @s fishing_rod+/enchant @s lure 3);BDS 不會把/enchant的結果告訴創造模式玩家。
- 實測等待時間(拋竿 →
- bedboo: 上游的任務邏輯和消息不變;浮漂是
fish()之後機器人擁有的第一個fishing_hook(忽略其他玩家的浮漂;上游會接受任何 浮漂),咬鉤是它上面的fish_hook_hook。與上游一樣,fish()本身沒有時間限制。
書
- 影響:
bot.writeBook、bot.signBook。 - Java:
edit_book { slot, pages[], title? }攜帶整本書,最多 100 頁;頁面是 NBT 字符串(nbt.value.pages.value.value= 頁面文本);服務器回顯被編輯的槽位。 - Bedrock:
- 必須先打開書:對手持的
writable_book進行一次物品使用(click_air)(新書隨後會帶著空的pages列表返回);與該使用在 同一 tick 到達服務器的編輯會被丟棄。 - 編輯逐頁進行:
book_edit { inventory_slot: hotbar slot, type: replace_page | add_page | delete_page | swap_pages, page_number, text, photo_name },署名是book_edit { type: sign, title, author, xuid }。BDS 對編輯不作任何回應;關閉書 (item_release)會讓它重新發送這本書(新的 stack id)。 - 物品 NBT:
pages: [{ text, photoname }](文本要用pages.value.value.map(p => p.text.value)讀取,而不是當作字符串列表); 成書另外帶author、title、xuid(離線時為 '')和generation0。18 個字符的標題會被接受。 - BDS 最多保留 50 頁,其餘的被丟棄。
- 必須先打開書:對手持的
- bedboo: 上游的檢查、消息和槽位處理(書被移到快捷欄槽位 0 並手持,之後恢復手持槽位 / 書所在槽位)。一次編輯是一個會話:
打開 → 若干
book_edit(只發送有變化的頁面,多餘的頁面從末尾刪除)→(sign)→ 釋放,以重新發送的書包含所請求的頁面(或成書) 作為確認;未得到確認的會話會以更長的打開延遲重試一次(總計 20 s,與上游的確認超時相同)。用書本身已有的頁面調用writeBook不會發送任何內容。超過 50 頁會被立即拒絕(too many pages: a Bedrock book holds at most 50 pages),此時尚未移動任何物品; 編輯失敗時仍會恢復手持槽位並把書放回原處。