Add bot development guide and protocol 777 reference
This commit is contained in:
@@ -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
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user