Node-X and NodeScript De-Obfuscation + Example Game

Node-X is the system and NodeScript is the code which I developed and which I use to create my CYOA/Multiple-Choice adventure games. It has been used as a DOS beta in my first game “Project Delta” (see IFComp 2008), as a DOS/Linux release version of Generation 1 in my second game “Trap Cave” (see IFComp 2009) and as a Windows beta of Generation 2 in my third game “Dead Hotel” (see IFComp 2011).

Beta versions of my Node-X system are usually called “internals” and release versions are called “externals”. Project Delta and Dead Hotel are internals, because you can run the games, but you can’t write your own adventures for the system/engine, because engine and game are both compiled in the exe file. Trap Cave is the only external so far, because you may run the game or not, but most important of all, you can code and write your own CYOA adventures for Node-X Generation 1, because the engine reads external game files, interpretes them and converts them into program code.

Trap Cave (incl. Node-X Generation 1)
ifarchive.org/indexes/if-arc … pcave.html

Trap Cave NodeScripts (*.nx)
ifarchive.org/indexes/if-arc … XGame.html

Now after 2-3 years I have decided to publish a de-obfuscated reference manual for NodeScript in this forum. Obfuscation is known as a method to confuse or express something in a way that it can only be understood by insiders.

For a more detailed definition of “Obfuscation” see these two wiki links:
en.wikipedia.org/wiki/Obfuscation
en.wikipedia.org/wiki/Obfuscated_code

So I made the NodeScript look obfuscated. I did this, not to confuse anyone or hide anything, but simply because I hadn’t coded any editor for my Node-X system. I had to type everything manually in a text editor. And I didn’t want to type or copy+paste the long names of variables and ENUMs every time when I coded my Trap Cave adventure. That’s why I replaced everything with very short abbreviations and made the Node-X engine understand those when a NodeScript file (*.nx) was read.

Now my fourth and upcoming CYOA/MCA game in 2012 is most likely to be an external version again, using the newer Node-X Generation 2 this time. The second generation has been showcased to a certain extent in my third game Dead Hotel. The fourth game will not only be a game release, but an editable system release aswell, using NodeScript as interpreter code in external game files.

Thus I’m releasing this de-obfuscated NodeScript reference manual for any CYOA author out there who may be interested to code custom Node-X adventures for generation 1 (included in Trap Cave download) and upcoming generation 2, and wants a better understanding of the script. This reference manual may also be helpful for experienced programmers on how to code a more advanced system or engine for CYOA/MCA games. And because I’m going to keep abbreviations in NodeScript. It not only creates smaller game files, although this is less of a problem in these modern days, but it is also faster to edit NodeScript with a text editor, because you don’t have to type so much.

Here we go…

[NX.NodeScript]
Gen = Generation
EC = EngineClass (see classes below)
TE = TextEncode (see encodes below)

[FI] = FileInfo
D = Date
T = Time

[GI] = GameInfo
T = Title
A = Author
V = Version
L = Language

[NI] = NetInfo
E = Email
U = URL

[GIF] = GameInterface
CS = ColorScreen
CT = ColorText
CTi = ColorTitle
CL = ColorLocation
CN = ColorNode
CK = ColorKey
CC = ColorChoice
CLi = ColorLine
LS = LineStyle

[FIF] = FileInterface
SF = SaveFile

[Inv] = Inventory
EC = ElementColor
EN = ElementName
SEN = SubElementName
SLN = SubLeftName
SRN = SubRightName
SLA = SubLeftAbbreviation
SRA = SubRightAbbreviation
EV = ExamineVerb
PV = PutVerb
PVA = PutVerbAdditive
CI = ColorItem

[PS] = PlayerStart
bInv = bInventory (Inventory bool flag, true or false)
N = StartNode
LI = StartLeftItem
RI = StartRightItem

[Ls] = Locations

[NTx] = NodeText x

[ATx] = AlternativeText x

[ITx] = ItemText x (Item Description)

[Cs] = Choices

[Qs] = Questions (yes/no type)

