Skip to main content

Relationships

Building Dynamic Relationships with Inworld AI Characters: Read our Blog Post.

Overview

Inworld AI's characters can develop two kinds of relationships with users - Friendship and Romance. These relationships evolve through different stages:

  • Friendship stages: Archenemy ↔ Enemy ↔ Acquaintance ↔ Friend ↔ Close Friend.
  • Romance stages: Date ↔ Relationship ↔ Life Partner.

What Influences These Relationships?

Characters' relationships change based on Relationship Updates like Trust or Distrust. How the character perceives interactions in conversations influences these relationship updates. We are working on feature iterations that will allow developers customize these values based on game events (like completing a quest).

Relationships and Updates Metrics

QualitiesFriendship LabelsRomance Labels
ArchenemyEnemyAcquaintanceFriendClose friendDateRelationshipLife partner
Trust/Distrust<0<0≥50≥100≥200≥50≥100≥200
Respect/Contempt<-200<-50≥0≥50≥200≥0≥50≥100
Familiar/Distant///≥100≥200≥50≥100≥200
Attraction/Aversion<-200<-50≥0≥50≥200≥50≥100≥200
Flirtatious/Serious<50<50<50<50<50≥50≥200≥200

The exact values are subject to future changes.

See it in Studio Chat

Studio chat window provides more minute details such as the increase or decrease changes for each quality value based on the user’s input at each turn of the conversation. These values persist and are associated with the Player Profile set by the user. Note that these are distinct from the Emotional changes that occur as a reaction to the user’s input.
Note: As part of a future update, we are working on exposing these values in all our advanced SDKs. Unity has access and outputs these value changes when they occur. In Unreal, a trigger is sent only when the relationship Label change occurs.

Studio Chat

Developers can enable dynamic relationships for a character under the Advanced -> Relationships menu of Studio - Edit Character UI. The slider affects the amount of change in the Qualities when detected by the character.

Relationship Slider

Track Character Relationships in Runtime

Unreal SDK

Relationships in Unreal SDK

At the moment, relationship changes are returned as a trigger from the On Trigger(Inworld Character) Node, and can be tied to other actions that may be triggered by the change in relationship such as a visual indicator (i.e hearts particle effect) or a change in the environment.

Example of the returned relationship label:

Trigger Name: inworld.relation.change
Trigger Params: {"label":"ACQUAINTANCE"}

Step values (numerical value changes in the various Qualities) at this time are not exposed in the Unreal Integration, we will work on making the value changes visible in Unreal as well, but currently only if the parameter changes entirely i.e ACQUAINTANCE to FRIEND, is the trigger sent.

Do note that similar to Long Term Memory, developers should Save the Session once a relationship change is detected in order for this change to persist. And when the project begins, a Restore from that Saved Session should be used in the StartSession node.

Unreal SDK Save Session

Unity SDK

In Unity, the relationship value changes for the Qualities are received and printed in the console, and as part of the Unity v3 SDK demo scenes you can see a visual representation of these value changes.

At the moment, relationship changes are returned as an event from the onRelationUpdated parameter of the InworldCharacter script. Similar to Unreal, you can listen to this event on an EventListener on other GameObjects and have other actions that may be triggered by the change in relationship as well.

Example of the returned Qualities changes detected in Unity, represented similarly to the Studio where each change is represented by green or red UI: Relationships in Unity SDK

As discussed above, you can also tie events to be fired or tie logic to the OnRelationUpdated() event that is thrown when there is a label change to the relationship detected by Inworld. Unity SDK Save Session

Relevant script snippets:

/// <summary>
/// Gets/Sets the charater's current relationship towards players. Will invoke onRelationUpdated when set.
/// </summary>
public RelationState CurrRelation
{
get => m_CurrentRelation;
set
{
if (m_VerboseLog)
InworldAI.Log($"{Name}: {m_CurrentRelation.GetUpdate(value)}");
m_CurrentRelation = value;
onRelationUpdated.Invoke();
}
}


protected virtual void ProcessPacket(InworldPacket incomingPacket)
{
onPacketReceived.Invoke(incomingPacket);
InworldController.Instance.CharacterInteract(incomingPacket);

switch (incomingPacket)
{
case ActionPacket actionPacket:
HandleAction(actionPacket);
break;
case AudioPacket audioPacket: // Already Played.
HandleLipSync(audioPacket);
break;
case ControlPacket controlPacket: // Interaction_End
break;
case TextPacket textPacket:
HandleText(textPacket);
break;
case EmotionPacket emotionPacket:
HandleEmotion(emotionPacket);
break;
case CustomPacket customPacket:
HandleTrigger(customPacket);
break;
case RelationPacket relationPacket:
HandleRelation(relationPacket);
break;
default:
Debug.LogError($"Received Unknown {incomingPacket}");
break;
}
}
protected virtual void HandleRelation(RelationPacket relationPacket) => CurrRelation = relationPacket.debugInfo.relation.relationUpdate;