Light Coding

This section isn't necessary for those uninterested in higher end stuff and who are satisfied with just writing dialogue for their ghost, and if that's the case, good for you! Don't feel obligated to look into this stuff if you don't want to! Your ghost will be fine without it. Feel free to move on.

But if you're intrigued by some of the features that my Hunter Smoker ghost has that the template does not, this section will briefly cover some of the concepts behind it.

I mentioned in the intro that I came into Ghosts knowing very little formal coding, so if you have no knowledge of coding either, then don't worry! You can pick it up too, I'm sure. And if you DO actually know coding, most of this will seem like child's play I bet. I would be v interested in all the cool things you'll undoubtedly be able to do with ghosts.

For such higher-end users who already know C pretty well, or variants of C at least, there isn't much I have to say to you since you're already on a way higher level than I am, haha. But what I can do is refer you to a few resources that you can use to try and understand a bit more about how AYA coding works. As mentioned, AYA is a variant of C - it isn't exactly C but it is similar in a lot of ways. Here's the manual for AYA although it is in Japanese, so you'll have to run it through a translator probably. Another useful resource is the Ayaya wiki, which has more info on AYA and YAYA functions (YAYA is a fork from AYA after AYA development stalled out, but YAYA is pretty similar to AYA).

But let's say you're like me and you're coming into this knowing very little about coding, and you want to learn a little bit more about it. Well, there's only a few real basic concepts to learn - once you have those grasped, you can use them in a lot of various creative ways.

Some quick notes

I'm just going to briefly cover the very basics of code, although if you are here you most likely already understand it. But I might as well be thorough!

//

Double slashes like this will comment out a line, making it so the code doesn't read it. By now you've seen all my commentary in the .dic files has been commented out like this. In Notepad++ with C language turned on, commented lines turn green. If you are going to be writing bits of your own code, you should comment on it and explain it for your own use later. I'm talking to you, self.

{}

All code or functions must be in a closed set of curly brackets like this, although you can nest brackets within themselves. Notepad++ will tell you when you have a loose bracket if you click on the line near it, which is handy, and it will also draw a line telling you where the matching bracket goes.

name
{
stuff
}

This is the basic format for most everything you'll see in the .dic files, and any kind of code that you yourself will be doing. You have the name of the function, an opening bracket, the contents of your function, and a closing bracket. You can, as mentioned above, nest brackets within the initial set, but in the end, it will still follow this format.

Basic Operators

There are a few things you can use code to do by the use of different sets of symbols, generally referred to as operators. I think. Again I'm not really a high-scale programmer or anything so my terminology may be wrong, haha. But anyway, here are a few you will probably see a lot and will, potentially, also be using. Many of them are based on mathematical operators you may recognize.


=

The = sign defines the value of something.
EXAMPLE
examplefunction
{
NightSky = 4
}
This here would change the value "NightSky" to be 4. If you want to change a value to a word rather than a number, you'd want to put it in quotation marks.
EXAMPLE
examplefunction
{
NightSky = "dark"
}
This would set the "NightSky" value to return as "dark".

==

Double == marks, on the other hand, evaluate something in an if statement (below). If you want to see if something equals a certain value, you'll want to use ==. I'd use this in an example, but it's really mostly used in if statements, so you'll see it below in just a second.

Remember: = and == are not the same thing! This has messed me up a few times when I forgot a = mark, haha.

+=
+

+ and += will add an amount to a value.

EXAMPLE
examplefunction
{
NightSky += 1
}

examplefunction
{
NightSky + 1
}

In this case, this would add 1 to the value of NightSky. Obviously you'd want NightSky to be storing some kind of number here.

The counterpoint to += or + is -= or -, as you can probably guess, which will subtract that amount from a value. Be careful not to get into negative numbers here by subtracting from zero, and also be aware that using += on zero may cause some odd behavior. Use the single + instead if you're going to be adding numbers to zero.

>=
<=

These are often used in if statements to check if something is greater or lesser than another value. >= would be greater than/equal to, and <= would be less than/equal to. Again, you'll see this below when we get to if statements.

!=

!= means "does not equal" basically, and is used in if statements for when two values do not equal each other, or if a value does not equal a certain parameter.

&&

