[Spoiler] Preview of the Journal (Patch r27)

You’re most of the way there! In the spirit of academic exercise, (ie, it may change still, though I don’t foresee it changing much in the near future) let me outline the general structure. As you already discerned, each entity has a “commands” component declared in their .json file. You add commands to an entity by adding references to json files to that section.

(Aside: Tony wrote an optimization so that if a file and its parent folder have the same name, and the file type is .json, you don’t have to include the whole path, just the folder. So to get to show_character_sheet.json, all you have to do is stop at data/commands/show_character_sheet)

If you look inside the command’s .json file, you’ll see:

{
“type” : “command”,

“name”: “show_character_sheet”, //this is the id, used by the commands component
“tooltip”: “Character sheet”, //appears in the ui
“description” : “Show detailed information about this character’s capabilities and personality”,
“icon”: “file(show_character_sheet.png)”, //changes the icon

“action”: “fire_event”, //describes what happens when the button is pushed in the UI
“event_name” : “show_character_sheet.stonehearth”, //name of the event fired
“event_data” : {} //data you want to package up to send.
}

The event that is fired is caught in the javascript file associated with the event (which you added to the manifest in your step 1.) From “show_character_sheet”:

$(document).ready(function(){
$(top).on(‘show_character_sheet.stonehearth’, function (_, e) {
//do stuff in javascript whenever the event is fired.
});
});

The variable “e” will contain the event data you passed in via the .json file. One day we’ll have documentation for how to write Stonehearth views, but you can theoretically do anything you want here from a javascript/html perspective.

And that’s commands in a nutshell, from a UI POV. Radiant TODO before it’s ready for prime time: go back and make sure it’s easy for an entity to access commands from different mods (folders that are peer to Stonehearth.)

But how do you get data generated and manipulated by JS back to the server, so your command can actually change the game world? You have to call a function from Javascript that exists on either the lua client or the lua server, probably using “radiant_call”:

radiant.call(‘name of the function you want to call’, data you want to pass );

The name of the function is either declared in C++ (starts with radiant:…) or in stonehearth’s manifest.json file. For example in:

radiant.call(‘radiant:play_sound’, ‘stonehearth:sounds:ui:carpenter_menu:confirm’ );

radiant:play_sound is a c++ function that plays a single sound, based from the location of the UI. stonehearth;sounds:ui:carpenter_menu:confirm is a sound declared in the stonehearth manifest.json.

Alternatively, this line from place_item.js calls a function declared in the stonehearth manifest.json (choose place item location) and passes it some data about the item to place:

radiant.call(‘stonehearth:choose_place_item_location’, item.entity_uri, item.full_sized_entity_uri)

The declaration of choose_place_item_location in the manifest looks like this:

     "choose_place_item_location" : {   //user-visible name
        "endpoint" : "client",                  //whether function lives in lua client or lua server
        "controller" : "file(call_handlers/place_item_call_handler.lua)"  //file that contains the function
     },

Somewhere inside place_item_call_handler.lua, there’s a function with this signature:

function PlaceItemCallHandler:choose_place_item_location(session, response, target_entity, entity_uri)
–handles all place-item logic, including the semi-transparent ghost item
–tells the lua server to actually place the item
–updates all the game logic.
end

And that’s about it!

2 Likes