Concepts
There are many unique concepts and ideas that are essential to understanding Jungle. This page will help you understand these core concepts and ideas.
Important Termsβ
- Tree: Collection of nodes connected together to form sequences.
- Node: Unit of logic/behavior that performs a specific task.
- Port: Connection point on a node where calls are sent or received.
- Edge: Link between an input port and output port.
- Call: Payload of data sent from an output port to an input port.
Node Variantsβ
Jungle has four node variants builtin. Each node variant has a unique purpose and use case. Understanding the differences between each node variant is essential to creating custom nodes.
Branch Nodeβ
One input port and multiple output ports. It is used for conditional logic and branching behavior.
IO Nodeβ
One input port and one output port. It is designed for simple logic and behavior. The "IO" stands for Input/Output.
Identity Nodeβ
One input port and one output port. Its port types are automatically defined based on the nodes connected to it. This makes it flexible and useful for nodes like "Wait for Seconds," which donβt need predefined inputs to function.
Event Nodeβ
No input ports and one or more output ports. It is used for event-driven logic and starts automatically when the tree is played.
Lifecyclesβ
Both trees and nodes follow a lifecycle managed by Jungle's runtime. Understanding the lifecycle will help you to better understand the process of creating and managing trees and nodes.
Treesβ
βΆοΈ On Played:β
- All event nodes in the tree are started.
- For example, the start node is an event node started when the tree is played.
π While Running:β
- The tree automatically manages and updates running nodes.
The tree will automatically stop when no nodes are running.
π On Stopped:β
- All running nodes (if any) are stopped.
- All created revert actions (if any) are called.
Nodesβ
βΆοΈ On Started:β
- The
OnStart
method is called on the node.
If the Stop
or CallAndStop
method is called from the OnStart
method,
the OnUpdate
, OnLateUpdate
, and OnFixedUpdate
methods will not be called by the runtime.
π While Running:β
- The
OnUpdate
,OnLateUpdate
, andOnFixedUpdate
methods are called on the node.
π On Stopped:β
- The
OnStop
method is called on the node.
Port Callsβ
Nodes use ports to send and receive data. Ports are linked by edges, which connect an output port on one node to an input port on another. Port calls always flow from an output port to an input port.
When a node makes a port call, it's sent from one of its output ports. The call then flows through the edge into the input ports of all nodes connected to the output port. Port calls can contain a value (called a payload) that can be used as an input for nodes.
The syntax for port calls is slightly different for each node variation, but the concept remains the same.
To send a port call, you can use either the Call
or CallAndStop
method on the current node:
Call
: Sends a port call to all connected nodes and lets the current node continue running.CallAndStop
: Sends a port call to all connected nodes and stops the current node.
Below are examples for making port calls for each node variant.
Branch Nodeβ
Branch nodes have multiple output ports, so you must specify the output port index when making a port call. The output port index is the index of the output port you want to call, starting from 0.
The Branch node Call
and CallAndStop
methods can take an array of Port.Call
or a single Port.Call
.
Ensure the payload type matches the type of its respective output port.
In this BranchNode
example, the node has two output ports.
- Output port one has an output type of integer, so the payload for calls on that port must be of type
int
. - Output port two has an output type of string, so the payload for calls on that port must be of type
string
.
using Jungle;
[BranchNode(
OutputPortNames = new[]
{
// ββββββββ Output port 1 name
"Output 1",
// ββββββββ Output port 2 name
"Output 2"
},
OutputPortTypes = new[]
{
// βββ Output port 1 type
typeof(int),
// ββββββ Output port 2 type
typeof(string)
}
)]
public class MyBranchNode : BranchNode<int>
...
BranchNode.Call(Port.Call[])
β
This example makes calls to both output ports and the node continues running.
Call(new []
{
// Port Index β β Payload
new Port.Call(0, 1),
// Port Index β βββββββββββββ Payload
new Port.Call(1, "Hello, World!")
});
BranchNode.Call(Port.Call)
β
This example makes individual calls to both output ports and the node continues running.
// Port Index β β Payload
Call(new Port.Call(0, 1));
// Port Index β βββββββββββββ Payload
Call(new Port.Call(1, "Hello, World!"));
BranchNode.CallAndStop(Port.Call[])
β
This example makes calls to both output ports and the node stops running.
CallAndStop(new []
{
// Port Index β β Payload
new Port.Call(0, 1),
// Port Index β βββββββββββββ Payload
new Port.Call(1, "Hello, World!")
});
BranchNode.CallAndStop(Port.Call)
β
This example makes individual calls to both output ports and the node stops running.
// Port Index β β Payload
CallAndStop(new Port.Call(0, 1));
// Port Index β βββββββββββββ Payload
CallAndStop(new Port.Call(1, "Hello, World!"));
IO Nodeβ
IO nodes have only one output port, so you do not need to specify the output port index when making a port call.
Because requiring a developer to always specify the first output port index would be redundant,
the Port.Call
object is not used.
The IO node Call
and CallAndStop
methods take a payload and do not require an output port index.
Make sure the type of the payload matches the type of the output port.
In this IONode
example, the node has one output port.
- The output port has an output type of integer, so the payload for calls on that port must be of type
int
.
using Jungle;
[IONode(
// ββββββ Output port name
OutputPortName = "Output",
// βββ Output port type
OutputPortType = typeof(int)
)]
public class MyIONode : IONode<int>
...
IONode.Call(object)
β
This example makes a call to the output port and the node continues running.
// β Payload
Call(1);
IONode.CallAndStop(object)
β
This example makes a call to the output port and the node stops running.
// β Payload
CallAndStop(1);
Identity Nodeβ
Identity nodes do not allow you to directly interact with the inputted and outputted payload.
Port calls are made using either the Call
or CallAndStop
methods without any arguments.
In this IdentityNode
example, the node has one output port that's set by the nodes input type.
using Jungle;
public class MyIdentityNode : IdentityNode
...
IdentityNode.Call()
β
This example makes a call to the output port and the node continues running.
Call();
IdentityNode.CallAndStop()
β
This example makes a call to the output port and the node stops running.
CallAndStop();
Event Nodeβ
Event nodes have one or multiple output ports, so you must specify the output port index when making a port call. The output port index is the index of the output port you want to call, starting from 0.
The Event node Call
and CallAndStop
methods can take an array of Port.Call
or a single Port.Call
.
Make sure the type of the payload matches the type of the output port.
In this EventNode
example, the node has two output ports.
- Output port one has an output type of integer, so the payload for calls on that port must be of type
int
. - Output port two has an output type of string, so the payload for calls on that port must be of type
string
.
using Jungle;
[EventNode(
OutputPortNames = new[]
{
// ββββββββ Output port 1 name
"Output 1",
// ββββββββ Output port 2 name
"Output 2"
},
OutputPortTypes = new[]
{
// βββ Output port 1 type
typeof(int),
// ββββββ Output port 2 type
typeof(string)
}
)]
public class MyEventNode : EventNode
...
EventNode.Call(Port.Call[])
β
This example makes calls to both output ports and the node continues running.
Call(new []
{
// Port Index β β Payload
new Port.Call(0, 1),
// Port Index β βββββββββββββ Payload
new Port.Call(1, "Hello, World!")
});
EventNode.Call(Port.Call)
β
This example makes individual calls to both output ports and the node continues running.
// Port Index β β Payload
Call(new Port.Call(0, 1));
// Port Index β βββββββββββββ Payload
Call(new Port.Call(1, "Hello, World!"));
EventNode.CallAndStop(Port.Call[])
β
This example makes calls to both output ports and the node stops running.
CallAndStop(new []
{
// Port Index β β Payload
new Port.Call(0, 1),
// Port Index β βββββββββββββ Payload
new Port.Call(1, "Hello, World!")
});
EventNode.CallAndStop(Port.Call)
β
This example makes individual calls to both output ports and the node stops running.
// Port Index β β Payload
CallAndStop(new Port.Call(0, 1));
// Port Index β βββββββββββββ Payload
CallAndStop(new Port.Call(1, "Hello, World!"));