NPC Interactions Are Hardcoded?

Just what it says on the tin. I’ve been wondering about this, after looking over the docs and the JSON entries. It looks like dialogue options are in JSON, so new dialogue can be made, but am I correct in figuring that new interactions (like, say, the chat-for-morale-boost option) are C++? I’m asking because certain older mods used Lua to apply new interactions, and without Lua support in more recent versions of the game then that means interactions have to apply through JSON or hard coding. I’ve seen some mods that were successfully converted from Lua to JSON, but most of those were item-based and not character-based.
So, if you wanted to add in options for additional interactions or actions related to NPCs, does that require cracking open C++?

There is a large library of dialogue conditions and dialogue effects which can be combined in various ways, but if you want an effect that is not currently present, then yes, someone needs to add it via C++.

FWIW, dialogue conditions and effects are generally super easy to write. Well, depending on what you want to have them do, they can be really complicated, but the basic structure for invoking an effect is pretty straightforward:

template<class T>
void conditional_t<T>::set_is_season( const JsonObject &jo )
    std::string season_name = jo.get_string( "is_season" );
    condition = [season_name]( const T & ) {
        const auto season = season_of_year( calendar::turn );
        return ( season == SPRING && season_name == "spring" ) ||
               ( season == SUMMER && season_name == "summer" ) ||
               ( season == AUTUMN && season_name == "autumn" ) ||
               ( season == WINTER && season_name == "winter" );

is the setter for the "is_season" dialogue condition, and

void talk_effect_fun_t::set_remove_effect( const JsonObject &jo, const std::string &member,
        bool is_npc )
    std::string old_effect = jo.get_string( member );
    function = [is_npc, old_effect]( const dialogue & d ) {
        player *actor = d.alpha;
        if( is_npc ) {
            actor = dynamic_cast<player *>( d.beta );
        actor->remove_effect( efftype_id( old_effect ), num_bp );

is the setter for the "remove_effect" dialogue effect.


Thank you, the information is very much appreciated!