[Nx] = Node x
bNF = bNodeFlag (true or false)
PCA = PreCallAction (see actions below)
PCF = PreCallFlag
PCJ = PreCallJump
L = Location
NT = NodeType (see types below)
T = NodeText
NC[x] = NodeChoice[x]
NJ[x] = NodeJump[x]
GQ = GateQuestion
GJK[x] = GateJumpKey[x]
NI = NodeItem
bIF = bItemFlag (true or false)
FSC = FlagSetChoice
FUC = FlagUnsetChoice
AT = AlternativeText
AC = AlternativeChoice
AJ = AlternativeJump

[Ix] = Item x
IT = ItemType (see types below)
IN = ItemName
T = ItemText
CT = CombineTag
CI = CombineItem
CV = CombineVerb
CVA = CombineVerbAdditive
bIU = bItemUndo (undo bool flag, true or false)
UV = UndoVerb
UVA = UndoVerbAdditive
UMI = UndoMasterItem
USI = UndoSlaveItem


EngineClasses (EC)

NJ = NodeJumper (default cyoa engine)
NL = NodeLinker (not yet implemented)


TextEncodes (TE)

R13 = Rot13
R47 = Rot47
2R = 2Rot/DoubleRot (combination of Rot13+Rot47)


PreCallActions (PCA) ENUMs for Nodes (things that happen before a node is called / a cyoa page is displayed)

none = PRE_None
HI = PRE_HideInventory
SI = PRE_ShowInventory
TI = PRE_TakeItemFromPlayer
GI = PRE_GiveItemToPlayer
AS = PRE_AutoSaveHere
IJ = PRE_ItemJump
AIJ = PRE_AnyItemJump
FJ = PRE_FlagJump
AF = PRE_AlternativeFlag
UF = PRE_UnsetFlag
SF = PRE_SetFlag
TF = PRE_ToggleFlag
IF = PRE_ItemFlag
CIF = PRE_CombinedItemFlag
UIF = PRE_UndoItemFlag
LIF = PRE_LeftItemFlag
RIF = PRE_RightItemFlag


NodeTypes (NT) ENUMs for Nodes (specific behaviour of a node / cyoa page)

DN = NT_DeadNode (a node with no choices, used for game over and end pages)
JN = NT_JumpNode (a node with no choices, but with one destination to jump to next)
GT = NT_GateNode (a node with a yes/no choice, gate question)
PN = NT_PathNode (a node with a number of choices and destinations, your regular cyoa page)
FN = NT_FlagNode (a node with choices, flag-controlled)
IN = NT_ItemNode (a node with choices, and a specific item to be either picked up or placed)


ItemTypes (IT) ENUMs

ST = IT_Standard (your regular item)
MC = IT_MasterCombiner (a master item which requires a slave item to create a new item)
SC = IT_SlaveCombiner (a slave item for a master item to create a new item)
  • Comazombie / Emilian Kowalewski

The documentation you just provided is pretty sparse. What exactly does PreCallJump mean, for example? What sort of arguments does it take?

It might be more useful to:

  1. Finish the translation of Trap Cave into English.
  2. Fix the bugs in Trap Cave.
  3. Add comments to the Trap Cave source to explain what you’re doing.

That’s because it’s a quick reference guide for understanding the abbreviations used. It’s not a tutorial or anything like that. It will follow in the future…

People say they have to be patient and things will come natural to them.

PreCallJump (PCJ) takes numbers, ranging from 1 to 255. The number corresponds with the number of the Node to jump to instead, depending on the PreCallAction (PCA) type.

Haha. Right, I should hurry up, because people in 2012 are dying to play Trap Cave 2009 in English. Nobody notified me that I had Diablo 3 status anyway. :wink:

But thanks for the hint. I may consider it on a more serious level and when I have more time…

You see, this community is not the only one I’m active on. Just because people see me posting here from time to time under my real name and with one of my many nicknames used on the internet, doesn’t mean that I can spend all energy and time in here to beat a dead horse, if you know what I mean. Right now I have additional and more promising projects going on in completely different gamer communities, such as FPS modding, which have nothing to do with Interactive Fiction and CYOA at all. So I need to schedule my time accordingly.

I can’t even tell at this moment if I’m going to take part in the next IFComp 2012 or not. So bear with me. I have to make some decisions in the next weeks and months to come…

