A Fabric implementation of TweakSuite
If you don't already know what TweakSuite does, read its README.
- You write de-obfuscated Yarn or Mojang code.
- You run the
executeGradle task. - TweakFabric compiles, remaps, decompiles, and sends your code to the game.
- Minecraft executes it. During runtime.
- Either build the client-side mod, or download it from the latest release.
- Launch Fabric with the mod installed
- Run the command
/tweakfabric newor clone the template repo to a directory of your choosing. - Write code, hit
executeand watch the magic happen.
On official mappings, classes with identical names in separate directories cannot compile.
Since we are working with Minecraft's client-side internals, we must tiptoe around how we access classes. When we happen to be using official mappings, Minecraft's classes don't have a package structure.
This makes it impossible to import them in a Java file, and thus when we remap our code, we must compile it in the same base package as every other Minecraft class, so it can reference Minecraft's classes.
This is only an issue on mojang's official mappings, because intermediary and yarn have their classes in organized subdirectories. If you want to use subdirectories, go with intermediary or yarn mappings. Usually, use intermediary by default, and on a few clients, you can reconfigure which mappings it should use.
TweakSuite caches the latest entrypoint(s) per-compilation.
With TweakFabric, you can re-run the most recent entrypoint(s),
using the keybind L by default.
This will re-run any code, regardless of safety, so be careful here.
This will attempt to stop TweakSuite's code execution.
You have two options:
- An in-game keybind (
Kby default) - The
killProcessesGradle task
Realistically, you’ll only need this if you get stuck in a while (true) loop.
And while I could tell you not to write infinite loops... let’s be real. They’re fun, and useful for testing.
So, the kill switch exists.
Safe infinite loop examples
Try to write safe infinite loops, like the following:
while (ThreadManager.permits()) {
// this is safe
}
while (true) { // this is also safe
ThreadManager.beg();
}
while (true) { // still safe
ThreadManager.sleepMS(100);
}
while (ThreadManager.sleepSec(1)) {
// safe again
}How it works
-
First, it asks nicely. If your code is merciful enough to use
ThreadManagerin the loop, the thread should honor the kill request. Terms and conditions apply for concurrency. -
Then, it chooses violence. If permit checking isn’t implemented (or was ignored), it escalates to
Thread#stop()orThreadKiller.kill(), depending on your JDK. This is unsafe, but it might work. -
If that still doesn’t work: You’re on your own. I suggest you reflect on your decisions, and then start using
ThreadManager.
Sincerely,
Redot ❤️