I have seen rather advanced examples, including most inventory systems, that incorporate JavaScript into Harlowe. How exactly are JS functions created and called in Harlowe, and where can I find some good examples?
Before you ask, I made this an open-ended discussion on purpose so I could keep discussing JavaScript in general. I just asked a question for the first post.
Javascript functions are defined within the Edit Story JavaScript area.
note: you should test to see if your function exists before trying to create it, I am using a very basic method to do this and there are other ways that also test if an existing property is actually a function.
For the functions to be available within the story (within scope) they need to be defined on a globally available object like window. You can define both functions that return a value and ones that don't:
if (! window.calculateValue) {
window.calculateValue = function(value1, value2) {
var result = value1 + value2;
return result;
};
}
if (! window.doInvisableTask) {
window.doInvisableTask = function() {
console.log('Invisable Task was done.');
};
}
... and you may want to use Namespaces to group your functions:
/* Using a namespace to colate the Inventory related functions */
if (! window.Inv) {
window.Inv = {};
Inv.addItem = function(item) {
console.log('Item added to inventory');
};
Inv.removeItem = function(item) {
console.log('Item removed from inventory');
};
}
Two of the common ways to invoke your functions are:
1. Within a (set:) macro:
(set: $var to calculateValue(1, 2))
(set: $dummy to doInvisableTask())
(set: $dummy to Inv.addItem('An Item'))
(set: $dummy to Inv.removeItem('An Item'))
Be careful with that. Because of the way Harlowe implements its history, using non-Harlowe mechanisms to modify objects (e.g. the object's native methods) can compromise the history. As long as you're only accessing them, you should be fine. Modifications, however, should only be done in the "standard" Harlowe way.
Comments
note: you should test to see if your function exists before trying to create it, I am using a very basic method to do this and there are other ways that also test if an existing property is actually a function.
For the functions to be available within the story (within scope) they need to be defined on a globally available object like window. You can define both functions that return a value and ones that don't: ... and you may want to use Namespaces to group your functions:
Two of the common ways to invoke your functions are:
1. Within a (set:) macro: 2. Use a <script> element:
I especially need to remember the second one.