Well, sometimes I don’t even know myself what I’m doing here. I just do it and watch what happens next. :mrgreen:
That’s my entire masterplan in this community. Just in case you missed it over the last 3 years.

Back when Trap Cave was released, I managed to work out the obfuscation methods and deduced most of what you’ve written here.

And I’m not necessarily asking for Trap Cave, but I do think there’s not much point in releasing a system without some sort of example game.

Also consider having your Node-X generate Javascript output. Take a look at The Play and Clod’s Quest.

Good for you.

Ofcourse you don’t ask for Trap Cave, Ralph. Exactly my point. LOL

You are really an impatient guy, aren’t you. Just what do you think was about to happen next in this thread? Why don’t you just be silent, sit back and enjoy.

Or as we Germans say: Immer mit der Ruhe, Junge. Nicht so hetzen. Ein Mann ist doch kein D-Zug. :unamused:

You know, right now I would rather like to write an example game (or better say tutorial) for other NodeScript authors out there. And I ask you to let me do it now instead of ranting about something which I won’t rant with you about, okay? Thank you. Have a nice day and sleep well.

Alright, cool people and CYOA authors out there. After we sorted this out and Ralph has got his extra info now that there will be no english version of Trap Cave, although that wouldn’t be a bad idea, we can now go back to business as usual and let’s hope we are not distracted again…

So now after I posted the de-obfuscated NodeScript reference guide here, I’m going to continue with a tutorial and an example game in NodeScript now, what I intended to do as a next step anyway, before someone rude in here jumped on me so impatiently about it. Well, patience seems to be a rare quality trade these days. Anyway, let’s start, shall we…

NodeScript Tutorial - Example

Ok, before you guys start to write any CYOA game in NodeScript, you should first make a concept of your environment. You could draw a floorplan, for instance. So let us make one now…

Here it is:

Now let me explain the floorplan (see above):

So this is just an example game. So we are not doing anything special here, just two rooms connected with a corridor to navigate in, so you guys can get a basic idea how to connect nodes in NodeScript and have basic adventure game layout for later expansion.

The green dots are our nodes. There is a total of 7 nodes for our example game here. As you can see, each of the nodes are connected in a logical fashion. Some of these nodes have so-called one-way paths and other ones have two-way paths. The arrows at each end of a line tell you if there is a one-way or a two-way connection between two nodes.

So far so good.

Now after we have made a floorplan for our example game, we have to define what the goal of the game should be. I won’t come up with any super complicated puzzle in this example here. Just a basic and short goal for easier understanding. Let’s say the player starts in Room A of the appartment (see Node 1, PS for PlayerStart) and his/her goal is to get out of the appartment. Escape the Appartment game, you get the idea. To leave the appartment the player has to open the door and get out. But the door is locked and the key to unlock the exit door lies on the table in Room B. Easy game. Player has to get the key, use it and open the door, then leave. As a little bonus I’ve also added a couch in Room B where the player can sit down on to rest. Just a fun bonus feature to make even this simple example game look more interesting.

Okay, let us begin scripting this type of adventure game… :sunglasses:

This can actually be done in a few minutes, but I will take a bit longer however, because I will give you detailed descriptions each time of what I’m currently doing.

Our first step: We open up a text editor. You can run Notepad in Windows, for example.

First thing we do is setting the so-called “shell” for our NodeScript adventure:

[NX.NodeScript]
Gen=1
EC=NJ

[FI]
D=06/19/2012
T=01:15

[GI]
T=Tutorial Game - Escape the Appartment
A=Comazombie
V=1.0
L=En

[GIF]
LS=double

[FIF]
SF=tutorial1

Easy start. In the header section [NX.NodeScript] we told the engine that we are coding for Generation 1 and that NodeJumper (NJ) is our EngineClass (EC). I left out TextEncode (TE), because we are writing our adventure in plain text and not in encrypted text (Rot13, Rot47, 2Rot). Note that the Node-X engine is smart enough to notice if a variable was set or is missing in the script. If it’s missing the engine will assume that the variable should remain unchanged and thus use the default setting for this particular variable. And the default setting for TextEncode (TE) is none or plaintext in this case. Also note that this is not always the case. Some variables have to be set in the script!

In the second section [FI] (FileInfo) we have manually set the date (D) and time (T) on which we started (or finished) writing our adventure. Simple, isn’t it.

