Taxonomy Icon

Containers

Watson Conversation is now Watson Assistant. Although some illustrations in this tutorial may show the service as Watson Conversation, the steps and processes will still work.

In Part 1, Part 2, and Part 3, you saw how to start your own Minecraft server inside a Docker container, first locally and then inside a container on the IBM Cloud. You also learned about building server-side plugins for Minecraft and adding those plugins to the Minecraft server running in Docker.

All of that was a prelude to this tutorial, the last in the series, which shows you how to use the power of the IBM Cloud environment in your plugin development, and at the same time add a little science to your game play in Minecraft. In this tutorial, you’ll see how to extend the Spigot server with a plugin that uses the Watson cognitive services.

IBM provides several Watson services on IBM Cloud that you can use to build cognitive solutions. These include the Watson Assistant service, Personality Insights, Natural Language Classifier, Visual Recognition, and more. Browse the complete list of Watson services.

In this tutorial, you’ll see how to build a plugin that uses the Watson Assistant service to answer questions about diseases — and then how to combine that plugin with another third-party Minecraft plugin that adds infectious diseases to your Minecraft villages. When you combine the two, players get a reason within the game to learn about diseases, as well as how to diagnose and treat them. This proof-of-concept integration shows how you can combine third-party plugins with your own plugins to use the power of Watson and IBM Cloud.

Create an IBM Cloud app and obtain the Watson Assistant service credentials

Let’s get started. First, we need to obtain an instance of the Watson Assistant service and get some credentials from that service instance in order to use them in our new plugin. Then we’ll build the plugin and install it into Docker and push that into the IBM Container.

To obtain the relevant credentials to access the IBM Cloud Watson Assistant service, we have to follow a roundabout process. If you’re writing an application using one of the Cloud Foundry runtimes, you can create a service and then bind that service to your runtime in order to obtain the credentials for the service, which flow to your runtime automatically through a set of environment variables. However, that same binding process doesn’t yet work as seamlessly for Docker containers, so we have to introduce a “dummy” application that we bind to the Watson Assistant service in order to obtain the right credentials. To do that, follow this procedure:

  1. Log in to the IBM Cloud using your IBM id and password. (If you don’t have an IBM id, you can get one when you register for your free IBM Cloud trial account.)
  2. Create an instance of the Watson Assistant service by selecting the Catalog link, navigating to the Platform > Watson section of the Catalog and selecting the Watson Assistant link from this section of the catalog. Screen shot of Conversation link in catalog
  3. Leave the default values in the create a Watson Assistant screen that appears next and click the Create button to create an instance of the Watson Assistant service. Take note of the name of the Watson Assistant service you just created. In the lower left, you can click the View Docs link to learn more about the service and the REST APIs you can use to access it. Screen shot of Conversation screen
  4. Create a new app by selecting the Catalog link, navigating to the Cloud Foundry Apps section of the Catalog and selecting the SDK for Node.js link from this section of the catalog. In the Create a Cloud Foundry App form that appears, Specify an APP Name that is unique (we use WatsonSpigotApp in our example). Leave the other default values and then click the Create button. This action will create and start an instance of a Node.js Cloud Foundry app. Navigate to the Connections page by clicking Connections in the left column of the newly created SDK for Node.js app.
  5. Add the Watson service to the app you just created by clicking the Create Connection button, search for the name of the Watson Assistant service you created in the previous step and Click the Connect button. This action binds the Watson Assistant service and restages the app. Screen shot: Binding the Watson Conversation service and restaging the app
  6. To retrieve the credentials for the newly created Watson Assistant service, expand the drop-down menu on the right and click the View Credentials menu items. This opens a dialog box with the endpoint URL and username and password. Screen shot: Dialog box with endpoint URL, username, and password
  7. Save these credentials (specifically, the URL, username, and password) because you will need them later to connect to this Watson Assistant service. Your credentials will be unique — this sample just shows you the form they take:
    
    "url": "https://gateway.watsonplatform.net/conversation/api",
    "username": "some‑long‑hyphenated‑set‑of‑characters",
    "password": "AVeryL0ngSer1esOfCharact3rs"
    

Create a workspace for the conversation with intents, entities, and a dialog

