[{"data":1,"prerenderedAt":449},["ShallowReactive",2],{"docs-\u002Fplatforms\u002Fvelocity":3},{"id":4,"title":5,"body":6,"description":439,"extension":440,"meta":441,"navTitle":442,"navigation":443,"path":444,"rawbody":445,"seo":446,"stem":447,"__hash__":448},"docs\u002Fplatforms\u002Fvelocity.md","Velocity",{"type":7,"value":8,"toc":427},"minimark",[9,13,21,26,66,69,73,83,87,95,120,124,127,150,154,178,184,208,212,218,384,388,391,397,406,410],[10,11,5],"h1",{"id":12},"velocity",[14,15,16,20],"p",{},[17,18,19],"code",{},"magicutils-velocity"," exposes platform wiring, config, logger, lang, and\ncommand integration in one artifact.",[22,23,25],"h2",{"id":24},"shared-bundle-install","Shared Bundle Install",[14,27,28,29,32,33,37,38,41,42,45,46,49,50,53,54,57,58,61,62,65],{},"If several plugins on the proxy use MagicUtils, install\n",[17,30,31],{},"magicutils-velocity-bundle"," as a ",[34,35,36],"strong",{},"standalone proxy plugin"," instead of shading\nMagicUtils into each one. It is a drop-in ",[17,39,40],{},"magicutils"," plugin that boots one\nshared ",[17,43,44],{},"MagicRuntime"," and registers ",[17,47,48],{},"\u002Fmagicutils"," (alias ",[17,51,52],{},"mu",") with diagnostics\nsub-commands. Downstream plugins declare a dependency on it (via\n",[17,55,56],{},"@Plugin(dependencies = ...)",") and register with the shared runtime through\n",[17,59,60],{},"VelocityMagicUtilsConsumerRegistry",", so ",[17,63,64],{},"\u002Fmagicutils mods"," lists them live. The\npublished bundle jar is a shaded runnable artifact — the same one exercised by\nthe compatibility smoke.",[14,67,68],{},"Do not do both: either embed MagicUtils in your plugin, or depend on the shared\nbundle — not both on the same proxy.",[22,70,72],{"id":71},"dependency","Dependency",[74,75,81],"pre",{"className":76,"code":78,"language":79,"meta":80},[77],"language-kotlin","dependencies {\n    implementation(\"dev.ua.theroer:magicutils-velocity:1.27.1\")\n}\n","kotlin","",[17,82,78],{"__ignoreMap":80},[22,84,86],{"id":85},"recommended-bootstrap","Recommended Bootstrap",[74,88,93],{"className":89,"code":91,"language":92,"meta":80},[90],"language-java","@Plugin(id = \"myplugin\", name = \"MyPlugin\", version = \"1.0.0\")\npublic final class MyPlugin {\n    private final ProxyServer proxy;\n    private final org.slf4j.Logger slf4j;\n    private final Path dataDirectory;\n    private VelocityBootstrap.RuntimeResult magic;\n\n    @Inject\n    public MyPlugin(ProxyServer proxy,\n                    org.slf4j.Logger slf4j,\n                    @DataDirectory Path dataDirectory) {\n        this.proxy = proxy;\n        this.slf4j = slf4j;\n        this.dataDirectory = dataDirectory;\n    }\n\n    @Subscribe\n    public void onProxyInitialize(ProxyInitializeEvent event) {\n        magic = VelocityBootstrap.forPlugin(proxy, this, \"MyPlugin\", dataDirectory)\n                .slf4j(slf4j)\n                .enableCommands()\n                .configureCommands(registry -> registry.registerCommand(new ExampleCommand()))\n                .buildRuntime();\n    }\n\n    @Subscribe\n    public void onProxyShutdown(ProxyShutdownEvent event) {\n        if (magic != null) {\n            magic.runtime().close();\n            magic = null;\n        }\n    }\n}\n","java",[17,94,91],{"__ignoreMap":80},[14,96,97,100,101,104,105,104,108,111,112,115,116,119],{},[17,98,99],{},"VelocityBootstrap"," creates the ",[17,102,103],{},"Platform",", ",[17,106,107],{},"ConfigManager",[17,109,110],{},"LoggerCore",",\n",[17,113,114],{},"LanguageManager",", and optional ",[17,117,118],{},"CommandRegistry"," for the plugin.",[22,121,123],{"id":122},"commands","Commands",[14,125,126],{},"Velocity commands register directly with the proxy command manager.",[128,129,130,138,144],"ul",{},[131,132,133,134,137],"li",{},"Use ",[17,135,136],{},"enableCommands()"," to create the registry during bootstrap.",[131,139,133,140,143],{},[17,141,142],{},"configureCommands(...)"," to register commands right away.",[131,145,133,146,149],{},[17,147,148],{},"asyncExecutor(...)"," when you want to override the default async executor\nused by the command layer.",[22,151,153],{"id":152},"sending-messages-to-a-player","Sending Messages To A Player",[14,155,156,157,164,165,167,168,170,171,174,175,177],{},"Unlike Bukkit\u002FFabric, the Velocity module ships ",[34,158,159,160,163],{},"no ",[17,161,162],{},"Logger"," wrapper"," — the\nbootstrap gives you a ",[17,166,110],{},", not the ",[17,169,162],{}," convenience type. To send a\nMiniMessage-formatted line to a specific command sender, resolve them to a\nMagicUtils ",[17,172,173],{},"Audience"," through the ",[17,176,103],{}," and hand it to the logger:",[74,179,182],{"className":180,"code":181,"language":92,"meta":80},[90],"Platform platform = magic.platform();\nLoggerCore logger = magic.logger();\n\nvoid message(CommandSource source, String miniMessage) {\n    Audience audience = source instanceof Player player\n            ? platform.playerByName(player.getUsername()) \u002F\u002F by username on the proxy\n            : platform.console();\n    if (audience != null) {\n        logger.info().to(audience).send(miniMessage); \u002F\u002F MiniMessage tags render,\n                                                       \u002F\u002F including \u003Cclick>\u002F\u003Chover>\n    }\n}\n",[17,183,181],{"__ignoreMap":80},[14,185,186,189,190,193,194,196,197,200,201,189,204,207],{},[17,187,188],{},"platform.playerByName(...)"," and ",[17,191,192],{},"platform.console()"," are the supported way to\nobtain an ",[17,195,173],{},"; the concrete Velocity audience type is package-private, so\nthere is no ",[17,198,199],{},"new VelocityAudience(...)",". Because the logger formats through\nMiniMessage, ",[17,202,203],{},"\u003Cclick:run_command:'...'>",[17,205,206],{},"\u003Chover:show_text:'...'>"," in the\nmessage become interactive chat components — handy for clickable command menus.",[22,209,211],{"id":210},"bootstrap-options","Bootstrap Options",[14,213,214,217],{},[17,215,216],{},"VelocityBootstrap.Builder"," supports additional configuration beyond the basics:",[219,220,221,234],"table",{},[222,223,224],"thead",{},[225,226,227,231],"tr",{},[228,229,230],"th",{},"Method",[228,232,233],{},"Description",[235,236,237,248,260,270,280,290,300,310,320,330,340,354,364,374],"tbody",{},[225,238,239,245],{},[240,241,242],"td",{},[17,243,244],{},"slf4j(logger)",[240,246,247],{},"Bind SLF4J logger for console output.",[225,249,250,254],{},[240,251,252],{},[17,253,136],{},[240,255,256,257,259],{},"Create a ",[17,258,118],{}," during bootstrap.",[225,261,262,267],{},[240,263,264],{},[17,265,266],{},"permissionPrefix(prefix)",[240,268,269],{},"Set the permission node prefix for commands.",[225,271,272,277],{},[240,273,274],{},[17,275,276],{},"asyncExecutor(executor)",[240,278,279],{},"Override the async executor used by the command layer.",[225,281,282,287],{},[240,283,284],{},[17,285,286],{},"configureCommands(consumer)",[240,288,289],{},"Register commands during bootstrap.",[225,291,292,297],{},[240,293,294],{},[17,295,296],{},"enableDiagnostics()",[240,298,299],{},"Enable the diagnostics service.",[225,301,302,307],{},[240,303,304],{},[17,305,306],{},"configureDiagnostics(consumer)",[240,308,309],{},"Register custom diagnostic checks.",[225,311,312,317],{},[240,313,314],{},[17,315,316],{},"bindClientLocaleSync(boolean)",[240,318,319],{},"Follow each player's client locale.",[225,321,322,327],{},[240,323,324],{},[17,325,326],{},"initLanguage(boolean)",[240,328,329],{},"Enable\u002Fdisable language manager initialization.",[225,331,332,337],{},[240,333,334],{},[17,335,336],{},"bindLoggerLanguage(boolean)",[240,338,339],{},"Bind the language manager to the logger.",[225,341,342,347],{},[240,343,344],{},[17,345,346],{},"setMessagesManager(boolean)",[240,348,349,350,353],{},"Set the global ",[17,351,352],{},"Messages"," language manager.",[225,355,356,361],{},[240,357,358],{},[17,359,360],{},"registerMessages(boolean)",[240,362,363],{},"Register the plugin's messages scope.",[225,365,366,371],{},[240,367,368],{},[17,369,370],{},"addMagicUtilsMessages(boolean)",[240,372,373],{},"Register built-in MagicUtils messages.",[225,375,376,381],{},[240,377,378],{},[17,379,380],{},"translations(consumer)",[240,382,383],{},"Configure additional translations.",[22,385,387],{"id":386},"player-events","Player Events",[14,389,390],{},"Velocity supports the platform-agnostic player lifecycle and message events:",[74,392,395],{"className":393,"code":394,"language":92,"meta":80},[90],"platform.subscribePlayerLifecycle(event -> {\n    if (event.type() == PlayerLifecycleType.JOIN) {\n        logger.info(event.playerName() + \" connected\");\n    }\n});\n",[17,396,394],{"__ignoreMap":80},[14,398,399,400,405],{},"See ",[401,402,404],"a",{"href":403},"core#player-events","Core \u002F Common Logic"," for the full event API.",[22,407,409],{"id":408},"notes","Notes",[128,411,412,418],{},[131,413,414,417],{},[17,415,416],{},"Platform.runOnMain(...)"," executes immediately because Velocity has no main\ngame thread.",[131,419,420,423,424,426],{},[17,421,422],{},"buildRuntime()"," returns a managed ",[17,425,44],{}," and wires shutdown cleanup\nthrough the plugin instance you pass to the platform provider.",{"title":80,"searchDepth":428,"depth":428,"links":429},3,[430,432,433,434,435,436,437,438],{"id":24,"depth":431,"text":25},2,{"id":71,"depth":431,"text":72},{"id":85,"depth":431,"text":86},{"id":122,"depth":431,"text":123},{"id":152,"depth":431,"text":153},{"id":210,"depth":431,"text":211},{"id":386,"depth":431,"text":387},{"id":408,"depth":431,"text":409},"Wire MagicUtils into a Velocity proxy plugin with VelocityBootstrap: config, logger, lang, and command integration in one artifact.","md",{},null,true,"\u002Fplatforms\u002Fvelocity","---\ntitle: Velocity\ndescription: 'Wire MagicUtils into a Velocity proxy plugin with VelocityBootstrap: config, logger, lang, and command integration in one artifact.'\n---\n\n# Velocity\n\n`magicutils-velocity` exposes platform wiring, config, logger, lang, and\ncommand integration in one artifact.\n\n## Shared Bundle Install\n\nIf several plugins on the proxy use MagicUtils, install\n`magicutils-velocity-bundle` as a **standalone proxy plugin** instead of shading\nMagicUtils into each one. It is a drop-in `magicutils` plugin that boots one\nshared `MagicRuntime` and registers `\u002Fmagicutils` (alias `mu`) with diagnostics\nsub-commands. Downstream plugins declare a dependency on it (via\n`@Plugin(dependencies = ...)`) and register with the shared runtime through\n`VelocityMagicUtilsConsumerRegistry`, so `\u002Fmagicutils mods` lists them live. The\npublished bundle jar is a shaded runnable artifact — the same one exercised by\nthe compatibility smoke.\n\nDo not do both: either embed MagicUtils in your plugin, or depend on the shared\nbundle — not both on the same proxy.\n\n## Dependency\n\n```kotlin\ndependencies {\n    implementation(\"dev.ua.theroer:magicutils-velocity:1.27.1\")\n}\n```\n\n## Recommended Bootstrap\n\n```java\n@Plugin(id = \"myplugin\", name = \"MyPlugin\", version = \"1.0.0\")\npublic final class MyPlugin {\n    private final ProxyServer proxy;\n    private final org.slf4j.Logger slf4j;\n    private final Path dataDirectory;\n    private VelocityBootstrap.RuntimeResult magic;\n\n    @Inject\n    public MyPlugin(ProxyServer proxy,\n                    org.slf4j.Logger slf4j,\n                    @DataDirectory Path dataDirectory) {\n        this.proxy = proxy;\n        this.slf4j = slf4j;\n        this.dataDirectory = dataDirectory;\n    }\n\n    @Subscribe\n    public void onProxyInitialize(ProxyInitializeEvent event) {\n        magic = VelocityBootstrap.forPlugin(proxy, this, \"MyPlugin\", dataDirectory)\n                .slf4j(slf4j)\n                .enableCommands()\n                .configureCommands(registry -> registry.registerCommand(new ExampleCommand()))\n                .buildRuntime();\n    }\n\n    @Subscribe\n    public void onProxyShutdown(ProxyShutdownEvent event) {\n        if (magic != null) {\n            magic.runtime().close();\n            magic = null;\n        }\n    }\n}\n```\n\n`VelocityBootstrap` creates the `Platform`, `ConfigManager`, `LoggerCore`,\n`LanguageManager`, and optional `CommandRegistry` for the plugin.\n\n## Commands\n\nVelocity commands register directly with the proxy command manager.\n\n- Use `enableCommands()` to create the registry during bootstrap.\n- Use `configureCommands(...)` to register commands right away.\n- Use `asyncExecutor(...)` when you want to override the default async executor\n  used by the command layer.\n\n## Sending Messages To A Player\n\nUnlike Bukkit\u002FFabric, the Velocity module ships **no `Logger` wrapper** — the\nbootstrap gives you a `LoggerCore`, not the `Logger` convenience type. To send a\nMiniMessage-formatted line to a specific command sender, resolve them to a\nMagicUtils `Audience` through the `Platform` and hand it to the logger:\n\n```java\nPlatform platform = magic.platform();\nLoggerCore logger = magic.logger();\n\nvoid message(CommandSource source, String miniMessage) {\n    Audience audience = source instanceof Player player\n            ? platform.playerByName(player.getUsername()) \u002F\u002F by username on the proxy\n            : platform.console();\n    if (audience != null) {\n        logger.info().to(audience).send(miniMessage); \u002F\u002F MiniMessage tags render,\n                                                       \u002F\u002F including \u003Cclick>\u002F\u003Chover>\n    }\n}\n```\n\n`platform.playerByName(...)` and `platform.console()` are the supported way to\nobtain an `Audience`; the concrete Velocity audience type is package-private, so\nthere is no `new VelocityAudience(...)`. Because the logger formats through\nMiniMessage, `\u003Cclick:run_command:'...'>` and `\u003Chover:show_text:'...'>` in the\nmessage become interactive chat components — handy for clickable command menus.\n\n## Bootstrap Options\n\n`VelocityBootstrap.Builder` supports additional configuration beyond the basics:\n\n| Method | Description |\n| --- | --- |\n| `slf4j(logger)` | Bind SLF4J logger for console output. |\n| `enableCommands()` | Create a `CommandRegistry` during bootstrap. |\n| `permissionPrefix(prefix)` | Set the permission node prefix for commands. |\n| `asyncExecutor(executor)` | Override the async executor used by the command layer. |\n| `configureCommands(consumer)` | Register commands during bootstrap. |\n| `enableDiagnostics()` | Enable the diagnostics service. |\n| `configureDiagnostics(consumer)` | Register custom diagnostic checks. |\n| `bindClientLocaleSync(boolean)` | Follow each player's client locale. |\n| `initLanguage(boolean)` | Enable\u002Fdisable language manager initialization. |\n| `bindLoggerLanguage(boolean)` | Bind the language manager to the logger. |\n| `setMessagesManager(boolean)` | Set the global `Messages` language manager. |\n| `registerMessages(boolean)` | Register the plugin's messages scope. |\n| `addMagicUtilsMessages(boolean)` | Register built-in MagicUtils messages. |\n| `translations(consumer)` | Configure additional translations. |\n\n## Player Events\n\nVelocity supports the platform-agnostic player lifecycle and message events:\n\n```java\nplatform.subscribePlayerLifecycle(event -> {\n    if (event.type() == PlayerLifecycleType.JOIN) {\n        logger.info(event.playerName() + \" connected\");\n    }\n});\n```\n\nSee [Core \u002F Common Logic](core.md#player-events) for the full event API.\n\n## Notes\n\n- `Platform.runOnMain(...)` executes immediately because Velocity has no main\n  game thread.\n- `buildRuntime()` returns a managed `MagicRuntime` and wires shutdown cleanup\n  through the plugin instance you pass to the platform provider.\n",{"title":5,"description":439},"platforms\u002Fvelocity","mPqsghSqjN4iCCSVW8moH0QrhqsOtIt-dTC9ZVeFG9s",1783944485844]