|
1 | | -> [!NOTE] |
2 | | -> This project is now being developed by Bookshelf team and has been renamed to Sniffer. Bookshelf has added more features to Sniffer and developed a VSCode plugin! So head over to their repository to stay updated~ |
3 | | -> |
4 | | -> It's worth mentioning that the original author is still actively contributing to Sniffer's development~ |
5 | | -> |
6 | | -> Sniffer: <https://github.com/mcbookshelf/sniffer> |
| 1 | +# Sniffer |
7 | 2 |
|
| 3 | +## Overview |
8 | 4 |
|
9 | | -# Datapack Breakpoint |
| 5 | +Sniffer is a debug adapter for Minecraft datapacks that allows you to debug your `.mcfunction` files directly from Visual Studio Code. It provides features like breakpoints, step execution, and variable inspection to make datapack development easier and more efficient. |
10 | 6 |
|
11 | | -English | [简体中文](README_zh.md) |
| 7 | +## Features |
12 | 8 |
|
13 | | -## Introduce |
| 9 | +- Set breakpoints in `.mcfunction` files |
| 10 | +- Connect to a running Minecraft instance |
| 11 | +- Inspect game state during debugging |
| 12 | +- Step through command execution |
| 13 | +- Path mapping between Minecraft and local files |
| 14 | +- Debug commands started with `#!` |
| 15 | +- Assert command |
| 16 | +- Log command (Much more powerful than `tellraw` or `say`) |
| 17 | +- Hot reload datapack changes |
14 | 18 |
|
15 | | -This is a fabric mod for Minecraft 1.21, which allows you to set breakpoints in the game and "freeze" the game when |
16 | | -the breakpoint is reached. |
| 19 | +## Requirements |
17 | 20 |
|
18 | | -## Usage |
| 21 | +- Minecraft with Fabric Loader |
| 22 | +- Visual Studio Code |
19 | 23 |
|
20 | | -* Set a breakpoint |
21 | 24 |
|
22 | | -In datapack, you can insert `#breakpoint` into .mcfunction file to set a breakpoint. For example: |
| 25 | +<!-- ## Installation |
23 | 26 |
|
24 | | -```mcfunction |
25 | | -#test:test |
| 27 | +### Minecraft Mod Installation |
| 28 | +
|
| 29 | +1. Install [Fabric Loader](https://fabricmc.net/use/) for your Minecraft version |
| 30 | +2. Download the Sniffer mod JAR from the [releases page](https://github.com/mcbookshelf/sniffer/releases) |
| 31 | +3. Place the JAR file in your Minecraft `mods` folder |
| 32 | +4. Launch Minecraft with Fabric |
| 33 | +
|
| 34 | +### VSCode Extension Installation |
| 35 | +
|
| 36 | +1. Open Visual Studio Code |
| 37 | +2. Go to the Extensions view (Ctrl+Shift+X) |
| 38 | +3. Search for "Sniffer" |
| 39 | +4. Click Install --> |
| 40 | + |
| 41 | +## Mod Configuration |
| 42 | +The mod can be configured through the in-game configuration screen, accessible via Mod Menu. |
| 43 | +You can also configure the mod in the `config/sniffer.json` file. |
| 44 | +The following options are available: |
| 45 | + |
| 46 | +### Debug Server Settings |
| 47 | +- **Server Port**: The port number for the debug server (default: 25599) |
| 48 | +- **Server path**: The path to the debug server (default: `/dap`) |
| 49 | + |
| 50 | +## Connecting to Minecraft |
| 51 | + |
| 52 | +1. Open your datapack project in VSCode |
| 53 | +2. Create a `.vscode/launch.json` file with the following configuration: |
| 54 | + |
| 55 | +```json |
| 56 | +{ |
| 57 | + "version": "0.2.0", |
| 58 | + "configurations": [ |
| 59 | + { |
| 60 | + "type": "sniffer", |
| 61 | + "request": "attach", |
| 62 | + "name": "Connect to Minecraft", |
| 63 | + "address": "ws://localhost:25599/dap" |
| 64 | + } |
| 65 | + ] |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +3. Start Minecraft with the Sniffer mod installed |
| 70 | +4. In VSCode, press F5 or click the "Run and Debug" button |
| 71 | +5. Select "Connect to Minecraft" from the dropdown menu |
| 72 | + |
| 73 | +You can now place breakpoints in your `.mcfunction` files and execute it from the game to step through the code. |
| 74 | + |
| 75 | +## Usage in Minecraft |
| 76 | + |
| 77 | +### Breakpoint |
| 78 | + |
| 79 | +The debugger can be controlled directly from Minecraft using the following commands: |
| 80 | + |
| 81 | +- `/breakpoint continue`: Resume execution after hitting a breakpoint |
| 82 | +- `/breakpoint step`: Execute the next command and pause |
| 83 | +- `/breakpoint step_over`: Skip to the next command in the current function |
| 84 | +- `/breakpoint step_out`: Continue execution until the current function returns |
26 | 85 |
|
| 86 | +All commands require operator permissions (level 2) to use. |
| 87 | + |
| 88 | +When execution is paused at a breakpoint, the gametick will be freezed. |
| 89 | + |
| 90 | +### Debug Command |
| 91 | + |
| 92 | +Comment started with `#!` are recognized as debug commands. They will be executed as same as the normal commands in the game but without Sniffer, those debug commands will only be considered as comments. |
| 93 | + |
| 94 | +Sniffer adds some useful commands for datapack developer. By using debug command, you can use those commands in your datapack without worrying about breaking your datapack in vanilla Minecraft. |
| 95 | + |
| 96 | +For example, if you want to place a breakpoint in your function: |
| 97 | + |
| 98 | +```mcfunction |
27 | 99 | say 1 |
28 | 100 | say 2 |
29 | | -#breakpoint |
30 | 101 | say 3 |
| 102 | +
|
| 103 | +#The function will stop at the line with `#!breakpoint` |
| 104 | +#!breakpoint |
31 | 105 | say 4 |
| 106 | +say 5 |
32 | 107 | ``` |
33 | 108 |
|
34 | | -In this case, after the game executes `say 2`, the game will be "frozen" because it meets the breakpoint. |
| 109 | +Also you can execute normal commands in debug command line: |
35 | 110 |
|
36 | | -When the game is "frozen", you can still move around, do whatever you want, just like execute the command `tick freeze`. |
37 | | -So you can check the game state, or do some debugging. |
38 | | - |
39 | | -* Step |
| 111 | +```mcfunction |
| 112 | +say 1 |
| 113 | +say 2 |
| 114 | +say 3 |
40 | 115 |
|
41 | | -When the game is "frozen", you can use the command `/breakpoint step` to execute the next command. In above example, |
42 | | -after the game meets the breakpoint, you can use `/breakpoint step` to execute `say 3`, and then use `/breakpoint step` |
43 | | -to execute `say 4`. When all commands are executed, the game will be unfrozen and continue running. |
| 116 | +#!execute if score @s test matches 1..10 run breakpoint |
| 117 | +say 4 |
| 118 | +say 5 |
| 119 | +``` |
44 | 120 |
|
45 | | -* Continue |
| 121 | +This breakpoint will only be triggerred when the score of the executor in test object is between 1 and 10. |
46 | 122 |
|
47 | | -When the game is "frozen", you can use the command `/breakpoint move` to unfreeze the game and continue running. |
| 123 | +### Assert |
48 | 124 |
|
49 | | -* Get Macro Arguments |
| 125 | +Assert command is used to check if a condition is true. If the condition is false, the mod will print an error message to the game chat. |
50 | 126 |
|
51 | | -By using `/breakpoint get <key>`, you can get the value of the macro argument if the game is executing a macro function. |
52 | | -For example: |
| 127 | +Syntax: `assert <expr>` |
53 | 128 |
|
54 | 129 | ```mcfunction |
55 | | -#test:test_macro |
| 130 | +say 1 |
| 131 | +say 2 |
| 132 | +say 3 |
56 | 133 |
|
57 | | -say start |
58 | | -#breakpoint |
59 | | -$say $(msg) |
60 | | -say end |
| 134 | +#!assert {(score @s test ) <= 10} |
| 135 | +say 4 |
| 136 | +say 5 |
61 | 137 | ``` |
62 | 138 |
|
63 | | -After executing `function test:test_macro {"msg":"test"}`, we passed the value `test` to the macro argument `msg` and |
64 | | -then the game will pause before `$say $(msg)`. At this time, you can use `/breakpoint get msg` to get the value `test`. |
| 139 | +This assert command will check if the score of the executor in test object is less than or equal to 10. |
65 | 140 |
|
66 | | -* Get Function Stack |
| 141 | +#### Expression Argument |
67 | 142 |
|
68 | | -By using `/breakpoint stack`, you can get the function stack of the current game. For example, if we have following two |
69 | | -functions: |
| 143 | +In sniffer command, you can use complex expression as command argument. Normally, an expression is surrounded by curly braces `{}`. Within an expression, you may obtain a value from an argument enclosed in parentheses and employ it in the expression’s evaluation. |
70 | 144 |
|
71 | | -```mcfunction |
72 | | -#test:test1 |
| 145 | +Supported expression arguments: |
| 146 | +- `score <score_holder> <objective>`: The same as `execute if score`. Returns an int value. |
| 147 | +- `data entity <entity>/storage <id>/block <pos> path`: The same as `execute if data`. Returns a nbt value. |
| 148 | +- `name <entity>`: return a text components with all names of the entities. |
| 149 | + |
| 150 | +> [!WARNING] |
| 151 | +> Owing to inherent limitations in the command-parsing system, the closing parenthesis of an expression argument must be preceded by at least one space |
| 152 | +
|
| 153 | +Supported operators: |
| 154 | +- `+`, `-`, `*`, `/`, `%`: Arithmetic operators |
| 155 | +- `==`, `!=`, `<`, `<=`, `>`, `>=`: Comparison operators |
| 156 | +- `&&`, `||`, `!`: Logical operators |
| 157 | +- `is`: Check if a value is a certain type. Returns a boolean value. Available types: `nbt`, `text`, `string`, `number`, `byte`, `short`, `int`, `long`, `float`, `double`, `int_array`, `long_array`,` byte_array`, `list`, `compound`, ` |
| 158 | + |
| 159 | +> [!Note] |
| 160 | +> No operator possesses intrinsic precedence; expressions are evaluated strictly from left to right. By nesting subexpressions, however, you can enforce prioritized evaluation |
73 | 161 |
|
| 162 | +### Log |
| 163 | + |
| 164 | +Log command is used to print a message to the game chat. The log message can contain expression arguments. |
| 165 | + |
| 166 | +Syntax: `log <log>` |
| 167 | + |
| 168 | +```mcfunction |
74 | 169 | say 1 |
75 | | -function test:test2 |
76 | 170 | say 2 |
| 171 | +say 3 |
77 | 172 |
|
78 | | -#test: test2 |
79 | | -say A |
80 | | -#breakpoint |
81 | | -say B |
| 173 | +#!log The score of @s in test objective is {(score @s test )} |
| 174 | +say 4 |
| 175 | +say 5 |
82 | 176 | ``` |
83 | 177 |
|
84 | | -When the game pauses at the breakpoint, you can use `/breakpoint stack` and the function stack will be printed in the |
85 | | -chat screen: |
| 178 | +This log command will print `The score of @s in test objective is 10` to the game chat. |
| 179 | + |
| 180 | +### Hot reload |
| 181 | + |
| 182 | +Sniffer can watch the changes of the datapack files (only `*.mcfunction` files currently) and reload them automatically. Hot reloading will not reload all resources, as it will only reload the function that is changed. It will not trigger functions with `#minecraft:load` tag too. In large-scale datapack projects, or if you installed kubejs mod, hot reloading can markedly mitigate unnecessary reload-induced pauses and stuttering. |
86 | 183 |
|
| 184 | +Hot reloading will watch any changes, create or delete of the datapack files. |
| 185 | + |
| 186 | +Hot reloading is not enabled by default. You must use the `watch start` command to start watching a datapack. Each time you re-enter the world, the watcher must be reestablished. After making any changes in the datapack, you can use the `watch reload` command to trigger hot reloading and apply changes in your datapack. A message will be sent to the game chat to tell you what changes have been actually applied. |
| 187 | + |
| 188 | +If the command parser encounters any error while parsing a function, the changes in the function will not apply, and a message will be sent to the game chat to tell you the error. |
| 189 | + |
| 190 | +Command Syntax: |
| 191 | + |
| 192 | +- `watch start <Datapack Folder Name>`: Start watching a datapack folder. |
| 193 | +- `watch stop <Datapack Folder Name>`: Stop watching a datapack folder. |
| 194 | +- `watch reload`: Trigger the hot loading to apply changes. |
| 195 | +- `watch auto [true|false]`: Set whether auto reloading is enabled. Auto reloading will apply any change once the watcher detects it. Default is `false`. If value is not provided, it will tell you if the auto reloading is enabled. |
| 196 | + |
| 197 | +## Development |
| 198 | + |
| 199 | +### Project Structure |
| 200 | + |
| 201 | +- `src/main`: Main mod code for Minecraft |
| 202 | +- `src/client`: Client-side mod code |
| 203 | +- `vscode`: VSCode extension source code |
| 204 | + |
| 205 | +### Building the Project |
| 206 | + |
| 207 | +To build the Minecraft mod: |
| 208 | + |
| 209 | +```bash |
| 210 | +./gradlew build |
87 | 211 | ``` |
88 | | -test:test2 |
89 | | -test:test |
90 | 212 |
|
| 213 | +To build the VSCode extension: |
| 214 | + |
| 215 | +```bash |
| 216 | +cd vscode |
| 217 | +npm install |
| 218 | +npm run build |
91 | 219 | ``` |
92 | 220 |
|
93 | | -* Run command in current context |
| 221 | +## License |
| 222 | + |
| 223 | +This project is licensed under the MPL-2.0 License - see the [LICENSE](LICENSE) file for details. |
| 224 | + |
| 225 | +## Contributing |
| 226 | + |
| 227 | +Contributions are welcome! Please feel free to submit a Pull Request. |
| 228 | + |
| 229 | +## Acknowledgements |
94 | 230 |
|
95 | | -By using `/breakpoint run <command>`, you can run any command in the current context, just like `execute ... run ...`. |
| 231 | +- [Fabric](https://fabricmc.net/) - Mod loader for Minecraft |
| 232 | +- [VSCode Debug Adapter](https://code.visualstudio.com/api/extension-guides/debugger-extension) - VSCode debugging API |
| 233 | +- [Datapack Debugger](https://github.com/Alumopper/Datapack-Debugger/) by [Alumopper](https://github.com/Alumopper) - Original implementation of the debugger, without the DAP layer |
0 commit comments