In the Watson Assistant service, a workspace is a named container for conversation artifacts (namely intents, entities, and the dialog), and has an optional description and language associated with it. Intents are words and strings with synonyms that represent the intent of the user’s input, entities are objects that are related to intents, and the dialog represents the conversation flow which includes intents and entities. Workspaces can be exported and imported to and from JSON with a maximum size limit of 10MB. Workspaces can be created and managed via a REST API or the Watson Assistant web dashboard interface. They can also be shared with members of a team who collocate when developing and maintaining a conversation service.

As mentioned before, intents capture the purpose or objective of the user’s input. Consider what capabilities you might want to provide to your users when planning intents. Then, capture as many real user inputs or questions and alternatives as possible that express the same input. Group similar questions to create an intent, the questions can then be supplied as examples of the intent. Intents are always prefixed with the “#” character. Intents can be exported to or imported from an external comma-separated value file. Once intents are created, your Watson Assistant workspace gets trained to handle these events. The sample conversation that accompanies this tutorial contains a single intent called “#information-on-diseases” and several examples of the intent such as:

  • list diseases available
  • what is diabetes?
  • what diseases do you have information on?

Please see the Watson Assistant service online documentation to learn more about intents.

Entities are terms or objects related to intents. For the sample intent “#information-on-diseases,” related terms or objects could be disease type, symptom, treatment, etc. The name of an entity is always prefixed with the “@” character. Entities have values associated with them, and those values can have synonyms or patterns associated with them. Like intents, entities can be imported from or exported to an external comma-separated value file. The sample conversation accompanying this tutorial contains a single intent called “@disease” and several values of the entity such as: diabetes, measles, and the flu with examples like cold, cough, and influenza. The Watson Assistant service also provides a list of system entities such as @sys-date and @sys-time which can be applied to any conversation. Please see the Watson Assistant service online documentation to learn more about entities.

A dialog represents the flow of the conversation that reacts to intents and entities with responses. It is represented as a set of dialog nodes that are connected depending on the flow. Each node contains at least one condition and one response. A condition represents the input that meets a specific criteria such as a matching intent or entity for the dialog node to provide a response. The response can be an answer to a question or an action to be executed, depending on the intent. The dialog can be structured to request additional information when the information provided in the intent or entity is not sufficient to respond to a user’s request. The context of the conversation can be captured and stored in context variables. In a dialog, nodes are evaluated from top to bottom. Dialog nodes can contain child nodes. When a node that has child nodes has been triggered, the conversation is evaluated against its child nodes, traversing the depth of the conversation tree and evaluating each node along the path. Default handling is also available when an unrecognized or unsupported intent or entity is encountered. The dialog can be created and managed via the Watson Assistant web user interface console or using the REST API. Please refer to the Watson Assistant service online documentation to learn more about creating dialogs.

In this tutorial, a sample Watson Assistant workspace has been provided on GitHub that contains a dialog with intents and entities. Executing a curl command to invoke a Watson Assistant REST API providing the workspace JSON as input (details provided later in the tutorial) creates a workspace with the dialog that is depicted in the image below. This dialog can be modified as desired, or a new one can be created. You can examine the Watson workspace JSON, WatsonConversationTest.json, or navigate through the workspace and modify the conversation from the Watson Assistant web dashboard once it has been created. As you extend the conversation sample or create a new one, you will want to add more intents. Note that the workspace, along with the intents, entities, and dialog, can be created and managed using the Watson Assistant web console or via the Watson Assistant REST API. To learn more about the Watson Assistant service, intents, entities, dialogs, and conversations, please refer to the Watson Assistant documentation that’s available on IBM Cloud.

Screen shot: Sample conversation

In this tutorial, the Watson Assistant Workspace with intents, entities, and the dialog will be created using the create workspace API via the curl command. The input to the API is a JSON called WatsonConversationTest.json that has been created and is available in the spigot-plugin-watson/input/ directory.

Change the directory to minecraft-project:


cd ~/minecraft project

Type the curl command as shown. If you’re copying it from a web page, make sure you format the double quotes correctly:


curl ‑X POST ‑u "bxxxx69b‑6xx1‑45xx‑axx9‑03xxxxxxx925":"35533rrNN" ‑H "Content‑Type: application/json" ‑d@./spigot‑plugin‑watson/input/WatsonConversation.json https://gateway.watsonplatform.net/conversation/api/v1/workspaces?version=2017‑05‑26