In the third section [GI] (GameInfo) we have set the title (T) of our example adventure, the name of the author (A), the version (V) of our game and last but not least, the language (L) in which we write our adventure. Notice that you can use three language types in NodeScript, English (L=en), German (L=de) and Custom (L=insert whatever text here). Depending on the language which you set (english or german) the game interface in Node-X will change accordingly. So if you are writing a german adventure then the interface in Node-X will also be in german language. Try not to mix up those two or you will have a game where the adventure itself is written in the one language, but the interface is in the other language. This will only confuse and even piss off gamers, so pay attention to that! :mrgreen:

In the fourth section [GIF] (GameInterface) we can set the interface colors of our adventure. But in this case we are fine with the default colors, so we leave out the color variables and only set the LineStyle (LS).

You can choose between following LineStyles:
single
double
wave
minus
equal
short
dot

The default LineStyle is single (LS=single).

In the fifth section [FIF] (FileInterface) we can define the name of the SaveFile (SF). When the player saves during a game or when the game itself autosaves (providing that we use the PreCallAction=AS for AutoSave feature) then we want the file to be named like that. You can use any desired name here. The filename should not be longer than 72 characters.

The shell for our example adventure is complete.

Now that we have build our shell, we have to define one more section before we can start to do the actual scripting of our example adventure:

[Inv]
EN=Body
SEN=hand
SLN=left
SRN=right
SLA=LH
SRA=RH
EV=examine
PV=put
PVA=in

Inventory Interface Customization! This is actually a very interesting and unique feature in Node-X, because we can customize the inventory interface to our liking. Ofcourse we assume that our game character is a human, so he/she has a body, a left hand and a right hand in which he/she can carry items, he/she can examine items and put an item in the opposite hand. So we will leave it at that.

BUT, and this is the interesting part, you could replace “Body”, “hand” and even “left” and “right” with something else. Same with “examine”, “put” and “in”. This can be useful for non-human or weird game characters. Use your imagination!

Example:
Let’s say our game character (in a different adventure than this!) is a robot which looks like R2D2 from Star Wars, but with long elastic tentacles which can grab and carry items. The robot doesn’t examine items, he scans them. Then our custom inventory interface would be defined as follows:

[Inv]
EN=Bot
SEN=tentacle
SLN=left
SRN=right
SLA=LT
SRA=RT
EV=scan
PV=put
PVA=in

The element name (EN) would be “Bot” in this case, not Body. The sub-element name (SEN) would be a “tentacle” attached to both sides of the robot, left and right (SLN, SRN). The robot will not “examine item”, but “scan item” (EV) as a choice in inventory mode (press the “I” key during a Node-X ingame session). The robot will “put item in left tentacle” or “put item in right tentacle”. That’s how the Node-X engine uses all the variables in the inventory interface.

As I said, this way you can define a custom inventory for a specific game character. Again, use your imagination! Maybe you can come up with something really unique and cool.

Okay, now on to scripting the actual adventure…

So this is our conceptual floorplan for our example game, right. Let us first define the locations. We have 4 locations in this adventure game altogether: “Room A”, “Room B”, “Corridor” and “Outside”. I sure could use prettier names for the locations, but since this is just an example game I leave it at that.

Now let’s add these locations to our [Ls] section in NodeScript:

[Ls]
1=Room A
2=Room B
3=Corridor
4=Outside

Notice that each location name corresponds to an ID reference number now. “Room A” is ID 1, “Room B” is ID 2 and so on. This is important later on when we define for each node in which location it is located.

In the next step we define the [PS] PlayerStart, although we haven’t build any nodes yet…

[PS]
bInv=true
N=1

We tell the engine to make the inventory available on gamestart (bInv) and on which node (N) the game starts. Notice that I’ve left out the StartLeftItem (LI) and StartRightItem (RI) variables, because in this example game the player starts with no items in any hand. If you want to let the player start the game with one or two specific items then add the ID reference number of a particular item as argument in any of the two variables.

For example:

bInv=true
N=1
LI=1
RI=2

ID Reference numbers in Node-X (Generation 1) always range from 1 to 255, regardless if it’s numbers for locations, choices, nodes, items, etc.

