Custom moveTo Command with Custom Auto-Complete

Using Naninovel C# APIs: adding custom actor implementations or commands, overriding engine services, integrating with other systems, etc.
Post Reply
BigBenEco
Posts: 7
Joined: 24 Apr 2023 04:18

Custom moveTo Command with Custom Auto-Complete

Post by BigBenEco »

This post is both an Explanation on how to add custom Auto-Complete attributes to your custom commands... and a request for help since I'm at the limit of my programming knowledge, I don't know what to google :/
I'm trying to figure out the Naninovel Bridging service so I can figure out Expressions and what variables are available and if I can add my own.

Say we make our new command, following https://naninovel.com/guide/custom-comm ... om-command

For this example, we will make a [moveTo] command (something I want so that the writer can interface with game systems without touching code)

For simplicity, we just have the task debug.log the info, and we'll keep the command basic with a single input parameter.

For context, this command is created such that it represents the player character moving around the world, going to locations in the main world, such as "Base" and/or navigating to sub rooms, such as "Main Lobby" (with the game doing logic to check if any events occur or not). The goal is to have the command list out world locations, and or sub rooms, similar to how the [goTo] command will list out available labels to jump to.

Image

As shown above, we can add attributes to make it [Required] [Nameless] and give it a nice [Description]!

However, notice the extra LocationContext attribute.
This is a custom attribute to provide the contextual list that shows up when you use the command.

Here's what I learned about creating the custom list of locations.

You can use ConstantContext and an Enum per the attribute example linked above... but that just a list, it doesn't do anything fancy, and it can't be automatically expanded upon using code. For this, the goal is to also have the list be automatically generated... somehow. So we'll create a custom attribute called LocationContext

LocationContext is AUTO GENERATED USING MAGIC as far as I can tell... something possibly related to this 'Bridging Service' I keep seeing mentions about in the comments, but no links to. It seems to be some magical part of Naninovel... that I can't get documentation on (nothing shows up on google?!).

Anyways, to create this attribute, we create a LocationContextAttribute, inheriting PararmeterContextAttribute (using ConstantContext and ActorContext as references)
Image

The main thing is that the "Location" in LocationContextAttribute is what gets pulled by the 'Bridging Service' to generate the name of the new attribute LocationContext.

I'm using the ValueContextType.Constant... which I think just a way of organizing the different types of values Naninovel.Metadata system has to deal with. ie, we don't want to use Actor because it 'could' show up with actor commands, such as @char... which would probably be fatal... idk, I don't know what's really going on.

The next main thing is the pathPrefix. I can have this as "Location" and it would work, I'll show in the next step how to add a bunch of 'locations', but in the above example, I included the expression for how the goTo command works, because I'm trying to figure out how to make a different expression with different variables... I just can 't find documentation.

Anyways, when this is just 'Location', we are setting up our custom attribute to look for locations. So now the question is, How do we make locations?

Well this is what the IMetadataProvider is used for

Image

Again, placeholder stuff to figure out how this works, and then worry about code that does fancy things, such as auto generate a list of locations based on other game files.

This requires the first function, GetMetadata, to return a project, which is filled with information, such as a list of actors, commands, resources, constants, variables, and functions. Based on the example provided on the attributes page, it looks like we can just return a new project and all the data gets incorparated. Since I'm using Constant before, I figure it would be smart to well... keep using constants, so I just fill the Constant[].

With the "Location/Test_Script" using the logic expression string pathPrefix = "Location/{:Path[0]??$Script}" such as what was in the second image, I know that the list of locations by be filtered by the script name, as indicated by $Script

And that's the end of the How To... because this is where I am stuck.

I basically want to create a $CurrentLocation variable... which the IDE can't really track, but we'll ignore that.

Right now "Location/Base" does not work. Ideally, what I want to do is specify Location.Room, or .Room if the writer knows the location. I don't want a bunch of Base_lobby, Base_Room1, Base_Room2 cluttering up the auto-complete list. So even if I can't get $CurrentLocation to work (because the idea doesn't make the most sense considering the IDE can't track game state), what I would like is to just list off locations, type the '.' token, and then have it list rooms, to sort of keep things clean and organized for my writer...

Is this even possible?

Anyways, a bit of a long story to get to a simple question... and that's just because I wanted to make this how-to guide after it took me a week or 2 to figure out naninovel enough. It feels like I'm a graduate student, sure there's all these documentations and technical stuff... but I'm still beating my head against a wall trying to figure it out, there wasn't a simple guide through the process.

Elringus
admin
Posts: 530
Joined: 11 May 2020 18:03

Re: Custom moveTo Command with Custom Auto-Complete

Post by Elringus »

Hey, Thanks for sharing this! Basically, as long the values you want to appear in the auto-complete list can be generated outside of playmode, it'll work. Eg, if the locations are a list of pre-defined values you enter in an editor menu it's ok. But if they're generated randomly at runtime based on player input, it would be more tricky to implement (your custom meta provider would need to hook on Unity's enter/exit playmode events and read game state).