You should see the following result:


{"name":"WatsonMinecraftSpigotConversation","created":"2018‑01‑01T01:54:14.997Z","updated":"2018‑01‑01T01:54:14.997Z","language":"en","metadata":{"api_version":{"major_version":"v1","minor_version":"2017‑05‑26"}},"description":"","workspace_id":"c704xxx‑32e5‑42fc‑a89e‑d907xxxx667","learning_opt_out":false}

Note the workspace_id that was created. You can navigate to the Watson Assistant service web console by clicking the Watson Assistant service link that’s available in the Connections tab of the WatsonSpigotApp you created in step 4 of the previous section. After successfully launching and logging into your instance of the Watson Assistant service, you will notice the new conversation workspace that you just created with the curl command. You can navigate through the workspace and look at the intents, entities, and dialog that were created and modify it to create a more complete conversation with additional intents and entities if desired.

Screen shot: Conversation workspace

Build a Spigot plugin to use the Watson Assistant service

Now that you have the right credentials, we can build our Spigot plugin.

Note: All the code referenced in this tutorial series is available on GitHub under the same project you cloned in Part 1. If you haven’t done so (say you skipped directly to this tutorial), then clone the following project from GitHub:

    
git clone  https://github.com/kgb1001001/minecraft‑project.git

The directory minecraft-project/spigot-plugin-watson/ includes the sample source code, libraries, and related artifacts to create an Eclipse project that is referenced in the rest of this tutorial.

