Skip to content

Commit b0a530c

Browse files
committed
Add comments and docstrings to example plugin code
Explain what each section does and why, so new developers can learn Endstone patterns by reading the template.
1 parent 7200c1c commit b0a530c

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

src/endstone_example/listener.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,33 @@
1+
"""Event listener demonstrating how to respond to player events.
2+
3+
Listeners are separate classes (not the Plugin itself) that hold @event_handler
4+
methods. Register them in on_enable with self.register_events(). This keeps
5+
event handling logic organized and out of the main plugin class.
6+
"""
7+
18
from endstone import ColorFormat
29
from endstone.event import PlayerJoinEvent, PlayerQuitEvent, event_handler
310
from endstone.plugin import Plugin
411

512

613
class ExampleListener:
714
def __init__(self, plugin: Plugin) -> None:
15+
# Keep a reference to the plugin so we can use its logger and config.
816
self._plugin = plugin
917

1018
@event_handler
1119
def on_player_join(self, event: PlayerJoinEvent) -> None:
20+
"""Called when a player joins the server."""
1221
player = event.player
22+
23+
# Modify the join message broadcast to all players.
24+
# ColorFormat constants add Minecraft formatting codes.
1325
event.join_message = f"{ColorFormat.YELLOW}{player.name} joined the game"
26+
27+
# Log the player's network address (useful for debugging, not shown to players)
1428
self._plugin.logger.info(f"{player.name} joined from {player.address}")
1529

1630
@event_handler
1731
def on_player_quit(self, event: PlayerQuitEvent) -> None:
32+
"""Called when a player leaves the server."""
1833
event.quit_message = f"{ColorFormat.YELLOW}{event.player.name} left the game"

src/endstone_example/plugin.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Example plugin demonstrating commands, configuration, and lifecycle methods."""
2+
13
from endstone import Player
24
from endstone.command import Command, CommandSender, ConsoleCommandSender
35
from endstone.plugin import Plugin
@@ -6,9 +8,14 @@
68

79

810
class ExamplePlugin(Plugin):
11+
# The prefix shown in log messages, e.g. [ExamplePlugin] Hello!
912
prefix = "ExamplePlugin"
13+
14+
# Must match the major.minor version of the Endstone API you are targeting.
1015
api_version = "0.11"
1116

17+
# Commands are declared as a dict. Each key is the command name, and the value
18+
# configures how it appears in-game. The "permissions" list controls who can use it.
1219
commands = {
1320
"hello": {
1421
"description": "Send a greeting",
@@ -17,6 +24,9 @@ class ExamplePlugin(Plugin):
1724
},
1825
}
1926

27+
# Permissions are declared separately from commands. The "default" field controls
28+
# who gets the permission automatically: True = everyone, "op" = operators only,
29+
# False = no one (must be explicitly granted).
2030
permissions = {
2131
"example.command.hello": {
2232
"description": "Allow users to use the /hello command.",
@@ -25,19 +35,42 @@ class ExamplePlugin(Plugin):
2535
}
2636

2737
def on_enable(self) -> None:
38+
"""Called when the plugin is enabled. Use this for setup."""
39+
40+
# Copies config.toml to the plugin's data folder on first run.
41+
# On subsequent runs it does nothing, preserving the user's edits.
2842
self.save_default_config()
43+
44+
# Register event listeners. Endstone scans the object for @event_handler
45+
# methods and hooks them into the event system.
2946
self.register_events(ExampleListener(self))
47+
3048
self.logger.info("ExamplePlugin enabled!")
3149

3250
def on_disable(self) -> None:
51+
"""Called when the plugin is disabled. Use this for cleanup."""
3352
self.logger.info("ExamplePlugin disabled!")
3453

3554
def on_command(self, sender: CommandSender, command: Command, args: list[str]) -> bool:
55+
"""Called when a player or the console runs one of this plugin's commands.
56+
57+
Args:
58+
sender: Who ran the command (Player, ConsoleCommandSender, etc.).
59+
command: The command that was executed.
60+
args: The arguments passed after the command name.
61+
62+
Returns:
63+
True if the command was handled successfully.
64+
"""
3665
match command.name:
3766
case "hello":
38-
greeting = self.config["greeting"] # from config.toml
67+
# Read the greeting from config.toml (editable by server admins)
68+
greeting = self.config["greeting"]
3969

40-
# Use isinstance to check the sender type
70+
# Use isinstance to tailor behavior to the sender type.
71+
# This is a common pattern since players and the console have
72+
# different capabilities (e.g. players can receive chat messages,
73+
# but the console can only write to the log).
4174
if isinstance(sender, Player):
4275
sender.send_message(f"{greeting}, {sender.name}!")
4376
elif isinstance(sender, ConsoleCommandSender):

0 commit comments

Comments
 (0)