Sponge Documentation

repository·api-12·Indexed 19 days ago

https://github.com/spongepowered/sponge

Sponge is a SpongeAPI implementation targeting vanilla Minecraft and 3rd party platforms like Forge and NeoForge, providing a unified API for building Minecraft plugins. This documentation covers development environment setup using Gradle, Java 21, and IDE configuration for IntelliJ IDEA and Eclipse, as well as technical details for implementing custom command argument parsers using AbstractArgumentParser, ArgumentParser, ClientNativeArgumentParser, and CustomArgumentParser.

Tokens
47.6K
Snippets
139
Records
176
Agent score
64%

What's inside Sponge

  1. Update your local Sponge clone

    api-12

    To synchronize your local repository with the official upstream repository, perform the following steps:

    1. git pull
    2. git submodule update
    3. ./gradlew build --refresh-dependencies
    git pull
    git submodule update
    ./gradlew build --refresh-dependencies
  2. Configure Eclipse for Sponge development

    api-12
    1. Install the Buildship plugin from the Eclipse Marketplace.
    2. Import the project via File > Import > Gradle as an Existing Gradle Project.

    Note: While supported, most developers use IntelliJ. Run configurations for client and server development are automatically generated upon import. If you modify them, do so on copies, as they are re-generated on every project import.

  3. Set up the Sponge development environment

    api-12

    Sponge uses the Gradle wrapper for its build system. It is recommended to use the provided wrapper rather than a local Gradle installation.

    • Unix/macOS: Use ./gradlew
    • Windows: Use gradlew

    Prerequisites:

    • Java 21

    Decompiling for IDE Sources: To enable browsable sources within your IDE, run the decompile task. You must re-run this command if the Minecraft version changes or if .accesswidener files are modified.

    ./gradlew :decompile

    ./gradlew :decompile
  4. Configure IntelliJ IDEA for Sponge development

    api-12
    1. Ensure the Gradle plugin is enabled in File > Settings > Plugins.
    2. Go to File > New > Project from Existing Sources > Gradle.
    3. Select the Sponge root folder.
    4. Ensure Use default gradle wrapper is selected.

    Note: Run configurations for client and server development are automatically generated upon import. If you modify them, do so on copies, as they are re-generated on every project import.

  5. Clone the Sponge repository

    api-12

    To properly clone the Sponge repository with all necessary submodules, use the --recursive flag. After cloning, you must copy the pre-commit hooks to ensure your local environment is set up for development.

    1. Clone the repo: git clone --recursive https://github.com/SpongePowered/Sponge.git
    2. Enter the directory: cd Sponge
    3. Install hooks: cp scripts/pre-commit .git/hooks
    git clone --recursive https://github.com/SpongePowered/Sponge.git
    cd Sponge
    cp scripts/pre-commit .git/hooks
  6. Configure dynamic choices and results mapping

    api-12

    When building a dynamic parameter, you can define how choices are retrieved and how they are converted to the target type using two different patterns:

    Use choicesAndResults to provide a Supplier<Map<String, ? extends T>>. This ensures that the keys of the map serve as the command choices and the values serve as the resulting objects, maintaining consistency between what the user types and what the command receives.

    Pattern 2: Separate Choices and Results

    Use choices(Supplier<? extends Collection<String>>) and results(Function<String, ? extends T>) independently. This is useful if the list of strings and the logic to resolve them come from different sources.

  7. Understand the SpongeCommandDispatcher

    api-12

    The SpongeCommandDispatcher is the central entrypoint for command processing in Sponge. It extends Mojang's CommandDispatcher to integrate Sponge's command management, event system, and permission checks into the Brigadier command tree.

    Key responsibilities include:

    • Command Parsing: Converting raw command strings into ParseResults while handling Sponge-specific logic like ExecuteCommandEvent.Pre and raw command mappings.
    • Command Execution: Managing the lifecycle of a command execution, including cause tracking (via CauseStackManager), phase transitions (via PhaseTracker), and posting ExecuteCommandEvent post-execution.
    • Suggestion Handling: Providing command completion suggestions, including specialized handling for non-Brigadier (raw) commands.
    • Permission Integration: Intercepting the parsing process to ensure users only see or execute commands they have permission to use via SpongeNodePermissionCache.
  8. Understand SpongeArgumentCommandNode for custom command arguments

    api-12

    In the Sponge command system, SpongeArgumentCommandNode<T> is a specialized command node used to handle arguments of a specific type T. It bridges the gap between the underlying Brigadier command tree and Sponge's high-level parameter system.

    Key characteristics:

    • Parsing: It uses an ArgumentParser<T> to convert raw input from a StringReader into a typed object of type T.
    • Context Storage: Once parsed, the resulting value is stored in the CommandContext using a Parameter.Key<? super T>.
    • Suggestions: It supports both standard suggestions and complex suggestions (via ComplexSuggestionNodeProvider). It also allows for ValueParameterModifier<T> to modify the list of suggestions provided to the user.
    • Optionality: Nodes can be marked as optional, allowing the command parser to proceed even if the argument is not present in the input string.
    • Usage Text: It provides custom usage text via ValueUsage, which determines how the argument appears in command help/usage strings.
  9. How BrigadierCommandRegistrar handles namespacing

    api-12

    The BrigadierCommandRegistrar automatically applies namespacing to commands to prevent collisions.

    • Sponge-aware registration: When registering via register(PluginContainer, LiteralArgumentBuilder, String...), the registrar prepends the plugin's ID to the command literal (e.g., pluginid:command). The command literal itself must not contain a colon (:) or a space.
    • Unaware/Mod registration: If a command is registered without a PluginContainer or is intended for non-Sponge frameworks, it may use the unknown namespace or attempt to resolve the container from the PhaseTracker.
    • Permission Wrapping: Commands that are not explicitly Sponge-aware may be wrapped in a SpongePermissionWrappedLiteralCommandNode to ensure they respect the necessary permission boundaries.
  10. Configure parameter completion and parsing logic

    api-12

    When building a SpongeParameterValue, the completer logic is determined as follows:

    1. If you call .completer(ValueCompleter completer), that specific completer is used.
    2. If you do not provide a completer, the builder iterates through all registered ValueParser instances. Any parser that also implements the ValueCompleter interface will be used.
      • If exactly one parser implements ValueCompleter, it is used.
      • If multiple parsers implement ValueCompleter, the builder creates a composite completer that aggregates results from all of them.
      • If no parsers implement ValueCompleter, an empty completer is used (returning no suggestions).
  11. Manage command context changes with Transactions

    api-12

    The SpongeCommandContextBuilder provides a transactional API to safely modify the context state. This is useful when you need to simulate or temporarily inject arguments/flags during a complex command execution flow.

    1. Start: Call startTransaction() to obtain a Transaction object. This pushes a new state onto a stack.
    2. Modify: Any subsequent calls to putEntry, withArgument, or addFlagInvocation will affect the transaction's view of the context rather than the base builder.
    3. Commit: Call commit(Transaction transaction) to apply the changes made during the transaction to the main builder. The provided transaction must be the current one at the top of the stack.
    4. Rollback: Call rollback(Transaction transaction) to discard all changes made during that transaction and revert to the state before startTransaction() was called.

    Note: You cannot start a transaction on an existing transaction (nested transactions are not supported via startTransaction).

    // Start a new transaction
    SpongeCommandContextBuilder.Transaction tx = builder.startTransaction();
    
    try {
        // Perform operations
        builder.putEntry(key, value);
        
        // Apply changes
        builder.commit(tx);
    } catch (Exception e) {
        // Revert changes
        builder.rollback(tx);
    }