In your Ubuntu or other environment (which you’ve been using for Parts 1, 2, and 3):

  1. Download the following jars to the $HOME/reflibs directory. You will need them in subsequent steps:
  2. Download the Watson Java SDK from https://github.com/watson-developer-cloud/java-sdk/releases/download/java-sdk-4.2.0/java-sdk-4.2.1-jar-with-dependencies.jar. More information about the SDK and examples can be found on GitHub.
  3. Build craftbukkit-1.8.8.jar by executing the following steps:
    • cd $HOME/reflibs
    • mkdir minecraft
    • wget "https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar" -O minecraft/BuildTools.jar
    • git config --global core.autocrlf input
    • java -jar minecraft/BuildTools.jar When these steps complete, you should have a craftbukkit-1.8.8.jar in your directory.
  4. Start Eclipse. On Ubuntu, run:
    ./eclipse/eclipse (The commands may vary a bit on other platforms.) Choose a workspace directory. (Eclipse writes its files to that directory.)
    Note: If Eclipse starts without the File menu showing, then kill Eclipse and restart it with the following command:
    UBUNTU_MENUPROXY=0 ./eclipse/eclipse
  5. Create a new project by selecting File > New > Java Project. Screen shot of creating a new project Specify the name as WatsonSpigotPlugin. Screen shot of naming the new project Click Next, and under Libraries, click Add External Jars…. Sceen shot of adding JARs Navigate to $HOME/reflibs and select craftbukkit-1.8.8.jar. Screen shot of selecting a JAR Click OK, and then click Finish on the next screen. A new project will be created in your Eclipse workspace with the name WatsonSpigotPlugin.
  6. Next we need to add some required dependency jars. Create a new folder under your WatsonSpigotPlugin project and call it lib. Screen shot of creating a new folder Copy the following four jars from your $HOME/reflibs directory into the lib directory that you just created:
    • commons-codec-1.10.jar
    • jackson-core-asl-1.9.13.jar
    • jackson-mapper-asl-1.9.13.jar
    • java-sdk-4.2.1-jar-with-dependencies.jar
  7. Add these jars to your project’s build path: Select them in Eclipse, right-click, and then select Build Path > Add to Build Path. Screen shot of moving JARs
  8. Create new package and name it com.ibm.minecraft.spigotplugin. Under the package com.ibm.minecraft.spigotplugin, create a new Java class and call it WatsonDialog. This creates the new class and loads the file in Eclipse. Screen shot of creating and loading a new class file
  9. Add the following code to your WatsonDialog.java:
    
    package com.ibm.minecraft.spigotplugin;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    import java.util.Properties;
    
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.plugin.java.JavaPlugin;
    
    import com.ibm.watson.developer_cloud.conversation.v1.Conversation;
    import com.ibm.watson.developer_cloud.conversation.v1.model.Context;
    import com.ibm.watson.developer_cloud.conversation.v1.model.InputData;
    import com.ibm.watson.developer_cloud.conversation.v1.model.MessageOptions;
    import com.ibm.watson.developer_cloud.conversation.v1.model.MessageResponse;
    
    public class WatsonConversation extends JavaPlugin {
        Conversation conversationService = null;
        Context context = null;
    
        static String USER_ID = null;
        static String USER_PASS = null;
        static String SERVICE_ENDPOINT = null;
        static String WORKSPACE_ID = null;
    
        static {
            System.out.println("NEW INSTANCE");
            try (InputStream is = WatsonConversation.class.getResourceAsStream("conversationservice.properties")) {
                Properties properties = new Properties();
                properties.load(is);
                USER_ID = properties.getProperty("userid", "");
                USER_PASS = properties.getProperty("userpass", "");
                SERVICE_ENDPOINT = properties.getProperty("service_endpoint", "");
                WORKSPACE_ID = properties.getProperty("workspace_id", "");
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    
        // Fired when plugin is first enabled
        @Override
        public void onEnable() {
            // getLogger().info("WatsonSpigotPlugin");
            conversationService = setupConversationService();
        }
    
        // Fired when plugin is disabled
        @Override
        public void onDisable() {}
    
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
            // getLogger().info("command: " + cmd.getName());
            // getServer().dispatchCommand(getServer().getConsoleSender(), cmd.getName());
            if (cmd.getName().equalsIgnoreCase("hello")) {
                sender.sendMessage("Welcome to Watson");
            }
            if (cmd.getName().equalsIgnoreCase("watson")) {
                if (args.length == 0) {
                    sender.sendMessage("WATSON Rocks!!");
                    return true;
                }
                if (args.length >= 1) {
                    StringBuilder str = new StringBuilder();
                    for (int i = 0; i < args.length; i++) {
                        str.append(args[i]);
                        if (i < args.length ‑ 1) {
                            str.append(" ");
                        }
                    }
                    String input = str.toString();
                    
                    //getLogger().info(input);
                    String response = getResponse(input, conversationService, this.context);
                    //getLogger().info(response);
                    sender.sendMessage("Watson response: " + response );
    
                    return true;
                }
            }
            return false;
        }
    
        public Conversation setupConversationService() {
            Conversation service = new Conversation(Conversation.VERSION_DATE_2017_05_26);
            // the user name and password from the VCAP_SERVICES env variable of the Conversation service instance
            service.setUsernameAndPassword(USER_ID, USER_PASS);
            service.setEndPoint(SERVICE_ENDPOINT);
    
            return service;
        }
    
        public String getResponse(String input, Conversation service, Context context) {
            // Create conversation
            if (context == null) {
                context = new Context();
                System.out.println("NEW CONTEXT");
            }
            InputData inputData = new InputData.Builder(input).build();
            MessageOptions options = new MessageOptions.Builder(WORKSPACE_ID)
                    .context(context)
                    .input(inputData)
                    .build();
    
            // Ask question
            MessageResponse response = service.message(options).execute();
            this.context = response.getContext();
            System.out.println("CONTEXT " + context.getConversationId());
    
            List<String> responseList = response.getOutput().getText();
            String resposeString = "";
            for (String string : responseList) {
                resposeString = resposeString + System.lineSeparator() + string;
            }
            
            return resposeString;
        }
    }
    
    The sample code in WatsonConversation.java is similar to the sample code for getting started with plugin development for the Spigot server. Note that the actual Watson Assistant URL used in the code is:
    https://gateway.watsonplatform.net/conversation/api/
  10. To provide the server with information on the Watson plugin, add a new file in the src folder by selecting src > New > File, and name the file plugin.yml. Screen shot of adding plugin.yml
  11. Add the following lines to plugin.yml:
    
    name: WatsonConversationPlugin
    main: com.ibm.minecraft.spigotplugin.WatsonConversation
    version: 1.0
    
    commands:
      hello:
        description: A new command
      watson:
        description: watson initial command
    
  12. To provide the server with information on the Watson plugin, we need to add a conversationservice.properties file under WatsonConversation.java. To do this, right-click WatsonSpigotPlugin > New > File and traverse to path /src/com/ibm/minecraft/spigotplugin. Type conversationservice.properties as the File name, and click Finish, as shown: Screen shot: Add a conversationservice.properties file Then edit this file with the information that you captured from the IBM Cloud Credentials collection part for the dialog service. Fill in essential information as shown:

    The workspace_id property that needs to be filled is the same that you obtained using the CURL command. Your final conversationservice.properties file will look like this:

    Note about WatsonConversation.json: The WatsonConversation.json file is the basic controlling file that is used to create the dialog scenarios used in this project. The configuration of WatsonConversation.json and additional information on how to define intents, entities, and dialogs as well as manage workspaces can be found in the online documentation.

  13. Define a MANIFEST.MF to reference the dependency jars for the plugin. Under the WatsonSpigotPlugin project, create a new folder and call it META-INF. In the META-INF folder, create a new file and call it MANIFEST.MF.
  14. Add the following lines to MANIFEST.MF. Make sure that last line in the file is a newline (carriage return).
    
    Manifest‑Version: 1.0
    Main‑Class: com.ibm.minecraft.spigotplugin.WatsonConversation
    Class‑Path: lib/jackson‑core‑asl‑1.9.13.jar lib/commons‑codec‑1.10.jar lib/jackson‑mapperasl‑1.9.13.jar lib/java‑sdk‑4.2.1‑jar‑with‑dependencies.jar
    
    
    
  15. In a terminal window, create a directory from which you will run the Spigot server with the Watson Spigot plugin:
    
    mkdir  $HOME/watsonspigot
    
  16. In Eclipse, export the WatsonSpigotPlugin project into a JAR as follows:
    1. Click File > Export.
    2. Under Java, select JAR File and click Next.
    3. Under Resources to Export, select WatsonSpigotPlugin, uncheck .classpath and .project, and specify the destination of the JAR as the same directory where you’re starting the Spigot server ($HOME/watsonspigot) and call it watsonqa.jar ($HOME/watsonspigot/watsonqa.jar).
    4. Click Next (don’t click Finish yet).
    5. Click Next again.
    6. On the JAR Manifest Specification page, make sure to select the option to use existing manifest from workspace.
    7. Click Finish. If you see a warning: “JAR export finished with warnings,” you may be using a different version of the dependencies jar file. Screen shot of JAR Manifest Specification page
  17. Run Docker to create a new image using the WatsonSpigotPlugin plugin. For this step, we’ll cd to the $HOME/watsonspigot directory, which needs the following:
    • Dockerfile
    • watsonqa.jar
  18. Change to the $HOME/watsonspigot/ directory and create a Dockerfile that includes the following lines:
    
    #Version 0.0.4
    #This version builds a spigot server
    #using the recommended build strategy for spigot
    #This is advantageous in that it's better for plugin development
    #and fits well with the Docker approach
    #it also adds a first Minecraft plugin into the bare spigot server
    #
    FROM ubuntu:16.04
    MAINTAINER Kyle Brown &brownkyl@us.ibm.com&
    RUN apt‑get update &&\
        apt‑get install ‑y git &&\
        apt‑get install ‑y default‑jdk &&\
        apt‑get install ‑y wget &&\
        mkdir minecraft &&\
        wget "https://hub.spigotmc.org//jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar" ‑O minecraft/BuildTools.jar &&\
        git config ‑‑global core.autocrlf input &&\
        java ‑jar minecraft/BuildTools.jar ‑‑rev 1.12.2 &&\
        apt‑get purge ‑y ‑‑autoremove git wget
    RUN echo "eula=true" > eula.txt &&\
        mkdir plugins
    ADD watsonqa.jar /plugins/watsonqa.jar
    #Install unzip
    RUN apt‑get install ‑y unzip
    RUN unzip ‑uo /plugins/watsonqa.jar ‑d /plugins/
    CMD java ‑Xms512m ‑Xmx1024m ‑jar spigot‑1.12.2.jar nogui
    EXPOSE 25565
    
    The lines highlighted in the previous code listing are the main differences from the other Dockerfiles you’ve seen in previous tutorials. Effectively, these lines create a new directory called plugins under $HOME/watsonspigot. Copy watsonqa.jar to the plugins directory, unzip that jar into the plugins directory, and then run the Spigot server. This is needed to make sure the plugin can access all the required dependency jars that were copied under the lib directory in the Eclipse project and referenced in the MANIFEST.MF file as described earlier. The folder should now look like this: Screen shot of the watsonspigot directory
  19. Build a new Docker image as follows (replace parallels with your login name):
    
    docker build ‑t="<repository name>/watsonspigotplugin" .
    
  20. Run the Spigot server with Watson Assistant plugin in:
    
    docker run ‑i ‑t ‑p=25565:25565 <repository name>/watsonspigotplugin
    
    If you see the following lines, your Spigot server with the Watson plugin started successfully:
    
    [00:04:07 INFO]: [WatsonSpigotPlugin] Enabling WatsonSpigotPlugin v1.0
    [00:04:07 INFO]: [WatsonSpigotPlugin] WatsonSpigotPlugin
    [00:04:07 INFO]: Done (12.659s)! For help, type "help" or "?"
    
  21. Connect your Minecraft client to your server (as described in the previous tutorials in this series).
  22. Once connected, ask Watson a question such as /Watson “What is diabetes.” The question text is passed to the Watson Assistant instance and the response is provided back to the player. The sample Watson Assistant accompanying this tutorial can provide responses to simple welcome and goodbye messages along with responses to questions like what is diabetes, measles and the flu. Screen shot of asking Watson a question

Host the Spigot server with the WatsonConversation and Disease plugins on IBM Cloud

So far, we’ve verified the functionality of the Spigot server with the Watson plugin locally in a Docker container. Next, let’s host this server with the WatsonConversation and Disease plugins on IBM Cloud.

  1. From your terminal, create a new directory $HOME/watsonspigotbluemix:
    
    mkdir $HOME/watsonspigotbluemix
    
  2. Copy watsonqa.jar that we extracted into $HOME/watsonspigot:
    
    cp $HOME/watsonspigot/watsonqa.jar $HOME/watsonspigotbluemix/
    
  3. In step 18 of the previous section we created a Docker file and included the WatsonConversation plugin that was created. In this section, we introduce a third-party plugin, the Disease plugin, which allows players to bring the terror and fear of infectious diseases to Minecraft town. With these diseases in play, you can leverage Doctor Watson via the plugin we’ve described earlier for information about the definition and symptoms of these diseases as well as the best treatment options. To add the Disease plugin, we’ll need to add one step to the Dockerfile we’ve used earlier to create the Watson plugin. Namely, we’ll need to download the jar for the disease plugin and add it to the plugins directory. For reference, we need to edit the Dockerfile (a copy is included below) and add the one line highlighted (near the bottom of the listing).
    
    #Version 0.0.4
    #This version builds a spigot server
    #using the recommended build strategy for spigot
    #This is advantageous in that it's better for plugin development
    #and fits well with the Docker approach
    #it also adds a first Minecraft plugin into the bare spigot server
    #
    FROM ubuntu:16.04
    MAINTAINER Kyle Brown &brownkyl@us.ibm.com&
    RUN apt‑get update &&\
        apt‑get install ‑y git &&\
        apt‑get install ‑y default‑jdk &&\
        apt‑get install ‑y wget &&\
        mkdir minecraft &&\
        wget "https://hub.spigotmc.org//jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar" ‑O minecraft/BuildTools.jar &&\
        git config ‑‑global core.autocrlf input &&\
        java ‑jar minecraft/BuildTools.jar ‑‑rev 1.12.2 &&\
        apt‑get purge ‑y ‑‑autoremove git wget
    RUN echo "eula=true" > eula.txt &&\
        mkdir plugins
    ADD watsonqa.jar /plugins/watsonqa.jar
    #Install unzip
    RUN apt‑get install ‑y unzip
    RUN unzip ‑uo /plugins/watsonqa.jar ‑d /plugins/
    RUN apt‑get install ‑y wget &&\
        wget "https://dev.bukkit.org/projects/byte‑disease/files/latest" ‑O /plugins/Disease.jar &&\
        apt‑get purge ‑y ‑‑autoremove wget
    CMD java ‑Xms512m ‑Xmx1024m ‑jar spigot‑1.12.2.jar nogui
    EXPOSE 25565
    
    Given this Dockerfile, you need to execute the same steps you ran earlier to build a Docker image and run it.
  4. To begin, open up a terminal, and type the following commands:
    
    bx login ‑a api.ng.bluemix.net
    
    You should have already created a namespace in Part 3. To check your namespace type:
    
    sudo bx cr namespaces
    
  5. Change to the directory that contains the Docker file and plugins. Then, build a docker image by executing this command at the command line to proceed, and as always, make sure you don’t forget the period (“.”) at the end!
    
    sudo docker build ‑t registry.ng.bluemix.net/<yourname>/watsonspigot .
    
  6. Now that your image is built, you will need to upload or push the image to the IBM Cloud container registry. You do that with the docker push command as shown here:
    
    sudo docker push registry.ng.bluemix.net/<yourname>/watsonspigot
    
    Executing this command can take several minutes, depending on your network speed. To verify that your image was successfully pushed, use the following command and look for your new image name in the list:
    
    bx cr image‑list
    
  7. In Part 3, you created a Kubernetes configuration file called deploy.yml. Change the configuration file to point to the new Docker image created and pushed to IBM Cloud as highlighted below and save the changed file in your watsonspigotbluemix directory.
    
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: spigot
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: spigot
        spec:
          containers:
          ‑ name: spigot
            image: registry.ng.bluemix.net/<yourname>//watsonspigot
    ‑‑‑
    apiVersion: v1
    kind: Service
    metadata:
      name: spigot‑service
      labels:
        run: spigot
    spec:
      selector:
        app: spigot
      type: NodePort
      ports:
       ‑ protocol: TCP
         port: 25565
    
  8. Before you run any commands from the Kubernetes cluster command line interface, ensure that the KUBECONFIG environment variable has been exported and points to the Kubernetes cluster config file:
    
    echo $KUBECONFIG
    /home/kylebrown/.bluemix/plugins/container‑service/clusters/Minecraft/kube‑config‑hou02‑Minecraft.yml
    
    Refer to the section “Creating a Cluster” in Part 3 for information on downloading the cluster configuration file. Now run the deployment configuration that you just edited to create a deployment using the create command in kubectl similar to what you did in Part 3.
    
    kubectl create ‑f deploy.yml
    
    If the deployment fails, you can clean up the deployment with the kubectl delete command and run the create command again.
  9. Finally, you need to obtain the public IP address and port number of the container service. Follow the instructions listed in the “Testing the server” section of Part 3 to learn how to get this information.
  10. Connect your Minecraft client to your server using the public IP address and port number as you did in the “Testing the server” section of Part 3. Once you’re connected to the server, you can issue /watson commands which use the WatsonConversation plugin and /disease commands that use the disease plugin that was added. Watson commands are prefixed with /watson and support a limited set of questions related to diseases. These diseases are defined by the sample conversation defined in the WatsonConversation.json dialog file that was created and imported earlier in this tutorial. An example of a simple Watson Assistant command would be:

    
    /watson what is diabetes
    
    Screen shot: Watson command and response Similarly, you can explore the disease plugin and the associated commands, such as:

    1. /disease help
    2. /disease list
    3. /disease check
    4. /disease infect <player> <disease>

    Check out the complete list of commands. (Some commands require admin permission.) Now that you have Watson Assistant for healthcare also accessible through the plugin, you can send any disease-related questions to Doctor Watson. For example, issue the following command to ask Watson about a disease:

    
    /watson what is measles
    
    Screen shot: Disease list We’ll leave the task of enhancing the Watson Assistant as an exercise for the reader. You now know how to combine several plugins including Watson services in your Minecraft server to create a more engaging gaming experience.

Conclusion

Now you’ve seen how to integrate the Watson Assistant service in a Spigot server and host it in a Docker container on IBM Cloud. While we have focused on the Watson Assistant service, you can use the same approach for more engaging gaming by using one or more of the other Watson services, such as Personality Insights (think about building teams of players), Natural Language Classifier (think about understanding player intent from their questions), and Visual Recognition (think about recognizing disease symptoms from images).

This concludes this tutorial series. Here’s to taking your Minecraft experience up a notch!