&& means AND, basically used when you want to check two values at once in an if statement.

||

|| means OR, when you want an if statement to check one value OR another value.

And those are basically all the operators I've used! With just this small set, you can do a lot of different things.

If Statements

Believe it or not, the vast majority of the stuff I've done with the ghost is through using if statements in unique ways. As you go through the .dic files, you'll see if show up a lot, along with its companions, elseif and else. If statements are generally set up like this.
EXAMPLE
examplefunction
{
if NightSky == "dark"
      {
      more stuff
      }
else
      {
      stuff
      }
}

In Notepad++, if and any operators will be highlighted in blue, which will make them easy to see. Notepad++ will also keep your spacing consistent when you hit tab or enter, which is really handy.

An if statement checks if something is true - what that something is depends on the words following. In this example, it's checking if NightSky equals "dark" by using the double == operator we talked about above. If NightSky DOES equal dark, it will run "more stuff". If it does NOT equal dark, it will run "stuff" instead.

Notice that there are new sets of brackets within our initial set. Any if statement needs a set of brackets to contain what it will do, and so will any else statement. You can see both the new sets of brackets are still within the larger set defined by examplefunction.

When condensed down to one line, an if statement would look like this.

EXAMPLE
examplefunction
{
if NightSky == "dark" { more stuff }
else { stuff }
}

If this makes it a little easier to see what I mean about the second pairs of brackets. You can format your code on the same line like this if you want, if that makes it easier for you to read. Personally I like spacing mine out.

EXAMPLE
examplefunction
{
if NightSky == "dark" {
      more stuff
      }
else {
      stuff
      }
}
You can also leave the brackets on the same line of the if or else statement and move the rest down if you want, that's also valid. You can move the brackets mostly anywhere practically, as long as they're there, they enclose what the function's going to do, and they're a closed set. Experiment a little and try and find which way to format your code works best for you.

Here are a few other examples of if statements using the operators we just talked about.

EXAMPLE
examplefunction
{
if NightSky >= 14
      {
      more stuff
      }
else
      {
      stuff
      }
}

This checks to see if NightSky is greater or equal to 14. If it is, it runs "more stuff". It it's not, it runs "stuff".

EXAMPLE
examplefunction
{
if NightSky <= 15
      {
      more stuff
      }
else
      {
      stuff
      }
}

Likewise, this checks if NightSky is less than 15, and if it is, it runs "more stuff". If it's not, it runs "stuff" instead.

EXAMPLE
examplefunction
{
if NightSky != "dark"
      {
      more stuff
      }
else
      {
      stuff
      }
}

Here, if NightSky does NOT equal "dark", then it runs "more stuff". If it DOES equal "dark", it runs "stuff" instead. Hopefully you're starting to get an idea of how this works.

Now, you can have an if statement check multiple things at once using some of the operators above.

EXAMPLE
examplefunction
{
if NightSky == "dark" && DaySky == "light"
      {
      more stuff
      }
else
      {
      stuff
      }
}
Here you can see we added a new value to check, DaySky. If NightSky equals "dark" AND Daysky equals "light", then it will run "more stuff". If BOTH of those values are not correct, it will run "stuff" instead. So for example, if NightSky equaled "dark" and DaySky also equaled "dark", then it would run "stuff" and not "more stuff" because BOTH values would not be correct.
EXAMPLE
examplefunction
{
if NightSky == "dark" || DaySky == "light"
      {
      more stuff
      }
else
       {
      stuff
      }
}
Here, we're using the OR operator, ||. Now this if statement checks to see if NightSky equals dark OR DaySky equals light. If EITHER value is correct, then it will run "more stuff". Thus even if one of them was wrong, as long as one was right, it would work.
EXAMPLE
examplefunction
{
if NightSky != DaySky
      {
      more stuff
      }
else
      {
      stuff
      }
}
You can also check values against each other. Here, if NightSky does NOT equal DaySky, then it runs "more stuff". If the two values DO equal each other, then it runs "stuff".

EXAMPLE
examplefunction
{
if NightSky == "dark" || DaySky == 15
      {
      more stuff
      }
else
      {
      stuff
      }
}

The two things you're checking don't have to be the same either, so you could check one value for a word and another for a number, like so.