Have you checked the pre-release docs on constant expression for 1.19? (https://naninovel.github.io/guide/ide-e ... xpressions) They contain a bit more info. I'd also suggest checking how pose metadata provider is implemented in 1.19 (Naninovel/Editor/Project/PoseMetadataProvider.cs); I guess it's similar to what you're trying to achieve. Also, don't forget that you have to sync metadata with VS Code (Ctrl + Shift + U) after it's changed in the Unity editor (eg, new location is added).

BigBenEco
Posts: 7
Joined: 24 Apr 2023 04:18

Re: Custom moveTo Command with Custom Auto-Complete

Post by BigBenEco »

Elringus wrote: 27 Aug 2023 09:20

Have you checked the pre-release docs on constant expression for 1.19? (https://naninovel.github.io/guide/ide-e ... xpressions)

No, Very Helpful! Thank you!
I was not aware of the Pre-release docs, the default guide and these forms are the only thing that ever shows up in my naninovel search results. Since this is a project I want to release, and I'm still learning Naninovel, I try to stick to the stable 1.18 release... but I do want to see the PoseMetadataProvider.

Now that I'm reading the pre-release docs, explaining where "Path" in "Labels/{:Path[0]??$Script}" comes from, I decided to open up the goTo command to read it more carefully,

Image

What looks interesting or helpful is it looks like for the goTo command to work, it uses two ContextAttributes, as well as each context attribute uses that indexing number thing, the first one being zero, the second being one. I'll see if I can't look into this and see if it is doing what I think it is doing, figure out something similar for my moveTo command.

Code: Select all

 
Elringus wrote: 27 Aug 2023 09:20

as long the values you want to appear in the auto-complete list can be generated outside of playmode, it'll work.

My newest programing philosophy comes from having to deal with more project management tasks for my job, where the majority of programming is just good organization of a project. With that said, my goal is to build most of the project simply by organizing the files, such as creating a file tree of locations and their rooms. I suspect this should allow the autocomplete list to be generated outside of playmode.

Code: Select all

 
Elringus wrote: 27 Aug 2023 09:20

Also, don't forget that you have to sync metadata with VS Code (Ctrl + Shift + U) after it's changed in the Unity editor (eg, new location is added).

You mention that... that's actually something that tripped me up in the beginning... something of a pet peeve. I wasn't going to say anything... but I noticed your name on these docs https://github.com/Naninovel/Documentat ... /tag/v1.19, which got me thinking... your name's on the Naninovel unity page! Hi!!!! I'm an anoying user with a request!!!! :P

Image

One thing I wish for in the guides is for this detail (that is easy to miss how important it is when initially skimming through the guides) to be emphasized with a screenshot. I find images are a good way to emphasize key points since they stand out against a wall of text.

Image

I do a fair amount of technical documentation for my job, making/designing specialty high power industrial machines that can kill people and destroy buildings. Its nothing as in-depth as code documentation, nor is the documentation I make meant for highly technical users. Anyone and everyone needs to know how to be safe with these machines, so a lot of my technical documentation is less about being technical, and more about being easy to read, and figuring out how to communicate the most important information when I can't expect users to fully ready the manual nor take the time to truly familiarize themselves with the system. You may have noticed with this post and my first post on these forums, I like to communicate with pictures, my method of technical communication for non technical users is the reason why.

Anyways, Joined the discord... But I may still post guides and questions here since these forums are more accessible to casual users googling for help.

Elringus
admin
Posts: 530
Joined: 11 May 2020 18:03

Re: Custom moveTo Command with Custom Auto-Complete

Post by Elringus »

Thanks for the suggestion! The editor menu is mentioned in most articles, so I'd have to include same picture everywhere, which would be annoying. There is a screenshot of the editor menu in the getting started guide, which is recommended to read before using the engine, hence I believe it should be enough to familiarize users with that aspect.

BigBenEco
Posts: 7
Joined: 24 Apr 2023 04:18

Re: Custom moveTo Command with Custom Auto-Complete

Post by BigBenEco »

I don't remember when or how I realized I needed to do the update Metadata, but now I do it religiously as I continue to add custom command features

UPDATE

Update for anyone who may find this thread in the future

I got some of the functionality I want
Scratch that, after another test, I got complete functionality! see end of list
Image

Image

So I did a few tests

  1. So Multiple context's can be used
  2. Only one of the same type of context may be used. IE

    Code: Select all

    [ConstantContext("Locations/Forest", 0), ConstantContext("Locations/Base", 1)]
    where using two ConstantContext breaks the bridging service and generates unexpected behavior (often acting like none of your changes or modifications have been applied).
  3. The order of [ , ] does not matter, Imagewhat matters is that second parameter, the namedIndex parameter if your code is based on the ConstantContextAttribute like mine Image
  4. There seems to be only 3 valid numbers, and only 2 may be used at a time
    A. default = -1, or you can use the number 0 or 1
    B. setting any to value of 0 seems to nullify any context that use the default namedIndex = -1
    C. an index of -1 or 0 appears before any '.' token
    D. and an index of 1 appears after the '.' token
    E. this matches the first description for namedIndex located in the parent class Image
    Which for context, name and value come from named parameter datatypes Image
    and for my command moveTo, the parameter "location" is of type NamedStringParameter

Code: Select all

 

Ok, now this is the part where I was going to say what the remaining issue was... but my latest test worked!!!!!!!!
Image

No "??" since I don't know what variables are available nor did this code really need a default expression to evaluate, remember the ":" to indicate a parameter. The pre-release doc certainly helped!

Context:
Image

Results:
Image

now I can either keep expanding the array of constants, or make code that auto generates this based on folder structure... for the future!

Elringus
admin
Posts: 530
Joined: 11 May 2020 18:03

Re: Custom moveTo Command with Custom Auto-Complete

Post by Elringus »

Thanks for sharing your findings! Glad you were able to achieve the goal. A little remark: you don't have to apply command alias if it's the same as command type name. Also, in C# you usually name types in pascal case, so the command type is better be MoveTo. Naniscript commands are not case sensitive, so you'd still be able to use @moveTo in scripts.

Post Reply