In the next step we look at the nodes in our floorplan (see above) and how we linked them logically together, so we can transform the concept into NodeScript code. We also have to define the proper choices in the [Cs] section for the nodes, aswell as the proper text displayed in each node.

But first take a closer look at each of the nodes themselves in our floorplan. This is important to determine how to define each node and thus set how the nodes should behave.

Node 1 is what I’m going to refer to as the startnode. This is where the player starts when the game begins. From there the player can go to either the exit door (Node 2) or to the corridor (Node 3). That’s two choices for this startnode: “go to door” and “go to corridor”. I will change “go to door” to “walk to door”, to add some variation in the text and not to use the same verb in a goto-choice every time.

Alright, let’s build the startnode. First we add the two choices to the [Cs] section, needed by the node:

[Cs]
1=go to corridor
2=walk to door

Then we add the NodeText [NT1] for the startnode:

[NT1]
1=You stand in your hotel appartment. There is an exit door in the south
2=and a corridor in the east.

Well, the text sounds pretty uninspired. But it does okay for this example game though. I’m not going to write a novel for this and try to win the Pulitzer prize here. :wink:

Ok, now we build the node [N1] itself:

[N1]
L=1
T=1
NT=PN
NC[1]=1
NC[2]=2
NJ[1]=3
NJ[2]=2

The startnode is located in Location (L) ID 1.
The text (T) displayed is ID 1.
And the NodeType (NT) is PathNode (PN). Although we could use a GateNode (GN) too in this case, because there are only two choices in the startnode which could also be queried with a GateQuestion (GQ), such as “Go to Corridor or walk to exit Door? (C/D)”. But we will stick with PathNodes, even if most - if not all - of our nodes in this example game will have only 2 choices at maximum.
The nodes use two choices (NC[1] and NC[2]) with IDs 1 and 2 and their according node jump destinations (NJ[1] and NJ[2]) with IDs 3 and 2. Notice that NC[1] corresponds to NJ[1], and NC[2] corresponds to NJ[2]. The [ID] numbers x of NodeChoice[x] and NodeJump[x] must be identical in order to refer to!

Let’s continue with the tutorial game…

Node 2 is going to be a special PathNode, because it has to do some flag checks for us prior to being called. In this case we add the PreCallAction (PCA) = PRE_ItemFlag (IF). So the engine checks if the player has a certain item in his/her inventory, which we refer to in NodeItem (NI). And if the player has the item then the engine displays an alternative choice (AC) with an alternative jump destination (AJ) on this node. In this case the alternative choice is “unlock door” and the alternative jump (AJ) refers to our last Node 7, where we want the player to go next after he/she unlocked the door.

Also, according to our conceptual floorplan, Node 2 connects with Node 3 in the corridor. So this node will use one regular choice “go to corridor” (ID 1) and the second alternative choice “unlock door” (ID 3). The text on the node will inform the player that he/she is in front of the exit door and that it’s locked. If the player doesn’t have the item then only the regular choices (NC[x]) are displayed. And if the player has the item then the alternative choice (AJ) is displayed in addition.

Notice that PRE_ItemFlag (IF) generally checks whether the player has the referred item in the inventory or not, but doesn’t check in which hand (left or right). If you want the engine to check this specifically then use either PRE_LeftItemFlag (LIF) or PRE_RightItemFlag (RIF) for PreCallAction. In that case the player has to carry the item in a specific hand to trigger the alternative choice on the node.

Ok, so let’s add this node:

First add the new required choice (ID 3) to our [Cs] choices section:

[Cs]
1=go to corridor
2=walk to door
3=unlock door

Now the node itself and the NodeText:

[NT2]
1=You stand in front of the exit door. It is locked!

[N2]
PCA=IF
NI=1
L=1
T=2
NT=PN
NC[1]=1
NJ[1]=3
AC=3
AJ=7

We also need to define our referred item (ID 1), but we will do that at a later point…

On to our next node in the floorplan:

Node 3 is another normal PathNode (PN) without any additional functionality this time, which looks like your regular CYOA/MCA page. It connects “Room A” with “Room B”. Since there is nothing special supposed to go in the corridor we just add 2 choices “go to Room A” and “go to Room B” to our [Cs] section and then refer to them as we build the node. Notice by looking at the arrows in the floorplan that I don’t intend to connect Node 3 with our StartNode 1 (PS), because I don’t want the player to hop back to the StartNode again. So I connect Node 3 directly with Node 2 on the one end and with the next Node 4 on the other end. But that’s a design decision which any author can make on his/her own here.

At this point, let me mention a technical aspect about Nodes for a moment. A Node in the Node-X engine can have a number of 6 regular choices (NC[1…6]) and 6 according jump destinations (NJ[1…6]), plus an alternative choice (AC) and an alternative jump destination (AJ), which makes it a total of 7 possible connections per node.

You may ask why 6 choices, why not 9 or even 10? The reason for this is that when I started developing and coding the Node-X engine in the year 2007 I wanted to be compatible with parser-style adventures, in case other authors or even I ever intend to convert a parser-based adventure into a CYOA-based adventure (!). You know, in a parser-based engine, such as Inform, you can usually give the player 6 commands to navigate in the environment. We all know them: it’s “go north”, “go south”, “go west”, “go east”, “go up” and “go down” (e.g. on a ladder). So in the CYOA-based Node-X engine you can do that for each node aswell. If you have a very complex and long CYOA adventure with floors above floors and lots of connected rooms, corridors, etc, then you can make each node in your game have 6 choices and 6 jump destinations each time, connected with other nodes which also have 6 choices and 6 destinations. Plus all the seventh alternative choices ofcourse. That would make a VERY complex Node-X based CYOA/MCA adaventure. But I can tell you from my experience that it’s unlikely that you will ever come up with such a complex adventure, because it’s too long and it would take more then 2 hours to play through the entire game. However, if you have the time and skill on your hands and intend to create such a huge and complex CYOA adventure/novel then go for it!
(Note that the maximum number of defined nodes, node texts, locations, choices, items and items descriptions is 255 each per adventure! So that’s a big one.)

Okay, back to our short and simple example game and our current built Node 3. We also define that this node is located in a different location (L), the “Corridor” (ID 3) which we’ve already defined in the beginning of this tutorial (see page 1 in this thread).

By the way, when I finish this short example game then I paste the entire NodeScript code in one post, so you don’t have to scroll and click through the pages in this thread.

Let’s build the node now:

[Cs]
1=go to corridor
2=walk to door
3=unlock door
4=go to room A
5=go to room B

Node 3 and NodeText 3:

[NT3]
1=You are in the appartment corridor.

[N3]
L=3
T=3
NT=PN
NC[1]=4
NC[2]=5
NJ[1]=2
NJ[2]=4

You may wonder why I haven’t connected Node 2 (in front of exit door) with Node 4 (inside Room B) directly and spared Node 3 (corridor), when there’s nothing going on in the corridor anyway. That’s because after we finish this example game we can expand it at a later point and make it bigger and more complex. For instance, we could add a door with a toilet room in the corridor and then just add a new choice and new jump destination to Node 3. This is much easier to make spontanous design changes or additions instead of scrapping entire node sections, just because we decided to change the layout during the design process. You should always build and place Nodes in your CYOA adventure in a way that they can be expanded and connected with additional nodes. Sometime it’s like this. You are building your CYOA game, but then suddenly you have different or additional ideas which you like to implement instead. So always add enough logic nodes from the beginning, even if it’s a simple node located in a boring location, such as an empty corridor. You never know if you might extend the corridor later.

Another webpage might be a better place for these. You might also like to consider writing a comparison document, comparing how Node-X compares with Choice Script and Undum and Inklewriter etc.

Good idea. I may post this on an own website (although I currently have none) or do it in a youtube video at a later time. Right now, let me finish what I have begun. I’m almost finished and it won’t take many posts anymore. Not that I do something half-baked again, if you understand what I mean. :wink:

I haven’t checked out Undum yet, but I have seen ChoiceScript (2011) many times and the new Inklewriter (2012) this year too. Yeah, these systems and programs are based on the same design concepts as my Node-X (2008) and borrowed a few techniques from it, directly or randomly. I would probably not do any comparison, because I don’t have any time for that this year. But perhaps the developers of those systems can compare it to my system instead, if they have the time to do so…

