NPC Dialogue Functions

Hey people,

I just became aware that NPC conversations have been moved to JSON files, which encouraged me to try my hand at introducing some new content. I have been unable to figure out how to do a couple of things which would be easy to do in other RPGs. I wonder whether there are any methods to achieve these, or if new functions need to be added for them to be possible. Without further ado, here are the problems I faced:

  1. Using random number arguments for cash rewards: I am able to provide the player with static cash amounts by using an effect such as “effect”: [ {“u_spend_cash”: -1000} ]. However, I couldn’t find a way to randomize the amount. I tried using the “rng” command found in “npc_class” type in a dialogue, with no success. Is there any way to achieve randomization here with a command or a workaround?

  2. Random chance of topic appearing: In most RPGs, you can make whether the topic/response is visible based on the realization of a random number. For instance, in Morrowind, you could check whether a global called Random100 would be greater/less than a number, where Random100 would be a random draw from uniform discrete [1,100]. I wonder if this is possible in C:DDA. I know I can introduce some randomization by creating 100 responses and picking x many of them to be one realization, and 100-x to be the other one, but that seems very inefficient.

  3. Basic math and comparisons: While the and/or/not function are very useful, it would be wonderful if one could make calculations in the dialogues. Again, the functions in “npc_class” type seem to be able to do this, but I couldn’t get something similar to work in dialogues. This could allow joint skill/stat/trait checks (not and/or statements, but rather things like “(intelligence * 5) + speech >= 20”.

  4. Creating/accessing/modifying integer values: I haven’t verified this, but it looks like one can “save” boolean information on a character by adding/removing custom effects. However, I couldn’t find a workaround for saving integer values. Is there a way to access the intensity of an effect? If so, perhaps custom effects with intensities can be used to create/access/modify integers. In other modding environments, you would usually modify/access a global or a local variable. Any way I can achieve a similar result?

  5. Dropping/removing apparel: There are very useful commands to make the player/NPC drop or unequip a weapon. However, I couldn’t find any similar function for dropping/removing apparel. Is there a way to achieve this with the existing functions?

I apologize in advance for the large number of questions. I really appreciate the fact that significant time has been invested into moving a lot of the dialogue functionality from the cpp code to json files. Hopefully this will result in the creation of a lot of new content.

The dynamic lines, effects, and conditions described in the doc/NPCs.md document are the only ones currently available through dialogue. You can’t use things described for other JSON entities, because the dialogue JSON parser doesn’t understand them.

It’s pretty easy for me to extend support for most of these.

In order:

  1. I can add this. It might not be a general interface, but durations and cash values should be straightforward.
  2. Random values as conditionals should be pretty straightforward I think. It probably needs to be linked to a switch response.
  3. General arithmetic is going to make the parser really complicated. I might have to defer on this.
  4. Effects in dialogue don’t have intensity. It’s probably easier to create an interface for setting local variables. I’ll check with Kevin about adding global variables - there are some questions about where to store and save them.
  5. I haven’t needed effects to make people remove apparel. It shouldn’t be hard to add, though.

Don’t feel bad about asking for more features, as long as you develop more content.

Thanks for the quick reply, and I am very happy to hear that these functionalities can be implemented. Thanks a lot, I really appreciate it!

After a few experiments, there is one more thing that might be useful:

  1. There are a few conditions that can be used in “dynamic line” such as “npc_female”, “is_female”, etc. I tried using these in a condition statement (e.g. { “is_female”: true }), but it didn’t work. Is it possible to use the conditions in “dynamic line” also in “responses”?

I want to unify conditionals and dynamic line conditions, but they’re currently separate sections of code.

The docs for dialogue are very complete, and if something isn’t listed as a dynamic line, effect, or condition, then it doesn’t exist.

I went ahead and unified dynamic line and response conditions, which also made it easier to do some of the other stuff you wanted. Among other things, you can now use u_male, u_female, npc_male, and npc_female in both dynamic lines and responses.

I’ll try to submit some PRs over the next week.

This is wonderful to hear, thanks a lot. I am looking forward to put these into good use.

I am particularly interested in seeing whether global or local integer storage will be possible. They could mean so much for developing new missions and various long-term interactions without dealing with the C++ code.

As it turns out, there’s a pre-existing API for setting arbitrary string values on creatures. So you’ll be able to do "effects": [ { "npc_set_var": "var_name", "type": "mission", "context": "FREE_MERCHANT_MISSION_1", "value": "gave_prospectus" } ] to set an NPC local variable, or "effects": [ { "u_set_var": "var_name", "type": "mission", "context": "FREE_MERCHANT_MISSION_1", "value": "gave_prospectus" } ] to set a PC “global” variable.

The type and context are required because Kevin doesn’t want there to be any chance of namespace collisions. The PR should be ready on Sunday or Monday.
(edit) Or, y’know, Friday night because this was very straightforward.