The week 6 of my work period involved a significant overhaul of the gameplay for the MasterOfOreon module. About a week ago, an Oreon would walk to an area assigned for the task and voilà task compeleted, an event which was only manifested by the removal of the area rendering. Now, blocks are being placed into the world as an outcome of the tasks being completed.

Modifications to the Oreons’ behaviors

A lot of modifications were made to the the Behavior tree of the Oreons in order to get the effect of tasks being performed for a period of time and then completed with the blocks being spawned. Different types of tasks, would involve different animations being run, so to implement this the Oreon BT diverges, at a point where it has been assigned a task and reached the target in the selected area, into various guard nodes which check for the assignedTaskType and decide the tree to “lookup” according to it. As an initial step only the build and plant behavior trees have been implemented.

{
    "sequence" : [
        {
            "animation": {
                "play": "MasterOfOreon:Build.animationPool",
                "loop": "MasterOfOreon:Build.animationPool"
            }
        },
        {
            "check_task_status" : {
                "child" : "move_to"
            }
        },
        "perform_task"
    ]
}

These new BTs are run when the Oreon has reached the target and is ready to perform a task, an animation simulating the Oreon performing a task is played until the subsequent child node check_task_status returns SUCCESS. The check_task_status node consists of the logic which checks whether the game time is beyond the time of completion of the task, which is defined in a taskCompletionTime field in the task component attached to the Oreon entity at the time of task assignment. This node returns a FAILURE until this time is reached and in the meantime, it also sets the target of the Oreon to a random nearby block in the selected area, this makes the Oreon move in the entire assigned area swirling its hammer in the process :D. The animation and check_task_status node are parented by a sequence node it is re-run until all its child nodes returns success, so until the task completion time is reached the animation is run thus creating the desired effect. After the task is completed the perform_task node is triggered, this is where the block-placing “magic” takes place.

Plant crops and watch’em grow

As you assign the area for the plant task, the Oreon walks to it and displays some of its hammer skiils. After the task completion time elapses oreon crops are placed in the area. This crops are implemented using the Changing Blocks module which replaces the placed blocks after a defined interval of time. Various stages in the growth of the crop are defined in different .block files which replaced one after another sequentially to create the plant growth effect.

Different stages in Oreon Crop growth

Construct a building

The build task implementation was another summit to conquer in itself, as it has various intricacies to be taken care of, to name a few : plopping whole structure in place which comprises of multiple blocks stacked on top of each other, spawning the said blocks in the area selected, replace any blocks which might be blocking the structure completion and many more :D. There are two modules which have the feature implemented, but both of them did that using entirely different means.

Conundrum : Cities or StructureTemplates

The Cities and the StructureTemplates module both can be used for building construction. They use different approaches for it though. The CIties module has a set of predefined parts like SimpleDoor, HipRoof and some predefined buildings SimpleChurch, Tower comprising of these parts and their relative positions using generators. It uses seperate rasterizers to add each of these parts to the world. The StructureTemplates on the other hand defines the position of all blocks in the building relative to center block and then stores it into a json file which is later used for spawning the building using the setBlock() method in the world provider which takes the block and the position it has to be placed as arguments. The buildings in ST are generated by using the toolbox item to obtain a StrucutureTemplateItem block and then selecting Record block addition to record all the blocks added, which can then be copied to the clipboard and stored in a json file. For details about the steps to construct a template see this wiki
I went with the StructureTemplates module because :

  • It is “lighter” than CIties with a dependency just on the Core module.
  • There are on-going efforts to emulate gradual building of the templates which would go well with the Oreon working process.
  • Getting a ST to spawn in the world was a lot easier than a Cities building, when I say “much easier” imagine 10 lines vs 250 lines of code :D. But in the process I implemented some rasterizers which would be moved into the Cities module so that anyone constructing buildings using it would not have to face much hassle.

Tackling a GooeysQuests bug

Initially I tried using one of the building templates in the GooeysQuests module. The inn template, but its construction was buggy, incomplete and also it was mid-air(but through this I got to know about the flight and ghost cheat, so cool). Discussing this with the mentors I came across the following issue with the GQ module :

On fiddling around with some breakpoints here and there for a while I got to know that the NPE was due to a torch block not added to the map correctly for placing into the world using the setBlock() method in ChunkImpl. The torch’s .block had a bug as it had an attribute named incorrectly, which caused the block not being registered correctly, thus the NPE.