Minecraft.Server/docs/DEVELOPMENT.en.md
This document is for contributors who are new to Minecraft.Server and need a practical map for adding or modifying features safely.
Minecraft.Server is the dedicated-server executable entry for this codebase.
Core responsibilities:
server.propertieslevel-id aligned with the actual save destinationbanned-players.json and banned-ips.jsonWindows64/ServerMain.cpp
PrintUsage() and ParseCommandLine()SetExeWorkingDirectory()WorldManager.hWorldManager.cpp
level-id first, then world-name fallbackServerProperties.hServerProperties.cpp
server.propertiesServerPropertiesConfigSaveServerPropertiesConfig() rewrites level-name, level-id, and white-listAccess/Access.hAccess/Access.cpp
Access/BanManager.hAccess/BanManager.cpp
banned-players.json and banned-ips.jsonAccess/WhitelistManager.hAccess/WhitelistManager.cpp
whitelist.jsonServerLogger.hServerLogger.cpp
startup, world-io, console, access, network, and shutdownServerLogManager.hServerLogManager.cpp
ban-ip <player>Console/ServerCli.cpp (facade)Console/ServerCliInput.cpp (linenoise input thread + completion bridge)Console/ServerCliParser.cpp (tokenization, quoted args, completion context)Console/ServerCliEngine.cpp (dispatch, completion, helpers)Console/ServerCliRegistry.cpp (command registration + lookup)Console/commands/* (individual commands)Main flow in Windows64/ServerMain.cpp:
SetExeWorkingDirectory() switches the current directory to the executable folder.server.properties via LoadServerPropertiesConfig().DedicatedServerConfig, then apply CLI overrides (-port, -ip/-bind, -name, -maxplayers, -seed, -loglevel, -help/--help/-h).ServerLogManager, and Access::Initialize(".").ServerPropertiesConfig.BootstrapWorldForServer(...).SaveServerPropertiesConfig().RunNetworkGameThreadProc).TickCoreSystems()HandleXuiActions()serverCli.Poll()-port <1-65535>-ip <addr> or -bind <addr>-name <name> (runtime max 16 chars)-maxplayers <1-8>-seed <int64>-loglevel <debug|info|warn|error>-help, --help, -hNotes:
level-name and level-id, and that happens when world bootstrap resolves identity changes.help / ?stoplistban <player> [reason ...]
ban-ip <address|player> [reason ...]
pardon <player>pardon-ip <address>
banlisttp <player> <target> / teleportgamemode <survival|creative|0|1> [player] / gmCLI behavior notes:
cmd and /cmd.ServerCliParser.Complete(...).server.propertiesbanned-players.jsonbanned-ips.jsonThis follows from SetExeWorkingDirectory(), so these files are resolved relative to Minecraft.Server.exe, not the shell directory you launched from.
Use this pattern when adding commands like /kick, /time, etc.
Console/commands/
CliCommandYourCommand.hCliCommandYourCommand.cppIServerCliCommand
Name(), Usage(), Description(), Execute(...)Aliases() and Complete(...)ServerCliEngine::RegisterDefaultCommands().CMakeLists.txt (MINECRAFT_SERVER_SOURCES)Minecraft.Server/Minecraft.Server.vcxproj (<ClCompile> / <ClInclude>)helpcmd and /cmdImplementation references:
CliCommandHelp.cpp for a simple no-arg commandCliCommandTp.cpp for multi-arg + completion + runtime checksCliCommandGamemode.cpp for argument parsing and aliasesCliCommandBanIp.cpp for access-backed behavior with connection metadataserver.properties KeyServerPropertiesConfig (ServerProperties.h).kServerPropertyDefaults (ServerProperties.cpp).LoadServerPropertiesConfig().
SaveServerPropertiesConfig().
ApplyServerPropertiesToDedicatedConfig(...)ServerMain.cpp (app.SetGameHostOption(...))PrintUsage() / ParseCommandLine() if the key also gets a CLI overrideNormalization details worth remembering:
level-id is normalized to a safe save ID and length-limited.server-name is capped to 16 runtime chars.max-players is clamped to 1..8.autosave-interval is clamped to 5..3600.level-type normalizes to default or flat.Primary code lives in Access/Access.cpp, Access/BanManager.cpp, and ServerLogManager.cpp.
When changing this area:
BanManager responsible for storage/caching, not live-network policy.Access.cpp so readers never block on disk I/O.ban-ip <player> depends on ServerLogManager::TryGetConnectionRemoteIp(...).SnapshotBannedPlayers() / SnapshotBannedIps() output.ban, ban-ip, pardon, pardon-ip, and banlist still workPrimary code is in WorldManager.cpp.
Current matching policy:
level-id (UTF8SaveFilename) first.When changing this logic:
ApplyWorldStorageTarget(...) usage consistent (title + save ID together).tickProc) to avoid async deadlocks.ServerMain.cppUse ServerLogger helpers:
LogDebug, LogInfo, LogWarn, LogErrorLogDebugf, LogInfof, etc.Use ServerLogManager when the event is specifically part of the transport/login/disconnect lifecycle.
Recommended categories:
startup for init/shutdown lifecycleworld-io for save/world operationsconsole for CLI command handlingaccess for ban/access control statenetwork for connection/login auditFrom repository root:
cmake -S . -B build -G "Visual Studio 17 2022" -A x64
cmake --build build --config Debug --target MinecraftServer
cd .\build\Debug
.\Minecraft.Server.exe -port 25565 -bind 0.0.0.0 -maxplayers 8 -name DedicatedServer
Notes:
server.properties, banned-players.json, and banned-ips.json are therefore read/written next to the executable.COMPILE.md.server.properties is missing or sparselevel-idbanlist output stays sane after adding/removing bans.vcxproj include newly added source filesRegisterDefaultCommands() and build-file entriesserver.properties or ban files seem to load from the wrong folder:
SetExeWorkingDirectory() moves the working directory to the executable folderTickCoreSystems() and HandleXuiActions() where requiredlevel-id normalization and matching logic in WorldManager.cppban-ip <player> cannot resolve an address:
ServerLogManager has a cached remote IP for that connectionServerPropertiesConfig, optionally copied into DedicatedServerConfig, and then applied in ServerMain.cpp