EXAMPLE
examplefunction
{
if NightSky == "dark" || DaySky == "light" && NoonSky == "purple"
      {
      more stuff
      }
else
      {
      stuff
      }
}
You can also combine operators, like here I'm using both AND and OR. In this cause, it would check if NightSky equals "dark" OR Daysky equals "light" AND NoonSky equals "purple". Both things on the OR side would have to be true for "more stuff" to run, so DaySky AND NoonSky would have to be correct to run "more stuff". I guess in terms of a math problem, it'd look like NightSky or (DaySky + NoonSky) if that makes sense.
EXAMPLE
examplefunction
{
if NightSky == "dark"
      {
      if DaySky == "light"
            {
            special stuff
            }
            else
            {
            other stuff
            }
      }
else
      {
      stuff
      }
}
You can also nest if statements within each other, although this can get very complicated quickly if you're not paying attention. Notepad++ is a great help here for keeping your spacing and brackets straight. Here, the first if checks to see if NightSky equals "dark". If it does equal "dark", it then goes to the next if check to see if DaySky equals "light". If it does, then it will run "special stuff". If NightSky equals "dark" but DaySky does NOT equal "light", then it will run "other stuff" instead. And if NightSky does not equal "dark" at all, then it will just run "stuff". You can use nested ifs to do a lot of creative things if you can keep them straight. You can nest as many ifs as you can keep track of.

The counterpart of any if statement is an else statement. The else takes care of what happens when the if isn't true, as you can see in all these examples. In some cases, you can get away with just an if statement, but most of the time you'll want an else. You can see singular ifs most frequently in aitalk.dic I believe. In those cases, all an if is doing is adding the option for more dialogue, so there's no need for an else. But these situations are unusual. Most of the time when they come up in the files, I'll point them out.

The other counterpoint to if and else is a combination of both, elseif.

EXAMPLE
examplefunction
{
if NightSky == "dark"
      {
      more stuff
      }
elseif NightSky == "orange"
      {
      other stuff
      }
else
      {
      stuff
      }
}

Elseifs fit inbetween if and else, as you can see. They essentially set up another check before the statement goes to else. If NightSky equals "dark", it runs "more stuff". HOWEVER, if NightSky doesn't equal "dark" but DOES equal "orange", then it runs "other stuff". And if doesn't equal either of those, it runs "stuff" instead.

Elseif statements go in order. When the function runs, it will check if the first statement is true - in our example's case, it will check first if NightSky equals "dark". If that statement is true, then it will simply run "more stuff" and finish. It won't check any of the rest of the things because it already found what it was looking for.

So, if the function checks the first value, "dark", and can't find it, it moves on to the next step, searching for "orange". If "orange" is true, then it runs "other stuff" and finishes. And if it can't find that, it goes to else. So you can see, the function progresses linearly until it either finds something that's true, or it goes to else and ends.

You can add as many elseifs to any if/else pair as you want, as long as they're slotted between the if and else as in this example. Using this, you can have a function check a whole variety of different conditions to see if something is true.

With this understanding of if, else, elseif, and the operators, go and take another look at the .dic files. Particularly study ones like bootend, menu, etc, and other ones that have a lot of code. You'll begin to see how these functions are put together, and hopefully any explanations I made within the file will begin to make even more sense than before.

Understanding how these things work and how they're put together is a key step in being able to create your own functions and your own if checks for whatever you can imagine.

How do I create my own function?

Just go ahead and define it in the code. You can create any function you want named anything you want, and put anything you want within the brackets, as long as the code you put in is valid, obviously.

[Insert Function Name Here]
{
[insert what you want your function to do here]
}

And done. It's really that simple. Of course, you have to understand how to code what you want your function to do, and how to call it or use it when you want to, but there are really no limits on what you can create.

Well... that's not entirely true. You shouldn't create functions with the same name as those that are already hardcoded into AYA. You can see a list of Shiori functions at the Crow-SSP dictionary, albeit in Japanese. But all the function names themselves are in English, so that's easy enough to read.

Speaking of that page, take a look at all the functions there. You can see there are a great many of them and their names usually give you an idea of what the function does. OnBatteryCritical for example happens when your laptop's battery is at critical. OnScreensaverStart runs when your screensaver starts. Some of the Shiori functions are more opaque in what they do though.

