<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.traincarts.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=RyanDo</id>
	<title>BergerHealer Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.traincarts.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=RyanDo"/>
	<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/p/Special:Contributions/RyanDo"/>
	<updated>2026-04-05T05:13:50Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.13</generator>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=Main_Page/zh-cn&amp;diff=7929</id>
		<title>Main Page/zh-cn</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=Main_Page/zh-cn&amp;diff=7929"/>
		<updated>2025-10-12T10:10:30Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;欢迎&#039;&#039;&#039;来到维基百科！&lt;br /&gt;
&lt;br /&gt;
== 快捷链接 ==&lt;br /&gt;
[[Special:MyLanguage/BKCommonLib|BKCommonLib]] • [[Special:MyLanguage/TrainCarts|TrainCarts]] • [[Special:MyLanguage/TC-Coasters|TC-Coasters]] • [[Special:MyLanguage/MyWorlds|MyWorlds]] &lt;br /&gt;
• [[Special:MyLanguage/SignLink|SignLink]] • [[Special:MyLanguage/Maplands|Maplands]] • [[Special:MyLanguage/Light-Cleaner|Light Cleaner]]&lt;br /&gt;
&lt;br /&gt;
== BKCommonLib ==&lt;br /&gt;
该运行库共享各种插件所需的所有通用代码，将它们一起放在库中可以大大减少重复代码量。插件各个都别具一格、富有特色，每当 Spigot 缺少某些功能时，该功能就会被收录进 BKCommonLib 里，这就是为什么这个库会变得如此庞大的原因之一：Spigot 不提供（也不想提供）的功能实在太多了。&lt;br /&gt;
&lt;br /&gt;
BKCommonLib 以每个插件为基础进行版本控制，因此当某个插件需要版本 2，并且安装了版本 1 时，会自动向服务器管理员发送通知，并且不启用这个插件。这可以防止因 BKCommonLib 版本过时而导致的各种问题。如果你想开发基于 BKCommonLib 的插件，请确保你是基于仍能提供你所需的功能的最早版本，这样你的插件才可以在较旧的 Spigot 版本上正常运行。&lt;br /&gt;
&lt;br /&gt;
除了程序和服务以外，这个库还提供了各种反射和对用户友好的方法来访问 net.minecraft.server。如果你的插件需要使用内部组件，但不想冒险修改字段和方法名称，可以让内部组件依赖 BKCommonLib，这允许你自保持 CraftBukkit 版本之间的兼容性，并减少静默问题的产生。&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/BKCommonLib|点击前往 BKCommonLib 百科。]]&lt;br /&gt;
&lt;br /&gt;
== TrainCarts ==&lt;br /&gt;
该插件会寻找矿车并尽可能将它们连接在一起。当两辆矿车&#039;&#039;连接&#039;&#039;在一起时，会组成一列车。&lt;br /&gt;
&lt;br /&gt;
一旦矿车成功连接，就会产生效果。整体速度会与其中的每个矿车的状态进行共享，保持稳定的矿车间隙。矿车间隙是可配置的，且拉伸间隙的力度也是可配置的。&lt;br /&gt;
&lt;br /&gt;
最终产物：一列火车！你可以移动它，把它做成过山车，也可以把它分成两半，看着列车相撞，你想怎么做都可以！q(≧▽≦q)~&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/TrainCarts|点击前往 TrainCarts 百科。]]&lt;br /&gt;
&lt;br /&gt;
== TC-Coasters ==&lt;br /&gt;
TC 附属插件，为 TC 添加隐形轨道。该插件可以让矿车在任何地方移动或飞行，隐形轨道还能与其他类型的轨道连接。配合附件修改矿车的样式，比如飞机、巴士等，通过隐形轨道创建飞行航线和客运路线等。你能通过交互式编辑对隐形轨道进行高度的自定义，不需要任何外部工具和编程知识。&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/TC-Coasters|点击前往 TC-Coasters 百科。]]&lt;br /&gt;
&lt;br /&gt;
== MyWorlds ==&lt;br /&gt;
该插件包含与世界相关的一切内容。&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/MyWorlds|点击前往 MyWorlds 百科。]]&lt;br /&gt;
&lt;br /&gt;
== SignLink ==&lt;br /&gt;
为 TC 和告示牌之间搭建桥梁，可轻松在告示牌上显示文本。&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/SignLink|点击前往 SignLink 百科。]]&lt;br /&gt;
&lt;br /&gt;
== Maplands ==&lt;br /&gt;
Maplands 是一个正在开发中的项目，旨在为 Minecraft 地图提供世界地图渲染。以等距视图显示世界，将地图链接在一起并创建一个大型的服务器世界总览，还有更多值得期待的功能正在开发中！&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/Maplands|点击前往 Maplands 百科。]]&lt;br /&gt;
&lt;br /&gt;
==Light Cleaner==&lt;br /&gt;
该插件会在玩家附近或整个世界范围内轻量级的重新生成区块。&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/Light-Cleaner|点击前往 Light Cleaner 百科。]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
主页有百科管理员维护。如果你对此页面有任何建议，请通过 Discord 联系管理员！&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=Translations:Main_Page/46/zh-cn&amp;diff=7928</id>
		<title>Translations:Main Page/46/zh-cn</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=Translations:Main_Page/46/zh-cn&amp;diff=7928"/>
		<updated>2025-10-12T10:10:21Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 快捷链接 ==&lt;br /&gt;
[[Special:MyLanguage/BKCommonLib|BKCommonLib]] • [[Special:MyLanguage/TrainCarts|TrainCarts]] • [[Special:MyLanguage/TC-Coasters|TC-Coasters]] • [[Special:MyLanguage/MyWorlds|MyWorlds]] &lt;br /&gt;
• [[Special:MyLanguage/SignLink|SignLink]] • [[Special:MyLanguage/Maplands|Maplands]] • [[Special:MyLanguage/Light-Cleaner|Light Cleaner]]&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=Main_Page/zh&amp;diff=7927</id>
		<title>Main Page/zh</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=Main_Page/zh&amp;diff=7927"/>
		<updated>2025-10-12T10:10:14Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt;&lt;br /&gt;
欢迎来到&#039;&#039;&#039;维基百科&#039;&#039;&#039;！&lt;br /&gt;
&lt;br /&gt;
== 快捷链接 ==&lt;br /&gt;
[[Special:MyLanguage/BKCommonLib|BKCommonLib]] • [[Special:MyLanguage/TrainCarts|TrainCarts]] • [[Special:MyLanguage/TC-Coasters|TC-Coasters]] • [[Special:MyLanguage/MyWorlds|MyWorlds]] &lt;br /&gt;
• [[Special:MyLanguage/SignLink|SignLink]] • [[Special:MyLanguage/Maplands|Maplands]] • [[Special:MyLanguage/Light-Cleaner|Light Cleaner]]&lt;br /&gt;
&lt;br /&gt;
== BKCommonLib ==&lt;br /&gt;
该工具库共享了各种插件所需的所有通用代码，将它们放在一个库中大大减少了重复代码的数量。特色工具种类繁多，每当Spigot中缺少某些功能时，它都会在BKCommonLib中添加。这就是它变得如此庞大的原因之一：Spigot中确实有很多东西（不打算）提供。&lt;br /&gt;
&lt;br /&gt;
BKCommonLib以每个插件为基础进行版本管理，因此当某个插件需要版本2，而安装的是版本1时，会自动向服务器管理员发送通知，同时禁用这个插件。这可以避免因BKCommonLib版本过时而引发的常见问题。如果你正在开发基于BKCommonLib的插件，请确保你依赖的是最早仍能提供你所需要功能的版本。这可以确保你的插件在较老的Spigot构建中仍能正常工作。&lt;br /&gt;
&lt;br /&gt;
除了程序和服务以外，该库还提供了各种反射和对用户友好的方法来访问net.minecraft.server。如果你的插件需要使用内部组件，但不想冒险修改字段和方法名称，可以让内部组件依赖BKCommonLib，这允许你自保持CraftBukkit版本之间的兼容性，并减少静默问题的产生。&lt;br /&gt;
&lt;br /&gt;
除了工具和服务之外，这个库还提供了多种反射和用户友好的方式来访问net.minecraft.server。如果你的插件需要使用内部组件，但你又不想冒改变字段和方法名称的风险，你可以依赖BKCommonLib来为你提供这些功能。这样，你就能够在CraftBukkit版本之间自动保持兼容性，并减少了静默失败的隐患。&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/BKCommonLib|点击前往BKCommonLib百科。]]&lt;br /&gt;
&lt;br /&gt;
== TrainCarts ==&lt;br /&gt;
该插件会寻找矿车并尽可能将它们连接在一起。当两辆矿车&#039;&#039;连接&#039;&#039;在一起时，会组成为一条列车。&lt;br /&gt;
&lt;br /&gt;
一旦矿车成功连接，就会产生效果。整体速度会与其中的每个矿车的状态进行共享，保持稳定的矿车间隙。矿车间隙是可配置的，且拉伸间隙的力度也是可配置的。&lt;br /&gt;
&lt;br /&gt;
最终产物：一列火车！你可以移动它，把它当作过山车，也可以把它分成两半，看看列车的相撞，你想怎么做都可以！q(≧▽≦q)~&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/TrainCarts|点击前往TrainCarts百科。]]&lt;br /&gt;
&lt;br /&gt;
== TC-Coasters ==&lt;br /&gt;
TC的附属插件，为TC添加隐形轨道。现在你可以让列车在任意位置移动或飞行，在轨道上滚动并与其他类型的轨道连接。自定义轨道可以通过交互的方式进行编辑，无需外部工具或脚本知识。&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/TC-Coasters|点击前往TC-Coasters百科。]]&lt;br /&gt;
&lt;br /&gt;
== MyWorlds ==&lt;br /&gt;
该插件包含与世界相关的一切内容。&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/MyWorlds|点击前往MyWorlds百科。]]&lt;br /&gt;
&lt;br /&gt;
== SignLink ==&lt;br /&gt;
插件与告示牌之间的桥梁，可轻松在告示牌上显示文本。&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/SignLink|点击前往SignLink百科。]]&lt;br /&gt;
&lt;br /&gt;
== Maplands ==&lt;br /&gt;
Maplands是一个正在开发中的项目，旨在为Minecraft地图提供世界地图渲染功能。以等距视图显示世界，将地图连接在一起并创建为一个大型的服务器世界总览，还有更多值得期待的功能正在开发中！&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/Maplands|点击前往Maplands百科。]]&lt;br /&gt;
&lt;br /&gt;
== Light Cleaner ==&lt;br /&gt;
该插件会在玩家附近或整个世界范围内轻量级的重新生成区块。&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/Light-Cleaner|点击前往Light Cleaner百科。]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
主页由管理员进行维护。如果你对此页面有任何建议，请通过Discord联系管理员！&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=Translations:Main_Page/46/zh&amp;diff=7926</id>
		<title>Translations:Main Page/46/zh</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=Translations:Main_Page/46/zh&amp;diff=7926"/>
		<updated>2025-10-12T10:10:07Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 快捷链接 ==&lt;br /&gt;
[[Special:MyLanguage/BKCommonLib|BKCommonLib]] • [[Special:MyLanguage/TrainCarts|TrainCarts]] • [[Special:MyLanguage/TC-Coasters|TC-Coasters]] • [[Special:MyLanguage/MyWorlds|MyWorlds]] &lt;br /&gt;
• [[Special:MyLanguage/SignLink|SignLink]] • [[Special:MyLanguage/Maplands|Maplands]] • [[Special:MyLanguage/Light-Cleaner|Light Cleaner]]&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=Main_Page/de&amp;diff=7925</id>
		<title>Main Page/de</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=Main_Page/de&amp;diff=7925"/>
		<updated>2025-10-12T10:09:27Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Willkommen&#039;&#039;&#039; im Wiki!&lt;br /&gt;
&lt;br /&gt;
==Schnelle Navigation==&lt;br /&gt;
[[Special:MyLanguage/BKCommonLib|BKCommonLib]] • [[Special:MyLanguage/TrainCarts|TrainCarts]] • [[Special:MyLanguage/TC-Coasters|TC-Coasters]] • [[Special:MyLanguage/MyWorlds|MyWorlds]] &lt;br /&gt;
• [[Special:MyLanguage/SignLink|SignLink]] • [[Special:MyLanguage/Maplands|Maplands]] • [[Special:MyLanguage/Light-Cleaner|Light Cleaner]]&lt;br /&gt;
&lt;br /&gt;
==BKCommonLib==&lt;br /&gt;
Diese Utility Bibliothek enthält all den in verschiedenen Plugins verwendeten selben Code, und das kombinieren in eine Bibliothek reduziert die anzahl an doppelten Code dramatisch. Die verwendeten Funktionen varieren und wann immer etwas in Spigot fehlt, wird es in BKCommonLib hinzugefügt. Dies ist eines der Gründe, warum es so gross ist: Weil es einfach eine menge dinge gibt, welche Spigot nicht anbieten (will).&lt;br /&gt;
&lt;br /&gt;
BKCommonLib hat eine Versionierung auf einer per-Plugin basis, sodass wenn ein Plugin Version 2 benötigt, jedoch Version 1 installiert ist, der Serverbesitzer automatisch informiert und das Plugin nicht gestartet wird. Dies verhindert oftmals auftretende Probleme mit veralteten BKCommonLib Versionen. Wenn du ein Plugin entwickelst, welches BKCommonLib verwendet, solltest du sicherstellen, dass dein Plugin die jüngste Version, welches das von dir verwendete Feature anbietet, verlangt. Das stellt sicher, dass dein Plugin auch auf älteren Spigot-Builds funktional bleibt.&lt;br /&gt;
&lt;br /&gt;
Anders als andere Utilities und Services, offeriert diese Bibliothek eine grosse anzahl and Reflektion und Benutzerfreundliche Wege um net.minecraft.server Code zu verwenden. Wenn dein Plugin die verwendung von Internem Code benötigt, du aber nicht riskieren willst, Feld und Methoden-Namen zu ändern, kannst du dich auf BKCommonLib verlassen, dir diese zu geben. Dies erlaubt es dir, automatisch zwischen CraftBukkit Versionen kompatibel zu bleiben und veringert leise Fehler-Fallen.&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/BKCommonLib|Klick Hier um zum BKCommonLib Wiki zu gelangen.]]&lt;br /&gt;
&lt;br /&gt;
==TrainCarts==&lt;br /&gt;
Dieses Plugin schaut nach verwendbaren Loren und verlinkt diese sofern möglich. Wenn zwei Loren &amp;quot;verlinkt&amp;quot; sind, werden diese Loren als ein einzelner Zug fungieren.&lt;br /&gt;
&lt;br /&gt;
Sobald Loren erfolgreich verlinkt wurden, wird ein Effekt abgespielt und Ihre Geschwindigkeit wird geteilt, mit einem individuelen Faktor für jede Lore, welche verwendet wird um eine Konstante Distanz zwischen den einzelnen Loren zu wahren. Dieser Abstand ist einstellbar, sowie die stärke in welcher dies geschieht.&lt;br /&gt;
&lt;br /&gt;
End-Resultat: Ein Zug! Du kannst ihn bewegen, eine Achterbahn aus ihr machen, sie teilen, Züge beim kollidieren zuschauen, was auch immer du mit Zügen machen willst. :)&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/TrainCarts|Klick hier um zum TrainCarts Wiki zu gelangen.]]&lt;br /&gt;
&lt;br /&gt;
==TC-Coasters ==&lt;br /&gt;
This add-on for Traincarts adds invisible rollercoaster track to Traincarts. You can now have trains move or fly anywhere, roll around the rails and connect with other types of track. The custom track can be interactively edited and require no external tools or scripting knowledge.&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/TC-Coasters|Klick hier um zum TC-Coasters Wiki zu gelangen.]]&lt;br /&gt;
&lt;br /&gt;
==MyWorlds==&lt;br /&gt;
Dieses Plugin enthält alles über Welten.&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/MyWorlds|Klick hier um zum MyWorlds Wiki zu gelangen.]]&lt;br /&gt;
&lt;br /&gt;
==SignLink==&lt;br /&gt;
Eine Brücke zwischen Plugins und Schildern zur einfachen Anzeige von Text auf Schildern.&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/SignLink|Klick hier um zum SignLink Wiki zu gelangen.]]&lt;br /&gt;
&lt;br /&gt;
==Maplands==&lt;br /&gt;
Maplands ist ein WIP Project welches Welt-Karten-Rendering für Minecraft Karten gibt. Zeige die Welt in einer Isometrischen Sicht an, kombiniere mehrere Karten um eine grosse Karte deiner Welt zu erstellen und vieles mehr das du erwarten kannst!&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/Maplands|Klick hier um zum Maplands Wiki zu gelangen.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;en&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
==Light Cleaner==&lt;br /&gt;
This plugin performs light regeneration of chunks near the player or the entire world.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;en&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/Light-Cleaner|Click here to go to the Light Cleaner wiki.]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Homepage wird von den Wiki-Administratoren gepflegt. Wenn Sie Vorschläge für diese Seite haben, wenden Sie sich bitte an einen Administrator!&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=Translations:Main_Page/46/de&amp;diff=7924</id>
		<title>Translations:Main Page/46/de</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=Translations:Main_Page/46/de&amp;diff=7924"/>
		<updated>2025-10-12T10:09:21Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Schnelle Navigation==&lt;br /&gt;
[[Special:MyLanguage/BKCommonLib|BKCommonLib]] • [[Special:MyLanguage/TrainCarts|TrainCarts]] • [[Special:MyLanguage/TC-Coasters|TC-Coasters]] • [[Special:MyLanguage/MyWorlds|MyWorlds]] &lt;br /&gt;
• [[Special:MyLanguage/SignLink|SignLink]] • [[Special:MyLanguage/Maplands|Maplands]] • [[Special:MyLanguage/Light-Cleaner|Light Cleaner]]&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=Main_Page/nl&amp;diff=7923</id>
		<title>Main Page/nl</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=Main_Page/nl&amp;diff=7923"/>
		<updated>2025-10-12T10:08:56Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Welkom&#039;&#039;&#039; op de wiki!&lt;br /&gt;
&lt;br /&gt;
==Snelle navigatie==&lt;br /&gt;
[[Special:MyLanguage/BKCommonLib|BKCommonLib]] • [[Special:MyLanguage/TrainCarts|TrainCarts]] • [[Special:MyLanguage/TC-Coasters|TC-Coasters]] • [[Special:MyLanguage/MyWorlds|MyWorlds]] &lt;br /&gt;
• [[Special:MyLanguage/SignLink|SignLink]] • [[Special:MyLanguage/Maplands|Maplands]] • [[Special:MyLanguage/Light-Cleaner|Light Cleaner]]&lt;br /&gt;
&lt;br /&gt;
==BKCommonLib==&lt;br /&gt;
Deze bibliotheek deelt alle gemeenschappelijke codebehoeften voor verschillende plugins, en door ze in één bibliotheek te hebben, wordt de hoeveelheid gedupliceerde code aanzienlijk verminderd. De aanbevolen hulpprogramma&#039;s zijn gevarieerd en wanneer er iets ontbreekt in Spigot, wordt het toegevoegd in BKCommonLib. Dit is een van de redenen waarom het zo groot is geworden: er zijn gewoon veel dingen die Spigot niet (wil) bieden.&lt;br /&gt;
&lt;br /&gt;
BKCommonLib heeft versiebeheer per plugin, dus wanneer een bepaalde plugin versie 2 nodig heeft en versie 1 is geïnstalleerd, wordt de servereigenaar automatisch op de hoogte gesteld en wordt de plugin niet ingeschakeld. Dit voorkomt de veel voorkomende ongelukken met verouderde BKCommonLib-versies. Als je een plugin ontwikkelt die BKCommonLib gebruikt, zorg er dan voor dat je afhankelijk bent van de vroegste versie die nog steeds de functies biedt die je nodig hebt. Dit zorgt ervoor dat je plugin functioneel blijft op oudere Spigot-builds.&lt;br /&gt;
&lt;br /&gt;
Behalve hulpprogramma&#039;s en services, biedt deze bibliotheek een breed scala aan reflectie en gebruiksvriendelijke manieren om toegang te krijgen tot net.minecraft.server. Als uw plug-in het gebruik van internals vereist, maar u niet het risico wilt lopen om de namen van velden en methoden te wijzigen, kunt u erop vertrouwen dat BKCommonLib ze levert. Hierdoor blijft je automatisch compatibel tussen CraftBukkit-versies en verminder je de kans op stille storingen.&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/BKCommonLib|Klik hier om naar de BKCommonLib wiki te gaan.]]&lt;br /&gt;
&lt;br /&gt;
==TrainCarts==&lt;br /&gt;
Deze plugin zoekt naar geschikte minecarts en koppelt deze indien mogelijk aan elkaar. Wanneer twee minecarts worden &amp;quot;gekoppeld&amp;quot;, werken de minecarts als één bewegende trein.&lt;br /&gt;
&lt;br /&gt;
Zodra de karren zijn gekoppeld, wordt een hoorbaar effect afgespeeld en wordt hun snelheid gedeeld in combinatie met een individuele factor voor elke minecarts, die wordt gebruikt om een ​​constante opening tussen karren te behouden. Deze opening is instelbaar, de kracht waarbij dit gebeurt ook.&lt;br /&gt;
&lt;br /&gt;
Eindresultaat: een trein! Je kunt het verplaatsen, er een achtbaan van maken, het in tweeën splitsen, treinen zien botsen, wat je maar wilt met treinen. :)&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/TrainCarts|Klik hier om naar de TrainCarts wiki te gaan.]]&lt;br /&gt;
&lt;br /&gt;
==TC-Coasters ==&lt;br /&gt;
This add-on for Traincarts adds invisible rollercoaster track to Traincarts. You can now have trains move or fly anywhere, roll around the rails and connect with other types of track. The custom track can be interactively edited and require no external tools or scripting knowledge.&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/TC-Coasters|Klik hier om naar de TC-Coasters wiki te gaan.]]&lt;br /&gt;
&lt;br /&gt;
==MyWorlds==&lt;br /&gt;
Deze plugin bevat alles met betrekking tot minecraft werelden.&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/MyWorlds|Klik hier om naar de MyWorlds wiki te gaan.]]&lt;br /&gt;
&lt;br /&gt;
==SignLink==&lt;br /&gt;
Een brug tussen plugins en bordjes zodat je makkelijk tekst kan weergeven op bordjes.&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/SignLink|Klik hier om naar de SignLink wiki te gaan.]]&lt;br /&gt;
&lt;br /&gt;
==Maplands==&lt;br /&gt;
Maplands is een work-in-progress-project dat de weergave van wereldkaarten naar Minecraft-kaarten levert. Geef de wereld weer in een isometrische weergave, koppel kaarten aan elkaar en creëer een enorm overzicht van je server, en er wordt nog veel meer verwacht!&lt;br /&gt;
&lt;br /&gt;
[[Special:MyLanguage/Maplands|Klik hier om naar de Maplands wiki te gaan.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;en&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
==Light Cleaner==&lt;br /&gt;
This plugin performs light regeneration of chunks near the player or the entire world.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div lang=&amp;quot;en&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;mw-content-ltr&amp;quot;&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/Light-Cleaner|Click here to go to the Light Cleaner wiki.]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
De homepagina wordt onderhouden door de wiki-beheerders. Als je een suggestie hebt voor deze pagina, neem dan contact op met de beheerder!&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=Translations:Main_Page/46/nl&amp;diff=7922</id>
		<title>Translations:Main Page/46/nl</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=Translations:Main_Page/46/nl&amp;diff=7922"/>
		<updated>2025-10-12T10:08:51Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Snelle navigatie==&lt;br /&gt;
[[Special:MyLanguage/BKCommonLib|BKCommonLib]] • [[Special:MyLanguage/TrainCarts|TrainCarts]] • [[Special:MyLanguage/TC-Coasters|TC-Coasters]] • [[Special:MyLanguage/MyWorlds|MyWorlds]] &lt;br /&gt;
• [[Special:MyLanguage/SignLink|SignLink]] • [[Special:MyLanguage/Maplands|Maplands]] • [[Special:MyLanguage/Light-Cleaner|Light Cleaner]]&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=Main_Page&amp;diff=7911</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=Main_Page&amp;diff=7911"/>
		<updated>2025-10-12T10:07:54Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Welcome&#039;&#039;&#039; to the wiki!&lt;br /&gt;
&lt;br /&gt;
==Quick navigation== &amp;lt;!--T:46--&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/BKCommonLib|BKCommonLib]] • [[Special:MyLanguage/TrainCarts|TrainCarts]] • [[Special:MyLanguage/TC-Coasters|TC-Coasters]] • [[Special:MyLanguage/MyWorlds|MyWorlds]] &lt;br /&gt;
• [[Special:MyLanguage/SignLink|SignLink]] • [[Special:MyLanguage/Maplands|Maplands]] • [[Special:MyLanguage/Light-Cleaner|Light Cleaner]]&lt;br /&gt;
&lt;br /&gt;
==BKCommonLib== &amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
This utility library shares all the common code needs for various plugins, and having them in one library heavily reduces the amount of duplicated code. The featured utilities are varied, and whenever something is missing in Spigot, it is added in BKCommonLib. This is one of the reasons why it has become this large: there are simply a lot of things Spigot doesn&#039;t (want to) offer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
BKCommonLib has versioning on a per-plugin basis, so when a certain plugin needs version 2, and version 1 is installed, the server owner is automatically notified and the plugin is not enabled. This prevents the common mishaps with outdated BKCommonLib versions. If you develop a plugin that uses BKCommonLib, make sure you depend on the earliest version that still offers the features you need. This makes sure your plugin remains functional on older Spigot builds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
Other than utilities and services, this library offers a wide variety of reflection and user-friendly ways of accessing net.minecraft.server. If your plugin requires the use of the internals, but you do not want to risk changing field and method names, you can depend on BKCommonLib to provide them for you. This allows you to remain compatible between CraftBukkit versions automatically, and reduces silent failure hazards.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/BKCommonLib|Click here to go to the BKCommonLib wiki.]]&lt;br /&gt;
&lt;br /&gt;
==TrainCarts== &amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
This plugin looks for suitable Minecarts and links them together if possible. When two Minecarts are being &amp;quot;linked&amp;quot;, the Minecarts will act as one single moving train.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
Once carts are successfully linked, an effect is played and their velocity is shared in combination with an individual factor for each Minecart, which is used to remain a steady gap between carts. This gap is adjustable, the force at which this happens as well.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:38--&amp;gt;&lt;br /&gt;
End result: a train! You can move it, make a roller-coaster out of it, split it in half, watch trains collide, whatever you want to do with trains. :)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/TrainCarts|Click here to go to the TrainCarts wiki.]]&lt;br /&gt;
&lt;br /&gt;
==TC-Coasters == &amp;lt;!--T:44--&amp;gt;&lt;br /&gt;
This add-on for Traincarts adds invisible rollercoaster track to Traincarts. You can now have trains move or fly anywhere, roll around the rails and connect with other types of track. The custom track can be interactively edited and require no external tools or scripting knowledge.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:45--&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/TC-Coasters|Click here to go to the TC-Coasters wiki.]]&lt;br /&gt;
&lt;br /&gt;
==MyWorlds== &amp;lt;!--T:40--&amp;gt;&lt;br /&gt;
This plugin features everything related to worlds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/MyWorlds|Click here to go to the MyWorlds wiki.]]&lt;br /&gt;
&lt;br /&gt;
==SignLink== &amp;lt;!--T:48--&amp;gt;&lt;br /&gt;
A bridge between plugins and signs to easily display text on signs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:49--&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/SignLink|Click here to go to the SignLink wiki.]]&lt;br /&gt;
&lt;br /&gt;
==Maplands== &amp;lt;!--T:42--&amp;gt;&lt;br /&gt;
Maplands is a work-in-progress project delivering world map rendering to Minecraft maps. Display the world in an isometric view, link maps together and create a huge overview of your server, and much more is anticipated!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:43--&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/Maplands|Click here to go to the Maplands wiki.]]&lt;br /&gt;
&lt;br /&gt;
==Light Cleaner== &amp;lt;!--T:50--&amp;gt;&lt;br /&gt;
This plugin performs light regeneration of chunks near the player or the entire world.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:51--&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/Light-Cleaner|Click here to go to the Light Cleaner wiki.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:47--&amp;gt;&lt;br /&gt;
The homepage is maintained by the wiki admins. If you have any suggestions for this page, please contact an admin! &amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=TrainCarts/Attachments&amp;diff=7902</id>
		<title>TrainCarts/Attachments</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=TrainCarts/Attachments&amp;diff=7902"/>
		<updated>2025-10-12T09:58:07Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages/&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:42--&amp;gt;&lt;br /&gt;
