💻 Architecture & Mixins Breakdown (Minecraft 26.3)
📌 Repository Source Disclaimer: The documentation in this Wiki reflects the current source code state in the repository, which may include recent unreleased commits or developmental features ahead of public release builds on CurseForge and Modrinth.
1. Official-Style Infobox
| Property | Technical Details |
|---|---|
| Target Java Package | net.vanillaoutsider.vo_creative_fly_speed |
| Bytecode Target Class | net.minecraft.server.level.ServerPlayer |
| Mixin Class | net.vanillaoutsider.vo_creative_fly_speed.mixin.ServerPlayerMixin |
| Injection Point | public void tick() at @At("HEAD") |
| Mixin Method Prefix | creativeflyspeed$applyFlySpeed |
| Stateless Logic Facade | FlySpeedLogic.applyFlySpeedToPlayer(ServerPlayer) |
| Algorithmic Complexity | $O(1)$ time complexity, $0\text{ bytes}$ heap allocation |
| Mixin Configuration | creative-fly-speed.mixins.json |
2. Step-by-Step Architectural Pipeline
[ Minecraft Server Engine ]
|
| (Runs 20 times per second)
v
[ ServerPlayer.tick() ] <================== INJECTION AT HEAD
|
+---> [ ServerPlayerMixin.creativeflyspeed$applyFlySpeed(CallbackInfo) ]
|
v
[ FlySpeedLogic.applyFlySpeedToPlayer(ServerPlayer) ]
|
+---> 1. Query player.gameMode.getGameModeForPlayer()
|
+---> 2. Query level().getGameRules().get(Rule)
|
+---> 3. Compute targetSpeed = 0.05F * (P / 1000.0F)
|
+---> 4. Compare Math.abs(abilities.getFlyingSpeed() - targetSpeed) > 1e-6F
| |
| +-- False -> Return immediately (0 allocations, 0 packets)
| |
| +-- True -> Mutate abilities.setFlyingSpeed(targetSpeed)
| Invoke player.onUpdateAbilities()
v
[ Normal ServerPlayer Movement Execution ]3. Mathematical Complexity & Performance Analysis
The Mixin Purity Law
ServerPlayerMixin contains strictly zero business logic. It functions as a pure mechanical trampoline delegating directly to FlySpeedLogic.
Algorithmic Complexity: $O(1)$
- Arithmetic Evaluation: The calculation consists of a single floating-point multiplication and division: $$\text{targetSpeed} = 0.05\text{F} \times \left(\frac{P}{1000.0\text{F}\right)$$
- Memory Footprint: Executes using JVM registers (primitive floats and ints) with zero object allocations per tick.
- Early Return Optimization: In steady-state flight (when the GameRule has not changed),
Math.abs(abilities.getFlyingSpeed() - targetSpeed) <= 1e-6Fevaluates to false, resulting in an immediate return with zero side effects.
4. Visual ASCII Class Dependency Diagram
+-------------------------------------------------------------+
| CreativeFlySpeedFabric |
| (Mod Initializer: Triggers static load of GameRules class) |
+-------------------------------------------------------------+
|
v
+-------------------------------------------------------------+
| CreativeFlySpeedRules |
| - CATEGORY: "vo_creative_fly_speed:fly_speed" |
| - CREATIVE_FLY_SPEED: GameRule<Integer> (Default: 1000) |
| - SPECTATOR_FLY_SPEED: GameRule<Integer> (Default: 1000) |
+-------------------------------------------------------------+
^
| (Queries GameRule Keys)
+-------------------------------------------------------------+
| FlySpeedLogic |
| - calculateSpeed(int permille) -> float |
| - applyFlySpeedToPlayer(ServerPlayer player) -> void |
+-------------------------------------------------------------+
^
| (Invoked on @At("HEAD"))
+-------------------------------------------------------------+
| ServerPlayerMixin |
| - Target: net.minecraft.server.level.ServerPlayer.tick() |
+-------------------------------------------------------------+5. Bytecode & Mixin Injection Descriptor Schema
Mixin Definition (ServerPlayerMixin.java)
java
package net.vanillaoutsider.vo_creative_fly_speed.mixin;
import net.minecraft.server.level.ServerPlayer;
import net.vanillaoutsider.vo_creative_fly_speed.FlySpeedLogic;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ServerPlayer.class)
public abstract class ServerPlayerMixin {
@Inject(method = "tick", at = @At("HEAD"))
private void creativeflyspeed$applyFlySpeed(final CallbackInfo ci) {
FlySpeedLogic.applyFlySpeedToPlayer((ServerPlayer) (Object) this);
}
}Mixin Configuration (creative-fly-speed.mixins.json)
json
{
"required": true,
"minVersion": "0.8",
"package": "net.vanillaoutsider.vo_creative_fly_speed.mixin",
"compatibilityLevel": "JAVA_25",
"mixins": [
"ServerPlayerMixin"
],
"injectors": {
"defaultRequire": 1
}
}6. Exhaustive Class & Method Reference Table
| Class Name | Method Signature | Modifiers | Purpose & Mechanics |
|---|---|---|---|
CreativeFlySpeedFabric | void onInitialize() | public | Fabric mod entrypoint. Bootstraps static GameRule class loading. |
CreativeFlySpeedFabricClient | void onInitializeClient() | public | Fabric client entrypoint. |
CreativeFlySpeedRules | <static initializer> | static | Dynamically registers category and rules via DynamicGameRuleManager. |
FlySpeedLogic | float calculateSpeed(int permille) | public static | Pure mathematical scaling helper: $0.05 \times (P / 1000.0)$. |
FlySpeedLogic | void applyFlySpeedToPlayer(ServerPlayer player) | public static | Evaluates player game mode, queries rules, verifies drift guard, and dispatches sync packet. |
ServerPlayerMixin | void creativeflyspeed$applyFlySpeed(CallbackInfo ci) | private | Injection hook at ServerPlayer.tick() @At("HEAD"). |
7. Developer & Addon Extension Hooks
Safe Reflection-Free Facade Usage
Because FlySpeedLogic is a public utility class, other mods within the Fabric runtime can invoke it directly without reflection:
java
import net.vanillaoutsider.vo_creative_fly_speed.FlySpeedLogic;
import net.minecraft.server.level.ServerPlayer;
public class CustomAdminTool {
public static void refreshPlayerFlight(ServerPlayer player) {
FlySpeedLogic.applyFlySpeedToPlayer(player);
}
}