inkle / ink

inkle's open source scripting language for writing interactive narrative.
http://www.inklestudios.com/ink
MIT License
4.15k stars 495 forks source link

Variable observers (and other ways of moving data between unity and the story) #413

Open Poltroon opened 6 years ago

Poltroon commented 6 years ago

In my planned game, on the Unity side there are a number of systems to do with character generation, battle, tech trees and so on. These systems get pretty heavy with some calculations I don't believe Ink is capable of, and they need access to pretty much all the variables to get and set them. So it makes sense to store the game state here.

But on the Ink side (which I'm using for missions and end of turn events), the story also needs access to pretty much the same stuff. Some choices only appear if certain conditions are met. And almost everything can be changed by your choices in the story.

Does anyone have any thoughts about the possibility / best way of sharing all the needed data between the unity side and story side?

Are variable observers part of the answer? How do they work? The documentation says:

You can register a delegate function to be called whenever a particular variable changes.

Which I don't understand.

Do I simply put the following in the update method?:

_inkStory.ObserveVariable ("health", (string varName, object newValue) => {
    SetHealthInUI((int)newValue);
});

...or do I also have to do something with functions on the Ink side?

joningold commented 6 years ago

There are loads of ways to communicate with the gamelayer.

Variable listeners watch for variables inside the ink changing value and then act on them. This is good for, say, updating UI to reflect internal ink values; or if you want to fire off complex consequences to some value change somewhere.

cheers jon

On Wed, Feb 21, 2018 at 2:51 PM Poltroon notifications@github.com wrote:

In my planned game, on the Unity side there are a number of systems to do with character generation, battle, tech trees and so on. These systems get pretty heavy with some calculations I don't believe Ink is capable of, and they need access to pretty much all the variables to get and set them. So it makes sense to store the game state here.

But on the Ink side (which I'm using for missions and end of turn events), the story also needs access to pretty much the same stuff. Some choices only appear if certain conditions are met. And almost everything can be changed by your choices in the story.

Does anyone have any thoughts about the possibility / best way of sharing all the needed data between the unity side and story side?

Are variable listeners part of the answer? How do they work? The documentation says:

You can register a delegate function to be called whenever a particular variable changes. Which I don't understand.

Do I simply put the following in the update method?:

_inkStory.ObserveVariable ("health", (string varName, object newValue) => { SetHealthInUI((int)newValue); });

...or do I have to do something with functions on the Ink side?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/inkle/ink/issues/413, or mute the thread https://github.com/notifications/unsubscribe-auth/AA40o_oVI-fliJb-cM4lEEg5fN9nKrAjks5tXC2MgaJpZM4SNw4s .

Poltroon commented 6 years ago

Thank you for the reply.

It's tricky because I would like both layers to be able to check and set almost anything, not for one to be just a reflection of the other.

As a blanket solution, would it be horrible to have variable observers always listening for every possible variable change within the story (in a large list), and get the game state in the unity layer updated that way?

alpapan commented 5 years ago

It would be awesome if we had an example of where this usually goes...! e.g would it go to under a story.canContinue (i'm looking at the Intercept) or in Enter?

You can register a delegate function to be called whenever a particular variable changes.  This can be useful to reflect the state of certain ink variables directly in the UI. For example:

_inkStory.ObserveVariable ("health", (string varName, object newValue) => {
    SetHealthInUI((int)newValue);
});

EDIT: Answering my own question. I've included on the Enter function (it works, but not sure if that is the best way or if it should go into the Awake). Certainly doesn't need to go into the story continue loop.

I'm also having problems following this without an example... sorry!:

The reason that the variable name is passed in is so that you can have a single observer function that observes multiple different variables.
papataci commented 3 years ago

Read with interest, but cannot figure out if i can read variable stored inside Unity Objects.

i create characters in Unity this way:

public class Character : MonoBehaviour
{
    public string characterName;
    public Sprite icon, fullFigure;
    public int health;
    public int damage;
    public int money;
    public List<string> inventoryList = new List<string>();
    public List<string> skillsSetList = new List<string>();
    public string mood;
    public enum Mood
    {
        noMood, pleased, neutral, upset, leaving
    }
}

how do i read the varibles stored in the Character?

can call functions from ink via binding, but can only write to the log:

public void GetCharacterHealth(string characterName)
    {
        Debug.Log("Health:"+GameObject.Find(characterName).GetComponent<Character>().health);
    }

can i put the Unity values in an Ink variable?

please help!