This package has been deprecated

Author message:

Package has been renamed to articy-js. Please use this package instead.

articy-node
TypeScript icon, indicating that this package has built-in type declarations

0.3.20 • Public • Published

Articy.Node

A node package for loading and executing Articy flows from JSON exports. Includes full TypeScript support.

Export from Articy

In order to use this package, you need a json file exported from Articy. Use the Export feature in Articy and save it somewhere in your project.

Creating a database

To access the data in the database, you'll need to load the exported JSON into a new instance of the database class

// Example GameDB.js

// Import data from the exported json
import GameData from "./exported.articy.json";
import { Database } from "articy-node";

// Create a new database
const GameDB = new Database(GameData)

// Export the database
export default GameDB;

Then, you can access objects from the database using getObject.

import GameDB from "GameDB";
import { FlowFragment } from "articy-node";

// Get a flow fragment by ID
const fragment = GameDB.getObject("0x01000000000018A3", FlowFragment);
console.log("Flow fragment text: ", fragment.properties.Text);

Flow Iteration

The model for flow iteration is styled after Redux, with various reducers that consume a GameFlowState and return a new, updated flow state.

// Create an iteration configuration. This tells the runtime which nodes it should stop on
const iterationConfig = { 
    stopAtTypes: ["DialogueFragment"]
};

// Given our database, startup a flow state at a given node ID
const [initialState, initialNode] = startupGameFlowState(GameDB, "0x01000000000018A3", iterationConfig);

// Access information about the current state
console.log("Current node id: ", initialState.id);
console.log("Value of variable Test.X: ", initialState.variables["Test"]["X"]);
console.log("Number of branches: ", initialState.branches.length);

// Move down the first branch
const [nextState, nextNode] = advanceGameFlowState(GameDB, initialState, iterationConfig, 0);

// Refresh the branch set
const stateWithRefreshedBranches = refreshBranches(GameDB, nextState, iterationConfig);

Registering New Types, Functions, and Features

Script Functions

// Register a new IsGreater function that takes two arguments
RegisterScriptFunction("IsGreater", (context, arg1, arg2) => {
    return arg1 > arg2;
});

Object Types

In most cases, you will not need to define new object types. This is only necessary if you want to customize the iteration functions (such as next or execute) or want to add new helper methods.

To register a new object type, define a new class deriving from either Entity, DialogueFragment or whatever base class is most appropriate. Then, mark the class with the @ArticyType decorator (or use RegisterDatabaseTypeClass if you don't have decorator support).

@ArticyType('MyCustomDialogueFragment') // this must match the technical name of your custom Template in Articy
class MyCustomDialogueFragment extends DialogueFragment // if using Typescript, you can add a <TemplateType> here to add type support for the template's features
{
    execute(context) {
        // custom logic when this node is executed in flow iteration
    }
}

Feature Handlers

A better alternative to making a new type is registering a Feature Handlers. Feature Handlers are registered functions that are called whenever a node with a given Feature is executed during iteration.

/* Let's say you created a new Feature in Articy called MusicSettings. It has one string in it called SongName.
 * We want to run some special music code whenever any node with that feature is executed as part of iteration.
 * This will work even if the node in question is not "stopped at" in iteration, and just passed over.
*/
RegisterFeatureExecutionHandler("MusicSettings", (db, feature, node, state) => {
    const musicToPlay = feature.SongName;
    // do something with musicToPlay
});

If you're using Typescript, you can type the feature argument to an interface matching the spec in Articy.

Redux Middleware

Suppose you want to write a custom script function that modifies your game state in some way (say, moving the player around on the screen or something) but you're using Redux. States are immutable. What can you do?

You can use the createScriptDispatchMiddleware included with this package. This addon not only gives script function handlers access to your current Redux store, but also gives them the ability to dispatch actions.

To use it, simply add it to your applyMiddleware call like so:

// Make the extensions
const extensions = compose(
    applyMiddleware(createScriptDispatchMiddleware())
);

// Create store
const store = createStore(reducer, initialState, extensions);

Now, script functions can not only access your application state, but they can also trigger actions using the Javascript yield keyword.

// Make sure your script function is a _generator_ function. 
// see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
RegisterScriptFunction('MovePlayerTo', function* (context, x, y) {
    // Read your application state in context.state
    
    // Trigger Redux actions
    yield { type: 'redux/move_action', x, y };
});

This will queue a Redux of action of type redux/move_action to be executed as soon as iteration is complete. This will only work if your iteration calls are happening during a Redux action of course.

This also works for RegisterFeatureExecutionHandler. Simply define the handler as a generator function and yield actions just as above.

Asset Loading

To support asset loading (such as images), just add an asset resolver function to the Database constructor. This method should, given an asset reference string in Articy return the assets filename. In webpack, this is easy.

import { Database } from "articy-node";

// Import game data from json
import GameData from "./game.articy.json";

// Asset resolver method
function assetResolver(assetRef: string) {
    // Articy exports all assets into an "Assets" folder relative to the exported .json file
    // Use webpack's require method to bundle these and map their filenames
    return require("./Assets/" + assetRef);
}

// Create database with resolver
const GameDB = new Database(GameData as ArticyData, assetResolver);

// Export
export default GameDB;

Now, given an Asset ID (from, say, a game entity) you can now get the full filename with the Database's getAssetFilename function.

// Load an entity by ID
const entity = GameDB.getObject("0xFFFFFFFF", Entity);

// Get its preview image
const assetFilename = GameDB.getAssetFilename(entity.properties.PreviewImage.Asset);

Missing Features

  • Localization support (coming soon)

Readme

Keywords

none

Package Sidebar

Install

npm i articy-node

Weekly Downloads

3

Version

0.3.20

License

MIT

Unpacked Size

599 kB

Total Files

23

Last publish

Collaborators

  • brwarner