You may be wondering, "this function looks cool, can I add it to my ghost?" and the answer is, sure! For the most part. Some may involve plug-ins your ghost may not have, specifically the ones under "External Application" that have Kinoko or Nekodori in the function name. But most of them should work. You should read their definition in the Crow-SSP dictionary carefully to understand what goes into them though and what they're for. There are so many, I won't get too much into them here, and all the major ones are already in your .dic files to begin with.

You can also create any value you want much like with functions. If you want to create a value like AmountofHorses so you can evaluate if it's greater than AmountofRaverGlowsticks, just stick it in there and do stuff with it in your function. Once the function is called at some point and the value is defined as equaling something (it won't exist unless it equals something, obviously), then you can use that value for whatever you want. So there are no real limitations on values either, make whatever values you want called whatever you want to do whatever you want.

How do I run my new function?

There are a few methods off the top of my head. One, you can use \![raise,FunctionName] as detailed in the SakuraScript page. Simply stick that at the end of a line of dialogue, and it will run.

The other way you can run your function is to tuck it into another function. Look through the .dic files and look at all the functions. Some run when you open a menu, some run when the ghost boots or closes, some run when you move the ghost too close to the side of the screen, or when the ghost is overlapping, or just when the ghost is talking in general, there are a lot of possibilities.

Let's say you made your own function, let's call it, ExampleFunction, and you want it to run whenever your ghost goes back to its idle pose using OnSurfaceRestore.

EXAMPLE
OnSurfaceRestore
{
ExampleFunction
--
"\0\s[0]\1\s[10]\e"
}
All you would do is put the name of your function within the code itself, and it will run. Here, it's offset from the normal OnSurfaceRestore dialogue with a -- just to have it on its own nice line. You can do this with most any code. Take a look at the OnBoot and OnFirstBoot functions within bootend.dic. See how the function defines values before it even gets to the ghost's dialogue? All you have to do to run a function is tuck it somewhere in another function before the normal dialogue.

You can see this clearly in OnBoot in bootend.dic, where before the ghost speaks, you can see a number of functions being called and assigned to values to determine exactly what the ghost will say. GetDaySlot, a unique user-defined function, runs and then the value it returns is stored in dayslot, for example. Once OnBoot has the value from the function, it can then use dayslot in a variety of if statements to check the day and determine what the ghost will say.

You can also call certain functions using envelopes, which you may remember from the SakuraScript page. This is particularly simple with dialogue based functions. Like...

EXAMPLE
RandomTalk
{
"Random dialogue."
"More random dialogue."
"Saying some random stuff."
"%(teatalking)"
}

teatalking
{
"Here's some tea talk."
"Talking about tea."
"Hey, how about that black tea?"
"Want some oolong tea?"
}

So here, you can see that you can store dialogue in a separate function, and then call it in RandomTalk by using an envelope. Each time RandomTalk hits the %(teatalking) envelope, it'll pull a line of dialogue from the teatalking function. I've seen some ghosts separate their dialogue into separate pools like this, maybe for organizational purposes, who knows. Maybe it'll come in handy for something you have in mind.

You can also pull more complicated functions using an envelope like this! The best example would be the %(birthchecked) envelope in the menu.dic, a user-defined function that checks if it's the user's birthday, but you can also see it in bootend.dic, with OnBoot getting passed onto %(normalboottalk). In the boot dialogue's case, OnBoot checks what day it is, and then if it's not any specific special day, it passes onto normalboottalk, which checks what time it is to do specific dialogue. If you have some complex things you want to check all at once, it can be helpful to make a list of those things in terms of priorities, then break them into separate functions. In OnBoot's case, the day is the most important, then the time. Always set up your most important if check first! Then work down from there.

You can also just link to your new function via a choice in a menu. So you'd just set up a choice using SakuraScript like...

\q[Click for my new function,MyNewFunction]
Then your user could click that choice and your new function will run. You can use this for a lot of things, like asking a ghost questions (\q[Tell me about yourself,GhostTalksAboutSelf], with GhostTalksAboutSelf being a pool of dialogue like teatalking above) but you'll probably use it most often for menu pages in my experience.