Alright, CYOA authors, let me hurry up and finish this tutorial game in this big post now, because as you see there are some forum members getting uncomfortable about it, for their reasons.

Ok, so now we add Node 4. This one links to three destinations, Node 5 (Couch), Node 6 (Table) and back to Node 3 (Corridor). We add the proper choices aswell. In this case “go to corridor” (ID 1), “sit on couch” (ID 6) and “walk to table” (ID 7). Since we hurry up we also add “take key” (ID 8) and “put key on table” (ID 9) in advance and refer to them in Node 6 (scroll down below). This makes our [CS] choices section complete.

[Cs]
1=go to corridor
2=walk to door
3=unlock door
4=go to room A
5=go to room B
6=sit on couch
7=walk to table
8=take key
9=put key on table

Node 4 and NodeText:

[NT4]
1=You stand in the living room of the appartment.

[N4]
L=2
T=4
NT=PN
NC[1]=1
NC[2]=6
NC[3]=7
NJ[1]=3
NJ[2]=5
NJ[3]=6

Now let’s quickly build Node 5 before we look at Node 6 in more detail and finish with Node 7. Node 5 is simple too. We let the player sit on the couch. We can extend the couch later or maybe add a puzzle there when we decide to expand our example game.

[NT5]
1=You sit on the couch, spread your arms and chill. What a nice day.
2=No zombie buggers around to agitate you.

[N5]
L=2
T=5
NT=PN
NC[1]=7
NC[2]=1
NJ[1]=6
NJ[2]=3

Notice that I didn’t link Node 5 with Node 4, only with Node 3 and Node 6, to make the navigation in that room faster and easier. Also see how this connection has created what I call a “loop” now. The player can individually navigate from Node 3 to Node 4, to either Node 5 or Node 6, and then all the way back to Node 3. This creates a perfect loop. Always try to create nice loops when you place and build nodes in your adventure. This is not only good design procedure, but also gives the player more freedom to navigate in your CYOA game and thus make it more fun and appear more polished.

So let’s add Node 6 now. This is a very special node type too. It’s an ItemNode (IN). It can have a referred item being put or placed on. In this case it’s going to be a “key” item (ID 1), which we have also referred to in Node 2 before. Also, we have to add the FlagSetChoice (FSC) “take key” and the FlagUnsetChoice (FUC) “put key on table”. FlagSet means in programmer’s terms that the item is on the node and thus the flag is set. FlagUnset is the opposite. Try to not confuse those two when you define the Choice ID reference numbers in FSC and FUC!

First build our ItemNode and everything:

[NT6]
1=You stand in front of the table.

[N6]
L=2
T=6
NT=IN
NC[1]=6
NC[2]=1
NJ[1]=5
NJ[2]=3
NI=1
bIF=false
FSC=8
FUC=9

Now we add and define the item (I1) itself and the corresponding ItemText (IT1) description:

[IT1]
1=An appartment door key.

[I1]
IT=ST
IN=key
T=1

Since this is just a quick example map we just use a short description for “key” item. In the item section we tell the engine that this is a standard item (IT=ST) an no combinable item and the text reference (T) and ofcourse the ItemName (IN).

Last but not least, we wrap this up with Node 7. This one is a DeadNode (DN) type with no choices, just the command prompt. Use deadnodes for game end (finished game) or game over (death during game) pages:

[NT7]
1=Congratulations! You unlocked the exit door and left the appartment.
3=THE END

[N7]
L=4
T=7
NT=DN

So finally here’s our complete and corresponding adventure for our floorplan concept example:

[NX.NodeScript]
Gen=1
EC=NJ

[FI]
D=06/19/2012
T=19:00

[GI]
T=Tutorial Game - Escape the Appartment
A=Comazombie
V=1.0
L=En

[GIF]
LS=double

[FIF]
SF=tutorial1

[Inv]
EN=Body
SEN=hand
SLN=left
SRN=right
SLA=LH
SRA=RH
EV=examine
PV=put
PVA=in

[Ls]
1=Room A
2=Room B
3=Corridor
4=Outside

[PS]
bInv=true
N=1

[Cs]
1=go to corridor
2=walk to door
3=unlock door
4=go to room A
5=go to room B
6=sit on couch
7=walk to table
8=take key
9=put key on table