[[File:Attachment_editor_wooden_car.png|thumb|A customized minecart is being edited using the attachment editor]]&lt;br /&gt;
[[File:Rotating_attachments.gif|thumb|Two model attachments are animated, demonstrating the use of hierarchy]]&lt;br /&gt;
&lt;br /&gt;
==Introduction== &amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;The Attachment Editor&#039;&#039;&#039; is an in-game interactive [[Special:MyLanguage/Map Display|Map Display]] with which individual carts of a train can be customized.&lt;br /&gt;
This menu is used to configure the appearance and behavior of carts, with a [[wikipedia:Tree structure|tree layout]]&lt;br /&gt;
showing the different attachments. Each attachment represents a part of the train, such as a moving entity or a seat designation.&lt;br /&gt;
Attachments added as a child to other attachments are positioned relative to the parent. This allows many attachments to be moved&lt;br /&gt;
and animated together as a whole.&lt;br /&gt;
&lt;br /&gt;
==Basic usage== &amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Command=== &amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
To start using the attachment editor, players need to give themselves the map item:&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{Command|train attachments|Give the player the attachment editor map item|train.command.editor}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Editing=== &amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
To edit a single cart of a train, and make it visible in the editor, you need to select the cart first.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/TrainCarts/Editing|» Editing]]&lt;br /&gt;
&lt;br /&gt;
===Navigation=== &amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
Each attachment is displayed on a different row, with an indent to the right every time it is added to a new parent. To navigate between attachments, use the Up/Down (W/S) steering controls. For each attachment selected, different menus can be accessed by pressing Left/Right (A/D) and Jump (spacebar) afterwards. Once inside a menu, the sneak button (shift) can be used to exit it again. This behavior is the same for all other menus. To move around while still viewing the editor, it can be placed into the off-hand (&#039;&#039;typically F&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
To add new attachments, duplicate them, change the position in the tree hierarchy, or to delete them, use the [[Special:MyLanguage/TrainCarts/Attachments/General|General menu]] denoted by three horizontal lines.&lt;br /&gt;
&lt;br /&gt;
===Dropping items=== &amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
[[File:Attachments_Drop_Item_Small.gif|thumb|An item is dropped from the inventory, configuring the attachment|link=File:Attachments_Drop_Item.gif]]&lt;br /&gt;
Menus where an item is being configured can be set instantly by dropping an item from the player&#039;s inventory. With the menu open, simply open the inventory, pick the item to set, and click on the outside of the inventory to drop it. The drop will be cancelled and the item set in the menu.&lt;br /&gt;
&lt;br /&gt;
===Numbers=== &amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
Number sliders are used to configure numeric values, such position coordinates. Pressing the Left/Right buttons once will increment/decrement a very small amount. Holding the buttons for a longer time causes the number to increment/decrement faster and faster the longer it is being held down.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
By holding Spacebar a number field can be reset to its default, usually 0. By holding spacebar and then pressing left/right, a special action can be performed. Usually this means inverting the value (-5 -&amp;gt; 5) or changing an angle in 90 degree steps.&lt;br /&gt;
&lt;br /&gt;
===Text=== &amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
Text is input using an anvil menu. After typing in the desired text, click on the emerald to proceed, or the barrier item to cancel the change.&lt;br /&gt;
&lt;br /&gt;
===Setting using commands=== &amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{Command|train menu set [value]|Set a numeric or text value for the currently selected menu|train.command.editor}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Gotchas== &amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
* Make sure to use &amp;lt;code&amp;gt;/train save name&amp;lt;/code&amp;gt; to save your train regularly! Only saved trains can be restored&lt;br /&gt;
* Make use of the [[Special:MyLanguage/TrainCarts/Train Spawn Chest|train storage chest]] to move your train around or to recombine the carts&lt;br /&gt;
* Change spacing between carts, and where wheels are positioned, in the [[Special:MyLanguage/TrainCarts/Attachments/Physical|Physical menu]]&lt;br /&gt;
* When animating, make sure your animation frames have a delta-T greater than 0. Otherwise animation speed will not function.&lt;br /&gt;
* The new Display Entities cannot be clicked by default:&lt;br /&gt;
** If you cannot click to edit a train, look at it and do &amp;lt;code&amp;gt;/train edit&amp;lt;/code&amp;gt; to select it&lt;br /&gt;
** To allow players to click on the cart to enter a seat, make sure to add a &#039;&#039;&#039;Hitbox attachment&#039;&#039;&#039;.&lt;br /&gt;
* You can save a sub-tree of attachments in the [[Special:MyLanguage/TrainCarts/Attachments/Model#Model_Store|Model Store]] in the [[Special:MyLanguage/TrainCarts/Attachments/General|General menu]], and create it in multiple places using the [[Special:MyLanguage/TrainCarts/Attachments/Model|&#039;&#039;&#039;Model Attachment&#039;&#039;&#039;]]. There is also a clipboard and import/export function.&lt;br /&gt;
&lt;br /&gt;
==Menu== &amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
===Appearance===&lt;br /&gt;
The Appearance Menu contains a selector at the top where the attachment type is configured, with the remainder of the menu automatically filled with this type&#039;s configuration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:left&amp;quot;&lt;br /&gt;
|+Attachment Types&lt;br /&gt;
! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Empty&#039;&#039;&#039; || Displays nothing. Used as a marker attachment to easily position multiple other attachments, and as an anchor for animations&lt;br /&gt;
|-bgcolor=&amp;quot;#dddddd&amp;quot;&lt;br /&gt;
| &#039;&#039;&#039;Hitbox&#039;&#039;&#039; || Creates an invisible box that can be clicked. Important for entering seats. Size is configured in the Position menu.&lt;br /&gt;
|-&lt;br /&gt;
| [[Special:MyLanguage/TrainCarts/Attachments/Entity|&#039;&#039;&#039;Entity&#039;&#039;&#039;]] || Displays an Entity like a Minecart or Mob&lt;br /&gt;
|-bgcolor=&amp;quot;#dddddd&amp;quot;&lt;br /&gt;
| [[Special:MyLanguage/TrainCarts/Attachments/Item|&#039;&#039;&#039;Item&#039;&#039;&#039;]] || Displays an Item on an Armorstand or using a Display Entity&lt;br /&gt;
|-&lt;br /&gt;
| [[Special:MyLanguage/TrainCarts/Attachments/Block|&#039;&#039;&#039;Block&#039;&#039;&#039;]] || Displays a Block using a Display Entity. Only available on Minecraft 1.20+.&lt;br /&gt;
|-bgcolor=&amp;quot;#dddddd&amp;quot;&lt;br /&gt;
| [[Special:MyLanguage/TrainCarts/Attachments/Seat|&#039;&#039;&#039;Seat&#039;&#039;&#039;]] || A seat where a single player or entity can sit&lt;br /&gt;
|-&lt;br /&gt;
| [[Special:MyLanguage/TrainCarts/Attachments/Model|&#039;&#039;&#039;Model&#039;&#039;&#039;]] || Loads in a full attachment configuration from the model store&lt;br /&gt;
|-bgcolor=&amp;quot;#dddddd&amp;quot;&lt;br /&gt;
| &#039;&#039;&#039;Text&#039;&#039;&#039; || Floating Text Balloon&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Platform&#039;&#039;&#039; || A moving shulker box that players can stand on. Does not work moving up.&lt;br /&gt;
|-bgcolor=&amp;quot;#dddddd&amp;quot;&lt;br /&gt;
| &#039;&#039;&#039;Schematic&#039;&#039;&#039; || Displays multiple blocks using a WorldEdit saved Schematic&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Light&#039;&#039;&#039; || When [https://www.spigotmc.org/resources/lightapi-fork.48247/ LightAPI] is installed, spawns a moving light source at the attachment position&lt;br /&gt;
|-bgcolor=&amp;quot;#dddddd&amp;quot;&lt;br /&gt;
| [[Special:MyLanguage/TrainCarts/Attachments/Sound|&#039;&#039;&#039;Sound&#039;&#039;&#039;]] || Adds a sound effect played with effect signs, command or the sequencer&lt;br /&gt;
|-&lt;br /&gt;
| [[Special:MyLanguage/TrainCarts/Attachments/Sequencer|&#039;&#039;&#039;Sequencer&#039;&#039;&#039;]] || Automatically plays effects. Used to create ambient sound loops, such as engine noises, or to activate particle effects on a loop, such as a smoke stack.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Physical=== &amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
The Physical Menu configures the length of the cart and where the rail-tracking wheels of the cart are positioned.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/TrainCarts/Attachments/Physical|» Physical Menu]]&lt;br /&gt;
&lt;br /&gt;
===Position=== &amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
The position menu configures the position and rotation of the attachment. Includes additional options for some types of attachments, such as scale and transform options for items.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/TrainCarts/Attachments/Position|» Position Menu]]&lt;br /&gt;
&lt;br /&gt;
===Animation=== &amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
Attachments can be animated, making them move or rotate around. This is especially useful for funfair rides, or animated doors.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:38--&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/TrainCarts/Attachments/Animation|» Animation Menu]]&lt;br /&gt;
&lt;br /&gt;
===General=== &amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
The general menu is used to add new attachments, delete them, move them around, name them or load/save them from the [[Special:MyLanguage/TrainCarts/Attachments/Model#Model_Store|model store]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:40--&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/TrainCarts/Attachments/General|» General Menu]]&lt;br /&gt;
&lt;br /&gt;
==Effect Activation== &amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
Effect attachments such as the [[Special:MyLanguage/TrainCarts/Attachments/Sound|sound attachment]] must be activated. First, the attachment must be [[Special:MyLanguage/TrainCarts/Attachments/General#Name|named in the general menu]]. It can then be activated in multiple ways:&lt;br /&gt;
* Using the [[Special:MyLanguage/TrainCarts/Signs/Effect|effect sign]]&lt;br /&gt;
* Using the &amp;lt;code&amp;gt;/train effect &amp;lt;name&amp;gt;&amp;lt;/code&amp;gt; command&lt;br /&gt;
* Using the [[Special:MyLanguage/TrainCarts/Attachments/Sequencer|sequencer attachment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Backlog== &amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Editor=== &amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
* [[Special:MyLanguage/TrainCarts/Attachments/Saving|Saving trains (needs a cross-link about import/export and the whole savedtrain logic)]]&lt;br /&gt;
-&amp;gt; Navigating the tree menu&lt;br /&gt;
&lt;br /&gt;
===Position=== &amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
* [[Special:MyLanguage/TrainCarts/Attachments/TransformType|Transform type]]&lt;br /&gt;
* [[Special:MyLanguage/TrainCarts/Attachments/Anchor|Anchor]]&lt;br /&gt;
&lt;br /&gt;
===Animations=== &amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
* [[Special:MyLanguage/TrainCarts/Animations/Overview|Overview]]&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=TrainCarts/Attachments/Sequencer/PianoRoll&amp;diff=7900</id>
		<title>TrainCarts/Attachments/Sequencer/PianoRoll</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=TrainCarts/Attachments/Sequencer/PianoRoll&amp;diff=7900"/>
		<updated>2025-10-12T09:57:32Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages/&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
[[File:Sequencer_piano_roll.png|thumb|Sequencer MIDI Piano Roll]]&lt;br /&gt;
&lt;br /&gt;
== Introduction == &amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
The piano roll acts as a digital music sheet to configure melodies or repeating effects. Vertically are pitch classes, or octaves, and horizontally is time. The pitch classes are compatible with [https://minecraft.wiki/w/Note_Block#Notes Minecraft note blocks]. The mid-range pitch class (pitch 1.0, &#039;&#039;F#&#039;&#039;) is indicated using a red line.&lt;br /&gt;
&lt;br /&gt;
== Menu == &amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Notes === &amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
Notes can be placed down after activating the &#039;&#039;place note&#039;&#039; button. This automatically focuses the piano roll, where with W/A/S/D movement controls the position of the cursor on the piano roll can be changed. The note is toggled with spacebar.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
It is also possible to first select a pattern of notes, and then place this pattern down multiple times on the piano roll. Placing the pattern down on top of an existing pattern removes the pattern again.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
The effect is previewed once when the note is placed down.&lt;br /&gt;
&lt;br /&gt;
=== Clear Chart === &amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
Use the clear chart button to clear everything, which cannot be reversed.&lt;br /&gt;
&lt;br /&gt;
=== Preview === &amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
Preview the MIDI sequence using the play button, or stop it again to abort. Displays a position marker as the MIDI sequence plays.&lt;br /&gt;
&lt;br /&gt;
=== Configuration === &amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
[[File:Sequencer_piano_roll_config.png|thumb|Sequencer MIDI Piano Roll Configuration]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
The music chart settings can be configured by activating the gear icon. Most important are the beats per minute, which controls the tempo of the sequence. The time measure and pitch classes can be used to change the resolution of the chart. If you need additional pitch ranges, increase the number of pitch classes. If you need additional notes per beat, change the note value. The time signature is more for the music literate among us.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=TrainCarts/Attachments/Sequencer/PianoRoll&amp;diff=7899</id>
		<title>TrainCarts/Attachments/Sequencer/PianoRoll</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=TrainCarts/Attachments/Sequencer/PianoRoll&amp;diff=7899"/>
		<updated>2025-10-12T09:57:27Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages/&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
[[File:Sequencer_piano_roll.png|thumb|Sequencer MIDI Piano Roll]]&lt;br /&gt;
&lt;br /&gt;
== Introduction == &amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
The piano roll acts as a digital music sheet to configure melodies or repeating effects. Vertically are pitch classes, or octaves, and horizontally is time. The pitch classes are compatible with [https://minecraft.wiki/w/Note_Block#Notes Minecraft note blocks]. The mid-range pitch class (pitch 1.0, &#039;&#039;F#&#039;&#039;) is indicated using a red line.&lt;br /&gt;
&lt;br /&gt;
== Menu == &amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Notes === &amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
Notes can be placed down after activating the &#039;&#039;place note&#039;&#039; button. This automatically focuses the piano roll, where with W/A/S/D movement controls the position of the cursor on the piano roll can be changed. The note is toggled with spacebar.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
It is also possible to first select a pattern of notes, and then place this pattern down multiple times on the piano roll. Placing the pattern down on top of an existing pattern removes the pattern again.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
The effect is previewed once when the note is placed down.&lt;br /&gt;
&lt;br /&gt;
=== Clear Chart === &amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
Use the clear chart button to clear everything, which cannot be reversed.&lt;br /&gt;
&lt;br /&gt;
=== Preview === &amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
Preview the MIDI sequence using the play button, or stop it again to abort. Displays a position marker as the MIDI sequence plays.&lt;br /&gt;
&lt;br /&gt;
=== Configuration === &amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
[[File:Sequencer_piano_roll_config.png|thumb|Sequencer MIDI Piano Roll Configuration]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
The music chart settings can be configured by activating the gear icon. Most important are the beats per minute, which controls the tempo of the sequence. The time measure and pitch classes can be used to change the resolution of the chart. If you need additional pitch ranges, increase the number of pitch classes. If you need additional notes per beat, change the note value. The time signature is more for the music literate among us.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=TrainCarts/Attachments/Sequencer/PianoRoll&amp;diff=7898</id>
		<title>TrainCarts/Attachments/Sequencer/PianoRoll</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=TrainCarts/Attachments/Sequencer/PianoRoll&amp;diff=7898"/>
		<updated>2025-10-12T09:57:22Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages/&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
[[File:Sequencer_piano_roll.png|thumb|Sequencer MIDI Piano Roll]]&lt;br /&gt;
&lt;br /&gt;
== Introduction == &amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
The piano roll acts as a digital music sheet to configure melodies or repeating effects. Vertically are pitch classes, or octaves, and horizontally is time. The pitch classes are compatible with [https://minecraft.wiki/w/Note_Block#Notes Minecraft note blocks]. The mid-range pitch class (pitch 1.0, &#039;&#039;F#&#039;&#039;) is indicated using a red line.&lt;br /&gt;
&lt;br /&gt;
== Menu == &amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Notes === &amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
Notes can be placed down after activating the &#039;&#039;place note&#039;&#039; button. This automatically focuses the piano roll, where with W/A/S/D movement controls the position of the cursor on the piano roll can be changed. The note is toggled with spacebar.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
It is also possible to first select a pattern of notes, and then place this pattern down multiple times on the piano roll. Placing the pattern down on top of an existing pattern removes the pattern again.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
The effect is previewed once when the note is placed down.&lt;br /&gt;
&lt;br /&gt;
=== Clear Chart === &amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
Use the clear chart button to clear everything, which cannot be reversed.&lt;br /&gt;
&lt;br /&gt;
=== Preview === &amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
Preview the MIDI sequence using the play button, or stop it again to abort. Displays a position marker as the MIDI sequence plays.&lt;br /&gt;
&lt;br /&gt;
=== Configuration === &amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
[[File:Sequencer_piano_roll_config.png|thumb|Sequencer MIDI Piano Roll Configuration]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
The music chart settings can be configured by activating the gear icon. Most important are the beats per minute, which controls the tempo of the sequence. The time measure and pitch classes can be used to change the resolution of the chart. If you need additional pitch ranges, increase the number of pitch classes. If you need additional notes per beat, change the note value. The time signature is more for the music literate among us.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=TrainCarts/API/SignAction&amp;diff=7892</id>
		<title>TrainCarts/API/SignAction</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=TrainCarts/API/SignAction&amp;diff=7892"/>
		<updated>2025-10-12T09:56:29Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages/&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
This TrainCarts API allows custom signs to be registered, so that the registered executor callback is automatically run when trains go past them. This makes it very easy to make trains perform unique actions using a third-party plugin.&lt;br /&gt;
&lt;br /&gt;
== Example Template == &amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
To begin, create a new class in your plugin with the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import org.bukkit.entity.Player;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
import com.bergerkiller.bukkit.tc.controller.MinecartMember;&lt;br /&gt;
import com.bergerkiller.bukkit.tc.events.SignActionEvent;&lt;br /&gt;
import com.bergerkiller.bukkit.tc.events.SignChangeActionEvent;&lt;br /&gt;
import com.bergerkiller.bukkit.tc.signactions.SignAction;&lt;br /&gt;
import com.bergerkiller.bukkit.tc.signactions.SignActionType;&lt;br /&gt;
import com.bergerkiller.bukkit.tc.utils.SignBuildOptions;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Displays a welcome message to the players in the train&lt;br /&gt;
 */&lt;br /&gt;
public class SignActionWelcome extends SignAction {&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
@Override&lt;br /&gt;
    public boolean match(SignActionEvent info) {&lt;br /&gt;
        // Checks that the second line starts with &#039;welcome&#039; (case-insensitive)&lt;br /&gt;
        return info.isType(&amp;quot;welcome&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
@Override&lt;br /&gt;
    public void execute(SignActionEvent info) {&lt;br /&gt;
        // When a [train] sign is placed, activate when powered by redstone when the train&lt;br /&gt;
        // goes over the sign, or when redstone is activated.&lt;br /&gt;
        if (info.isTrainSign()&lt;br /&gt;
                &amp;amp;&amp;amp; info.isAction(SignActionType.GROUP_ENTER, SignActionType.REDSTONE_ON)&lt;br /&gt;
                &amp;amp;&amp;amp; info.isPowered() &amp;amp;&amp;amp; info.hasGroup()&lt;br /&gt;
        ) {&lt;br /&gt;
            for (MinecartMember&amp;lt;?&amp;gt; member : info.getGroup()) {&lt;br /&gt;
                sendGreetingForCart(info, member);&lt;br /&gt;
            }&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
// When a [cart] sign is placed, activate when powered by redstone when each cart&lt;br /&gt;
        // goes over the sign, or when redstone is activated.&lt;br /&gt;
        if (info.isCartSign()&lt;br /&gt;
                &amp;amp;&amp;amp; info.isAction(SignActionType.MEMBER_ENTER, SignActionType.REDSTONE_ON)&lt;br /&gt;
                &amp;amp;&amp;amp; info.isPowered() &amp;amp;&amp;amp; info.hasMember()&lt;br /&gt;
        ) {&lt;br /&gt;
            sendGreetingForCart(info, info.getMember());&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
public void sendGreetingForCart(SignActionEvent info, MinecartMember&amp;lt;?&amp;gt; member) {&lt;br /&gt;
        // Lines 3 and 4 configure the message to send&lt;br /&gt;
        String message = info.getLine(2) + info.getLine(3);&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
// Send to all player passengers of the cart (could be multiple seats!)&lt;br /&gt;
        for (Player passenger : member.getEntity().getPlayerPassengers()) {&lt;br /&gt;
            passenger.sendMessage(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
@Override&lt;br /&gt;
    public boolean build(SignChangeActionEvent event) {&lt;br /&gt;
        // This is executed when a player places down a sign matching this sign action&lt;br /&gt;
        // Permissions are checked and then a message is displayed to the player&lt;br /&gt;
        // For simplicity you can use the SignBuildOptions API for this.&lt;br /&gt;
        // You are free to use your own code here that checks permissions/etc.&lt;br /&gt;
        return SignBuildOptions.create()&lt;br /&gt;
                .setName(event.isCartSign() ? &amp;quot;cart welcome greeter&amp;quot; : &amp;quot;train welcome greeter&amp;quot;)&lt;br /&gt;
                .setDescription(&amp;quot;sends a welcome message to all players in the train&amp;quot;)&lt;br /&gt;
                .handle(event.getPlayer());&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
This is a simple example of a sign that sends a message to all players in the train. By default signs will support the standard TrainCarts conventions for the first line, where redstone options can be configured. The second line is typically used to match the sign type, and the last two lines are free to be used for anything.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
To register the above class, perform the following in your plugin&#039;s main class:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import org.bukkit.plugin.java.JavaPlugin;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
import com.bergerkiller.bukkit.tc.signactions.SignAction;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
public class TCWelcomeSign extends JavaPlugin {&lt;br /&gt;
    public final SignActionWelcome signActionWelcome = new SignActionWelcome();&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
@Override&lt;br /&gt;
    public void onEnable() {&lt;br /&gt;
        // Register the signs&lt;br /&gt;
        SignAction.register(signActionWelcome);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
@Override&lt;br /&gt;
    public void onDisable() {&lt;br /&gt;
        // Unregister the signs to prevent problems during /reload&lt;br /&gt;
        SignAction.unregister(signActionWelcome);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
It is important to both &#039;&#039;&#039;register&#039;&#039;&#039; and &#039;&#039;&#039;unregister&#039;&#039;&#039; the sign. That way, when the server is reloaded, or the plugin or reloaded using for example &#039;&#039;PlugMan&#039;&#039;, things don&#039;t break.&lt;br /&gt;
&lt;br /&gt;
== The Execute Method == &amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
Various events are sent to signs and can be handled by the sign. All events are handled through the &#039;&#039;&#039;execute(event)&#039;&#039;&#039; callback.&lt;br /&gt;
&lt;br /&gt;
=== Cart/Train Enter and Leave === &amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
When each individual &#039;&#039;cart&#039;&#039; hits a piece of track with a sign matching the sign action, the &#039;&#039;&#039;MEMBER_ENTER&#039;&#039;&#039; event is fired. When they move off the track again, a &#039;&#039;&#039;MEMBER_LEAVE&#039;&#039;&#039; event is fired. Similarly, for entire trains, a &#039;&#039;&#039;GROUP_ENTER&#039;&#039;&#039; and &#039;&#039;&#039;GROUP_LEAVE&#039;&#039;&#039; is fired.&lt;br /&gt;
&lt;br /&gt;
=== Redstone === &amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
When the sign becomes powered from an unpowered state, &#039;&#039;&#039;REDSTONE_ON&#039;&#039;&#039; and &#039;&#039;&#039;REDSTONE_CHANGE&#039;&#039;&#039; fire. In reverse, &#039;&#039;&#039;REDSTONE_OFF&#039;&#039;&#039; and &#039;&#039;&#039;REDSTONE_CHANGE&#039;&#039;&#039; fire. When the power state doesn&#039;t change, but other blocks nearby change redstone levels that might influence the sign behavior, just &#039;&#039;&#039;REDSTONE_CHANGE&#039;&#039;&#039; is fired. The event has helper methods to figure out the power state of the sign or a given direction of the sign.&lt;br /&gt;
&lt;br /&gt;
=== Movement === &amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
Every tick, while the train is moving, a &#039;&#039;&#039;MEMBER_MOVE&#039;&#039;&#039; event is fired. By default through, this is disabled for performance reasons. To use this event, override &#039;&#039;&#039;isMemberMoveHandled(event)&#039;&#039;&#039; and return true there.&lt;br /&gt;
&lt;br /&gt;
=== Updates === &amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
When players enter the train, leave it, properties change or other similar events occur, a &#039;&#039;&#039;MEMBER_UPDATE&#039;&#039;&#039; event fires. This is useful if the sign uses such information to, for example, toggle a lever.&lt;br /&gt;
&lt;br /&gt;
== Loaded Changed Event == &amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
The &#039;&#039;&#039;loadedChanged(event, loaded)&#039;&#039;&#039; method can be overrided to get notified when a sign matching this sign action is loaded or unloaded on the server. A sign is loaded when placed, or when a chunk loads with the sign in it. A sign is unloaded when destroyed, or when a chunk unloads with the sign in it. Be careful not to load or unload chunks in this method. This is a useful method to cache data in memory while the sign is in use.&lt;br /&gt;
&lt;br /&gt;
== Remote Control == &amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
Remote control enables the sign to be activated by redstone, to then operate on one or more trains by name pattern. To use remote control with the sign, override &#039;&#039;&#039;canSupportRC()&#039;&#039;&#039; and return true.&lt;br /&gt;
&lt;br /&gt;
== Path Finding == &amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
Some advanced methods can be overrided to make the sign act as a node in the [[Special:MyLanguage/TrainCarts/PathFinding|path-finding]] network:&lt;br /&gt;
* &#039;&#039;isRailSwitcher(event)&#039;&#039; - Return true if this sign switches the rails from/to any direction&lt;br /&gt;
* &#039;&#039;getRailDestinationName(event)&#039;&#039; - Return non-null to provide a unique destination name&lt;br /&gt;
* &#039;&#039;isPathFindingBlocked(event, railState)&#039;&#039; - Return true to tell the path finding algorithm that in this direction no further movement is possible&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=TrainCarts/MobEntering&amp;diff=7889</id>
		<title>TrainCarts/MobEntering</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=TrainCarts/MobEntering&amp;diff=7889"/>
		<updated>2025-10-12T09:56:07Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages/&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Putting mobs into Minecarts == &amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
Mobs are put into minecarts through a [[Special:MyLanguage/TrainCarts/Signs/Property|collision property]] rule. By default this automatic entering is disabled. To turn it on for a train you have just spawned or [[Special:MyLanguage/TrainCarts/Commands#Selecting|selected]], run the following command:&lt;br /&gt;
&amp;lt;pre&amp;gt;/train collision mobs enter&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
This command only changes this for the one train you had selected.&lt;br /&gt;
&lt;br /&gt;
== Default Behavior == &amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
If you want all minecarts placed by players to put mobs into them by default, you have two options. You can make it so that minecarts placed by players are vanilla Minecraft minecarts, but that means they cannot be trains. [[Special:MyLanguage/TrainCarts/VanillaMinecarts|See this page for more information about that.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
Alternatively, you can change the default setting for newly placed minecarts. To do so, edit &amp;lt;code&amp;gt;plugins/Train_Carts/DefaultTrainProperties.yml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
There&#039;s multiple blocks of configurations:&lt;br /&gt;
* &#039;&#039;&#039;default&#039;&#039;&#039; is for normal players&lt;br /&gt;
* &#039;&#039;&#039;admin&#039;&#039;&#039; for players with the &amp;lt;code&amp;gt;train.properties.admin&amp;lt;/code&amp;gt; permission (OP by default)&lt;br /&gt;
* &#039;&#039;&#039;spawner&#039;&#039;&#039; is for trains spawned with the m/s/p/etc. syntax, on spawner signs. Does not apply to saved trains that are spawned.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
For the category/categories you want to edit, find the line:&lt;br /&gt;
&amp;lt;pre&amp;gt;collision: {}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Or, it might look like this if it already had some configurations:&lt;br /&gt;
&amp;lt;pre&amp;gt;  collision:&lt;br /&gt;
    players: DEFAULT&lt;br /&gt;
    misc: PUSH&lt;br /&gt;
    train: LINK&lt;br /&gt;
    block: DEFAULT&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
And change it to:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  collision:&lt;br /&gt;
    animal: ENTER&lt;br /&gt;
    monster: ENTER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can leave previous options if they existed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
On more modern versions of TrainCarts this can work too:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  collision:&lt;br /&gt;
    mobs: ENTER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
Then, either restart the server, or run this command:&lt;br /&gt;
&amp;lt;pre&amp;gt;/train globalconfig reload --defaulttrainproperties&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Other Options == &amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
Besides &#039;&#039;mobs&#039;&#039; there is a more fine-grained list of categories of mobs that can be set specific collision options for. The names are case-sensitive, and must be lower-cased. On newer versions of TrainCarts plural names work, too.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! YAML Key !! Category Description&lt;br /&gt;
|-&lt;br /&gt;
| pet || Tameable animals&lt;br /&gt;
|-&lt;br /&gt;
| jockey || Jockey mounts that can spawn for monsters, like spiders, skeletons, zombie and chickens&lt;br /&gt;
|-&lt;br /&gt;
| killer_bunny || Rabbit mob, that is a killer bunny specialized type&lt;br /&gt;
|-&lt;br /&gt;
| npc || Mobs that are NPCs, like villagers&lt;br /&gt;
|-&lt;br /&gt;
| animal || Passive animal mobs including mobs like the bat and squid&lt;br /&gt;
|-&lt;br /&gt;
| monster || Hostile monster mobs, including slimes, golems and phantom&lt;br /&gt;
|-&lt;br /&gt;
| passive || Passive mobs. Large overlap with animal&lt;br /&gt;
|-&lt;br /&gt;
| neutral || Neutral mobs that can become aggressive. For example, enderman.&lt;br /&gt;
|-&lt;br /&gt;
| hostile || Hostile mobs that cannot be passive. For example, creeper.&lt;br /&gt;
|-&lt;br /&gt;
| tameable || Same as pet. Tameable animals&lt;br /&gt;
|-&lt;br /&gt;
| utility || Utility mobs. Only Golems.&lt;br /&gt;
|-&lt;br /&gt;
| boss || Boss mobs. Ender dragon, wither.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=TrainCarts/Editing&amp;diff=7888</id>
		<title>TrainCarts/Editing</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=TrainCarts/Editing&amp;diff=7888"/>
		<updated>2025-10-12T09:55:32Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
TrainCarts tracks what minecart entity a player is currently editing. Most [[TrainCarts/Commands|commands]] and also the [[TrainCarts/Attachments|attachment editor]] operate on the train the player has selected. There are various ways to change what train is being edited, each method will be explained on this page.&lt;br /&gt;
&lt;br /&gt;
== Placing down new minecarts ==&lt;br /&gt;
Whenever players place down new minecarts, or use the [[TrainCarts/Train_Spawn_Chest|train spawn chest]], the cart or train is automatically selected. After placing down a minecart players can therefore instantly use commands to configure it.&lt;br /&gt;
&lt;br /&gt;
== Sitting inside a minecart ==&lt;br /&gt;
When entering a train, players will automatically edit the cart they entered. When they leave the cart again, the cart remains selected.&lt;br /&gt;
&lt;br /&gt;
== Damaging while sneaking ==&lt;br /&gt;
When a cart is hit while sneaking, or &#039;&#039;slapped&#039;&#039;, the cart is not destroyed and instead the cart is selected. Similarly, when damaging a cart in survival, players can select carts.&lt;br /&gt;
&lt;br /&gt;
== Edit command ==&lt;br /&gt;
The &#039;&#039;edit&#039;&#039; command can also be used to select carts. This can be done by specifying the name of the train, or by looking at the cart to edit. A particle effect is displayed when a train is selected.&lt;br /&gt;
{{Command|train edit|Edits the cart a player is looking at|must be a train owner}}&lt;br /&gt;
{{Command|train edit [name]|Edits the train with a given name|must be a train owner}}&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=TrainCarts/Acceleration&amp;diff=7887</id>
		<title>TrainCarts/Acceleration</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=TrainCarts/Acceleration&amp;diff=7887"/>
		<updated>2025-10-12T09:55:24Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Acceleration is the rate at which trains speed up or slow down. This is an important metric when launching or stopping trains. TrainCarts supports various ways of specifying acceleration in both metric and imperial units.&lt;br /&gt;
&lt;br /&gt;
As a base unit TrainCarts uses &#039;&#039;blocks/tick&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;&#039;&#039; This can be understood as: &#039;&#039;Increase the speed by &amp;lt;value&amp;gt; blocks/tick every tick&#039;&#039;. A single tick is 1/20 second. All units are case-insensitive. Some mix-matching of units is possible, for example, you can use &#039;&#039;20m/hh&#039;&#039; even though it is not listed.&lt;br /&gt;
&lt;br /&gt;
== Syntax ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Input&lt;br /&gt;
! blocks/tick&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;&lt;br /&gt;
! Explanation&lt;br /&gt;
|-&lt;br /&gt;
| 0.2&amp;lt;br&amp;gt;0.2/tt&lt;br /&gt;
| 0.2&lt;br /&gt;
| When no unit is specified, the value is in blocks/tick&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 20m/ss&amp;lt;br&amp;gt;20/ss&amp;lt;br&amp;gt;20/s2&amp;lt;br&amp;gt;20/s/s&lt;br /&gt;
| 0.05&lt;br /&gt;
| Unit in blocks/second&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; (or m/s&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;). Can be specified with 2x s, or s2. The &#039;&#039;m&#039;&#039; before the unit is optional.&lt;br /&gt;
|-&lt;br /&gt;
| 30km/h/s&amp;lt;br&amp;gt;30kmh/s&amp;lt;br&amp;gt;30kmph/s&lt;br /&gt;
| 0.020833&lt;br /&gt;
| Unit in kilometers/hour per second. Can be specified as km/h, kmh or kmph.&lt;br /&gt;
|-&lt;br /&gt;
| 3.28ft/s/s&amp;lt;br&amp;gt;3.28ft/ss&lt;br /&gt;
| 0.0025&lt;br /&gt;
| Unit in feet/second&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 1.0mi/h/s&amp;lt;br&amp;gt;1.0mph/s&lt;br /&gt;
| 0.0011176&lt;br /&gt;
| Unit in miles/hour per second. mi/h can be specified as mph.&lt;br /&gt;
|-&lt;br /&gt;
| 1.5G&lt;br /&gt;
| 0.0367875&lt;br /&gt;
| Unit based on G-forces. 1G is assumed to be 9.81m/s&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=TrainCarts/Velocity&amp;diff=7885</id>
		<title>TrainCarts/Velocity</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=TrainCarts/Velocity&amp;diff=7885"/>
		<updated>2025-10-12T09:55:16Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Velocity is the speed of the train. Speed syntax is important for [[TrainCarts/Signs/Launcher#Third_line|Launcher signs]], [[TrainCarts/Signs/Property#Properties|Speed limit property]] and any other places where a speed is specified.&lt;br /&gt;
&lt;br /&gt;
As a base unit TrainCarts uses &#039;&#039;blocks/tick&#039;&#039; This can be understood as: &#039;&#039;Move the train by &amp;lt;value&amp;gt; blocks every tick&#039;&#039;. A single tick is 1/20 second. All units are case-insensitive. Some mix-matching of units is possible, for example, you can use &#039;&#039;20m/h&#039;&#039; even though it is not listed. For a change in velocity, see [[TrainCarts/Acceleration]].&lt;br /&gt;
&lt;br /&gt;
== Syntax ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Input&lt;br /&gt;
! blocks/tick&lt;br /&gt;
! Explanation&lt;br /&gt;
|-&lt;br /&gt;
| 0.2&amp;lt;br&amp;gt;0.2/t&lt;br /&gt;
| 0.2&lt;br /&gt;
| When no unit is specified, the value is in blocks/tick&lt;br /&gt;
|-&lt;br /&gt;
| 20m/s&amp;lt;br&amp;gt;20/s&lt;br /&gt;
| 1.0&lt;br /&gt;
| Unit in blocks/second (or m/s). The &#039;&#039;m&#039;&#039; before the unit is optional.&lt;br /&gt;
|-&lt;br /&gt;
| 30km/h&amp;lt;br&amp;gt;30kmh&amp;lt;br&amp;gt;30kmph&lt;br /&gt;
| 0.4167&lt;br /&gt;
| Unit in kilometers/second. Can be specified as km/h, kmh or kmph.&lt;br /&gt;
|-&lt;br /&gt;
| 3.28ft/s&lt;br /&gt;
| 0.05&lt;br /&gt;
| Unit in feet/second&lt;br /&gt;
|-&lt;br /&gt;
| 1.0mi/h&amp;lt;br&amp;gt;1.0mph&lt;br /&gt;
| 0.022352&lt;br /&gt;
| Unit in miles/hour. mi/h can be specified as mph.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=TrainCarts/API&amp;diff=7884</id>
		<title>TrainCarts/API</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=TrainCarts/API&amp;diff=7884"/>
		<updated>2025-10-12T09:55:03Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages/&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
TrainCarts is written in a way to allow third-party plugins to extend it. Various mechanics are built-in api&#039;s implemented by TrainCarts, such as the different vanilla rails, signs and more. For programmers, this page details the different modules in TrainCarts that can be used in third-party plugins.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Custom Signs == &amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
The &#039;&#039;&#039;SignAction&#039;&#039;&#039; API allows custom signs to be registered with the plugin so that trains can activate them, much like the built-in [[Special:MyLanguage/TrainCarts/Signs|TrainCarts signs]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/TrainCarts/API/SignAction|» SignAction API]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Custom Track == &amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
The &#039;&#039;&#039;RailType&#039;&#039;&#039; and &#039;&#039;&#039;RailLogic&#039;&#039;&#039; API allows custom rail types to be registered. Vanilla Minecart Track uses this same API.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/TrainCarts/API/Rail|» Rail API]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Custom Attachments == &amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
Custom &#039;&#039;&#039;Attachment Types&#039;&#039;&#039; can be registered to extend what visible capabilities trains can support. Once registered, they become selectable in the in-game [[Special:MyLanguage/TrainCarts/Attachments|attachment editor menu]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/TrainCarts/API/Attachments|» Attachments API]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/ConfigurationAPI&amp;diff=7883</id>
		<title>BKCommonLib/ConfigurationAPI</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/ConfigurationAPI&amp;diff=7883"/>
		<updated>2025-10-12T09:53:35Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
Let&#039;s be honest here...YAML configuration is a pain to work with. The defaults system requires additional files to be added, it is impossible to automatically cast types, and the support for headers is terrible. The Configuration API makes working with configuration a breeze.&lt;br /&gt;
&lt;br /&gt;
Configuration node and value paths are delimited by &#039;.&#039;-characters. To obtain the value of setting in the node settings, you would use path settings.setting.&lt;br /&gt;
&lt;br /&gt;
Usage&lt;br /&gt;
Configuration works using stored nodes in a tree of data, as this is how YAML operates.&lt;br /&gt;
&lt;br /&gt;
Loading and saving configuration&lt;br /&gt;
We will mainly cover configuration reading from file and saving to file. The API is built around the principle to read and write files, so there is little support for anything else. If you wish to read or write to another storage system, you can use the loadFromStream and saveToStream methods found in [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/config/BasicConfiguration.java BasicConfiguration].&lt;br /&gt;
&lt;br /&gt;
To start a new configuration for a file in, for example, plugin enable, you can do the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;FileConfiguration config = new FileConfiguration(this, &amp;quot;config.yml&amp;quot;);&lt;br /&gt;
if (config.exists()) {&lt;br /&gt;
    config.load(); // Load the configuration from the file&lt;br /&gt;
} else {&lt;br /&gt;
    config.set(&amp;quot;config1&amp;quot;, 12);&lt;br /&gt;
    config.set(&amp;quot;config2&amp;quot;, 14);&lt;br /&gt;
    config.save(); // Saves the new data to file&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
System.out.println(config.get(&amp;quot;config1&amp;quot;, Integer.class));&lt;br /&gt;
System.out.println(config.get(&amp;quot;config2&amp;quot;, Integer.class));&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Getting values and their defaults==&lt;br /&gt;
There is a major difference in getting values between this API and the default Bukkit implementation. In the Configuration API, the defaults specified are automatically set in the configuration if the value was not found. This makes it tonnes easier to start a (new) configuration. In the example above it first checked if the file exists, but this can be done a lot easier:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;FileConfiguration config = new FileConfiguration(this, &amp;quot;config.yml&amp;quot;);&lt;br /&gt;
config.load();&lt;br /&gt;
System.out.println(config.get(&amp;quot;config1&amp;quot;, 12));&lt;br /&gt;
System.out.println(config.get(&amp;quot;config2&amp;quot;, 14));&lt;br /&gt;
config.save();&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Loading is allowed if the file does not exist, it will simply not load anything in that case. When getting the two values, it will automatically assign &#039;12&#039; to &#039;config1&#039; if such a node was not loaded. When saving, it will automatically update these values.&lt;br /&gt;
&lt;br /&gt;
Various stored types are supported, including all enumeration types (like Material and GameMode). To perform the same as the above but with Lists or Arrays, you can do the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;List&amp;lt;Integer&amp;gt; ints = config.getList(&amp;quot;blockIds&amp;quot;, Integer.class);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It will automatically create an empty list in this case if it wasn&#039;t set. If you wish to specify defaults as well: this is possible. Non-integer convertable values are automatically filtered from the list, so no worries of having a String in there.&lt;br /&gt;
&lt;br /&gt;
==Nodes==&lt;br /&gt;
YAML is a tree-based storage system, so support for Configuration Nodes is there as well. You do not have to use node objects to create nodes, but they can make it easier to pass around configuration in your plugin to several components. You can use getNode(path) to get a node. If the node does not yet exist, it is made and returned. For that reason, this method never returns null.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ConfigurationNode entities = config.getNode(&amp;quot;entities&amp;quot;);&lt;br /&gt;
maxCount = entities.get(&amp;quot;maxCount&amp;quot;, 225);&lt;br /&gt;
message = entities.get(&amp;quot;message&amp;quot;, &amp;quot;You have reached the maximum amount of entities&amp;quot;);&lt;br /&gt;
EntityLogic.initialize(entities);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is no difference between ConfigurationNode functionality and Configuration functionality - File/Basic Configuration is a node as well. The only difference is that a ConfigurationNode does not store information such as file, indent and other settings.&lt;br /&gt;
&lt;br /&gt;
==Headers==&lt;br /&gt;
The Configuration API adds support for configuration headers, to give useful descriptions of configuration nodes and values. It produces output such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# This is the configuration of MyAwesomePlugin&lt;br /&gt;
&lt;br /&gt;
# Sets the awesomeness of this plugin&lt;br /&gt;
awesomeness: 85&lt;br /&gt;
&lt;br /&gt;
# Controls what levels of awesomeness are enabled&lt;br /&gt;
enabledLevels:&lt;br /&gt;
  # Whether awesome looks are enabled&lt;br /&gt;
  looks: true&lt;br /&gt;
  # Whether awesome usage is enabled&lt;br /&gt;
  usage: false&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, the first header (the &#039;main&#039; header) has a slightly different syntax. This is to prevent the first node header (awesomeness) from conflicting with the main header. Setting node headers is very easy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;// Set the top-level header&lt;br /&gt;
config.setHeader(&amp;quot;This is the configuration of MyAwesomePlugin&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Set the header of an option&lt;br /&gt;
config.setHeader(&amp;quot;awesomeness&amp;quot;, &amp;quot;\nSets the awesomeness of this plugin&amp;quot;);&lt;br /&gt;
config.setHeader(&amp;quot;enabledLevels&amp;quot;, &amp;quot;\nControls what levels of awesomeness are enabled&amp;quot;);&lt;br /&gt;
config.setHeader(&amp;quot;enabledLevels.looks&amp;quot;, &amp;quot;Whether awesome looks are enabled&amp;quot;);&lt;br /&gt;
config.setHeader(&amp;quot;enabledLevels.usage&amp;quot;, &amp;quot;Whether awesome usage is enabled&amp;quot;);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can use the newline character &#039;\n&#039; to have multiple header lines, or to create empty lines (as seen in the example). There is also an addHeader method, which basically appends more text to the current header on a new line. This is somewhat equivalent to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;config.setHeader(&amp;quot;awesomeness&amp;quot;, config.getHeader(&amp;quot;awesomeness&amp;quot;) + &amp;quot;\n&amp;quot; + &amp;quot;Something added on a new line&amp;quot;);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
By setting defaults while getting data from a configuration, it is a lot easier to perform loading and saving. The addition of per-node headers allows configuration fil&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/TabView&amp;diff=7882</id>
		<title>BKCommonLib/TabView</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/TabView&amp;diff=7882"/>
		<updated>2025-10-12T09:49:52Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
BKCommonLib features an advanced method of changing what is shown when players press tab, previously known as the &#039;Player List&#039;. With our service you can alter every cell of this list based on column and row indices. In combination, it features a name generation scheme that allows you to place the same text multiple times. Minecraft limits the text you can put to 16 characters, so we were forced to abide it. If you have the same text twice, this limit becomes 14 (due to the name generation appending two characters).&lt;br /&gt;
&lt;br /&gt;
==Initialization of your tab view==&lt;br /&gt;
To use this service, first of all obtain a TabView instance while enabling your plugin. You can do this in onEnable, but doing it in the constructor or field area of your plugin class is fine too. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;public class MyPlugin extends JavaPlugin {&lt;br /&gt;
    private TabView tabView = TabView.createTab(3, 20);&lt;br /&gt;
&lt;br /&gt;
    public void onEnable() {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void onDisable() {&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Please note that it is not possible to create new tabs while the server is running. This is because BKCommonLib can not alter the shown player list dimensions of existing players, and it requires a re-login to fix. To avoid these bugs, the &#039;&#039;&#039;maximum dimensions&#039;&#039;&#039; of the tab view you need have to be specified while your plugin starts up. After loading up, you can demand player lists that are smaller than the one you create on startup, but you can not create larger ones. If you expect to be using a variable size tab list, be sure to initialize a tab view of the maximum size you expect.&lt;br /&gt;
&lt;br /&gt;
The maximum width you can use is 3, the maximum height is 20. This is the same as the server enforces.&lt;br /&gt;
&lt;br /&gt;
==Altering your tab view==&lt;br /&gt;
Now you have a TabView instance, what can you do with it? Well, you can set, for each cell, what text and ping icon to display in it. To do so there are many methods available to you. You can fill all cells at once, fill a single row or column, set an area or a single cell. You can also create sub-views into your TabView so you can send it to a method and alter it there, with bounds checking. Look into the JavaDoc and you&#039;ll be amazed at the possibilities.&lt;br /&gt;
&lt;br /&gt;
==Displaying your tab view==&lt;br /&gt;
Updates for changes made in the tab are automatically sent to all viewers at the end of each server tick, so no worries of having to update manually each tick. To display your Tab View to a player, or to all players, use the &#039;&#039;&#039;displayTo&#039;&#039;&#039; and &#039;&#039;&#039;displayToAll&#039;&#039;&#039; methods. In the case of displayToAll, all players that join the server will automatically see your Tab View as well. If you want to see whether a Tab View is shown to a Player (for example, to provide a toggle), you can use the &#039;&#039;&#039;isDisplayedTo&#039;&#039;&#039; method.&lt;br /&gt;
&lt;br /&gt;
What happens when two plugins try to display a tab? Well, the previous tab will be hidden and the new tab will be shown. Please, do not abuse this by forcing a display each tick. It is up to the users to decide what they want to see, so provide a command toggle! Don&#039;t automate or schedule the display of tabs, it will only cause annoyance by the users.&lt;br /&gt;
&lt;br /&gt;
==Displaying the default player list again==&lt;br /&gt;
If you want to display the default player list again, or an empty list, use the &#039;&#039;&#039;TabView.DEFAULT&#039;&#039;&#039; or &#039;&#039;&#039;TabView.EMPTY&#039;&#039;&#039; constants. By calling &#039;&#039;&#039;TabView.DEFAULT.displayToAll()&#039;&#039;&#039; everyone sees the (auto-updated) player list again.&lt;br /&gt;
&lt;br /&gt;
===But I want both!===&lt;br /&gt;
Adding automatic player name and ping updates to custom tabs would create a confusing API, so if you wish to show player names behind, around or after your own Tab View, it is best if you do this yourself. You can use a tick task to set all text and ping values in your custom tab view. No changes are sent if the name didn&#039;t change, so it won&#039;t cause lag. Updating the text or ping of a cell is pretty much instant, there is no heavy operation involved.&lt;br /&gt;
&lt;br /&gt;
===What if I want to show a different view per player?===&lt;br /&gt;
You can do so by cloning the TabView instance created on startup. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;TabView myView = this.tabView.clone();&lt;br /&gt;
myView.set(0, 0, player.getName(), TabView.PING_NONE);&lt;br /&gt;
myView.displayTo(player);&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you want different (smaller!) sizes, you can use &#039;&#039;&#039;cloneResize(width, height)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
Below is an example code for displaying the player names, experience and their time lived in a table. A maximum of 17 players is supported. For initialization the example initialization code above was used. This code can be put anywhere, in this case it was put in a command handler. You can also place it in the enable logic of the plugin, but be aware that other plugins that do the same could cause conflicts then. It&#039;s best to allow users to toggle your Tab View on or off.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;// Show header at line 1, 2 and 3&lt;br /&gt;
tabView.fillRow(0, &amp;quot;==============&amp;quot;, TabView.PING_1);&lt;br /&gt;
tabView.fillRow(1, TabView.TEXT_NONE, TabView.PING_NONE);&lt;br /&gt;
tabView.setRowText(1, &amp;quot;Players&amp;quot;, &amp;quot;Experience&amp;quot;, &amp;quot;Time Alive&amp;quot;);&lt;br /&gt;
tabView.fillRow(2, &amp;quot;==============&amp;quot;, TabView.PING_1);&lt;br /&gt;
// Show scores&lt;br /&gt;
int line = 3;&lt;br /&gt;
for (Player player : Bukkit.getOnlinePlayers()) {&lt;br /&gt;
	tabView.set(0, line, player.getPlayerListName(), TabView.PING_FULL);&lt;br /&gt;
	tabView.set(1, line, &amp;quot;&amp;quot; + player.getTotalExperience(), TabView.PING_FULL);&lt;br /&gt;
	tabView.set(2, line, &amp;quot;&amp;quot; + (player.getTicksLived() / 20) + &amp;quot;s&amp;quot;, TabView.PING_FULL);&lt;br /&gt;
	line++;&lt;br /&gt;
	// Out of bounds!&lt;br /&gt;
	if (line &amp;gt;= tabView.getHeight()) {&lt;br /&gt;
		break;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
// Display to everyone&lt;br /&gt;
tabView.displayToAll();&amp;lt;/pre&amp;gt;&lt;br /&gt;
This creates the resulting image: TabView example result&lt;br /&gt;
&lt;br /&gt;
==Conflicting plugins==&lt;br /&gt;
If there is another plugin that alters the player list view, it might not get to do what it wants to do since BKCommonLib blocks it when a custom TabView is being shown. When the DEFAULT TabView is shown, other plugins can safely send their messages, since BKCommonLib then allows these messages to go through. When DEFAULT is not shown, BKCommonLib will keep track of these discarded messages and send them again when DEFAULT is shown again.&lt;br /&gt;
&lt;br /&gt;
So, if your plugin shows a custom TabView, it is best to allow players to toggle this off by showing the DEFAULT tab view. Any other plugin that was trying to show something will get a chance to do so then.&lt;br /&gt;
&lt;br /&gt;
==Some tips and tricks==&lt;br /&gt;
* To wipe everything previously shown, use fillAll(&amp;quot;&amp;quot;, 0)&lt;br /&gt;
* To quickly set everything, use setArea/Column/RowText&lt;br /&gt;
* You can clone an entire view using clone()&lt;br /&gt;
* You can get a newly sized TabView by using cloneResize(newWidth, newHeight)&lt;br /&gt;
* There are many TabView.PING_X constants to display certain ping icons&lt;br /&gt;
* You do not have to limit the displayed text by 16, this is done for you&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=MyWorlds/ManagingWorlds&amp;diff=7871</id>
		<title>MyWorlds/ManagingWorlds</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=MyWorlds/ManagingWorlds&amp;diff=7871"/>
		<updated>2025-10-12T09:49:26Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages/&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==How to create, load, save, unload, delete and copy worlds== &amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
This page covers all the details for creating new worlds, loading existing worlds, saving worlds, unloading worlds and world file operations such as delete and copy.&lt;br /&gt;
&lt;br /&gt;
==Setting up the server== &amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
The server always generates a few initial worlds, which are mainworld, mainworld_nether and mainworld_the_end (if hellworld is enabled). It is required to have these worlds loaded at all times, and since MyWorlds enables after these worlds are loaded, MyWorlds is unable to alter the properties of these main worlds. If you plan on not using the overworld/nether/the end worlds, you still have to have them loaded. You can change &#039;keep spawn loaded&#039; to false so these worlds do not occupy any memory, and change &#039;mainworld&#039; to the desired main world where new people spawn in the config.yml. Then these worlds are not used (but could be used).&lt;br /&gt;
&lt;br /&gt;
==Preface== &amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
All commands except delete match the world name you type in against already existing worlds. If you have a world named &#039;CreeperCraft12&#039;, you can access the world using &#039;Creeper&#039; or &#039;Craft12&#039; as well. It first looks for world names that equal your name entered, then the world names containing what you entered and finally the world names contained in what you entered.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
For command permissions, [[MyWorlds/Permissions|see here]].&lt;br /&gt;
&lt;br /&gt;
==Creating New Worlds== &amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
The first step is to create new worlds you want to use on your server. There are two kinds of ways you can create worlds, they will be listed separately.&lt;br /&gt;
&lt;br /&gt;
===Creating Vanilla worlds=== &amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
To create normal/nether/flat/the_end worlds, you can use the commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;/world create worldname_environment(::options) (seed)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
The ()-surrounded parts are optional. If no seed is specified, a random seed is used instead. When worldname_environment is used, the environment type is appended to the world name, while with worldname/environment it will not append it to the name. Appending the world environment to the name is recommended, since it eases loading the worlds if no configuration is available for it yet. Not specifying an environment means that the NORMAL environment will be used. Bear in mind that the Bukkit &#039;Environment&#039; and &#039;Worldtype&#039; are merged as one in MyWorlds. To have a &#039;nether flatworld&#039;, you use &#039;nether_flat&#039; as environment. Note that most combinations are not used by Bukkit at all and are a bit useless, they are only useful if you have a modded server such as MCPC+ where these custom options are used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
In the case of the flatworld generator, you can specify addition world options to specify what type of layers to generate. These are the same options as can be seen in the &#039;Create new world - Customize&#039; windows in the client. It is here that you can, for example, change the height of the flatworld, change block types or include populators such as ores, villages and trees. The format of the options is a bit vague, you can find more help on this subject on the Minecraft Wiki.&lt;br /&gt;
&lt;br /&gt;
===Creating worlds using a generator plugin=== &amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
You can also specify a world generator plugin to generate the worlds for you. When these plugins ask for a &#039;World manager&#039; to do so, just like Multiverse, MyWorlds allows you to do this. Similar to &#039;world options&#039; above, you can specify a generator plugin and generator arguments in the command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;/world create worldname_environment:plugin(:arguments) (seed)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
Arguments and seed are optional. Some plugins support arguments, others don&#039;t. For more help on what the arguments are and what the format is, visit the plugin pages of these generator plugins.&lt;br /&gt;
&lt;br /&gt;
===Examples=== &amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
Command	Result&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| /world create world1 || Creates a new overworld called &#039;world1&#039;&lt;br /&gt;
|-&lt;br /&gt;
| /world create world1_nether || Creates a new netherworld called &#039;world1_nether&#039;&lt;br /&gt;
|-&lt;br /&gt;
| /world create mynether/nether || Creates a new netherworld called &#039;mynether&#039;&lt;br /&gt;
|-&lt;br /&gt;
| /world create HippoCraft/flat 251 || Creates a new flatworld called &#039;HippoCraft&#039; using seed 251&lt;br /&gt;
|-&lt;br /&gt;
| /world create waterworld/flat::2;7,5x1,5x3,5x12,90x9;1;biome_1,village || Creates a flat waterworld&lt;br /&gt;
|-&lt;br /&gt;
| /world create Space:bSpace:awesome || Create a spaceworld using the bSpace generator plugin with the &#039;awesome&#039; settings&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Loading existing worlds== &amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
You want to load worlds created by others or by a previous/other plugin: this is of course possible. But, if the world is completely new and unknown to MyWorlds its configuration, be VERY sure to specify all arguments required to load the world properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| /world load worldname || Loads world &#039;worldname&#039;&lt;br /&gt;
|-&lt;br /&gt;
| /world load worldname/nether || Loads world &#039;worldname&#039; as a &#039;nether&#039; environment world&lt;br /&gt;
|-&lt;br /&gt;
| /world load worldname/nether:plugin:arguments || Loads world &#039;worldname&#039; making use of a chunk generator plugin &amp;quot;plugin&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
The same create world command syntax is applied. The seed and world options are stored in the world data file, and don&#039;t have to be specified. The environment and optional generator plugin, however, do have to be specified, as it is not stored in the world. Of course, if you already loaded the world once before, just using &amp;lt;code&amp;gt;/world load worldname&amp;lt;/code&amp;gt; is sufficient, since MyWorlds already knows what kind of environment and generator plugin the world uses. The other commands only apply when loading worlds not created by MyWorlds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
Not specifying the right environment or generator plugin will cause chunks to be generated at the borders of the world that do not match with the world. For example, loading a flatworld named &#039;creativeworld&#039; for the first time without specifying the &#039;flat&#039; environment will cause overworld chunks to be generated at the borders.&lt;br /&gt;
&lt;br /&gt;
==Listing available environments/generators== &amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
You can use &amp;lt;code&amp;gt;/world listgenerators&amp;lt;/code&amp;gt; to show a list of all available generator plugins. Using &amp;lt;code&amp;gt;/world create&amp;lt;/code&amp;gt; will list the usage in combination with all available environments.&lt;br /&gt;
&lt;br /&gt;
==Listing available worlds== &amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
You can use &amp;lt;code&amp;gt;/world list&amp;lt;/code&amp;gt; to list all available (loaded, broken and not loaded) worlds. All folders containing a level.dat or a region folder are listed.&lt;br /&gt;
&lt;br /&gt;
==Unloading worlds== &amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
To unload worlds when you no longer need them, use &amp;lt;code&amp;gt;/world unload worldname&amp;lt;/code&amp;gt;. In case you having autosaving disabled for the world, use &amp;lt;code&amp;gt;/world save worldname&amp;lt;/code&amp;gt; before unloading just to avoid losing progress.&lt;br /&gt;
&lt;br /&gt;
==Saving worlds== &amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
To save worlds, use &amp;lt;code&amp;gt;/world save worldname&amp;lt;/code&amp;gt; to save a single world or /world save all to save all worlds. Instead of &#039;all&#039; you can also use &#039;*&#039;.&lt;br /&gt;
&lt;br /&gt;
==Copying worlds - renaming worlds== &amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
You can copy a world to a new name using &amp;lt;code&amp;gt;/world copy worldname newworldname&amp;lt;/code&amp;gt;. The new world can then be loaded again. All world properties from the old world are copied over as well, including generator plugin and environment information. After copying you can load the world safely and/or delete the previous world. You need the right permissions to do this in-game, you can always do this through the console.&lt;br /&gt;
&lt;br /&gt;
==Deleting worlds== &amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
To delete a world from disk permanently, use &amp;lt;code&amp;gt;/world delete worldname&amp;lt;/code&amp;gt;. The worldname must be completely accurate. Name matching is not used, since deleting the wrong world would become possible then. You need the right permissions to do this in-game, you can always do this through the console.&lt;br /&gt;
&lt;br /&gt;
==Repairing worlds== &amp;lt;!--T:38--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
Shit happens, so it may occur that a world no longer loads properly or the server crashes when loading the world. To repair these worlds, you can use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:40--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;/world repair worldname&lt;br /&gt;
/world repair worldname seed&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you know what seed the world used, it is best to specify that as well. Just in case the level.dat of the world got corrupted and it can no longer read the seed from it, it can use your specified seed to regenerate the settings. It is best if you keep a backup of your level.dat somewhere so that, may it ever get corrupted, you can fix it up without losing settings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
Apart from regenerating the level.dat, it also goes by all region files and:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:42--&amp;gt;&lt;br /&gt;
Removes chunks that are lost (compression error), and will be regenerated&lt;br /&gt;
Relocate chunks&lt;br /&gt;
Keep a backup of the old, unchanged region files&lt;br /&gt;
In all cases, every chunk lost is an actual chunk lost, there is nothing that can be done about that. Making frequent backups of the world is recommended for that reason.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:43--&amp;gt;&lt;br /&gt;
Only unloaded worlds can be repaired. If your corrupted world is the main world, set up a small server somewhere and repair it using that, or simply change the main world in the server configuration and then repair it while unloaded.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=MyWorlds/ManagingWorlds&amp;diff=7866</id>
		<title>MyWorlds/ManagingWorlds</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=MyWorlds/ManagingWorlds&amp;diff=7866"/>
		<updated>2025-10-12T09:49:11Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages/&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==How to create, load, save, unload, delete and copy worlds== &amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
This page covers all the details for creating new worlds, loading existing worlds, saving worlds, unloading worlds and world file operations such as delete and copy.&lt;br /&gt;
&lt;br /&gt;
==Setting up the server== &amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
The server always generates a few initial worlds, which are mainworld, mainworld_nether and mainworld_the_end (if hellworld is enabled). It is required to have these worlds loaded at all times, and since MyWorlds enables after these worlds are loaded, MyWorlds is unable to alter the properties of these main worlds. If you plan on not using the overworld/nether/the end worlds, you still have to have them loaded. You can change &#039;keep spawn loaded&#039; to false so these worlds do not occupy any memory, and change &#039;mainworld&#039; to the desired main world where new people spawn in the config.yml. Then these worlds are not used (but could be used).&lt;br /&gt;
&lt;br /&gt;
==Preface== &amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
All commands except delete match the world name you type in against already existing worlds. If you have a world named &#039;CreeperCraft12&#039;, you can access the world using &#039;Creeper&#039; or &#039;Craft12&#039; as well. It first looks for world names that equal your name entered, then the world names containing what you entered and finally the world names contained in what you entered.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
For command permissions, [[MyWorlds/Permissions|see here]].&lt;br /&gt;
&lt;br /&gt;
==Creating New Worlds== &amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
The first step is to create new worlds you want to use on your server. There are two kinds of ways you can create worlds, they will be listed separately.&lt;br /&gt;
&lt;br /&gt;
===Creating Vanilla worlds=== &amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
To create normal/nether/flat/the_end worlds, you can use the commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;/world create worldname_environment(::options) (seed)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
The ()-surrounded parts are optional. If no seed is specified, a random seed is used instead. When worldname_environment is used, the environment type is appended to the world name, while with worldname/environment it will not append it to the name. Appending the world environment to the name is recommended, since it eases loading the worlds if no configuration is available for it yet. Not specifying an environment means that the NORMAL environment will be used. Bear in mind that the Bukkit &#039;Environment&#039; and &#039;Worldtype&#039; are merged as one in MyWorlds. To have a &#039;nether flatworld&#039;, you use &#039;nether_flat&#039; as environment. Note that most combinations are not used by Bukkit at all and are a bit useless, they are only useful if you have a modded server such as MCPC+ where these custom options are used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
In the case of the flatworld generator, you can specify addition world options to specify what type of layers to generate. These are the same options as can be seen in the &#039;Create new world - Customize&#039; windows in the client. It is here that you can, for example, change the height of the flatworld, change block types or include populators such as ores, villages and trees. The format of the options is a bit vague, you can find more help on this subject on the Minecraft Wiki.&lt;br /&gt;
&lt;br /&gt;
===Creating worlds using a generator plugin=== &amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
You can also specify a world generator plugin to generate the worlds for you. When these plugins ask for a &#039;World manager&#039; to do so, just like Multiverse, MyWorlds allows you to do this. Similar to &#039;world options&#039; above, you can specify a generator plugin and generator arguments in the command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;/world create worldname_environment:plugin(:arguments) (seed)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
Arguments and seed are optional. Some plugins support arguments, others don&#039;t. For more help on what the arguments are and what the format is, visit the plugin pages of these generator plugins.&lt;br /&gt;
&lt;br /&gt;
===Examples=== &amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
Command	Result&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| /world create world1 || Creates a new overworld called &#039;world1&#039;&lt;br /&gt;
|-&lt;br /&gt;
| /world create world1_nether || Creates a new netherworld called &#039;world1_nether&#039;&lt;br /&gt;
|-&lt;br /&gt;
| /world create mynether/nether || Creates a new netherworld called &#039;mynether&#039;&lt;br /&gt;
|-&lt;br /&gt;
| /world create HippoCraft/flat 251 || Creates a new flatworld called &#039;HippoCraft&#039; using seed 251&lt;br /&gt;
|-&lt;br /&gt;
| /world create waterworld/flat::2;7,5x1,5x3,5x12,90x9;1;biome_1,village || Creates a flat waterworld&lt;br /&gt;
|-&lt;br /&gt;
| /world create Space:bSpace:awesome || Create a spaceworld using the bSpace generator plugin with the &#039;awesome&#039; settings&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Loading existing worlds== &amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
You want to load worlds created by others or by a previous/other plugin: this is of course possible. But, if the world is completely new and unknown to MyWorlds its configuration, be VERY sure to specify all arguments required to load the world properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| /world load worldname || Loads world &#039;worldname&#039;&lt;br /&gt;
|-&lt;br /&gt;
| /world load worldname/nether || Loads world &#039;worldname&#039; as a &#039;nether&#039; environment world&lt;br /&gt;
|-&lt;br /&gt;
| /world load worldname/nether:plugin:arguments || Loads world &#039;worldname&#039; making use of a chunk generator plugin &amp;quot;plugin&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
The same create world command syntax is applied. The seed and world options are stored in the world data file, and don&#039;t have to be specified. The environment and optional generator plugin, however, do have to be specified, as it is not stored in the world. Of course, if you already loaded the world once before, just using &amp;lt;code&amp;gt;/world load worldname&amp;lt;/code&amp;gt; is sufficient, since MyWorlds already knows what kind of environment and generator plugin the world uses. The other commands only apply when loading worlds not created by MyWorlds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
Not specifying the right environment or generator plugin will cause chunks to be generated at the borders of the world that do not match with the world. For example, loading a flatworld named &#039;creativeworld&#039; for the first time without specifying the &#039;flat&#039; environment will cause overworld chunks to be generated at the borders.&lt;br /&gt;
&lt;br /&gt;
==Listing available environments/generators== &amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
You can use &amp;lt;code&amp;gt;/world listgenerators&amp;lt;/code&amp;gt; to show a list of all available generator plugins. Using &amp;lt;code&amp;gt;/world create&amp;lt;/code&amp;gt; will list the usage in combination with all available environments.&lt;br /&gt;
&lt;br /&gt;
==Listing available worlds== &amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
You can use &amp;lt;code&amp;gt;/world list&amp;lt;/code&amp;gt; to list all available (loaded, broken and not loaded) worlds. All folders containing a level.dat or a region folder are listed.&lt;br /&gt;
&lt;br /&gt;
==Unloading worlds== &amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
To unload worlds when you no longer need them, use &amp;lt;code&amp;gt;/world unload worldname&amp;lt;/code&amp;gt;. In case you having autosaving disabled for the world, use &amp;lt;code&amp;gt;/world save worldname&amp;lt;/code&amp;gt; before unloading just to avoid losing progress.&lt;br /&gt;
&lt;br /&gt;
==Saving worlds== &amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
To save worlds, use &amp;lt;code&amp;gt;/world save worldname&amp;lt;/code&amp;gt; to save a single world or /world save all to save all worlds. Instead of &#039;all&#039; you can also use &#039;*&#039;.&lt;br /&gt;
&lt;br /&gt;
==Copying worlds - renaming worlds== &amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
You can copy a world to a new name using &amp;lt;code&amp;gt;/world copy worldname newworldname&amp;lt;/code&amp;gt;. The new world can then be loaded again. All world properties from the old world are copied over as well, including generator plugin and environment information. After copying you can load the world safely and/or delete the previous world. You need the right permissions to do this in-game, you can always do this through the console.&lt;br /&gt;
&lt;br /&gt;
==Deleting worlds== &amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
To delete a world from disk permanently, use &amp;lt;code&amp;gt;/world delete worldname&amp;lt;/code&amp;gt;. The worldname must be completely accurate. Name matching is not used, since deleting the wrong world would become possible then. You need the right permissions to do this in-game, you can always do this through the console.&lt;br /&gt;
&lt;br /&gt;
==Repairing worlds== &amp;lt;!--T:38--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
Shit happens, so it may occur that a world no longer loads properly or the server crashes when loading the world. To repair these worlds, you can use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:40--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;/world repair worldname&lt;br /&gt;
/world repair worldname seed&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you know what seed the world used, it is best to specify that as well. Just in case the level.dat of the world got corrupted and it can no longer read the seed from it, it can use your specified seed to regenerate the settings. It is best if you keep a backup of your level.dat somewhere so that, may it ever get corrupted, you can fix it up without losing settings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
Apart from regenerating the level.dat, it also goes by all region files and:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:42--&amp;gt;&lt;br /&gt;
Removes chunks that are lost (compression error), and will be regenerated&lt;br /&gt;
Relocate chunks&lt;br /&gt;
Keep a backup of the old, unchanged region files&lt;br /&gt;
In all cases, every chunk lost is an actual chunk lost, there is nothing that can be done about that. Making frequent backups of the world is recommended for that reason.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:43--&amp;gt;&lt;br /&gt;
Only unloaded worlds can be repaired. If your corrupted world is the main world, set up a small server somewhere and repair it using that, or simply change the main world in the server configuration and then repair it while unloaded.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=MyWorlds/ManagingWorlds&amp;diff=7865</id>
		<title>MyWorlds/ManagingWorlds</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=MyWorlds/ManagingWorlds&amp;diff=7865"/>
		<updated>2025-10-12T09:49:04Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: Marked this version for translation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages/&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==How to create, load, save, unload, delete and copy worlds== &amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
This page covers all the details for creating new worlds, loading existing worlds, saving worlds, unloading worlds and world file operations such as delete and copy.&lt;br /&gt;
&lt;br /&gt;
==Setting up the server== &amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
The server always generates a few initial worlds, which are mainworld, mainworld_nether and mainworld_the_end (if hellworld is enabled). It is required to have these worlds loaded at all times, and since MyWorlds enables after these worlds are loaded, MyWorlds is unable to alter the properties of these main worlds. If you plan on not using the overworld/nether/the end worlds, you still have to have them loaded. You can change &#039;keep spawn loaded&#039; to false so these worlds do not occupy any memory, and change &#039;mainworld&#039; to the desired main world where new people spawn in the config.yml. Then these worlds are not used (but could be used).&lt;br /&gt;
&lt;br /&gt;
==Preface== &amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
All commands except delete match the world name you type in against already existing worlds. If you have a world named &#039;CreeperCraft12&#039;, you can access the world using &#039;Creeper&#039; or &#039;Craft12&#039; as well. It first looks for world names that equal your name entered, then the world names containing what you entered and finally the world names contained in what you entered.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
For command permissions, [[MyWorlds/Permissions|see here]].&lt;br /&gt;
&lt;br /&gt;
==Creating New Worlds== &amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
The first step is to create new worlds you want to use on your server. There are two kinds of ways you can create worlds, they will be listed separately.&lt;br /&gt;
&lt;br /&gt;
===Creating Vanilla worlds=== &amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
To create normal/nether/flat/the_end worlds, you can use the commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;/world create worldname_environment(::options) (seed)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
The ()-surrounded parts are optional. If no seed is specified, a random seed is used instead. When worldname_environment is used, the environment type is appended to the world name, while with worldname/environment it will not append it to the name. Appending the world environment to the name is recommended, since it eases loading the worlds if no configuration is available for it yet. Not specifying an environment means that the NORMAL environment will be used. Bear in mind that the Bukkit &#039;Environment&#039; and &#039;Worldtype&#039; are merged as one in MyWorlds. To have a &#039;nether flatworld&#039;, you use &#039;nether_flat&#039; as environment. Note that most combinations are not used by Bukkit at all and are a bit useless, they are only useful if you have a modded server such as MCPC+ where these custom options are used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
In the case of the flatworld generator, you can specify addition world options to specify what type of layers to generate. These are the same options as can be seen in the &#039;Create new world - Customize&#039; windows in the client. It is here that you can, for example, change the height of the flatworld, change block types or include populators such as ores, villages and trees. The format of the options is a bit vague, you can find more help on this subject on the Minecraft Wiki.&lt;br /&gt;
&lt;br /&gt;
===Creating worlds using a generator plugin=== &amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
You can also specify a world generator plugin to generate the worlds for you. When these plugins ask for a &#039;World manager&#039; to do so, just like Multiverse, MyWorlds allows you to do this. Similar to &#039;world options&#039; above, you can specify a generator plugin and generator arguments in the command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;/world create worldname_environment:plugin(:arguments) (seed)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
Arguments and seed are optional. Some plugins support arguments, others don&#039;t. For more help on what the arguments are and what the format is, visit the plugin pages of these generator plugins.&lt;br /&gt;
&lt;br /&gt;
===Examples=== &amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
Command	Result&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| /world create world1 || Creates a new overworld called &#039;world1&#039;&lt;br /&gt;
|-&lt;br /&gt;
| /world create world1_nether || Creates a new netherworld called &#039;world1_nether&#039;&lt;br /&gt;
|-&lt;br /&gt;
| /world create mynether/nether || Creates a new netherworld called &#039;mynether&#039;&lt;br /&gt;
|-&lt;br /&gt;
| /world create HippoCraft/flat 251 || Creates a new flatworld called &#039;HippoCraft&#039; using seed 251&lt;br /&gt;
|-&lt;br /&gt;
| /world create waterworld/flat::2;7,5x1,5x3,5x12,90x9;1;biome_1,village || Creates a flat waterworld&lt;br /&gt;
|-&lt;br /&gt;
| /world create Space:bSpace:awesome || Create a spaceworld using the bSpace generator plugin with the &#039;awesome&#039; settings&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Loading existing worlds== &amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
You want to load worlds created by others or by a previous/other plugin: this is of course possible. But, if the world is completely new and unknown to MyWorlds its configuration, be VERY sure to specify all arguments required to load the world properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| /world load worldname || Loads world &#039;worldname&#039;&lt;br /&gt;
|-&lt;br /&gt;
| /world load worldname/nether || Loads world &#039;worldname&#039; as a &#039;nether&#039; environment world&lt;br /&gt;
|-&lt;br /&gt;
| /world load worldname/nether:plugin:arguments || Loads world &#039;worldname&#039; making use of a chunk generator plugin &amp;quot;plugin&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
The same create world command syntax is applied. The seed and world options are stored in the world data file, and don&#039;t have to be specified. The environment and optional generator plugin, however, do have to be specified, as it is not stored in the world. Of course, if you already loaded the world once before, just using &amp;lt;code&amp;gt;/world load worldname&amp;lt;/code&amp;gt; is sufficient, since MyWorlds already knows what kind of environment and generator plugin the world uses. The other commands only apply when loading worlds not created by MyWorlds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
Not specifying the right environment or generator plugin will cause chunks to be generated at the borders of the world that do not match with the world. For example, loading a flatworld named &#039;creativeworld&#039; for the first time without specifying the &#039;flat&#039; environment will cause overworld chunks to be generated at the borders.&lt;br /&gt;
&lt;br /&gt;
==Listing available environments/generators== &amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
You can use &amp;lt;code&amp;gt;/world listgenerators&amp;lt;/code&amp;gt; to show a list of all available generator plugins. Using &amp;lt;code&amp;gt;/world create&amp;lt;/code&amp;gt; will list the usage in combination with all available environments.&lt;br /&gt;
&lt;br /&gt;
==Listing available worlds== &amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
You can use &amp;lt;code&amp;gt;/world list&amp;lt;/code&amp;gt; to list all available (loaded, broken and not loaded) worlds. All folders containing a level.dat or a region folder are listed.&lt;br /&gt;
&lt;br /&gt;
==Unloading worlds== &amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
To unload worlds when you no longer need them, use &amp;lt;code&amp;gt;/world unload worldname&amp;lt;/code&amp;gt;. In case you having autosaving disabled for the world, use &amp;lt;code&amp;gt;/world save worldname&amp;lt;/code&amp;gt; before unloading just to avoid losing progress.&lt;br /&gt;
&lt;br /&gt;
==Saving worlds== &amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
To save worlds, use &amp;lt;code&amp;gt;/world save worldname&amp;lt;/code&amp;gt; to save a single world or /world save all to save all worlds. Instead of &#039;all&#039; you can also use &#039;*&#039;.&lt;br /&gt;
&lt;br /&gt;
==Copying worlds - renaming worlds== &amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
You can copy a world to a new name using &amp;lt;code&amp;gt;/world copy worldname newworldname&amp;lt;/code&amp;gt;. The new world can then be loaded again. All world properties from the old world are copied over as well, including generator plugin and environment information. After copying you can load the world safely and/or delete the previous world. You need the right permissions to do this in-game, you can always do this through the console.&lt;br /&gt;
&lt;br /&gt;
==Deleting worlds== &amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
To delete a world from disk permanently, use &amp;lt;code&amp;gt;/world delete worldname&amp;lt;/code&amp;gt;. The worldname must be completely accurate. Name matching is not used, since deleting the wrong world would become possible then. You need the right permissions to do this in-game, you can always do this through the console.&lt;br /&gt;
&lt;br /&gt;
==Repairing worlds== &amp;lt;!--T:38--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
Shit happens, so it may occur that a world no longer loads properly or the server crashes when loading the world. To repair these worlds, you can use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:40--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;/world repair worldname&lt;br /&gt;
/world repair worldname seed&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you know what seed the world used, it is best to specify that as well. Just in case the level.dat of the world got corrupted and it can no longer read the seed from it, it can use your specified seed to regenerate the settings. It is best if you keep a backup of your level.dat somewhere so that, may it ever get corrupted, you can fix it up without losing settings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
Apart from regenerating the level.dat, it also goes by all region files and:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:42--&amp;gt;&lt;br /&gt;
Removes chunks that are lost (compression error), and will be regenerated&lt;br /&gt;
Relocate chunks&lt;br /&gt;
Keep a backup of the old, unchanged region files&lt;br /&gt;
In all cases, every chunk lost is an actual chunk lost, there is nothing that can be done about that. Making frequent backups of the world is recommended for that reason.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:43--&amp;gt;&lt;br /&gt;
Only unloaded worlds can be repaired. If your corrupted world is the main world, set up a small server somewhere and repair it using that, or simply change the main world in the server configuration and then repair it while unloaded.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=MyWorlds/ManagingWorlds&amp;diff=7864</id>
		<title>MyWorlds/ManagingWorlds</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=MyWorlds/ManagingWorlds&amp;diff=7864"/>
		<updated>2025-10-12T09:48:58Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages/&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==How to create, load, save, unload, delete and copy worlds==&lt;br /&gt;
&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
This page covers all the details for creating new worlds, loading existing worlds, saving worlds, unloading worlds and world file operations such as delete and copy.&lt;br /&gt;
&lt;br /&gt;
==Setting up the server== &amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
The server always generates a few initial worlds, which are mainworld, mainworld_nether and mainworld_the_end (if hellworld is enabled). It is required to have these worlds loaded at all times, and since MyWorlds enables after these worlds are loaded, MyWorlds is unable to alter the properties of these main worlds. If you plan on not using the overworld/nether/the end worlds, you still have to have them loaded. You can change &#039;keep spawn loaded&#039; to false so these worlds do not occupy any memory, and change &#039;mainworld&#039; to the desired main world where new people spawn in the config.yml. Then these worlds are not used (but could be used).&lt;br /&gt;
&lt;br /&gt;
==Preface== &amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
All commands except delete match the world name you type in against already existing worlds. If you have a world named &#039;CreeperCraft12&#039;, you can access the world using &#039;Creeper&#039; or &#039;Craft12&#039; as well. It first looks for world names that equal your name entered, then the world names containing what you entered and finally the world names contained in what you entered.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
For command permissions, [[MyWorlds/Permissions|see here]].&lt;br /&gt;
&lt;br /&gt;
==Creating New Worlds== &amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
The first step is to create new worlds you want to use on your server. There are two kinds of ways you can create worlds, they will be listed separately.&lt;br /&gt;
&lt;br /&gt;
===Creating Vanilla worlds=== &amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
To create normal/nether/flat/the_end worlds, you can use the commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;/world create worldname_environment(::options) (seed)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
The ()-surrounded parts are optional. If no seed is specified, a random seed is used instead. When worldname_environment is used, the environment type is appended to the world name, while with worldname/environment it will not append it to the name. Appending the world environment to the name is recommended, since it eases loading the worlds if no configuration is available for it yet. Not specifying an environment means that the NORMAL environment will be used. Bear in mind that the Bukkit &#039;Environment&#039; and &#039;Worldtype&#039; are merged as one in MyWorlds. To have a &#039;nether flatworld&#039;, you use &#039;nether_flat&#039; as environment. Note that most combinations are not used by Bukkit at all and are a bit useless, they are only useful if you have a modded server such as MCPC+ where these custom options are used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
In the case of the flatworld generator, you can specify addition world options to specify what type of layers to generate. These are the same options as can be seen in the &#039;Create new world - Customize&#039; windows in the client. It is here that you can, for example, change the height of the flatworld, change block types or include populators such as ores, villages and trees. The format of the options is a bit vague, you can find more help on this subject on the Minecraft Wiki.&lt;br /&gt;
&lt;br /&gt;
===Creating worlds using a generator plugin=== &amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
You can also specify a world generator plugin to generate the worlds for you. When these plugins ask for a &#039;World manager&#039; to do so, just like Multiverse, MyWorlds allows you to do this. Similar to &#039;world options&#039; above, you can specify a generator plugin and generator arguments in the command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;/world create worldname_environment:plugin(:arguments) (seed)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
Arguments and seed are optional. Some plugins support arguments, others don&#039;t. For more help on what the arguments are and what the format is, visit the plugin pages of these generator plugins.&lt;br /&gt;
&lt;br /&gt;
===Examples=== &amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
Command	Result&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| /world create world1 || Creates a new overworld called &#039;world1&#039;&lt;br /&gt;
|-&lt;br /&gt;
| /world create world1_nether || Creates a new netherworld called &#039;world1_nether&#039;&lt;br /&gt;
|-&lt;br /&gt;
| /world create mynether/nether || Creates a new netherworld called &#039;mynether&#039;&lt;br /&gt;
|-&lt;br /&gt;
| /world create HippoCraft/flat 251 || Creates a new flatworld called &#039;HippoCraft&#039; using seed 251&lt;br /&gt;
|-&lt;br /&gt;
| /world create waterworld/flat::2;7,5x1,5x3,5x12,90x9;1;biome_1,village || Creates a flat waterworld&lt;br /&gt;
|-&lt;br /&gt;
| /world create Space:bSpace:awesome || Create a spaceworld using the bSpace generator plugin with the &#039;awesome&#039; settings&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Loading existing worlds== &amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
You want to load worlds created by others or by a previous/other plugin: this is of course possible. But, if the world is completely new and unknown to MyWorlds its configuration, be VERY sure to specify all arguments required to load the world properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Command !! Description&lt;br /&gt;
|-&lt;br /&gt;
| /world load worldname || Loads world &#039;worldname&#039;&lt;br /&gt;
|-&lt;br /&gt;
| /world load worldname/nether || Loads world &#039;worldname&#039; as a &#039;nether&#039; environment world&lt;br /&gt;
|-&lt;br /&gt;
| /world load worldname/nether:plugin:arguments || Loads world &#039;worldname&#039; making use of a chunk generator plugin &amp;quot;plugin&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
The same create world command syntax is applied. The seed and world options are stored in the world data file, and don&#039;t have to be specified. The environment and optional generator plugin, however, do have to be specified, as it is not stored in the world. Of course, if you already loaded the world once before, just using &amp;lt;code&amp;gt;/world load worldname&amp;lt;/code&amp;gt; is sufficient, since MyWorlds already knows what kind of environment and generator plugin the world uses. The other commands only apply when loading worlds not created by MyWorlds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
Not specifying the right environment or generator plugin will cause chunks to be generated at the borders of the world that do not match with the world. For example, loading a flatworld named &#039;creativeworld&#039; for the first time without specifying the &#039;flat&#039; environment will cause overworld chunks to be generated at the borders.&lt;br /&gt;
&lt;br /&gt;
==Listing available environments/generators== &amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
You can use &amp;lt;code&amp;gt;/world listgenerators&amp;lt;/code&amp;gt; to show a list of all available generator plugins. Using &amp;lt;code&amp;gt;/world create&amp;lt;/code&amp;gt; will list the usage in combination with all available environments.&lt;br /&gt;
&lt;br /&gt;
==Listing available worlds== &amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
You can use &amp;lt;code&amp;gt;/world list&amp;lt;/code&amp;gt; to list all available (loaded, broken and not loaded) worlds. All folders containing a level.dat or a region folder are listed.&lt;br /&gt;
&lt;br /&gt;
==Unloading worlds== &amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
To unload worlds when you no longer need them, use &amp;lt;code&amp;gt;/world unload worldname&amp;lt;/code&amp;gt;. In case you having autosaving disabled for the world, use &amp;lt;code&amp;gt;/world save worldname&amp;lt;/code&amp;gt; before unloading just to avoid losing progress.&lt;br /&gt;
&lt;br /&gt;
==Saving worlds== &amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
To save worlds, use &amp;lt;code&amp;gt;/world save worldname&amp;lt;/code&amp;gt; to save a single world or /world save all to save all worlds. Instead of &#039;all&#039; you can also use &#039;*&#039;.&lt;br /&gt;
&lt;br /&gt;
==Copying worlds - renaming worlds== &amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
You can copy a world to a new name using &amp;lt;code&amp;gt;/world copy worldname newworldname&amp;lt;/code&amp;gt;. The new world can then be loaded again. All world properties from the old world are copied over as well, including generator plugin and environment information. After copying you can load the world safely and/or delete the previous world. You need the right permissions to do this in-game, you can always do this through the console.&lt;br /&gt;
&lt;br /&gt;
==Deleting worlds== &amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
To delete a world from disk permanently, use &amp;lt;code&amp;gt;/world delete worldname&amp;lt;/code&amp;gt;. The worldname must be completely accurate. Name matching is not used, since deleting the wrong world would become possible then. You need the right permissions to do this in-game, you can always do this through the console.&lt;br /&gt;
&lt;br /&gt;
==Repairing worlds== &amp;lt;!--T:38--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
Shit happens, so it may occur that a world no longer loads properly or the server crashes when loading the world. To repair these worlds, you can use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:40--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;/world repair worldname&lt;br /&gt;
/world repair worldname seed&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you know what seed the world used, it is best to specify that as well. Just in case the level.dat of the world got corrupted and it can no longer read the seed from it, it can use your specified seed to regenerate the settings. It is best if you keep a backup of your level.dat somewhere so that, may it ever get corrupted, you can fix it up without losing settings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
Apart from regenerating the level.dat, it also goes by all region files and:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:42--&amp;gt;&lt;br /&gt;
Removes chunks that are lost (compression error), and will be regenerated&lt;br /&gt;
Relocate chunks&lt;br /&gt;
Keep a backup of the old, unchanged region files&lt;br /&gt;
In all cases, every chunk lost is an actual chunk lost, there is nothing that can be done about that. Making frequent backups of the world is recommended for that reason.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:43--&amp;gt;&lt;br /&gt;
Only unloaded worlds can be repaired. If your corrupted world is the main world, set up a small server somewhere and repair it using that, or simply change the main world in the server configuration and then repair it while unloaded.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/NBTTagAPI&amp;diff=7858</id>
		<title>BKCommonLib/NBTTagAPI</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/NBTTagAPI&amp;diff=7858"/>
		<updated>2025-10-12T09:48:11Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
To use NBT Tag objects to store information, or to interact with the Minecraft server internals which uses this format, BKCommonLib provides wrapper classes to work with them safely. These classes are:&lt;br /&gt;
&lt;br /&gt;
CommonTag - for storing actual raw data like floats, doubles, String, arrays, etc. All other tag types extend this one.&lt;br /&gt;
CommonTagList - for storing integer-indexed values of the same type. Implements List.&lt;br /&gt;
CommonTagCompound - for storing text-mapped values of different types. Implements Map.&lt;br /&gt;
NBTUtil - for server-specific operations like loading and saving entities&lt;br /&gt;
The CommonTag classes are so-called &#039;wrapper&#039; classes around actual internal NBT tag objects. They make it easier, and safer, to pass around tags. Internally, no CommonTag objects are stored, only the NBT types. Like all wrapper classes extending BasicWrapper, you can get (and set) the internal handle of the tag. This way you are able to use these objects with internal logic. In general, you will not really use that, but it&#039;s there.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
There are several use cases for these tags:&lt;br /&gt;
&lt;br /&gt;
==Working with NBT &#039;handle&#039; Tags==&lt;br /&gt;
You can construct a CommonTag from the handle using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;CommonTag tag = CommonTag.create(handle);&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you are absolutely certain about the type of handle you pass in, you can cast the result to CommonTagList or Compound directly. After creation you can work on it directly, and changes you perform automatically update the handle you passed in initially.&lt;br /&gt;
&lt;br /&gt;
==Creating new tags==&lt;br /&gt;
To construct new CommonTags from data, there are several options:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;CommonTag tag1 = CommonTag.create(&amp;quot;myTagName&amp;quot;, &amp;quot;text&amp;quot;);&lt;br /&gt;
CommonTag tag2 = new CommonTag(&amp;quot;myIntData&amp;quot;, 12);&lt;br /&gt;
CommonTagList tagList = new CommonTagList();&lt;br /&gt;
CommonTagList tagList = new CommonTagList(&amp;quot;MyName&amp;quot;, someListOfValues);&lt;br /&gt;
CommonTagCompound compound = new CommonTagCompound(&amp;quot;SomeMap&amp;quot;, someMapOfValues);&amp;lt;/pre&amp;gt;&lt;br /&gt;
When no name is provided, a &#039;null&#039; name is used. A tag name is not required, a value always is. You can not construct a data tag (CommonTag) without non-null and supported data. For that reason, this will NOT work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;CommonTag myData = new CommonTag(&amp;quot;Data&amp;quot;, null);&lt;br /&gt;
myData.setData(12);&amp;lt;/pre&amp;gt;&lt;br /&gt;
This has to do with the fact that the internal handle can not change after creation, and it is impossible to hotswap this type.&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
You can set the name of the tag using setName and get the current name using getName.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Data&#039;&#039;&#039;&lt;br /&gt;
All Common Tags provide setData and getData methods. These methods directly change the data stored by the internal implementation. In the case of CommonTagList and Compound, it allows you to directly set a map or list of values, instead of adding or removing a single mapped value.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Values&#039;&#039;&#039;&lt;br /&gt;
CommonTagList and Compound implement Map and List in a way that it stores other CommonTags, but if all you want is the value and do not want to create a wrapper class to get it each time, you can use the &#039;values&#039; methods.&lt;br /&gt;
&lt;br /&gt;
They store multiple values (or entries), so to make a distinction, index or text-mapped data are called values. They are called this way because it obtains the value from a tag stored. CommonTagList has many methods for adding, removing, getting and setting values, CommonTagList has many methods for putting, removing and getting values.&lt;br /&gt;
&lt;br /&gt;
==Getting values==&lt;br /&gt;
At compile time it is never really certain what type of data is stored. For this reason, there are many overloads that automatically convert values. This way you are able to get a &#039;String&#039; from an int or byte tag, or the other way around, without issues. To do this, you do have to specify the Class type to obtain, or a non-null default. Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;CommonTagCompound data = new CommonTagCompound(&amp;quot;data&amp;quot;);&lt;br /&gt;
data.putValue(&amp;quot;x&amp;quot;, 12);&lt;br /&gt;
data.putValue(&amp;quot;y&amp;quot;, 15);&lt;br /&gt;
data.putValue(&amp;quot;difficulty&amp;quot;, -1);&lt;br /&gt;
String textX = data.getValue(&amp;quot;x&amp;quot;, String.class);&lt;br /&gt;
double doubleY= data.getValue(&amp;quot;y&amp;quot;, 0.0);&lt;br /&gt;
Difficulty diffculty = data.getValue(&amp;quot;difficulty&amp;quot;, Difficulty.class, null);&lt;br /&gt;
if (difficulty != null) {&lt;br /&gt;
   System.out.println(difficulty);&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
As you can see, it is even possible to obtain a difficulty from the difficulty identifier. The internal conversion system takes care of that for you.&lt;br /&gt;
&lt;br /&gt;
==Using tags as lists and maps==&lt;br /&gt;
CommonTagList and Compound fully implement List and Map respectively. This includes iteration and other logic. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;CommonTagList list = new CommonTagList(12, 14, 16, 18, 12, -3);&lt;br /&gt;
for (CommonTag tag : list) {&lt;br /&gt;
    System.out.println(&amp;quot;VALUE: &amp;quot; + tag.getData(0));&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also note the getData(0), which gets the data as an Integer with 0 as default if this fails. If you wish to access the data directly, you can use the getAllValues method for list to do so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;for (int value : list.getAllValues(int[].class)) {&lt;br /&gt;
    System.out.println(value);&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Do note that this allocates a new int[] array for the result.&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
This API allows you to use tags as maps, lists or actual data. Additionally, it provides methods to directly obtain values from lists and maps, without creating new tags. It utilizes the internal conversion system to dynamically obtain values of any type you want, without forced method overloads. This allows further integration of NBT in other, generic classes.&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/PluginBase&amp;diff=7855</id>
		<title>BKCommonLib/PluginBase</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/PluginBase&amp;diff=7855"/>
		<updated>2025-10-12T09:47:56Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
For more information, see also:&lt;br /&gt;
&lt;br /&gt;
* [[BKCommonLib/Localization|Localization]]&lt;br /&gt;
* [[BKCommonLib/PermissionDefaults|Permission Defaults]]&lt;br /&gt;
* [[BKCommonLib/Metrics|Metrics]]&lt;br /&gt;
PluginBase is a basic JavaPlugin base class that eases the use of Localization, Permissions, error handling, logging and more. The base implementation takes care of a lot of things going on in the background, including a BKCommonLib compatibility check.&lt;br /&gt;
&lt;br /&gt;
==Features==&lt;br /&gt;
All common plugin routines are taken care of. They will all be listed below. To use PluginBase in your plugin, simply instantiate it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;public class MyPlugin extends PluginBase {&lt;br /&gt;
    @Override&lt;br /&gt;
    public void enable() {&lt;br /&gt;
        // Enable logic&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public void disable() {&lt;br /&gt;
        // Disable logic&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public boolean command(CommandSender sender, String command, String[] args) {&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public int getMinimumLibVersion() {&lt;br /&gt;
        return Common.VERSION;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
==BKCommonLib routines==&lt;br /&gt;
getMinimumLibVersion() has to be overrided when using this base class. This method tells BKCommonLib the minimum version this plugin supports, so a proper message can be sent to the end-user if BKCommonLib is outdated. This avoids needless dependency-related issues.&lt;br /&gt;
&lt;br /&gt;
==Localization==&lt;br /&gt;
The localization() method is called before enabling and can be used to load Locale information to read/write from/to the Localization.yml. You can load single localization lines or an entire enumeration of them using the loadLocale and loadLocales methods. Examples:&lt;br /&gt;
&lt;br /&gt;
Loading localization lines one by one&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;@Override&lt;br /&gt;
public void localization() {&lt;br /&gt;
    loadLocale(&amp;quot;noperm&amp;quot;, ChatColor.RED + &amp;quot;You do not have permission!&amp;quot;);&lt;br /&gt;
    loadLocale(&amp;quot;nobuild&amp;quot;, ChatColor.RED + &amp;quot;You can not build here!&amp;quot;);&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Loading localization lines from a class containing constants, or an enum&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;@Override&lt;br /&gt;
public void localization() {&lt;br /&gt;
    loadLocales(MyLocale.class);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class MyLocale extends LocalizationEnum {&lt;br /&gt;
    public static final MyLocale NOPERM = new MyLocale(&amp;quot;noperm&amp;quot;, ChatColor.RED + &amp;quot;You do not have permission!&amp;quot;);&lt;br /&gt;
    public static final MyLocale NOBUILD = new MyLocale(&amp;quot;nobuild&amp;quot;, ChatColor.RED + &amp;quot;You can not build in world %0%!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    private Localization(String name, String defValue) {&lt;br /&gt;
        super(name, defValue);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public String get(String... arguments) {&lt;br /&gt;
        return MyPlugin.getInstance().getLocale(this.getName(), arguments);&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
The benefit of using a Locale class like the above is that you do not have to use getLocale(name), allowing you to get localization messages a lot easier. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;MyLocale.NOPERM.message(player);&lt;br /&gt;
MyLocale.NOBUILD.message(player, player.getWorld().getName());&amp;lt;/pre&amp;gt;&lt;br /&gt;
==Permission defaults==&lt;br /&gt;
It works exactly the same way localization works, but instead you override permissions() and use the loadPermission and loadPermissions methods. The equivalent enumeration class to use is called PermissionEnum. This enumeration automatically provides methods for permission checks, such as handle and has.&lt;br /&gt;
&lt;br /&gt;
==Commands==&lt;br /&gt;
BKCommonLib automatically gives you the name version command to display the currently running plugin and BKCommonLib version. It also takes care of permission issues, by using and handling the NoPermissionException. If this is thrown for the console, a message is displayed that the command is not possible for use in the console.&lt;br /&gt;
&lt;br /&gt;
==Dependencies==&lt;br /&gt;
The updateDependency method is called whenever a new plugin enables, and after your plugin has enabled it calls it once for all currently enabled plugins. It allows you to keep track of dependencies, or to change some internal settings to provide support.&lt;br /&gt;
&lt;br /&gt;
==Metrics==&lt;br /&gt;
You can automatically use Metrics by adding the following in the plugin.yml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;metrics: true&amp;lt;/pre&amp;gt;&lt;br /&gt;
By default this is disabled. To use Metrics, call the provided hasMetrics and getMetrics methods. There is no need to start the Metrics instance when enabling, PluginBase does that for you. For more information about Metrics, see this page.&lt;br /&gt;
&lt;br /&gt;
==Other==&lt;br /&gt;
* &#039;&#039;&#039;handle&#039;&#039;&#039; allows you to handle errors occurring in your plugin, which takes care of proper formatting and plugin disabling for critical errors&lt;br /&gt;
* &#039;&#039;&#039;log&#039;&#039;&#039; and &#039;&#039;&#039;logAction&#039;&#039;&#039; uses the plugin&#039;s logger to write messages, it&#039;s a simple shortcut&lt;br /&gt;
* &#039;&#039;&#039;register&#039;&#039;&#039; methods allow you to register Bukkit or packet listeners, and to register commands/commandhandlers&lt;br /&gt;
* &#039;&#039;&#039;getDataFile&#039;&#039;&#039; obtains a File object pointing to a file relative to the plugin &#039;workspace&#039; directory&lt;br /&gt;
* Properly disables other plugins depending on you before your plugin disables to avoid conflicts&lt;br /&gt;
* Handles enable, disable and command method errors automatically&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/Metrics&amp;diff=7854</id>
		<title>BKCommonLib/Metrics</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/Metrics&amp;diff=7854"/>
		<updated>2025-10-12T09:47:40Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Update|BKCommonLib|10 June 2021|reason=BKCommonLib now uses bStats metrics.|date=16 June 2023}}&lt;br /&gt;
==Introduction==&lt;br /&gt;
[https://dev.bukkit.org/linkout?remoteUrl=https%253a%252f%252fmcstats.org%252f Metrics] is a service provided by &#039;&#039;&#039;Hidendra&#039;&#039;&#039; to keep track of plugin statistics. It allows plugin developers to see who uses their plugin the most, and to keep track of certain features. This makes it easier to decide on new features and to see what parts of the plugin really matter to most people. The data is sent anonymously, that is, no server IP/player names/personal information is sent to the database.&lt;br /&gt;
&lt;br /&gt;
You do not want to participate in this as a server? Aw...oh well, you can opt-out on Metrics globally in the metrics configuration file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;plugins\PluginMetrics\config.yml &amp;lt; change opt-out: to true.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Metrics in BKCommonLib==&lt;br /&gt;
A Metrics implementation, almost entirely similar as the one provided by mcstats, is included in BKCommonLib. It provides an easy API layer to set up the data you wish to send to the server. Instead of scheduling a task to update it every other time, or having synchronization issues, the Metrics implementation in BKCommonLib works slightly differently.&lt;br /&gt;
&lt;br /&gt;
==Creating Metrics for your plugin==&lt;br /&gt;
How to obtain a [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/metrics/Metrics.java Metrics] class instance to use it in your plugin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===PluginBase===&lt;br /&gt;
If you use [[BKCommonLib/PluginBase|PluginBase]] for your plugin, all you have to do is add &#039;metrics: true&#039; to the plugin.yml of the plugin. After that you can obtain the Metrics instance using the provided &#039;&#039;&#039;getMetrics()&#039;&#039;&#039; method. Before using it, check that metrics is available (and enabled) using the &#039;&#039;&#039;hasMetrics()&#039;&#039;&#039; method, otherwise errors will occur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Manually===&lt;br /&gt;
To manually create a new Metrics instance, use the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Metrics metrics = Metrics.initialize(this);&lt;br /&gt;
if (metrics != null) {&lt;br /&gt;
    // Add your graphs here&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can also create a new Metrics instance using the provided constructor, and handle the errors yourself. In that case, make sure you also call start() once all graphs are added. The initialize method does that for you.&lt;br /&gt;
&lt;br /&gt;
==Adding graphs==&lt;br /&gt;
Graphs in this implementation work slightly different than the ones found elsewhere. In BKCommonLib, Metrics graphs contain an &#039;&#039;&#039;onUpdate&#039;&#039;&#039; method in which the values can be set. It also does not contain a &#039;Plotter&#039; class, instead it uses a map of values. it is up to the plugin to fill or update the data in the graph. The &#039;&#039;&#039;onUpdate&#039;&#039;&#039; method is called on the main thread (synchronized), so it is thread-safe to access Bukkit or plugin resources.&lt;br /&gt;
&lt;br /&gt;
To add a graph, use &#039;&#039;&#039;Metrics.addGraph&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Changing plotter values in graphs==&lt;br /&gt;
A plotter value is basically a single value for part of a graph displayed on [https://mcstats.org mcstats.org]. For example, if you have a Commands graph, you can add plotter values for all commands the plugin provides, mapped to the amount of times it was performed.&lt;br /&gt;
&lt;br /&gt;
Plotter values have to be numeric (int, double, float, etc.), non-numeric text is not possible simply because it can&#039;t be displayed in a graph.&lt;br /&gt;
&lt;br /&gt;
There are several methods to change &#039;plotter&#039; values:&lt;br /&gt;
* &#039;&#039;&#039;clearPlotters&#039;&#039;&#039; - removes all set plotters&lt;br /&gt;
* &#039;&#039;&#039;togglePlotter&#039;&#039;&#039; - Adds a plotter with value &#039;1&#039; if enabled, or removes the plotter if disabled&lt;br /&gt;
* &#039;&#039;&#039;addPlotter&#039;&#039;&#039; - Adds a plotter mapping the value to a key&lt;br /&gt;
&lt;br /&gt;
Example graph implementation (found in enable() of a PluginBase):&lt;br /&gt;
&amp;lt;pre&amp;gt;// Total server memory&lt;br /&gt;
getMetrics().addGraph(new Graph(&amp;quot;Total server memory&amp;quot;) {&lt;br /&gt;
    @Override&lt;br /&gt;
    public void onUpdate(Plugin plugin) {&lt;br /&gt;
        clearPlotters();&lt;br /&gt;
        // Get server total memory in MB (&amp;gt;&amp;gt; 20 = / (1024 * 1024))&lt;br /&gt;
        final long mem = Runtime.getRuntime().totalMemory() &amp;gt;&amp;gt; 20;&lt;br /&gt;
        final String key;&lt;br /&gt;
        if (mem &amp;lt;= 512) {&lt;br /&gt;
            key = &amp;quot;0-512 MB&amp;quot;;&lt;br /&gt;
        } else if (mem &amp;lt;= 1024) {&lt;br /&gt;
            key = &amp;quot;512-1024 MB&amp;quot;;&lt;br /&gt;
        } else if (mem &amp;lt;= 2048) {&lt;br /&gt;
            key = &amp;quot;1024-2048 MB&amp;quot;;&lt;br /&gt;
        } else if (mem &amp;lt;= 4096) {&lt;br /&gt;
            key = &amp;quot;2048-4096 MB&amp;quot;;&lt;br /&gt;
        } else if (mem &amp;lt;= 8192) {&lt;br /&gt;
            key = &amp;quot;4096-8192 MB&amp;quot;;&lt;br /&gt;
        } else if (mem &amp;lt;= 16384) {&lt;br /&gt;
            key = &amp;quot;8-16 GB&amp;quot;;&lt;br /&gt;
        } else {&lt;br /&gt;
            key = &amp;quot;16+ GB&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        togglePlotter(key, true);&lt;br /&gt;
    }&lt;br /&gt;
});&amp;lt;/pre&amp;gt;&lt;br /&gt;
This produces a graph as follows (pie chart): Total server memory - Pie chart&lt;br /&gt;
&lt;br /&gt;
==Default graph implementations==&lt;br /&gt;
BKCommonLib also includes some &#039;common&#039; Graph implementations. These are:&lt;br /&gt;
* [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/metrics/MyDependingPluginsGraph.java MyDependingPluginsGraph] - shows the plugins depending on your plugin&lt;br /&gt;
* [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/metrics/SoftDependenciesGraph.java SoftDependenciesGraph] - shows the plugins enabled that your plugin has a soft dependency on&lt;br /&gt;
&lt;br /&gt;
Important notes&lt;br /&gt;
* &#039;&#039;&#039;onUpdate&#039;&#039;&#039; is not called if the server opted out, also if the server opted out after your metrics instance was started.&lt;br /&gt;
* &#039;&#039;&#039;getMetrics()&#039;&#039;&#039; throws an exception if no metrics is available - use &#039;&#039;&#039;hasMetrics()&#039;&#039;&#039; before using it&lt;br /&gt;
* To use metrics in &#039;&#039;&#039;PluginBase&#039;&#039;&#039;, add the &#039;&#039;&#039;metrics: true&#039;&#039;&#039; to the plugin.yml. By default metrics is disabled.&lt;br /&gt;
* Only use numeric plotter values&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=MyWorlds/Permissions&amp;diff=7853</id>
		<title>MyWorlds/Permissions</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=MyWorlds/Permissions&amp;diff=7853"/>
		<updated>2025-10-12T09:47:21Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Below the permission nodes of MyWorlds. Works best with Luckperms as it better handles .* permissions natively.&lt;br /&gt;
&lt;br /&gt;
== Command permissions ==&lt;br /&gt;
The following permissions are used with the respectable Commands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command !! Permission Node !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| /world create || myworlds.world.create || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world load || myworlds.world.load || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world unload || myworlds.world.unload || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world list || myworlds.world.list || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world info || myworlds.world.info || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world portals || myworlds.world.portals || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world listgenerators || myworlds.world.listgenerators || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world setdefaultportal || myworlds.world.setportal || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world spawn || myworlds.world.spawn || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world evacuate || myworlds.world.evacuate || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world repair || myworlds.world.repair || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world save|| myworlds.world.save || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world saving || myworlds.world.setsaving || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world delete || myworlds.world.delete || NO&lt;br /&gt;
|-&lt;br /&gt;
| /world copy || myworlds.world.copy || NO&lt;br /&gt;
|-&lt;br /&gt;
| /world difficulty || myworlds.world.difficulty || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world togglepvp || myworlds.world.togglepvp || OP &lt;br /&gt;
|-&lt;br /&gt;
| /world op || myworlds.world.op || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world deop || myworlds.world.deop || OP &lt;br /&gt;
|-&lt;br /&gt;
| /world togglespawnloaded || myworlds.world.togglespawnloaded || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world allowspawn || myworlds.world.allowspawn || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world denyspawn || myworlds.world.denyspawn || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world weather || myworlds.world.weather || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world time || myworlds.world.time || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world gamemode || myworlds.world.gamemode || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world setspawn || myworlds.world.setspawn || OP&lt;br /&gt;
|-&lt;br /&gt;
| /world config || myworlds.world.config|| OP&lt;br /&gt;
|-&lt;br /&gt;
| /tpp|| myworlds.tpp || OP&lt;br /&gt;
|}&lt;br /&gt;
== Chat permissions ==&lt;br /&gt;
The following permissions set with what world(s) a player can chat when being on certain or any world. Chat permissions need to be enabled in the Configuration first.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Situation !! Permission&lt;br /&gt;
|-&lt;br /&gt;
| The player can chat with world2 from world1 || myworlds.world.chat.world1.world2 &lt;br /&gt;
|-&lt;br /&gt;
| The player can chat with every world from world1 || myworlds.world.chat.world1.* &lt;br /&gt;
|-&lt;br /&gt;
| The player can chat with world2 from every world || myworlds.world.chat.*.world2&lt;br /&gt;
|-&lt;br /&gt;
| The player can chat globally from every world with every world (default OP) || myworlds.world.chat.*.*&lt;br /&gt;
|-&lt;br /&gt;
| The player can chat in every world, but not to other worlds (default true)|| myworlds.world.chat.*&lt;br /&gt;
|-&lt;br /&gt;
| The player can chat in world1 (also needed to chat with other worlds from world1) || myworlds.world.chat.world1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; For all other permissions it is needed to have the permissions to use chat in a certain world:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;myworlds.world.chat.world1.world2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
He needs permission to use the chat in world1 too, so he also needs one or both of these two:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;myworlds.world.chat.world1&lt;br /&gt;
myworlds.world.chat.*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==General permissions==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Permission node !! Extra information !! Default&lt;br /&gt;
|-&lt;br /&gt;
| Sets if the player can enter a world || myworlds.world.enter.[name]] || [name] is the world name || NO*&lt;br /&gt;
|-&lt;br /&gt;
| Sets if the player can enter any world || myworlds.world.enter.* || || OP*&lt;br /&gt;
|-&lt;br /&gt;
| Sets if the player can enter a portal || myworlds.portal.enter.[name]] || [name] is the portal name || NO*&lt;br /&gt;
|-&lt;br /&gt;
| Sets if the player can enter any portal || myworlds.portal.enter.* || || OP*&lt;br /&gt;
|-&lt;br /&gt;
| Sets if the player can teleport to a world || myworlds.world.teleport.[name]] || [name] is the world name || NO*&lt;br /&gt;
|-&lt;br /&gt;
| Sets if the player can teleport to any world || myworlds.world.teleport.* ||  || OP*&lt;br /&gt;
|-&lt;br /&gt;
| Sets if the player can teleport to a portal || myworlds.portal.teleport.[name]] || [name] is the portal name || NO*&lt;br /&gt;
|-&lt;br /&gt;
| Sets if the player can teleport to any portal || myworlds.portal.teleport.*  || || OP*&lt;br /&gt;
|-&lt;br /&gt;
| Sets if the player can create portals || myworlds.portal.create || || OP&lt;br /&gt;
|-&lt;br /&gt;
| Sets if the player can replace portals || myworlds.portal.override || || OP*&lt;br /&gt;
|-&lt;br /&gt;
| Sets if the player can use (enter) portals || myworlds.portal.use || || YES&lt;br /&gt;
|-&lt;br /&gt;
| Sets if the player can build on a world || myworlds.world.build.[name]] || [name] is the world name || NO*&lt;br /&gt;
|-&lt;br /&gt;
| Sets if the player can build on any world || myworlds.world.build.* || || OP*&lt;br /&gt;
|-&lt;br /&gt;
| Sets if the player can use blocks on a world || myworlds.world.use.[name] || [name] is the world name || NO*&lt;br /&gt;
|-&lt;br /&gt;
| Sets if the player can use blocks on any world || myworlds.world.use.* || || OP*&lt;br /&gt;
|-&lt;br /&gt;
| Sets if the player is ignored during game mode changes || myworlds.world.ignoregamemode || || FALSE&lt;br /&gt;
|-&lt;br /&gt;
| Sets if the player is ignored during per-world inventory changes || myworlds.world.keepinventory || || OP&lt;br /&gt;
|-&lt;br /&gt;
| Sets whether the player can generate nether portals when taking a linked nether portal || myworlds.world.linknether || || TRUE&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;* = Needs to be enabled in the main [[MyWorlds/Configuration|Configuration]]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Portal enter permissions are for when a player enters the physical portal. The portal name (second line on the sign)&amp;amp;nbsp;is used, &#039;&#039;&#039;not&#039;&#039;&#039; the destination name (third line).&lt;br /&gt;
* Portal enter permissions are not used when teleporting using chat commands, you need to use the teleport permissions then&lt;br /&gt;
* World enter permissions are active when entering portals, and when teleporting to portals and worlds using chat command&lt;br /&gt;
* Portal and world teleport permissions are only used when teleporting using chat commands, they are not active when walking into a physical portal&lt;br /&gt;
A player can teleport to another portal by entering a portal when these two conditions are met:&lt;br /&gt;
&lt;br /&gt;
* Portal enter permissions are disabled, the player has &#039;enter any portal&#039; permission or the player has the specific permission for the portal he entered&lt;br /&gt;
* World enter permissions are disabled, the player has &#039;enter any world&#039; permission or the player has the specific permission for the world he is about to enter&lt;br /&gt;
A player can teleport to another world using chat commands when these three conditions are met:&lt;br /&gt;
&lt;br /&gt;
* The player has access over the &#039;teleport to portal&#039; or &#039;world spawn&#039; commands&lt;br /&gt;
* World enter permissions are disabled, the player has &#039;enter any world&#039; permission or the player has the specific permission for the world he is about to teleport to&lt;br /&gt;
* World teleport permissions are disabled, the player has &#039;teleport to any world&#039; permission or the player has the specific permission to teleport to the world&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/Task&amp;diff=7850</id>
		<title>BKCommonLib/Task</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/Task&amp;diff=7850"/>
		<updated>2025-10-12T09:47:06Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
The Task class is a wrapper class for starting Bukkit scheduler tasks (synchronized only). They can be used to execute a task with a certain tick delay, or with a certain tick interval. They can easily be started and stopped.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Tasks are abstract implementations - you need to make a new Class that extends the Task class and implement the run() method. In there you can execute your logic. In almost all cases, you will want to do something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Task myTask = new Task(MyPlugin.plugin) {&lt;br /&gt;
    @Override&lt;br /&gt;
    public void run() {&lt;br /&gt;
        Bukkit.broadcastMessage(&amp;quot;Test after 10 ticks!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}.start(10);&amp;lt;/pre&amp;gt;&lt;br /&gt;
As you can see, all start() and stop() methods return the &#039;this&#039; Task instance, allowing calls to be chained and the Task to be stored in a single line. In case of a task in your own plugin, this is a general way of doing it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;public class MyPlugin extends JavaPlugin {&lt;br /&gt;
    private Task myTask;&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public void onEnable() {&lt;br /&gt;
        myTask = new Task(this) {&lt;br /&gt;
            @Override&lt;br /&gt;
            public void run() {&lt;br /&gt;
                Bukkit.broadcastMessage(&amp;quot;This message is displayed about every second&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }.start(20, 20);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public void onDisable() {&lt;br /&gt;
        Task.stop(myTask);&lt;br /&gt;
        myTask = null;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
It is possible to use myTask.stop() instead, but in the event that myTask is not initialized (and is null) Task.stop is more secure, as it includes a null check. Who knows, perhaps there was an error while enabling or for some other reason your task ended up nulled sooner.&lt;br /&gt;
&lt;br /&gt;
==Start types==&lt;br /&gt;
You can start in multiple ways:&lt;br /&gt;
&lt;br /&gt;
* Task.start() - runs the task a single time at the end of the current tick&lt;br /&gt;
* Task.start(10) - runs the task a single time in 10 ticks&lt;br /&gt;
* Task.start(10, 20) - runs the task every 20 ticks, with a delay of 10 ticks before starting to repeat&lt;br /&gt;
==Next-tick tasks==&lt;br /&gt;
Since you have to start these tasks so often, there is an alternative to using the Task class for executing next-tick tasks: CommonUtil.nextTick. It allows you to schedule a Runnable to execute at the end of the current tick, similar to how Task.start() works. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;CommonUtil.nextTick(new Runnable() {&lt;br /&gt;
    @Override&lt;br /&gt;
    public void run() {&lt;br /&gt;
        Bukkit.broadcastMessage(&amp;quot;Next tick message!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
});&amp;lt;/pre&amp;gt;&lt;br /&gt;
You do not have to pass in a Plugin instance, and it is also impossible to cancel the task once scheduled. When BKCommonLib disables all remaining tasks are discarded - only use this to schedule tasks while the server is enabling or running, not when disabling.&lt;br /&gt;
&lt;br /&gt;
==Tips for passing in parameters==&lt;br /&gt;
It is possible that you want to use data obtained in an event or function to pass into the scheduled task - so how to easily use it? Making your own Task wrapper class with all these variables stored is possible, but also very inefficient. Java has a nice trick for that: final variables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;@EventHandler&lt;br /&gt;
public void onPlayerJoin(PlayerJoinEvent event) {&lt;br /&gt;
    final Player player = event.getPlayer();&lt;br /&gt;
    new Task(plugin) {&lt;br /&gt;
        @Override&lt;br /&gt;
        public void run() {&lt;br /&gt;
            player.sendMessage(&amp;quot;Welcome to our server!&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }.start(40);&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Be very careful with this, as it IS prone to memory leaks. As a rule of thumb, don&#039;t use final variables to pass them into repeating tasks, as these variables then never get garbage collected. Even better would be to use primitive types only - a player name instead of a Player.&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/Localization&amp;diff=7848</id>
		<title>BKCommonLib/Localization</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/Localization&amp;diff=7848"/>
		<updated>2025-10-12T09:46:54Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
BKCommonLib will create a Localization.yml file in the plugin&#039;s folder if the plugin contains localized keys or commands. Commands are automatically read from plugin.yml file in the plugin itself, which allows users to externally modify the usages and descriptions of commands without opening up the plugin in an archive extracting program.&lt;br /&gt;
&lt;br /&gt;
== The keys==&lt;br /&gt;
Localization keys have to be lower-cased, otherwise they are not detected and probably overwritten as well. This is important later on, if you want to make argument-specific nodes. They have to be lower-case too.&lt;br /&gt;
&lt;br /&gt;
==Colors==&lt;br /&gt;
The § &#039;text formatting code&#039; can be used to add colors and other formatting styles to the messages. See this page for more information about the characters to put after this sign.&lt;br /&gt;
&lt;br /&gt;
==Arguments==&lt;br /&gt;
Some localization nodes allow arguments from the plugin to be passed into the message. These arguments are surrounded by percentage signs. %0% is the first argument, %1% is the second argument, and so on. This identifier does not have to be in the message, you can leave it out.&lt;br /&gt;
&lt;br /&gt;
==Argument specific nodes==&lt;br /&gt;
It is possible to use completely different messages for different arguments from the plugin. For example, there is the player.enter node that looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;someplugin:&lt;br /&gt;
  player:&lt;br /&gt;
    enter: §ePlayer %0% joined the server! Say hello!&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can give a special welcome message to the player called player1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;someplugin:&lt;br /&gt;
  player:&lt;br /&gt;
    enter:&lt;br /&gt;
        default: §ePlayer %0% joined the server! Say hello!&lt;br /&gt;
        player1: §eThe magnificent player1 joined the server, bow before his might!&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This applies to all nodes that have an input argument. It is possible to extend this logic for two arguments as well, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;someplugin:&lt;br /&gt;
  use:&lt;br /&gt;
    default: You used a %0% against a %1%!&lt;br /&gt;
    sword:&lt;br /&gt;
      default: You used a powerful sword against a %1%&amp;lt;/pre&amp;gt;&lt;br /&gt;
      block: You used a sword against a block, it&#039;s not very effective!&lt;br /&gt;
Note how the second argument is still %1%. The argument key stays the same for sub-argument nodes. This is to prevent confusion when copy-pasting the same message and allow small modifications. Otherwise you would have to change all %0% arguments to the argument name, which can be tiresome.&lt;br /&gt;
&lt;br /&gt;
==Example in MyWorlds==&lt;br /&gt;
You can set an enter message for worlds. This example has a special enter message for world1 and Lowgrass:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;world:&lt;br /&gt;
  enter:&lt;br /&gt;
    default: §aYou teleported to world &#039;%0%&#039;!&lt;br /&gt;
    world1: §aYou teleported to world 1, have a nice stay!&lt;br /&gt;
    lowgrass: §aYou teleported to the nicely built Lowgrass, have fun there!&amp;lt;/pre&amp;gt;&lt;br /&gt;
As can be seen, the node is a lowercase lowgrass and not Lowgrass. As stated in the beginning, localization keys have to be lower case.&lt;br /&gt;
&lt;br /&gt;
==Internals==&lt;br /&gt;
You can skip this part if you are not programming using the library. BKCommonLib features built-in Localization reading for plugins extending the PluginBase in BKCommonLib. It automatically manages localization nodes reading and writing from/to the Localization.yml file in the plugin&#039;s folder.&lt;br /&gt;
&lt;br /&gt;
This localization system automatically reads all command descriptions and usages found in the plugin.yml of your plugin and makes them configurable in the Localization.yml file. Alternatively, the plugin can add more nodes using the loadLocale(path, value) method. This method will check the localization file for the node, and if it doesn&#039;t exist, it adds the default value specified to it. This should be done in the localization() method, which is fired right before enabling the plugin.&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=MyWorlds/Localization&amp;diff=7846</id>
		<title>MyWorlds/Localization</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=MyWorlds/Localization&amp;diff=7846"/>
		<updated>2025-10-12T09:46:40Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
BKCommonLib will create a Localization.yml file in the plugin&#039;s folder if the plugin contains localized keys or commands. Commands are automatically read from plugin.yml file in the plugin itself, which allows users to externally modify the usages and descriptions of commands without opening up the plugin in an archive extracting program.&lt;br /&gt;
&lt;br /&gt;
==The keys==&lt;br /&gt;
Localization keys have to be lower-cased, otherwise they are not detected and probably overwritten as well. This is important later on, if you want to make argument-specific nodes. They have to be lower-case too.&lt;br /&gt;
&lt;br /&gt;
==Colors==&lt;br /&gt;
The § &#039;text formatting code&#039; can be used to add colors and other formatting styles to the messages. See this page for more information about the characters to put after this sign.&lt;br /&gt;
&lt;br /&gt;
==Arguments==&lt;br /&gt;
Some localization nodes allow arguments from the plugin to be passed into the message. These arguments are surrounded by percentage signs. %0% is the first argument, %1% is the second argument, and so on. This identifier does not have to be in the message, you can leave it out.&lt;br /&gt;
&lt;br /&gt;
==Argument specific nodes==&lt;br /&gt;
It is possible to use completely different messages for different arguments from the plugin. For example, there is the player.enter node that looks like this:&lt;br /&gt;
&lt;br /&gt;
someplugin:&lt;br /&gt;
  player:&lt;br /&gt;
    enter: §ePlayer %0% joined the server! Say hello!&lt;br /&gt;
You can give a special welcome message to the player called player1:&lt;br /&gt;
&lt;br /&gt;
someplugin:&lt;br /&gt;
  player:&lt;br /&gt;
    enter:&lt;br /&gt;
        default: §ePlayer %0% joined the server! Say hello!&lt;br /&gt;
        player1: §eThe magnificent player1 joined the server, bow before his might!&lt;br /&gt;
This applies to all nodes that have an input argument. It is possible to extend this logic for two arguments as well, for example:&lt;br /&gt;
&lt;br /&gt;
someplugin:&lt;br /&gt;
  use:&lt;br /&gt;
    default: You used a %0% against a %1%!&lt;br /&gt;
    sword:&lt;br /&gt;
      default: You used a powerful sword against a %1%&lt;br /&gt;
      block: You used a sword against a block, it&#039;s not very effective!&lt;br /&gt;
Note how the second argument is still %1%. The argument key stays the same for sub-argument nodes. This is to prevent confusion when copy-pasting the same message and allow small modifications. Otherwise you would have to change all %0% arguments to the argument name, which can be tiresome.&lt;br /&gt;
&lt;br /&gt;
==Example in MyWorlds==&lt;br /&gt;
You can set an enter message for worlds. This example has a special enter message for world1 and Lowgrass:&lt;br /&gt;
&lt;br /&gt;
world:&lt;br /&gt;
  enter:&lt;br /&gt;
    default: §aYou teleported to world &#039;%0%&#039;!&lt;br /&gt;
    world1: §aYou teleported to world 1, have a nice stay!&lt;br /&gt;
    lowgrass: §aYou teleported to the nicely built Lowgrass, have fun there!&lt;br /&gt;
As can be seen, the node is a lowercase lowgrass and not Lowgrass. As stated in the beginning, localization keys have to be lower case.&lt;br /&gt;
&lt;br /&gt;
==Internals==&lt;br /&gt;
You can skip this part if you are not programming using the library. BKCommonLib features built-in Localization reading for plugins extending the PluginBase in BKCommonLib. It automatically manages localization nodes reading and writing from/to the Localization.yml file in the plugin&#039;s folder.&lt;br /&gt;
&lt;br /&gt;
This localization system automatically reads all command descriptions and usages found in the plugin.yml of your plugin and makes them configurable in the Localization.yml file. Alternatively, the plugin can add more nodes using the loadLocale(path, value) method. This method will check the localization file for the node, and if it doesn&#039;t exist, it adds the default value specified to it. This should be done in the localization() method, which is fired right before enabling the plugin.&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/General&amp;diff=7845</id>
		<title>BKCommonLib/General</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/General&amp;diff=7845"/>
		<updated>2025-10-12T09:46:06Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
There are various utilities that have nothing to do with Bukkit or Minecraft alone. These are utilities working with mathematics, logic, strings and blockfaces. There are a lot of utilities, and listing them all here is going to result in too much information. Instead the basic features covered are listed so you know where to find them.&lt;br /&gt;
&lt;br /&gt;
==Math==&lt;br /&gt;
[https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/utils/MathUtil.java MathUtil] contains various common operations involving math:&lt;br /&gt;
&lt;br /&gt;
* length, lengthSquared, distance, distanceSquared, normalize - both 2D and 3D vector length operations&lt;br /&gt;
* wrapAngle, getAngleDifference, toChunk, Long&amp;lt;&amp;gt;2Int, fixNaN, clamp, lerp, atan2 - for simplistic number calculations&lt;br /&gt;
* getLookAtYaw/Pitch, getDirection, isHeadingTo, move, rotate - for rotation-based vector calculations and checks&lt;br /&gt;
==BlockFace==&lt;br /&gt;
[https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/utils/FaceUtil.java FaceUtil] contains various common operations involving the conversion from and to BlockFaces:&lt;br /&gt;
&lt;br /&gt;
* Conversion between yaw and BlockFace&lt;br /&gt;
* Conversion between vector directions and BlockFace&lt;br /&gt;
* Conversion between &#039;notch&#039; (0-7) and BlockFace&lt;br /&gt;
* Several BlockFace constants for easier logic&lt;br /&gt;
==Logic==&lt;br /&gt;
[https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/utils/LogicUtil.java LogicUtil] contains methods to work with general logic such as checking for null and returning something else, logic involving collections and more:&lt;br /&gt;
&lt;br /&gt;
* Conversion between primitive and boxed class types&lt;br /&gt;
* Checking whether an Object is null or empty&lt;br /&gt;
* Checking whether an index is in bounds of an array or list&lt;br /&gt;
* Dynamically creating arrays and getting array elements&lt;br /&gt;
* Checking to see if a given value is present in a primitive type array&lt;br /&gt;
==String==&lt;br /&gt;
[https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/utils/StringUtil.java StringUtil] contains methods to format Strings, get the first index of text in a String and other String-related operations:&lt;br /&gt;
&lt;br /&gt;
* Get the width of text in Minecraft font (might become deprecated)&lt;br /&gt;
* Get the first index of multiple pieces of text&lt;br /&gt;
* Get the text before or after a piece of text&lt;br /&gt;
* Obtain a String filled with certain text appended N times&lt;br /&gt;
* Trimming the end or start of text from whitespaces&lt;br /&gt;
* Combining multiple pieces of text together with a delimiter, or using , and and&lt;br /&gt;
* Converting &amp;quot;-surrounded parts into a single element (for command argument conversion)&lt;br /&gt;
* Get the amount of successive times a given character is present in a text&lt;br /&gt;
* Chat style conversion methods&lt;br /&gt;
* Replacing text, or all text&lt;br /&gt;
==Parsing==&lt;br /&gt;
[https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/utils/ParseUtil.java ParseUtil] takes care of number, boolean and enum parsing. Note that the Conversion system already includes redirects to this class:&lt;br /&gt;
&lt;br /&gt;
* Parsing booleans, checking whether a piece of text can be interpreted as a boolean&lt;br /&gt;
* Parsing numbers, checking whether a piece of text can be interpreted as a number&lt;br /&gt;
* Parsing enumerations from text, generic&lt;br /&gt;
* Parsing materials, by checking for an ID or the material name&lt;br /&gt;
==Time==&lt;br /&gt;
[https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/utils/TimeUtil.java TimeUtil] is used to convert between time and text, by interpreting words such as &#039;day&#039; and &#039;night&#039; and turning it into Minecraft time. Although it has something to do with Minecraft, it is still basic logic. Methods:&lt;br /&gt;
&lt;br /&gt;
* get Minecraft time from text&lt;br /&gt;
* get name in text format from Minecraft time&lt;br /&gt;
* getting the current time in a certain date format&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/Conversion&amp;diff=7844</id>
		<title>BKCommonLib/Conversion</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/Conversion&amp;diff=7844"/>
		<updated>2025-10-12T09:45:52Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
BKCommonLib features a broad and versatile data type conversion system to convert (or cast, in some cases) one data type to another. For example, conversion between:&lt;br /&gt;
&lt;br /&gt;
* numeric values (byte, short, int, long, float, double)&lt;br /&gt;
* String (or String producing object) data and numeric values&lt;br /&gt;
* Collections and arrays (list, set, map, object array, primitive array (int[]))&lt;br /&gt;
* Wrappers and their handles (CommonTag, Entity, World, Chunk, DataWatcher, etc.)&lt;br /&gt;
* Enumerations and Strings (Material, GameMode, PermissionDefault, etc.)&lt;br /&gt;
* Properties (item container and item, difficulty and difficulty ID, etc.)&lt;br /&gt;
* Custom (plugins can register their own)&lt;br /&gt;
Whenever you set something in a generic way, or try to obtain one in a generic way, the Conversion service takes care of it. It is used in most of the data storage classes BKCommonLib provides, including configuration and NBT API. The conversion service adds functionality where serialization and de-serialization of data fails.&lt;br /&gt;
&lt;br /&gt;
==Converter==&lt;br /&gt;
The [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/conversion/Converter.java Converter] takes care of the conversion from an unknown Object to a certain output type. It also provides several helper methods to make working with converters easier. These, if not provided in a base class, can be copied over without an issue. The default base class, which provides the basic needs, is called [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/conversion/BasicConverter.java BasicConverter].&lt;br /&gt;
&lt;br /&gt;
Every converter defines several methods:&lt;br /&gt;
* &#039;&#039;&#039;convert&#039;&#039;&#039; (and overloads) converts to the output type of the converter. The convert without default should be final.&lt;br /&gt;
* &#039;&#039;&#039;getOutputType&#039;&#039;&#039; tells the Conversion service what type of Object this converter can produce&lt;br /&gt;
* &#039;&#039;&#039;isCastingSupported&#039;&#039;&#039; tells the Conversion service whether the produced type allows casting (e.g. Entity to Creeper)&lt;br /&gt;
* &#039;&#039;&#039;isRegisterSupported&#039;&#039;&#039; tells the Conversion service whether the converter can be registered at all&lt;br /&gt;
Make sure that for converters that produce common types, such as Object and Integer, the isRegisterSupported returns false. Not doing so may result in your (limited) converter replacing other converters that can actually do the job. This mainly applies to conversion from property owner to property. You do not want your &#039;Item to Item Material&#039; converter to replace the &#039;Anything to Material&#039; converter.&lt;br /&gt;
&lt;br /&gt;
==Conversion types==&lt;br /&gt;
You can access and use default converters in the [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/conversion/type/ConversionTypes.java ConversionTypes] class, or it&#039;s extension, the [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/conversion/Conversion.java Conversion] class.&lt;br /&gt;
&lt;br /&gt;
==Converter pair==&lt;br /&gt;
A [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/conversion/ConverterPair.java ConverterPair] is a combination of two Converters that can convert from one to the other, and back. The class is self-explanatory. These pairs can be used to provide self-converting collections, accessors and other two-way &#039;setting and getting&#039; types. All default pairs can be found in the [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/conversion/ConversionPairs.java ConversionPairs] class.&lt;br /&gt;
&lt;br /&gt;
==Translator==&lt;br /&gt;
The main use case for Converter Pairs is reflection. To access a field of type &#039;net.minecraft.server.Entity&#039; without losing type information, you can provide a &#039;&#039;&#039;translation&#039;&#039;&#039;. For example, the definition of the field &#039;passenger&#039; in the nms.Entity class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;public static final TranslatorFieldAccessor&amp;lt;Entity&amp;gt; = entityTemplate.getField(&amp;quot;passenger&amp;quot;).translate(ConversionPairs.entity);&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now you can get and set the passenger using Bukkit entities. The TranslatorFieldAccessor allows you to still get and set the base type (nms.Entity), but no type is exposed (it&#039;s an Object).&lt;br /&gt;
&lt;br /&gt;
==Converting to a generic type==&lt;br /&gt;
To convert a value to a type that is not known at compile time (generics), use the following method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Object input = ...;&lt;br /&gt;
Class&amp;lt;T&amp;gt; typeToGet = ...;&lt;br /&gt;
T default = ...;&lt;br /&gt;
T value = Conversion.convert(input, typeToGet, default);&amp;lt;/pre&amp;gt;&lt;br /&gt;
The default is returned when conversion, for some reason, fails. There are also overloads of this method to return null on failure, or to use the default class type instead of typeToGet.&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/PermissionDefaults&amp;diff=7843</id>
		<title>BKCommonLib/PermissionDefaults</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/PermissionDefaults&amp;diff=7843"/>
		<updated>2025-10-12T09:45:41Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
All permissions, with a description and a default value, can be found in the PermissionDefaults.yml file. Open it using a text editor and you can view an hierarchical view of all permissions of the plugin. In here you can freely change the default permission value (op/not_op/true/false) for all permissions the plugin uses. A server reload or restart is required for new permission nodes to take effect.&lt;br /&gt;
&lt;br /&gt;
==Variable permissions==&lt;br /&gt;
Sometimes so-called &#039;variable&#039; permission nodes exist. They are, by default, shown with a main name followed up by a * node. These nodes allow additional sub-permissions to be added, or represent a permission for a certain world, player or some other name. An example of a such a permission can be found below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;myplugin:&lt;br /&gt;
    use:&lt;br /&gt;
        &#039;*&#039;:&lt;br /&gt;
            default: op&lt;br /&gt;
            description: Can use all tools&lt;br /&gt;
        hammer:&lt;br /&gt;
            default: true&lt;br /&gt;
            description: Can use the hammer tool&lt;br /&gt;
        drill:&lt;br /&gt;
            default: false&lt;br /&gt;
            description: Can use the drill tool&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above example, OP players can use all tools. This includes the drill! All players can use the hammer, but no one can use the drill. Note that the false default is usually pointless, because not-added variable permissions are false by default anyhow. Generally you would want to add either true or op as default for these sub-permission nodes. (hammer and drill)&lt;br /&gt;
&lt;br /&gt;
==Permission nodes==&lt;br /&gt;
The nodes in the file correspond to the permission nodes you can give to players. In the above example, you can use the permission node &#039;myplugin.use.hammer&#039; to allow a player to use the hammer. If you wish to give someone the use for all tools, you can use &#039;myplugin.use.*&#039;. Again, the nodes in PermissionDefaults.yml are defaults; you can override them for individual players or groups.&lt;br /&gt;
&lt;br /&gt;
==Permission plugins==&lt;br /&gt;
If you wish to use a permission plugin that doesn&#039;t use Super Permissions, you can install Vault to redirect the permission handling. BKCommonLib automatically detects when Vault is enabled and will switch to using Vault for permission handling.&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=MyWorlds/SeperateInventories&amp;diff=7842</id>
		<title>MyWorlds/SeperateInventories</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=MyWorlds/SeperateInventories&amp;diff=7842"/>
		<updated>2025-10-12T09:45:26Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Configuration==&lt;br /&gt;
MyWorlds has an advanced system in place to separate player data on different &#039;island&#039; groups of worlds. This way you can prevent items going between worlds, while allowing them between linked worlds in survival. Player data is saved inside the world folder, in standard Minecraft NBT format. No special database is used.&lt;br /&gt;
&lt;br /&gt;
To begin using this system, set useWorldInventories to true in plugins/My_Worlds/config.yml.&lt;br /&gt;
&lt;br /&gt;
The moment it is turned on, all worlds will have their own inventory state. This includes the player&#039;s items, experience, potion effects, health, hunger. Normally all player data is stored on the main world (&#039;world&#039;). Now this is no longer the case, it means players on other worlds will see their inventory wiped. Their items are still there, but only on the main world.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll have to arrange &#039;&#039;&#039;inventory migration&#039;&#039;&#039; if you have existing players. Make a backup of the main world&#039;s playerdata folder. This ensures players don&#039;t lose their inventory/experience/etc. due to a missing merged inventory world configuration.&lt;br /&gt;
&lt;br /&gt;
To start, you will probably want to merge the main world/nether/end inventories. Use the following command (replace &#039;world&#039; with your main world name):&lt;br /&gt;
&amp;lt;pre&amp;gt;/world inventory merge world world_nether world_the_end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Migration===&lt;br /&gt;
MyWorlds loads player data in two stages. First the main world&#039;s player data is loaded. If that data points to the player being in another world with a different inventory, then that world&#039;s player data is loaded. If players were on a world pre-migration that is now on a separate, split inventory, they will log on and see that their inventory is empty.&lt;br /&gt;
&lt;br /&gt;
To fix that, copy the affected player&#039;s player data file to the world they were last on. If you copy all the main world&#039;s player data files to the split-off worlds, this will fix it for everyone, but it will also cause all players that weren&#039;t on the split-off world to have the same inventory as they have on the main world. Basically, it&#039;s complicated, which is why backups are important.&lt;br /&gt;
&lt;br /&gt;
==Commands==&lt;br /&gt;
&lt;br /&gt;
The main command to manage world inventory configuration is the /world inventory command. Syntax is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/world inventory merge [world1] [world2] [world3]&lt;br /&gt;
&lt;br /&gt;
/world inventory split [world1] [world2] [world3]&lt;br /&gt;
&lt;br /&gt;
/world inventory enable [world]&lt;br /&gt;
&lt;br /&gt;
/world inventory disable [world]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When merging inventories, all their state is shared. The data of this shared state is saved in the first world argument of your merge command, in the example &#039;world1&#039;. If players have existing data on a particular world you want to keep, make sure to use this world name as a first argument.&lt;br /&gt;
&lt;br /&gt;
When splitting, world name order doesn&#039;t matter. Each world you specify is detached from any shared state, and given its own inventory for that world alone. To migrate a world, you can first split it from the original shared world group, then use merge to connect it to the other group.&lt;br /&gt;
&lt;br /&gt;
No player data will ever be lost as a result of splitting/merging. If you accidentally &#039;lose&#039; people&#039;s data by setting the main world for an inventory group, you can either copy the worldname/playerdata folder to the right place, or use the split command for that world to allow players to (temporarily) access their old inventories again.&lt;br /&gt;
&lt;br /&gt;
With enable/disable, inventory saving for that world can be turned off entirely. When players rejoin the world, their inventory will be completely wiped every time.&lt;br /&gt;
&lt;br /&gt;
==Permissions==&lt;br /&gt;
&lt;br /&gt;
There are several permissions which configure inventory behavior:&lt;br /&gt;
myworlds.world.inventory - Whether the inventory merge/split/etc. commands can be used&lt;br /&gt;
myworlds.world.keepinventory - Makes player exempt from splitting inventories, always keeping the inventory when switching between worlds.&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/Scoreboards&amp;diff=7835</id>
		<title>BKCommonLib/Scoreboards</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/Scoreboards&amp;diff=7835"/>
		<updated>2025-10-12T09:45:12Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==ScoreBoards==&lt;br /&gt;
Scoreboards are new functions that came with mc 1.5. It allows you to popup a gui in the screen of a player and put custom inferomation inside of it. This already has a very weak api in NMS but we decided to redo it and support global settings as well.&lt;br /&gt;
The Scoreboards from BKCommonLib allows you to merge with orther plugins unlike the NMS api.&lt;br /&gt;
&lt;br /&gt;
Here is an example:&lt;br /&gt;
&amp;lt;pre&amp;gt;Player player = Bukkit.getOnlinePlayers()[0]; //just get an online player as example&lt;br /&gt;
CommonScoreboard  board = CommonScoreboard.get(player); //Get the scoreboard form the player&lt;br /&gt;
CommonObjective sidebar = board.getObjective(Display.SIDEBAR); //Get the sidebar scoreboard&lt;br /&gt;
sidebar.show(); //Shwo the sidebar (use siderbar.hide() to hide)&lt;br /&gt;
sidebar.createScore(&amp;quot;kills&amp;quot;, 17); //Create a new score called &#039;kills&#039; and make the value 17&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can also edit the score if the value needs to be changed.&lt;br /&gt;
&amp;lt;pre&amp;gt;CommonScore kills = siderbar.getScore(&amp;quot;kills&amp;quot;);&lt;br /&gt;
kills.setValue(18); //Change the value to 18 kills&lt;br /&gt;
kills.update(); //Don&#039;t forget ot update the score after changing it!&amp;lt;/pre&amp;gt;&lt;br /&gt;
And if the display name from the sidebar is not the thing you want, you can allways call this:&lt;br /&gt;
&amp;lt;pre&amp;gt;sidebar.setDisplayName(&amp;quot;PvP Info&amp;quot;);&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can also create Scoreboard teams:&lt;br /&gt;
&amp;lt;pre&amp;gt;CommonTeam team = CommonScoreboard.getTeam(&amp;quot;example&amp;quot;);&lt;br /&gt;
if(team == nul) {&lt;br /&gt;
    team = CommonScoreboard.createTeam(&amp;quot;example&amp;quot;);&lt;br /&gt;
    team.setSendToAll(true); //set if team is visible for everyone&lt;br /&gt;
    team.show(); //Create team&lt;br /&gt;
    team.setDisplayName(&amp;quot;Example&amp;quot;); //Not sure where this is used for&lt;br /&gt;
    team.setPrefix(ChatColor.RED.toString()); //Prefix (in front of name)&lt;br /&gt;
    team.setSuffix(&amp;quot; - Example&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
team.addPlayer(player);&amp;lt;/pre&amp;gt;&lt;br /&gt;
These are all available displays:&lt;br /&gt;
&lt;br /&gt;
* LIST - Tab list (i think)&lt;br /&gt;
* SIDEBAR - Right sidebar of your screen&lt;br /&gt;
* BELOWNAME - Below nametags&lt;br /&gt;
&lt;br /&gt;
Showing off a BELOWNAME example:&lt;br /&gt;
&amp;lt;pre&amp;gt;Player player = event.getPlayer(); //Player who will see the food from lenis0012&lt;br /&gt;
Player lenis0012 = Bukkit.getPlayer(&amp;quot;lenis0012&amp;quot;); //Example player to show food from&lt;br /&gt;
CommonObjective obj = CommonScoreboard.get(player).getObjective(Display.BELOWNAME);&lt;br /&gt;
obj.setDisplayName(&amp;quot;Hunger&amp;quot;);&lt;br /&gt;
obj.show(); //Allways call this&lt;br /&gt;
obj.createScore(&amp;quot;lenis0012&amp;quot;, &amp;quot;lenis0012&amp;quot;, (int) lenis0012.getFoodLevel());&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result of nametag:&lt;br /&gt;
&lt;br /&gt;
lenis0012&lt;br /&gt;
&lt;br /&gt;
20 Hunger&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/IIIT&amp;diff=7826</id>
		<title>BKCommonLib/IIIT</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/IIIT&amp;diff=7826"/>
		<updated>2025-10-12T09:44:56Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page covers the item to item, inventory to item, item to inventory and inventory to inventory transfer principles. It covers how item(s) go from one place to another, and the methods available to achieve this. It also covers several other item utilities, new base classes you can use and use cases.&lt;br /&gt;
&lt;br /&gt;
==ItemParser==&lt;br /&gt;
An ItemParser is used to define the rules for a transfer operation. It can be created from user input using a certain format, but can also be created in-code. An item parser has the following &#039;fields&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Has amount&#039;&#039;&#039; and &#039;&#039;&#039;amount&#039;&#039;&#039;: the maximum amount of items that is allowed to be transferred, and whether this is used&lt;br /&gt;
* &#039;&#039;&#039;Has type&#039;&#039;&#039; and &#039;&#039;&#039;type&#039;&#039;&#039;: the item type to be transferred, and whether an item type restriction is there&lt;br /&gt;
* &#039;&#039;&#039;Has data&#039;&#039;&#039; and &#039;&#039;&#039;data&#039;&#039;&#039;: the item data to be transferred, and whether an item data restriction is there All these settings will be used when transferring items.&lt;br /&gt;
&lt;br /&gt;
==Parsed format==&lt;br /&gt;
There are rules defined to create an item parser from user input, these are:&lt;br /&gt;
&lt;br /&gt;
* The : sign delimits type and data&lt;br /&gt;
* The &#039;&#039;&#039;x&#039;&#039;&#039;, &#039;&#039;&#039;X&#039;&#039;&#039;, &#039;&#039;&#039;*&#039;&#039;&#039;, &#039;&#039;&#039;&amp;lt;space&amp;gt;&#039;&#039;&#039;, &#039;&#039;&#039;&amp;lt;comma&amp;gt;&#039;&#039;&#039; and &#039;&#039;&#039;@&#039;&#039;&#039; signs are used to delimit data/type and the amount&lt;br /&gt;
* Type can be the material ID, or the material name, or part of a material name (it uses ParseUtil.parseMaterial)&lt;br /&gt;
* Data can be a value from 0 to 15, or an identifier of data for the type (e.g. wood, stone, etc.)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Examples&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Format !! Result&lt;br /&gt;
|-&lt;br /&gt;
| 5xwood || 5 pieces of wood&lt;br /&gt;
|-&lt;br /&gt;
| 12@ironore || 12 pieces of iron ore&lt;br /&gt;
|-&lt;br /&gt;
| 5xwool:red || 5 pieces of red wool&lt;br /&gt;
|-&lt;br /&gt;
| 6xcoal:1 || 6 pieces of charcoal&lt;br /&gt;
|-&lt;br /&gt;
| 22xlog:birch || 22 pieces of birch logs&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Transfer and Item Utilities==&lt;br /&gt;
All utilities can be found in [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/utils/ItemUtil.java ItemUtil]. All methods called &#039;transfer&#039; transfer items from one place to another. There are also methods to check whether a full transfer is possible at all, allowing you to check it before having a failing result.&lt;br /&gt;
&lt;br /&gt;
This class also contains several other item-related utilities, such as those to clone items, clone inventory contents, transfer item metadata, constructing an empty item which has a handle, and much more. Whenever you run into something that has to do with items, check whether there is a method in ItemUtil that could make your life easier.&lt;br /&gt;
&lt;br /&gt;
==Inventories==&lt;br /&gt;
There are also several base classes you can use. All of them extend CraftInventory (or another type used by the implementation), so it is required to compile against CraftBukkit to get around &#039;class hierarchy&#039; errors. They pose no real threat in this case. The base classes are:&lt;br /&gt;
* [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/inventory/InventoryBase.java InventoryBase] - a base class that has everything implemented except the getting and setting of items&lt;br /&gt;
* [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/inventory/InventoryBaseImpl.java InventoryBaseImp] - base implementation backed by an array of ItemStack&lt;br /&gt;
* [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/inventory/MergedInventory.java MergedInventory] - an inventory of inventories, merging multiple together as one&lt;br /&gt;
If you need a quick and dirty way to implement your own Inventory type, these base classes make this a lot easier. Since the base class extends CraftBukkit&#039;s inventory, you are automatically provided with the latest methods Bukkit has to offer.&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/Block&amp;diff=7819</id>
		<title>BKCommonLib/Block</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/Block&amp;diff=7819"/>
		<updated>2025-10-12T09:44:44Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
BlockUtil contains various handy Block-related utilities. It offers:&lt;br /&gt;
&lt;br /&gt;
* get Block State cast to a certain type (null on failure)&lt;br /&gt;
* get Block Data cast to a certain type (null on failure)&lt;br /&gt;
* Shortcuts for get/setFacing&lt;br /&gt;
* get Block attached face or Block&lt;br /&gt;
* Toggling all levers attached to a block&lt;br /&gt;
* get all Block States in a cuboid area&lt;br /&gt;
See also: MaterialUtil for block type equality checks. It contains various material properties, for example, to check whether a material is a type of rails or sign, or whether a block is a power source. It can save some time implementing your own systems if used right.&lt;br /&gt;
&lt;br /&gt;
==Block State==&lt;br /&gt;
Unlike block.getState(), this version won&#039;t throw random NPE&#039;s when the tile entity is glitched. There is also an overload to cast to a certain type of state, for example, a chest. This can be useful to reduce the amount of code needed to get a chest state. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Chest chest = BlockUtil.getState(block, Chest.class);&lt;br /&gt;
if (chest != null) {&lt;br /&gt;
    // Work with it&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Block Material Data==&lt;br /&gt;
Optimized version of Block.getState().getData() - creates Material Data without first creating a (useless) BlockState instance. It also includes several safety checks to avoid malformed data resulting in unusable MaterialData classes. Glitched signs are fixed right up! Usage is very similar to the getState methods.&lt;br /&gt;
&lt;br /&gt;
==Getting block states in an area==&lt;br /&gt;
This optimized method allows obtaining all nearby chests, signs, furnaces and other tile entities that have specific Block States. This way you can heavily optimize your previous for-loop check. Note that this method is not cross-thread safe - only use it on the main thread.&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/ForDevelopers&amp;diff=7818</id>
		<title>BKCommonLib/ForDevelopers</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/ForDevelopers&amp;diff=7818"/>
		<updated>2025-10-12T09:44:34Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Update|BKCommonLib|18 November 2020|reason=BKCommonLib is now a Gradle project, not a Maven project.|date=16 February 2023}}&lt;br /&gt;
==Introduction==&lt;br /&gt;
This is a page where help is given for new and existing developers of BKCommonLib and everything related to it. If something needs to be redone or fixed, you can find information regarding it here.&lt;br /&gt;
&lt;br /&gt;
==BKCommonLib project structure==&lt;br /&gt;
BKCommonLib is a maven project - you need to support it to contribute to it. If you are using the Eclipse IDE, you can install [https://projects.eclipse.org/projects/technology.m2e m2eclipse] so you can properly import maven projects. To install this software, go to the marketplace in the Eclipse GUI and install it from there. See also: [https://marketplace.eclipse.org/marketplace-client-intro installation instructions].&lt;br /&gt;
&lt;br /&gt;
Upon first looking over all packages and classes it may seem overwhelming - and it is. BKCommonLib is extremely large, but it has a fixed structure.&lt;br /&gt;
&lt;br /&gt;
* Internal and server packages: try not to touch these, here is where all our CraftBukkit-specific logic resides&lt;br /&gt;
* Reflection: here is where we put all fields and methods contained within CraftBukkit so others can access it safely&lt;br /&gt;
* Proxies and Bases: here we store all base classes that can be extended or worked with. Includes math utility classes such as vectors&lt;br /&gt;
* [[BKCommonLib/Conversion|Conversion]]: here are all convertors meant for converting one datatype to the other&lt;br /&gt;
* Collections: here we store all special type of collections, such as those that convert one type to the other dynamically&lt;br /&gt;
* [[BKCommonLib/CommonEntity|Entity]] and [[BKCommonLib/Controller|Controller]]: all Entity-related utility classes which add new functionality, of which controllers&lt;br /&gt;
* [[BKCommonLib/EventsAndListeners|Events]]: Some events plugins can use, fired by BKCommonLib. See also: internal.&lt;br /&gt;
* [[BKCommonLib/Localization|Localization]] and [[BKCommonLib/PermissionDefaults|Permissions]]: speaks for itself, base classes for name given&lt;br /&gt;
* [[BKCommonLib/ConfigurationAPI|Config]] and [[BKCommonLib/NBTTagAPI|NBT]]: speaks for itself, helper classes for dealing with configuration/file data storage/NBT tags&lt;br /&gt;
* [[BKCommonLib/Scoreboards|Scoreboards]]: the Scoreboards API of BKCommonLib&lt;br /&gt;
* [[BKCommonLib/TabView|Tab]]: the Tab API of BKCommonLib&lt;br /&gt;
* Wrappers: for working with internal classes through a secure and non-reflection ridden layer&lt;br /&gt;
* [[BKCommonLib/General|Utils]]: All classes contain static utility methods that can be used for whatever purpose you seek&lt;br /&gt;
If you need to fix a bug or want to have a new feature, your first step is looking at which packages are or could be affected. Please don&#039;t make new packages for already covered things, it works confusing. If you plan on moving a class around, be sure to keep a (deprecated) redirecting proxy class behind so depending plugins don&#039;t stop working all of a sudden.&lt;br /&gt;
&lt;br /&gt;
==BKCommonLib build process==&lt;br /&gt;
When first starting to work with it, you may notice that there are no package versions in the net.minecraft.server and org.bukkit.craftbukkit imports. The resulting build, however, does. How come? Well, to skip the process of manually updating all versions, we do multiple things:&lt;br /&gt;
&lt;br /&gt;
* Use reflection where possible so we don&#039;t need these imports&lt;br /&gt;
* Use [https://github.com/bergerkiller/Spinot Spinot] instead of CraftBukkit/Spigot to build against&lt;br /&gt;
* Use the &#039;maven-shade-plugin&#039; to turn all imports to the proper versioned imports instead&lt;br /&gt;
In addition we have several other dependencies and respective repositories for per-plugin compatibility.&lt;br /&gt;
&lt;br /&gt;
==Jenkins build server and GitHub==&lt;br /&gt;
We use GitHub to host our projects and have our own CI build server to build the GitHub projects on. Here is a checklist to see whether the Jenkins build server is ready to go:&lt;br /&gt;
&lt;br /&gt;
* GitHub, Git server, Git client and other Git-related plugins are installed and set active (manage/manage plugins)&lt;br /&gt;
* JDK 6u38 and 7 are installed (manage/configure system)&lt;br /&gt;
* Git account information including a valid SSH key is set and hooks are set on manual (manage/configure system)&lt;br /&gt;
Per job (configuration):&lt;br /&gt;
&lt;br /&gt;
* GitHub project path is set and Sourcecode management is set on &#039;git&#039; and configured fully&lt;br /&gt;
* Repository URL and GitHub project path is the same (&amp;lt;nowiki&amp;gt;http://github.com/etc/etc&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
* &#039;Build when changes are sent&#039; checked, nothing else by default&lt;br /&gt;
* JDK 6 or 7 is selected properly for building the project (usually 6)&lt;br /&gt;
* Github plugin hook url (&amp;lt;nowiki&amp;gt;http://sitename.something/github-webhook/&amp;lt;/nowiki&amp;gt;) is added to service hooks on the GitHub project&lt;br /&gt;
* Post-build step &#039;archive artifacts&#039; is set (output: target/*.jar)&lt;br /&gt;
* Multiple branches? Be sure to specify &#039;origin/master&#039; if needed!&lt;br /&gt;
Common errors and issues:&lt;br /&gt;
&lt;br /&gt;
* Dependency issues on the server and not locally: delete the .m2/repository/* contents locally and refresh&lt;br /&gt;
* Compilation failure: change between different compiler versions until it works&lt;br /&gt;
* This is not what I wanted to build!: make sure it isn&#039;t building the wrong branch&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=MyWorlds/Portals&amp;diff=7815</id>
		<title>MyWorlds/Portals</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=MyWorlds/Portals&amp;diff=7815"/>
		<updated>2025-10-12T09:44:21Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:myworlds_portals_examples.png|thumb|right|Several types of portals on display]]&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Besides commands, this plugin comes with the simplest cross-world teleportation solution: Actual portals. Walk from world to world simply, by walking into a portal. To make a portal, all you have to do is place a [portal] sign nearby a block structure that looks like a portal.&lt;br /&gt;
&lt;br /&gt;
There are three types of portals to choose from:&lt;br /&gt;
* Nether portals&lt;br /&gt;
* End portals&lt;br /&gt;
* Water portals&lt;br /&gt;
&lt;br /&gt;
== Default Portal Destination ==&lt;br /&gt;
MyWorlds Portals are created using signs. If you want player-created nether portals or naturally generated end gateways to send players to a certain destination, configure that using &amp;lt;code&amp;gt;/world endportal&amp;lt;/code&amp;gt; and &amp;lt;/code&amp;gt;/world netherportal&amp;lt;/code&amp;gt;. [[MyWorlds/Commands#Set_default_nether_portal_or_end_portal_behavior|See the commands page for more information.]]&lt;br /&gt;
&lt;br /&gt;
=== Vanilla Defaults ===&lt;br /&gt;
Nether portals automatically teleport players from &#039;&#039;worldname&#039;&#039; to &#039;&#039;worldname_nether&#039;&#039; and back. Similarly an end gateway teleportation is automatically set up between &#039;&#039;worldname&#039;&#039; and &#039;&#039;worldname_the_end&#039;&#039;. If this is not working, run the following commands while in the world to apply the options to (/tpp worldname). This assumes world names &amp;quot;overworld&amp;quot;, &amp;quot;nether_world&amp;quot; and &amp;quot;end_world&amp;quot;. Replace these with the names of your worlds.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! From where !! Command !! Explanation&lt;br /&gt;
|-&lt;br /&gt;
| overworld || /mw netherportal destination nether_world&amp;lt;br&amp;gt;/mw netherportal mode nether_link&amp;lt;br&amp;gt;/mw endportal destination end_world&amp;lt;br&amp;gt;/mw endportal mode end_platform || When players enter a nether portal in the overworld they should go to /8 coordinates (nether link mode) to the nether world. When they enter an end gateway they should teleport to the end platform in the end world.&lt;br /&gt;
|-&lt;br /&gt;
| nether_world || /mw netherportal destination overworld&amp;lt;br&amp;gt;/mw netherportal mode nether_link || When players enter a nether portal in the nether, teleport x8 (nether link) to the overworld&lt;br /&gt;
|-&lt;br /&gt;
| end_world || /mw endportal destination overworld&amp;lt;br&amp;gt;/mw endportal mode respawn || When players enter an end gateway in the end, respawn the player at their bed or world spawn&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Nether Link Permissions ===&lt;br /&gt;
If you have a default portal mode set to &#039;&#039;&#039;nether_link&#039;&#039;&#039;, then it will create a new nether portal on the destination world (at x8 coordinates). For this creation, players require the following permission (default true):&lt;br /&gt;
&amp;lt;code&amp;gt;myworlds.world.linknether&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Enable ==&lt;br /&gt;
This portal behavior must be enabled in MyWorlds&#039; &#039;&#039;config.yml&#039;&#039; before they can be used. If portal signs aren&#039;t working, first check that all relevant portal types are enabled:&lt;br /&gt;
&amp;lt;pre&amp;gt;# Turns different types of portals on or off&lt;br /&gt;
# When the portal is disabled, MyWorlds will not handle the portal&#039;s logic&lt;br /&gt;
enabledPortals:&lt;br /&gt;
  # Turns handling of nether portal teleportation on or off&lt;br /&gt;
  # Vanilla Minecraft will handle nether portals when disabled&lt;br /&gt;
  netherPortal: true&lt;br /&gt;
  # Turns handling of end portal teleportation on or off&lt;br /&gt;
  # Vanilla Minecraft will handle end portals when disabled&lt;br /&gt;
  endPortal: true&lt;br /&gt;
  # Enables or disables the water stream portals&lt;br /&gt;
  waterPortal: true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
=== Nether portals and End gateways ===&lt;br /&gt;
Standard nether portals and end gateways can also be used as portals. For a custom frame or shape, this command can be used to get a special item to place them down:&lt;br /&gt;
{{Command|world giveportal [end/nether]|Gives an item to place end/nether portals|myworlds.world.giveportal}}&lt;br /&gt;
&lt;br /&gt;
=== Water portals ===&lt;br /&gt;
To use water as a portal, the water must be surrounded on at least two sides with a solid block and at least one side with open air. This is to prevent random lakes to act as portals. With a hole in the ground you can prevent the water from flooding outwards. Water is counted as a solid block, so they can be infinitely wide.&lt;br /&gt;
&lt;br /&gt;
=== Portal Sign ===&lt;br /&gt;
[[Image:myworlds_portal_sign_placement.png|thumb|right|Portal sign is placed below a nether portal, teleporting players inside]]&lt;br /&gt;
{{sign|[portal]|name|destination|title}}&lt;br /&gt;
&lt;br /&gt;
For each line:&lt;br /&gt;
* on the first line: [portal]&lt;br /&gt;
* on the second line the portal name. You can teleport to this portal by this name, for example, with /tpp [name].&lt;br /&gt;
* on the third line the portal or world name to teleport to. This is taken when the portal is entered.&lt;br /&gt;
* optionally on the fourth line the destination display name (otherwise uses portal/world name on third line). Can be left empty.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
{{sign|[portal]|Portal1|HubWorld|}}&lt;br /&gt;
&lt;br /&gt;
==== Placement ====&lt;br /&gt;
Players are teleported to the first open space above the portal sign. You can put the portal sign underground, and the player will be teleported on top of the solid blocks above. It is safe to put the portal sign below the portal itself, cyclical teleports are prevented.&lt;br /&gt;
&lt;br /&gt;
=== Cleaning up portals ===&lt;br /&gt;
If you want to remove a portal you lost, you can remove the saved portal data from: &#039;&#039;root\plugins\My Worlds\portals.txt&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Teleporting to portals ===&lt;br /&gt;
Please see the /world teleport and /tpp commands on the [[MyWorlds/Commands#Teleport_to_portal_or_world_spawn|Commands page]]&lt;br /&gt;
&lt;br /&gt;
=== Use with Traincarts ===&lt;br /&gt;
The Traincarts plugin supports this type of sign for creating (cross-world) train teleporters. [[TrainCarts/Signs/Teleporter|See this page for more information]].&lt;br /&gt;
&lt;br /&gt;
== Rejoin Portals ==&lt;br /&gt;
Rejoin portals are special portals which mimic the &#039;&#039;/world rejoin&#039;&#039; command. Rejoining means a player is teleported to the last position of the world name put on the sign. You must specify one of the worlds that should be rejoined on the last line.&lt;br /&gt;
&lt;br /&gt;
{{sign|[portal rejoin]|Portal1||world|}}&lt;br /&gt;
&lt;br /&gt;
To make sure rejoining &#039;world&#039; also rejoins &#039;world_nether&#039; if the player was last in the nether, see the [[MyWorlds/Commands#Last_Position|lastposition command]] to merge worlds. This way players also rejoin the last world they were on when rejoining one of the merged worlds.&lt;br /&gt;
&lt;br /&gt;
== Additional Options ==&lt;br /&gt;
Additional options that don&#039;t really fit on the sign can be configured using the &amp;lt;code&amp;gt;/world setportaloption &amp;lt;portal name&amp;gt; &amp;lt;option&amp;gt; &amp;lt;value&amp;gt;&amp;lt;/code&amp;gt; command. If you want to set per portal whether mobs and items can pass through the portal, rather than relying on the global option in config.yml, this can be set per portal here:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/world setportaloption hub playersonly [no/yes]&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/Controller&amp;diff=7808</id>
		<title>BKCommonLib/Controller</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/Controller&amp;diff=7808"/>
		<updated>2025-10-12T09:43:46Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
The EntityController class contains various methods a plugin can override to alter entity behaviour.&lt;br /&gt;
&lt;br /&gt;
==Functionalities==&lt;br /&gt;
* Altering, cancelling or completely rewriting entity movement physics&lt;br /&gt;
* Handling block collisions, cancelling them&lt;br /&gt;
* Handling entity collisions, cancelling them&lt;br /&gt;
* Handling onTick to disable or completely alter Entity logic&lt;br /&gt;
* Handling damage dealt to the Entity&lt;br /&gt;
* Handling entity interaction (by players)&lt;br /&gt;
* Altering the name of an Entity&lt;br /&gt;
* Handling when an Entity dies&lt;br /&gt;
&lt;br /&gt;
==How to use==&lt;br /&gt;
Entity Controllers are used in combination with Common Entities. Assigning one is fairly simple: use setController. There is no need to manually bind the entity to the controller, setController takes care of that for you.&lt;br /&gt;
&lt;br /&gt;
For example, here we assign an onBlockCollision handler for items to create an explosion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Item item = ...;&lt;br /&gt;
CommonItem entity = CommonEntity.get(item);&lt;br /&gt;
entity.setController(new EntityController&amp;lt;CommonItem&amp;gt;() {&lt;br /&gt;
    @Override&lt;br /&gt;
    public boolean onBlockCollision(Block block, BlockFace hitFace) {&lt;br /&gt;
        block.getWorld().createExplosion(block.getLocation(), 5.0f);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
});&amp;lt;/pre&amp;gt;&lt;br /&gt;
What you put in the (overridden) methods is completely up to you. You can (literally) make pigs fly.&lt;br /&gt;
&lt;br /&gt;
==Replacing all entities==&lt;br /&gt;
If you wish to replace all entities globally, so set controllers whenever a new Entity is added to the server, you can use the EntityAdd event provided by BKCommonLib:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;@EventHandler(priority = EventPriority.LOWEST)&lt;br /&gt;
public void onEntityAdd(EntityAddEvent event) {&lt;br /&gt;
    if (!(event.getEntity() instanceof Item)) {&lt;br /&gt;
        return;&lt;br /&gt;
    } &lt;br /&gt;
    CommonEntity.get((Item) event.getEntity()).setController(new CustomItemController());&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/Packets&amp;diff=7807</id>
		<title>BKCommonLib/Packets</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/Packets&amp;diff=7807"/>
		<updated>2025-10-12T09:43:36Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
To keep keep track of packets being sent between the server and the client, BKCommonLib provides a packet listener to intercept and handle these packets. When [https://www.spigotmc.org/resources/protocollib.1997/ ProtocolLib] is found, this plugin is used to provide the listening, otherwise a hacky workaround is used. We recommend you install ProtocolLib as well for that reason.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
How to register a packet listener and how to read and change the packets.&lt;br /&gt;
&lt;br /&gt;
==Registering==&lt;br /&gt;
Use the following method to register your [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/protocol/PacketListener.java PacketListener] implementing class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;PacketUtil.addPacketListener(plugin, myPacketListener, PacketType.OUT_CHAT);&amp;lt;/pre&amp;gt;&lt;br /&gt;
To create a Packet listener class for your plugin, create a new Class that implements PacketListener, and override the &#039;&#039;&#039;onPacketReceive&#039;&#039;&#039; and &#039;&#039;&#039;onPacketSend&#039;&#039;&#039; methods. There are INcoming and OUTgoing Packet Types, they register for the methods respectively.&lt;br /&gt;
&lt;br /&gt;
==Working with packets==&lt;br /&gt;
Packets change all the time, so it was not possible to include a wrapper class for each and every packet. To work with packets, BKCommonLib provides you a reflection-based system for accessing fields and constructing new packets, namely [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/protocol/PacketType.java PacketType]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;@Override&lt;br /&gt;
public void onPacketSend(PacketSendEvent event) {&lt;br /&gt;
    CommonPacket packet = event.getPacket();&lt;br /&gt;
    if (packet.getType() == PacketType.OUT_CHAT) {&lt;br /&gt;
        String oldMessage = packet.read(PacketType.OUT_CHAT.message);&lt;br /&gt;
        if (oldMessage.contains(&amp;quot;curse&amp;quot;)) {&lt;br /&gt;
            packet.write(PacketType.OUT_CHAT.message, oldMessage.replace(&amp;quot;curse&amp;quot;, &amp;quot;curse is awesome&amp;quot;));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
There are also methods to read/write a certain parameter index or by name, but they are generally unsafe. We recommend you use the PacketFields constants for this instead, so your plugin remains compatible when fields change. For example, if the &#039;message&#039; String field is replaced with a List of Strings, we can still provide you with a (deprecated) message field which sets that other field.&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/FileData&amp;diff=7806</id>
		<title>BKCommonLib/FileData</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/FileData&amp;diff=7806"/>
		<updated>2025-10-12T09:43:26Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
To make raw data storage possible without the common try-catch logic blurring your vision, there are data reading and writing classes to help you. IO exceptions, missing files or access errors are automatically dealt with.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
To use it, create a new instance of the class (nested class), implement the read/write methods and call read() or write() at the end. Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;DataReader&lt;br /&gt;
new DataReader(filename) {&lt;br /&gt;
    public void read(DataInputStream stream) throws IOException {&lt;br /&gt;
        final int count = stream.readInt();&lt;br /&gt;
        for (int i = 0; i &amp;lt; count; i++) {&lt;br /&gt;
             data.add(stream.readInt());&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}.read();&lt;br /&gt;
DataWriter&lt;br /&gt;
new DataWriter(filename) {&lt;br /&gt;
    public void write(DataOutputStream stream) throws IOException {&lt;br /&gt;
        int count = stream.writeInt(data.size());&lt;br /&gt;
        for (Integer val : data) {&lt;br /&gt;
            data.writeInt(val.intValue());&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}.write();&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Compressed DataReader/DataWriter==&lt;br /&gt;
The exact same code, only use the respective classes instead. The data is compressed using a DeflaterOutputStream and decompressed using a InflaterInputStream&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
You are using nested classes here, which means that it is not possible to access all variables &#039;just like that&#039;. To access a variable from within read or write, you have several options:&lt;br /&gt;
&lt;br /&gt;
Declare them statically or provide a way to access them statically (getInstance())&lt;br /&gt;
Declare the variables final&lt;br /&gt;
Example of final variables being used this way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;public void writeMyValue(String filename) {&lt;br /&gt;
    final int value = this.getSpecialValue(); // Variable is final, therefore we can access it&lt;br /&gt;
    new DataWriter(filename) {&lt;br /&gt;
        public void write(DataOutputStream stream) throws IOException {&lt;br /&gt;
            stream.writeInt(value);&lt;br /&gt;
        }&lt;br /&gt;
    }.write();&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/Recipes&amp;diff=7788</id>
		<title>BKCommonLib/Recipes</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/Recipes&amp;diff=7788"/>
		<updated>2025-10-12T09:43:13Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
[https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/utils/RecipeUtil.java RecipeUtil] provides various utility methods to work with item crafting and furnace recipes. It allows you to obtain the information required to do various recipe-related operations.&lt;br /&gt;
&lt;br /&gt;
==Craft Recipes==&lt;br /&gt;
To perform crafting operations, BKCommonLib has it&#039;s own implementation, or wrapper class, to store and use a crafting (table) recipe: [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/inventory/CraftRecipe.java CraftRecipe]. In this class, all required input items and resulting output item(s) are stored. You can then, by calling just one method, perform the crafting in an inventory, with an optional maximum amount of times.&lt;br /&gt;
&lt;br /&gt;
==Obtaining a Craft Recipe==&lt;br /&gt;
There are methods in [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/utils/RecipeUtil.java RecipeUtil] to obtain the Craft Recipes that are able to produce a given item, this method is called &#039;&#039;&#039;getCraftingRequirements&#039;&#039;&#039;. As a plugin, you can then go through all recipes and try to craft something, or design your own filter to get the desired results.&lt;br /&gt;
&lt;br /&gt;
==Example of Craft Recipes being used==&lt;br /&gt;
The following example will try to craft 64 wood &#039;pieces&#039; (one item with amount 64) using the items from a player inventory. Note that &#039;&#039;&#039;craft&#039;&#039;&#039; does not take in account how many items you get per crafting operation, therefore &#039;&#039;&#039;craftItems&#039;&#039;&#039; was added that takes care of that. It only uses the first recipe that can be found in this example, so other ways to craft wood are ignored.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Inventory inventory = player.getInventory();&lt;br /&gt;
CraftRecipe[] recipes = RecipeUtil.getCraftingRequirements(Material.WOOD, null);&lt;br /&gt;
if (recipes.length &amp;gt; 0) {&lt;br /&gt;
    recipes[0].craftItems(inventory, 64);&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you want to be certain that crafting is possible, make a copy of the inventory (e.g. InventoryBaseImpl) and pass that into the crafting method first.&lt;br /&gt;
&lt;br /&gt;
==Furnace &#039;recipes&#039;==&lt;br /&gt;
The furnace does not really maintain a list of recipes, instead it more or less assigns a property to certain items that make them &#039;furnace craftable&#039;. For that reason, and because the output amount is always 1, no special FurnaceCraftRecipe is added. Instead, you can obtain the furnace results, check the fuel time of items, check whether an item is fuel and whether an item can be heated, and so on. All of these methods can be found in [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/utils/RecipeUtil.java RecipeUtil].&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=MyWorlds/Configuration&amp;diff=7773</id>
		<title>MyWorlds/Configuration</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=MyWorlds/Configuration&amp;diff=7773"/>
		<updated>2025-10-12T09:42:59Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Configuration==&lt;br /&gt;
Below the general configuration nodes found in:&lt;br /&gt;
&lt;br /&gt;
root\plugins\My Worlds\config.yml&lt;br /&gt;
&lt;br /&gt;
For world-specific settings, see [[MyWorlds/WorldConfiguration|World Configuration]]&lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
Below the configuration nodes with matching descriptions are given:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Node !! Default !! Description !! Value type&lt;br /&gt;
|-&lt;br /&gt;
| usePermissions || false || Sets if the Permission 3.* plugin is used || Boolean&lt;br /&gt;
|-&lt;br /&gt;
| useWaterTeleport || true || Sets if water Portals are used || Boolean&lt;br /&gt;
|-&lt;br /&gt;
| allowPortalNameOverride || false || Sets if portals can be replaced || Boolean&lt;br /&gt;
|-&lt;br /&gt;
| teleportInterval || 2000 || The minimum delay between portal teleportations in miliseconds || Number&lt;br /&gt;
|-&lt;br /&gt;
| timeLockInterval || 20 || Sets the interval, in ticks, to re-set the time when locked || Number&lt;br /&gt;
|-&lt;br /&gt;
| useWorldOperators || false  || Sets if the world-specific OP&amp;amp;nbsp;lists are used || Boolean&lt;br /&gt;
|-&lt;br /&gt;
| locale || default || Sets the localization file to use|| Text&lt;br /&gt;
|-&lt;br /&gt;
| useWorldEnterPermissions || false || Sets if world enter permission nodes are used || Boolean&lt;br /&gt;
|-&lt;br /&gt;
| usePortalEnterPermissions || false || Sets if portal enter permission nodes are used || Boolean&lt;br /&gt;
|-&lt;br /&gt;
| useWorldTeleportPermissions || false || Sets if world teleport permission nodes are used || Boolean&lt;br /&gt;
|-&lt;br /&gt;
| usePortalTeleportPermissions|| false || Sets if portal teleport permission nodes are used || Boolean&lt;br /&gt;
|-&lt;br /&gt;
| useWorldBuildPermissions || false || Sets if world build permission nodes are used || Boolean&lt;br /&gt;
|-&lt;br /&gt;
| useWorldUsePermissions || false || Sets if world use permission nodes are use || Boolean&lt;br /&gt;
|-&lt;br /&gt;
| useWorldChatPermissions || false || Sets if world chat permission nodes are used || Boolean&lt;br /&gt;
|-&lt;br /&gt;
| useWorldInventories || true || Sets if world inventories are separated using the settings || Boolean&lt;br /&gt;
|-&lt;br /&gt;
| onlyObsidianPortals || false || Sets if portals have to be surrounded by obsidian blocks to function || Boolean&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/NetworkController&amp;diff=7769</id>
		<title>BKCommonLib/NetworkController</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/NetworkController&amp;diff=7769"/>
		<updated>2025-10-12T09:42:48Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
The EntityNetworkController class provides ways of altering how clients (players) observe an Entity. For example, you can use it to make cows look like pigs to all players, or some other nifty trick. The default implementation of the EntityNetworkController also contains various bugfixes and code optimizations to make your live easier.&lt;br /&gt;
&lt;br /&gt;
==Functionalities==&lt;br /&gt;
* Alter the spawn packets&lt;br /&gt;
* Alter packets sent to update entity position&lt;br /&gt;
* Keep track of what players can &#039;see&#039; an Entity&lt;br /&gt;
* Handle player viewers being added or removed&lt;br /&gt;
&lt;br /&gt;
==How to use==&lt;br /&gt;
Just like Entity Controllers, you can assign it to Common Entities. They can only be assigned to entities that have been spawned on a world, mind you. If you want to spawn an Entity with a network controller, use the spawn(location, networkController) method instead. Example code to change the spawn packet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Entity bukkitEntity = ...;&lt;br /&gt;
CommonEntity&amp;lt;?&amp;gt; entity = CommonEntity.get(bukkitEntity);&lt;br /&gt;
entity.setNetworkController(new EntityNetworkController&amp;lt;CommonEntity&amp;lt;?&amp;gt;&amp;gt;() {&lt;br /&gt;
    @Override&lt;br /&gt;
    public CommonPacket getSpawnPacket() {&lt;br /&gt;
        return PacketFields.VEHICLE_SPAWN.newInstance(entity.getEntity(), 13);&lt;br /&gt;
    }&lt;br /&gt;
});&amp;lt;/pre&amp;gt;&lt;br /&gt;
In general, you probably won&#039;t be using network controllers. If you do, and wish to alter live entities, you may have to respawn the entity after attaching the network controller for new spawn messages to have effect.&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=MyWorlds/WorldConfiguration&amp;diff=7760</id>
		<title>MyWorlds/WorldConfiguration</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=MyWorlds/WorldConfiguration&amp;diff=7760"/>
		<updated>2025-10-12T09:42:37Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==World Configuration==&lt;br /&gt;
Below the world configuration nodes of MyWorlds found in:&lt;br /&gt;
&lt;br /&gt;
root\plugins\My Worlds\worlds.yml&lt;br /&gt;
&lt;br /&gt;
For the general configuration, see the [[MyWorlds/Configuration|Configuration]] page&lt;br /&gt;
&lt;br /&gt;
==World configuration==&lt;br /&gt;
Every world has their own properties. Below the setting nodes with a description is given:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting node !! Description !! Value type&lt;br /&gt;
|-&lt;br /&gt;
| loaded || If the world is loaded (on startup) || Boolean&lt;br /&gt;
|-&lt;br /&gt;
| keepSpawnLoaded || If the world spawn is kept in memory|| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| environment || The world environment. (NORMAL/NETHER) || Environment&lt;br /&gt;
|-&lt;br /&gt;
| chunkGenerator || The name of the chunk generator plugin to use || Plugin name&lt;br /&gt;
|-&lt;br /&gt;
| gamemode || The game mode applied to the players that join the world || Game mode&lt;br /&gt;
|-&lt;br /&gt;
| lockedtime  || The time the world is locked to. (tick time) || Number&lt;br /&gt;
|-&lt;br /&gt;
| defaultPortal || The default destination portal for the world || Portal or World name&lt;br /&gt;
|-&lt;br /&gt;
| operators || The operator player names || Player array&lt;br /&gt;
|-&lt;br /&gt;
| deniedCreatures || The creatures who are denied to spawn on the world || Creature type array&lt;br /&gt;
|-&lt;br /&gt;
| holdWeather || If the weather states on this world are locked/frozen || Boolean&lt;br /&gt;
|-&lt;br /&gt;
| diffuculty || The set difficulty of the world || Difficulty&lt;br /&gt;
|-&lt;br /&gt;
| spawn || The spawn point of the world || Coordinate (xyz) with degree angles&lt;br /&gt;
|-&lt;br /&gt;
| world || The spawn point of the world: world name || World name&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The above settings can also be altered through [[MyWorlds/Commands|commands]].&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/CommonEntity&amp;diff=7751</id>
		<title>BKCommonLib/CommonEntity</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/CommonEntity&amp;diff=7751"/>
		<updated>2025-10-12T09:42:26Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
The CommonEntity class provides additional advanced entity utilities Bukkit does not provide. Most evidently, these are:&lt;br /&gt;
&lt;br /&gt;
Utilities to alter entity position, velocity&lt;br /&gt;
Perform cross-world teleportation of all entity types&lt;br /&gt;
Added properties (isInWater, isMoving, etc.)&lt;br /&gt;
Entity controllers&lt;br /&gt;
Entity network controllers&lt;br /&gt;
In addition, it contains several &#039;specialized&#039; CommonEntity extensions. For example, minecarts, players and items have an additional class to handle the entity-specific methods. More CommonEntity extensions are added as the project goes on, but it partially depends on what Bukkit is unable to provide by default.&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
The basic usage of CommonEntity instances is as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Creating a new entity and spawning it afterwards&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;CommonEntity&amp;lt;?&amp;gt; entity = CommonEntity.create(EntityType.CREEPER);&lt;br /&gt;
// Some pre-spawn conditions, and what not&lt;br /&gt;
entity.spawn(location);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Obtaining a (new) CommonEntity from an existing Entity&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;CommonEntity&amp;lt;?&amp;gt; entity = CommonEntity.get(entity);&lt;br /&gt;
CommonPlayer player = CommonEntity.get(playerEntity);&lt;br /&gt;
CommonItem item = CommonEntity.get(itemEntity);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Entity Controllers==&lt;br /&gt;
CommonEntity is the hub for Entity Controllers. For more information, see [[BKCommonLib/Controller|this page]].&lt;br /&gt;
&lt;br /&gt;
==Entity Network Controllers==&lt;br /&gt;
For spawned CommonEntities, network controllers can be assigned as well. For more information, see [[BKCommonLib/NetworkController|this page]].&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
	<entry>
		<id>https://wiki.traincarts.net/index.php?title=BKCommonLib/EventsAndListeners&amp;diff=7743</id>
		<title>BKCommonLib/EventsAndListeners</title>
		<link rel="alternate" type="text/html" href="https://wiki.traincarts.net/index.php?title=BKCommonLib/EventsAndListeners&amp;diff=7743"/>
		<updated>2025-10-12T09:42:09Z</updated>

		<summary type="html">&lt;p&gt;RyanDo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
BKCommonLib keeps track of several server events that can not be monitored using Bukkit alone. The following events (and listeners) are available:&lt;br /&gt;
&lt;br /&gt;
==Entities==&lt;br /&gt;
The following entity related events are available:&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/events/EntityAddEvent.java EntityAddEvent] - when an entity is added to the server&lt;br /&gt;
* [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/events/EntityRemoveEvent.java EntityRemoveEvent] - when an entity is removed from a world&lt;br /&gt;
* [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/events/EntityRemoveFromServerEvent.java EntityRemoveFromServerEvent] - when an entity is permanently removed from the server&lt;br /&gt;
* [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/events/EntityMoveEvent.java EntityMoveEvent] - fired every tick to update entity movement. This event is optimized.&lt;br /&gt;
&lt;br /&gt;
==Packets==&lt;br /&gt;
The following events are available when registering a [[BKCommonLib/Packets|PacketListener]]:&lt;br /&gt;
* [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/events/PacketReceiveEvent.java PacketReceiveEvent] when a packet is received from the client&lt;br /&gt;
* [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/events/PacketSendEvent.java PacketSendEvent] when a packet is about to be sent to the client&lt;br /&gt;
&lt;br /&gt;
==Internal==&lt;br /&gt;
Developers should ignore these events, as they are mainly used to keep track of internal BKCommonLib changes:&lt;br /&gt;
* [https://github.com/bergerkiller/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/internal/TimingsListener.java TimingsListener] for keeping track of execution times on the server&lt;/div&gt;</summary>
		<author><name>RyanDo</name></author>
	</entry>
</feed>