How do I add my own menu pages?

Basically, when you set up a choice with \q, you put in a Displayed Name and a linkedfunction, like \q[Displayed Name,linkedfunction].

What you're going to want to do is write up a new function for the new page for your menu. Use \b2 to use a big balloon as necessary, study how the menu is already set up in menu.dic and copy it as you need, put whatever it is you're going to put in this new function.

Once you write up your new menu page function, you link to it with a \q option within your existing menu. So it'd be something like, \q[New Page,newmenupage], although with your name and values as you see fit.

Look at menu.dic and see how the \q choices are already laid out. Simply insert your new page among them. Save and test your ghost to make sure it still works after you do, and check your new page link to make sure it leads to your new menu page. You can then do whatever you want with your new menu page, like add more choices for some other thing you want to do. Here's an example. First, I'll write the new menu page.

NewMenuPage
{
"Here's stuff in a new menu page. I'll use the \b2 tag because I want to use the larger balloon."
--
[new menu stuff]
}
And I stick this somewhere in menu.dic. Then I go find the normal existing menu dialogue for the ghost. We'll use Triangle from the template, since his menu is simple.
OpenKeroMenu
{
"\1\s[10]\b[2] This is a menu introduction dialogue."
--
"\n\n[half]/
\![*]\q[Update,keroupdatecheck]\n/
\![*]\q[Bug report,bugreport]\n\n/
\![*]\q[Test variable,testvariable]\n\n/
\![*]\q[Nothing,keroCANCEL]\e"
}
Then I just stick the new menu page in with the others.
OpenKeroMenu
{
"\1\s[10]\b[2] This is a menu introduction dialogue."
--
"\n\n[half]/
\![*]\q[Update,keroupdatecheck]\n/
\![*]\q[The New Menu Page,NewMenuPage]\n/
\![*]\q[Bug report,bugreport]\n\n/
\![*]\q[Test variable,testvariable]\n\n/
\![*]\q[Nothing,keroCANCEL]\e"
}
And voila! You can do this as many times as you want with however many menus you want to have. Can make real labyrinthine menus if you want to. You can also rearrange or rework the existing menus to point to different things or functions you define, if you don't like the template's functions.

So how do I specifically create a feelings system for my ghost?

Doing something like this is complicated really, and it depends on how your ghost is set-up. So, instead I'm going to explain conceptually what I did, and I'm going to hope you can use what I explained above to try to put it together on your own.

Basically, you're going to want to define a value for your ghost's feelings. In my case, I have two (well, three, but for this page, there are two) for Hunter and Smoker. I called them hunterfeelings and smokerfeelings. Then, when certain things happened, I would use += or -= to add or subtract from that value. Since you can't do this kind of thing within RandomTalk since that function is pretty much only for dialogue (see aitalk.dic), I would often put these feelings changes at the end of chains, which were more self-contained and flexible, or as a result of choices in a menu.

Once the values were in place, I could then evaluate them in if statements. So I could go "if hunterfeelings >= 25, then yada yada happens".

That's the basic jist of how it works. The little heart in the menu actually changes depending on a series of if statements as well, like if hunterfeelings is greater than 10, it displays a heart that's 10% full, and so on. If you look in the img folder, you'll see that there's a heart picture for all stages of their feelings, which are displayed depending on what that if check returns. All of the heart coding is in its own function, which is called whenever you open either of their menus, much the same way GetDaySlot's value was stored in dayslot when the ghost runs OnBoot. If you look at Hunter and Smoker's code, you'll probably see it more clearly. But I'll put some examples here.