[NT1]
1=You stand in your hotel appartment. There is an exit door in the south
2=and a corridor in the east.

[N1]
L=1
T=1
NT=PN
NC[1]=1
NC[2]=2
NJ[1]=3
NJ[2]=2

[NT2]
1=You stand in front of the exit door. It is locked.

[N2]
PCA=IF
NI=1
L=1
T=2
NT=PN
NC[1]=1
NJ[1]=3
AC=3
AJ=7

[NT3]
1=You are in the appartment corridor.

[N3]
L=3
T=3
NT=PN
NC[1]=4
NC[2]=5
NJ[1]=2
NJ[2]=4

[NT4]
1=You stand in the living room of the appartment.

[N4]
L=2
T=4
NT=PN
NC[1]=1
NC[2]=6
NC[3]=7
NJ[1]=3
NJ[2]=5
NJ[3]=6


[NT5]
1=You sit on the couch, spread your arms and chill. What a nice day.
2=No zombie buggers around to agitate you.

[N5]
L=2
T=5
NT=PN
NC[1]=7
NC[2]=1
NJ[1]=6
NJ[2]=3

[NT6]
1=You stand in front of the table.

[N6]
L=2
T=6
NT=IN
NC[1]=6
NC[2]=1
NJ[1]=5
NJ[2]=3
NI=1
bIF=false
FSC=8
FUC=9

[IT1]
1=An appartment door key.

[I1]
IT=ST
IN=key
T=1

[NT7]
1=You unlocked the exit door and left the appartment.
3=THE END

[N7]
L=4
T=7
NT=DN
  1. Copy&Paste this script in Notepad and save it as tutorial1.nx to the \Game… subdirectory.
  2. Edit the index.ini file and add the following lines:
[Group3]
Name=NodeScript Tutorial Games
File[1]=tutorial1.nx
  1. Launch nxi.exe, go to “Load Adventure”, go to Group 3 page and choose the adventure to run.
    As an alternative you can type nxi.exe tutorial1.nx in DOS to instantly launch the gamefile.

Finally, here is a screenshot how this scripted example game should look like in Node-X Generation 1:

Also let me add the generated protocol of the test session for this example game, which can be used as a walkthrough:

------------------------ Node-X1.1 Game Protocol BEGIN ------------------------

Session starts.

Date: 2012/19/06
Time: 19:16:07

>run tutorial1.nx

Title  : Tutorial Game - Escape the Appartment
Author : Comazombie
Version: 1.0 (English)

You stand in your hotel appartment. There is an exit door in the south
and a corridor in the east.

>walk to door

You stand in front of the exit door. It is locked.

>go to corridor

You are in the appartment corridor.

>go to room B

You stand in the living room of the appartment.

>sit on couch

You sit on the couch, spread your arms and chill. What a nice day.
No zombie buggers around to agitate you.

>walk to table

You stand in front of the table.

>take key
>go to corridor

You are in the appartment corridor.

>go to room A

You stand in front of the exit door. It is locked.

>unlock door

You unlocked the exit door and left the appartment.

THE END

>quit game

Session ends.

Date: 2012/19/06
Time: 19:17:26

Total Playtime: 00:01:19

------------------------- Node-X1.1 Game Protocol END -------------------------

With this I end the tutorial. Hope this was useful. And don’t forget to check Node-X Generation 2 this October. As I said, I’m not sure if I will take part as an author in IFComp 2012 or not. But if I finish my other projects in the other communities and have some time left for Interactive Fiction I will see what I can come up with in this hard-to-impress community this year, if anything…

CU

P.S. If you have any questions or want more tutorials for all the other Node-X features not presented in this short tutorial then don’t hesistate to ask.

You are asking me to code a Javascript version of Node-X? Am I understanding this correctly?

What exactly is it that I should take a look at in the games “The Play” and “Clod’s Quest” which you provided as an example?

Yes, I think you should code a Javascript version of Node-X. (You could potentially do this as an middle-end under Undum.)

I picked “The Play” as an illustration of general user experience, for story-driven CYOA. I picked Clod’s Quest as an illustration of an inventory-driven CYOA, and as an example of a subengine under Undum.