Add bot development guide and protocol 777 reference

This commit is contained in:
Tanner
2026-11-05 15:45:14 +00:00
parent b71774b9aa
commit b89f0f6ed2
2 changed files with 17629 additions and 0 deletions
+67
View File
@@ -0,0 +1,67 @@
# Bot Development Notes
- Target **Minecraft 26.3 / protocol 777 only**. Do not add old-version compatibility.
- Put protocol-777 changes in the main modules; do not create `*_26_3.py` copies.
- Entry point: `python mosfet.py` from this repository root; use `.venv` dependencies.
- Use the editable sibling `../pyCraft` checkout for shared protocol packet support.
- Keep packet IDs and layouts aligned with `PROTOCOL_777.html` and the local 26.3 server; do not infer them from older protocol versions.
- You can test bots on the Minecraft server running locally: `SERVER=127.0.0.1`.
- The local server runs out of `~/tmp/minecraft`. Read `server.properties` for the RCON password.
- Use offline test accounts `mosfet1` and, when an observer is needed, `mosfet2`; read passwords from environment variables, never hard-code them.
- If `python mosfet.py` is already running, feel free to kill the script.
- Stop test bots and confirm no bot process remains afterward.
- Don’t change existing job sequencing/behavior unless the request asks for it; port packet and data handling in place.
- Check README and command gates before assuming a legacy command is available on 26.3.
- Run tests with `.venv/bin/python -m unittest discover -s tests -v`.
- Run a syntax check with `.venv/bin/python -m compileall -q mosfet tests` and `git diff --check`.
- Add regression tests for packet encodings, world-state behavior, and migrated job state transitions.
- If changes span both repositories, commit bot and pyCraft changes separately.
## Theory
- **Runtime flow:** `mosfet.py` owns global state, the dashboard, and hot reload; it calls `mosfet/connect.py` to connect and initialize the 26.3 runtime.
- **Connection setup:** `connect.py` handles offline login/AuthMe and wires the current world, entity, inventory, chat, command, game, and job adapters.
- **Packet-to-state flow:** `../pyCraft/minecraft/networking/modern.py` defines protocol-777 wire packets; `mosfet/protocol/modern.py` and `packets.py` add bot-specific packet classes; `mosfet/protocol/managers.py` updates cached world, entities, and inventory.
- **Tick flow:** `mosfet/bot.py` advances movement/physics, then ticks the active job and game actions. `mosfet/path.py` supplies A* navigation over `mosfet/world.py` and the loaded block-state cache.
- **Commands and jobs:** `mosfet/commands.py` parses chat commands; `mosfet/job.py` selects existing job sequences; each `mosfet/jobs/*.py` module implements a state machine. Keep job sequencing intact unless requested.
- **Game actions:** `mosfet/game.py` sends current-protocol actions such as block breaking, inventory selection, item use, and punches/arm swings.
- **Data:** `mosfet/info/data/26.3/` contains checked-in Minecraft data; `mosfet/info/{blocks,items,mobs,mcdata}.py` exposes it to runtime code. `PROTOCOL_777.html` is the local packet reference.
- **Validation:** `tests/` contains offline regression tests; use the test and compile commands above before committing.
## Live Checks
- For one-off live checks, start `mosfet.py` inside a Python heredoc so the test can inspect `app.g` and shut the bot down cleanly. Run from the repo root, keep `SERVER=127.0.0.1`, and let `GAME_PASSWORD` come from the environment.
```sh
SERVER=127.0.0.1 PLAYER_NAME=mosfet1 .venv/bin/python - <<'PY'
import importlib.util, os, threading, time
spec = importlib.util.spec_from_file_location(
"mosfet_runtime", os.path.abspath("mosfet.py"))
app = importlib.util.module_from_spec(spec)
spec.loader.exec_module(app)
g = app.g
runner = threading.Thread(target=app.main, name="mosfet-test", daemon=True)
runner.start()
try:
deadline = time.monotonic() + 20
while time.monotonic() < deadline:
if g.get("connected") and g.get("pos") and g.chunks.check_loaded(2):
break
time.sleep(0.1)
else:
raise TimeoutError("bot did not finish joining/loading nearby chunks")
print("mosfet1 position:", tuple(g.pos))
g.commands.handle_chat(("CHAT", "test", "tester: 1ping"))
finally:
if g.get("job") and g.get("connection") and g.connection.connected:
g.job.stop()
g.running = False
runner.join(timeout=5)
if runner.is_alive():
raise RuntimeError("bot test thread did not stop")
PY
```
- Give enough time for the bot and world to load.
- Always include the `finally` cleanup.
+17562
View File
File diff suppressed because it is too large Load Diff