Select.Didntseeit
{
smokerfeelings -= 1

"\0\s[1173]Easy way to remedy that, you know?\1\s[1204]\i[4]Like %(username)'s gonna waste %(hisher) time watching a movie just for you.\w5\0\s[1096]\n\n[half]I wasn't tellin %(himher) to, I was just sayin. Get off my back.\e:chain=end"
}
First, a chain led to a question, with one of the answers leading to this conclusion. Smoker loses a relationship point since she doesn't like your answer.
Select.brushhunter
{
if hunterfeelings >= 45
{
hunterfeelings += 1

"\1\s[1037]What, really? \w4Haha, are you sure? \w4That's kinda weird, you know?\w4 But,\w4 I dunno... \w6\s[1181]I guess you can, if you really want to.\w9\s[1182]\n\n[half]\_q(Move your mouse back and forth over the brush)\e" }
else
{
"\1\s[1025]Uh...\w6 no, that's okay, %(username). \w5I mean, I don't even know you that well, it's kinda weird, don't you think? \w6\s[1039]I mean, if we were buds or something maybe that'd be different...\e"
}
}
Here, there's a check to see if hunterfeelings is above a certain value. If it is, it runs the first bit of dialogue and also raises those feelings up a point. If it's not high enough, it'll instead run the second bit of dialogue.
OnHunterClick
{
huntersleeping = "off"
bothsleeping = "off"
hunterheart = GetHFeelings
--
"\1\b[2]\s[10]"
[...]
\![*]\q[Nothing,HunterCANCEL]\_l[145,180]%(hunterheart)\_l[40,180]Run time: %(passhour):%(passmin) \e" }
Here's a snip from when you double click Hunter and bring up her menu. You can see that a value called "hunterheart" is defined as equaling a function called "GetHFeelings". Then at the bottom of her menu dialogue, it calls the hunterheart value with %(hunterheart).
GetHFeelings
{
if hunterfeelings >= 110
{"\_a[hunterheartclick]\_b[img\heart11.png,inline]\_a"}
elseif hunterfeelings >= 100
{"\_a[hunterheartclick]\_b[img\heart10.png,inline]\_a"}
elseif hunterfeelings >= 90
{"\_a[hunterheartclick]\_b[img\heart9.png,inline]\_a"}
elseif hunterfeelings >= 80
{"\_a[hunterheartclick]\_b[img\heart8.png,inline]\_a"}
elseif hunterfeelings >= 70
{"\_a[hunterheartclick]\_b[img\heart7.png,inline]\_a"}
elseif hunterfeelings >= 60
{"\_a[hunterheartclick]\_b[img\heart6.png,inline]\_a"}
elseif hunterfeelings >= 50
{"\_a[hunterheartclick]\_b[img\heart5.png,inline]\_a"}
elseif hunterfeelings >= 40
{"\_a[hunterheartclick]\_b[img\heart4.png,inline]\_a"}
elseif hunterfeelings >= 30
{"\_a[hunterheartclick]\_b[img\heart3.png,inline]\_a"}
elseif hunterfeelings >= 20
{"\_a[hunterheartclick]\_b[img\heart2.png,inline]\_a"}
elseif hunterfeelings >= 10
{"\_a[hunterheartclick]\_b[img\heart1.png,inline]\_a"}
elseif hunterfeelings >= 5
{"\_a[hunterheartclick]\_b[img\heart0.png,inline]\_a"}
elseif hunterfeelings >= 1
{"\_a[hunterheartclick]\_b[img\heartgrey.png,inline]\_a"}
elseif hunterfeelings <= 0
{"\_a[hunterheartclick]\_b[img\heartblack.png,inline]\_a"}
}
And here's the GetHFeelings function mentioned just above! You can use functions to get values like this, then store them in an envelope you can display in dialogue or menus. You can see here that when the if check returns a certain value, it displays the right heart image with \_b and links it to a function called hunterheartclick using \_a.
OnHunterFeelings
{
if hunterfeelings >= 110
{
"\1\s[10]\_q\f[bold,1]%(huntername)'s Feelings:\f[bold,0]\n\n[half]%(huntername)...\nthinks you're awesome. %(hunterfeelings) %(hpunchcounter)\n\n/
\![*]\q[Back,OnHunterClick]\e" }
elseif
[...]
Here, I use %(hunterfeelings) to display the value of hunterfeelings when you check your relationship status with them, and %(hpunchcounter) to show how many times you've punched her. I really need to figure out a fancier set up for this menu...

You can display almost any variable you're tracking or anything that'd return a value of some sort using an envelope. This is useful for statscreens.

How do I add items?

This also is fairly involved, and mostly involves a lot of if statements again. Conceptually, you'll want to create your items and make a page for them in your menu. Whether or not you "have" an item gets assigned a value, in my case things like "gotbrush" or "goteggplant" or whatever. When you open the item page, there's an if check to see if the value for getting the item is true. If it is, the item appears and is usable, using a mixture of link script like \_a in anchor.dic and in-balloon images with \_b.

Various actions or situations change the "gotitem" value using the = operator, which gives the user the item. Then the item is rigged up with its own menu for using it, and its own functions related to what happens when you use it. Here's an example.

OnItemscreen
{
if gotbrush == 1
{"\_a[brush]\_b[img\brush.png,inline]\_a"}
elseif gotbrush == 0
{"\_b[img\nobrush.png,inline]"}
[...] }
Here's a simplified snip from Hunter and Smoker's item menu. It's not the whole thing, thus the ... at the end. But you can see that there's a check for if the user has the item (if gotbrush equals one), and if it does, it displays the right brush image with a link to the brush menu screen. Otherwise, if the user does not have the brush (if it equals zero), then it just shows the faded out image with no link.

How do I set up a different "mode"?

Setting up a "mode" where your ghost draws only from a certain pool of dialogue is doable, although again, somewhat complicated. Look in aitalk.dic, in particular look at RandomTalk. You'll notice it follows the name { stuff } format of most any other functions, it just has a ton of dialogue in it.

Now, you can break up RandomTalk with an if just like with any other function. You just have to be careful and thorough when you do it. Keep in mind that there will be no overlap between your pools of dialogue, unless you deliberately copy the same dialogue into both pools. It is an if/else situation, after all. And keep in mind ALL DIALOGUE has to be in one of the pools. You can't have loose dialogue if you do this, it has to be in the if or the else.

EXAMPLE
RandomTalk : nonoverlap
{
if hypotheticalmode == "on"
      {
      "\0\s[0]Here is hypothetical mode dialogue.\e"
      }
else
      {
      "\0\s[0]Here is normal random dialogue.\e"
      }
}
You can see here how the dialogue is now split between a hypotheticalmode and the normal, random dialogue that you already have written. To switch into a mode, all you need to do is change the value for the mode to "on" using =. You have to set up a situation for you to turn the mode on of course, like an item or perhaps a certain chain conversation or function. Once the mode is on, when the ghost goes to call dialogue, it will do the if check and see that the mode returns as "on", and will thus only read dialogue from that pool. And you have to have something turn the mode to "off" when you're done as well, usually easily slipped into OnClose, OnBoot, or OnGhostChanged when the ghost reloads or something like that. Otherwise your ghost will get stuck in the mode.

How do I collect user input using an input box?

Maybe you want to ask the user a question and want to store the value or something like that. Well, it's not super hard, exactly, but it does involve an aspect I haven't touched on so much yet. If you look at the Crow-SSP encyclopedia I've linked a few times, you'll notice that many of the functions have a Reference0 associated with them, or a number of References really. What Reference0 is depends on the function, so it's rarely ever the same between them.

Now, first you'll want to set up an input box, using the input box scripting advice from the SakuraScript page. You'll want to link it to a new function you are writing. So if your function was named "OnExampleFunction", your input box call would look like, "\![open,inputbox,OnExampleFunction,-1]".

When you write code for OnExampleFunction, the user's input will be stored as reference0. You can see this in action most clearly in nameteach.dic. The user inputs their name into a box linked to OnNameTeach, and their input is checked in if statements using reference0 in the following OnNameTeach function. You can take reference0 and store it as any kind of value you want. For example, the user puts in the type of ice cream they like, and in your ExampleFunction, you could put "reference0 = TypeofIcecream". You could then call or use the TypeofIceCream value for whatever you want. Here's a solid example.

GatheringInfo
{
"So, what's your favorite type of ice cream?\![open,inputbox,OnIceCream,-1]"
}

OnIceCream
{
TypeofIceCream = reference0

"Oh, %(TypeofIceCream) is my favorite too!"
"Bleh, I hate %(TypeofIceCream)."
}
Something like that. As a note, when input boxes are involved, I'd usually link them to a function that starts with On, like OnFunction. They usually work better that way.

If I can think of any other random coding tidbits, I'll put them here, but for now, I think that should about cover it.

<--Phase 4 - SakuraScript

Phase 5 - Network Update-->