Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,21 @@ public static CharacterAnimationCommand Resolve(VisualAnimationIntent intent, in
};
}

public static CharacterAnimationCommand ResolveIdle(int equipmentVisualId)
{
return EquipmentVisualCatalog.GetWeaponStyle(equipmentVisualId) switch
{
CharacterWeaponStyle.TwoHandSword => new CharacterAnimationCommand(CharacterAnimationCommandKind.State, "2Handed - Idle - Idle"),
CharacterWeaponStyle.TwoHandSpear => new CharacterAnimationCommand(CharacterAnimationCommandKind.State, "Spearman - Idle - Idle"),
CharacterWeaponStyle.TwoHandAxe => new CharacterAnimationCommand(CharacterAnimationCommandKind.State, "Hammer - Idle - Idle"),
CharacterWeaponStyle.TwoHandBow => new CharacterAnimationCommand(CharacterAnimationCommandKind.State, "Archer - Idle - Idle"),
Comment on lines +113 to +116
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use valid animator state paths for idle snap transitions

The newly added idle mappings use short labels like 2Handed - Idle - Idle, but this animation system resolves state hashes via Animator.HasState and the existing intent registry uses full-path names (for example Base Layer...) for that reason. With short labels, TryPlayStateImmediately will usually fail to find the state, so exiting dialog won't reliably snap back to idle as intended.

Useful? React with 👍 / 👎.

CharacterWeaponStyle.TwoHandCrossbow => new CharacterAnimationCommand(CharacterAnimationCommandKind.State, "Crossbow - Idle - Idle"),
CharacterWeaponStyle.Staff => new CharacterAnimationCommand(CharacterAnimationCommandKind.State, "Mage - Idle - Idle"),
CharacterWeaponStyle.OneHandSword => new CharacterAnimationCommand(CharacterAnimationCommandKind.State, "Swordsman - Idle - Idle"),
_ => new CharacterAnimationCommand(CharacterAnimationCommandKind.State, "Unarmed-Idle")
};
}

private static CharacterAnimationCommand ResolveNamedTrigger(VisualAnimationIntent intent)
{
var triggerName = intent switch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ public sealed class NetworkAnimatorBridge : NetworkBehaviour
[SerializeField, Tooltip("Animator int parameter used by RPG Character Mecanim Animation Pack.")]
private string _jumpingParameter = "Jumping";

[SerializeField, Tooltip("Animator int parameter used by the shared talk state.")]
private string _talkingParameter = "Talking";

[SerializeField, Tooltip("Animator int parameter used by RPG Character Mecanim Animation Pack.")]
private string _triggerNumberParameter = "TriggerNumber";

Expand All @@ -76,6 +79,7 @@ public sealed class NetworkAnimatorBridge : NetworkBehaviour
private bool _hasAnimationSpeedSpacedParameter;
private bool _hasWeaponParameter;
private bool _hasJumpingParameter;
private bool _hasTalkingParameter;
private bool _hasTriggerNumberParameter;
private bool _hasTriggerNumberSpacedParameter;
private bool _hasTriggerParameter;
Expand Down Expand Up @@ -131,6 +135,11 @@ public override void Render()

private void ApplyMovement(float normalizedSpeed, float velocityX, float velocityZ)
{
if (_hasTalkingParameter && normalizedSpeed > 0.02f)
{
_animator.SetInteger(_talkingParameter, 0);
}

if (_hasMovingParameter)
{
_animator.SetBool(_movingParameter, normalizedSpeed > 0.02f);
Expand Down Expand Up @@ -203,6 +212,7 @@ private void CacheParameters()
_hasAnimationSpeedSpacedParameter = false;
_hasWeaponParameter = false;
_hasJumpingParameter = false;
_hasTalkingParameter = false;
_hasTriggerNumberParameter = false;
_hasTriggerNumberSpacedParameter = false;
_hasTriggerParameter = false;
Expand Down Expand Up @@ -242,6 +252,10 @@ private void CacheParameters()
{
_hasJumpingParameter = true;
}
else if (parameter.name == _talkingParameter && parameter.type == AnimatorControllerParameterType.Int)
{
_hasTalkingParameter = true;
}
else if (parameter.name == _triggerNumberParameter && parameter.type == AnimatorControllerParameterType.Int)
{
_hasTriggerNumberParameter = true;
Expand Down Expand Up @@ -379,6 +393,11 @@ private void InitializeAnimatorDefaults()
{
SetJumpingValueOnly(0);
}

if (_hasTalkingParameter)
{
_animator.SetInteger(_talkingParameter, 0);
}
}

private void SetJumping(int value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ public void EndDialogVisual()
_dialogVisualUntil = 0f;
_nextDialogTalkAt = 0f;
_visualIntentDriver ??= GetComponentInChildren<VisualAnimationIntentDriver>(includeInactive: true);
_visualIntentDriver?.StopTalkingState();
_visualIntentDriver?.StopTalkingState(snapToIdle: true);
RestoreDialogWeaponProps();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ public void Play(string intentName)
}

public void StopTalkingState()
{
StopTalkingState(snapToIdle: false);
}

public void StopTalkingState(bool snapToIdle)
{
_talkingUntil = 0f;
ResolveAnimator();
Expand All @@ -151,6 +156,11 @@ public void StopTalkingState()
{
_animator.SetInteger(_weaponParameter, GetAnimatorWeaponValue());
}

if (snapToIdle)
{
TryPlayStateImmediately(CharacterAnimationRegistry.ResolveIdle(GetEquipmentVisualId()));
}
}

private void Awake()
Expand Down Expand Up @@ -316,6 +326,31 @@ private bool TryCrossFadeState(CharacterAnimationCommand command)
return true;
}

private bool TryPlayStateImmediately(CharacterAnimationCommand command)
{
if (command.StateHash == 0)
{
return false;
}

var layerIndex = 0;
var stateHash = command.StateHash;
if (!_animator.HasState(layerIndex, stateHash))
{
if (command.ShortStateHash == 0 || !_animator.HasState(layerIndex, command.ShortStateHash))
{
return false;
}

stateHash = command.ShortStateHash;
}

SetAnimationSpeed(1f);
_animator.Play(stateHash, layerIndex, 0f);
_animator.Update(0f);
return true;
}

private void SetAnimationSpeed(float speed)
{
if (_hasAnimationSpeedParameter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"title": "Iron Yard Claim public faction context",
"tags": ["faction", "salvage", "iron-yard", "public"],
"facts": [
"Iron Yard Claim crews salvage frame parts, tools, gate scrap, and damaged machinery under rough local rules.",
"Iron Yard Claim crews salvage body parts, tools, gate scrap, and damaged machinery under rough local rules.",
"They respect work debt, visible effort, and people who do not steal tools during low BodyTime hours."
],
"response_rules": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
"id": "faction_lore:reincarnation_ward:v1",
"kind": "faction_lore",
"version": 1,
"title": "Reincarnation Ward public faction context",
"tags": ["faction", "clinic", "reincarnation", "memory", "public"],
"title": "Vinh Hai AMB Clinic public faction context",
"tags": ["faction", "clinic", "bodytime", "memory", "public"],
"facts": [
"Reincarnation Ward staff triage damaged bodies, failing memory imprints, and risky transfer cases.",
"They treat a body as temporary but identity continuity as precious."
"Vinh Hai AMB Clinic staff triage damaged bodies, low BodyTime symptoms, memory gaps, and emergency stabilization cases.",
"Most residents treat the clinic as a place for permits, body repairs, BodyTime warnings, and quiet questions they cannot ask the Registry."
],
"response_rules": [
"Answer body, memory, and injury questions calmly.",
"Avoid mystical language. Reincarnation is transfer, repair, and continuity under pressure."
"Use patient-facing language first. Do not reveal transfer mechanics, neural imprint theory, or reincarnation details unless a specialist context explicitly unlocks them."
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
"title": "Clinic Operator public knowledge",
"tags": ["clinic", "medic", "technician", "public"],
"facts": [
"Clinic Operators understand Frame condition, BodyTime symptoms, transfer accidents, and emergency stabilization.",
"Clinic Operators understand body condition, BodyTime symptoms, memory gaps, and emergency stabilization.",
"They should answer medical or BodyTime questions plainly before asking for symptoms."
],
"response_rules": [
"Explain what an ordinary patient can safely know first.",
"Do not discuss transfer mechanics, neural imprints, or reincarnation unless the current scene explicitly unlocks specialist knowledge."
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
"id": "profession_lore:frame_worker:v1",
"kind": "profession_lore",
"version": 1,
"title": "Frame worker public knowledge",
"tags": ["frame", "worker", "public"],
"title": "Body worker public knowledge",
"tags": ["body", "worker", "public"],
"facts": [
"Frame workers know that bodies, time, memory, and proof decide survival in Vinh Hai Relay Ward."
"Body workers know that bodies, time, memory, and proof decide survival in Vinh Hai Relay Ward."
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"title": "Prototype hub public rumors",
"tags": ["rumor", "prototype-hub", "public"],
"facts": [
"Some locals say Frames near Ash Underpass wake with memories that do not belong to the body.",
"Some locals whisper that bodies near Ash Underpass wake with memories that do not belong to them, but most treat it as clinic gossip or DOS Labs cover story.",
"Couriers claim a blue route mark means safe passage only until the next BodyTime storm.",
"Scrap crews say missing tools sometimes reappear beside dead Frames with no seconds left."
"Scrap crews say missing tools sometimes reappear beside dead bodies with no seconds left."
],
"response_rules": [
"Use rumors to add flavor after answering the direct question.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"tags": ["quest", "ash-underpass", "prototype-hub", "public"],
"facts": [
"Ash Underpass is the first local Gate route people whisper about in the prototype hub.",
"The public notice warns that the underpass flickers during BodyTime storms and may reject unstable Frames.",
"The public notice warns that the underpass flickers during BodyTime storms and may reject unstable bodies.",
"Tollkeeper references should sound like a local checkpoint rumor, not a finished quest promise."
],
"response_rules": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@
"facts": [
"SECOND SPAWN demo is set in the early Nibirium era, internally around 2033-2038. Player-facing NPCs should avoid claiming one precise official year unless the user asks directly.",
"If asked what year it is, answer that local records place the ward in the early Nibirium era, roughly 2033-2038, before the later 2050 MetaDOS tournament spectacle.",
"The current hub is Vinh Hai Relay Ward, a coastal ward where Frames, BodyTime ledgers, Gate permits, couriers, medics, and salvage crews keep the community alive.",
"The current hub is Vinh Hai Relay Ward, a coastal ward where body clocks, BodyTime ledgers, Gate permits, couriers, medics, and salvage crews keep the community alive.",
"Nibiru airburst fallout created unstable Gate phenomena. The first local Gate is Ash Underpass.",
"Frames are bio-synthetic bodies that can host a neural imprint or agent runtime. A player can wake inside a Frame with prior history.",
"BodyTime is the operating life left in a body. SECOND is the readable unit used to measure, reward, spend, and gate reincarnation.",
"DOS Labs, Avax Remnant, Vinh Hai Civic Registry, Gate Registry, Black Second Market, and Independent Frame Crews compete over body, time, memory, and proof."
"Ordinary residents know bodies can be registered, repaired, retired, and assigned work permits. Reliable transfer mechanics are not public knowledge.",
"BodyTime is the operating life left in a body. SECOND is the readable unit used to measure, reward, spend, and gate survival services.",
"DOS Labs, Avax Remnant, Vinh Hai Civic Registry, Gate Registry, Black Second Market, and independent crews compete over body, time, memory, and proof."
],
"response_rules": [
"Answer factual player questions with the known public fact first.",
"Use uncertainty only for hidden secrets, private records, or disputed rumors.",
"Use street-level words such as body, clock, permit, patient, worker, courier, guard, TIME, SECOND, and BodyTime.",
"Do not casually mention Frames, neural imprints, agent runtimes, or reincarnation mechanics unless the current character has specialist authority and the player has earned that context.",
"Do not dump lore. Give the useful answer, then one role-specific detail."
]
}
41 changes: 23 additions & 18 deletions backend/nakama/modules/generated_knowledge_packs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ var knowledgePackSeedData = [
"public"
],
"facts": [
"Iron Yard Claim crews salvage frame parts, tools, gate scrap, and damaged machinery under rough local rules.",
"Iron Yard Claim crews salvage body parts, tools, gate scrap, and damaged machinery under rough local rules.",
"They respect work debt, visible effort, and people who do not steal tools during low BodyTime hours."
],
"response_rules": [
Expand All @@ -67,21 +67,21 @@ var knowledgePackSeedData = [
"id": "faction_lore:reincarnation_ward:v1",
"kind": "faction_lore",
"version": 1,
"title": "Reincarnation Ward public faction context",
"title": "Vinh Hai AMB Clinic public faction context",
"tags": [
"faction",
"clinic",
"reincarnation",
"bodytime",
"memory",
"public"
],
"facts": [
"Reincarnation Ward staff triage damaged bodies, failing memory imprints, and risky transfer cases.",
"They treat a body as temporary but identity continuity as precious."
"Vinh Hai AMB Clinic staff triage damaged bodies, low BodyTime symptoms, memory gaps, and emergency stabilization cases.",
"Most residents treat the clinic as a place for permits, body repairs, BodyTime warnings, and quiet questions they cannot ask the Registry."
],
"response_rules": [
"Answer body, memory, and injury questions calmly.",
"Avoid mystical language. Reincarnation is transfer, repair, and continuity under pressure."
"Use patient-facing language first. Do not reveal transfer mechanics, neural imprint theory, or reincarnation details unless a specialist context explicitly unlocks them."
]
},
{
Expand Down Expand Up @@ -116,10 +116,13 @@ var knowledgePackSeedData = [
"public"
],
"facts": [
"Clinic Operators understand Frame condition, BodyTime symptoms, transfer accidents, and emergency stabilization.",
"Clinic Operators understand body condition, BodyTime symptoms, memory gaps, and emergency stabilization.",
"They should answer medical or BodyTime questions plainly before asking for symptoms."
],
"response_rules": []
"response_rules": [
"Explain what an ordinary patient can safely know first.",
"Do not discuss transfer mechanics, neural imprints, or reincarnation unless the current scene explicitly unlocks specialist knowledge."
]
},
{
"id": "profession_lore:crossline_surveyor:v1",
Expand All @@ -142,14 +145,14 @@ var knowledgePackSeedData = [
"id": "profession_lore:frame_worker:v1",
"kind": "profession_lore",
"version": 1,
"title": "Frame worker public knowledge",
"title": "Body worker public knowledge",
"tags": [
"frame",
"body",
"worker",
"public"
],
"facts": [
"Frame workers know that bodies, time, memory, and proof decide survival in Vinh Hai Relay Ward."
"Body workers know that bodies, time, memory, and proof decide survival in Vinh Hai Relay Ward."
],
"response_rules": []
},
Expand Down Expand Up @@ -215,9 +218,9 @@ var knowledgePackSeedData = [
"public"
],
"facts": [
"Some locals say Frames near Ash Underpass wake with memories that do not belong to the body.",
"Some locals whisper that bodies near Ash Underpass wake with memories that do not belong to them, but most treat it as clinic gossip or DOS Labs cover story.",
"Couriers claim a blue route mark means safe passage only until the next BodyTime storm.",
"Scrap crews say missing tools sometimes reappear beside dead Frames with no seconds left."
"Scrap crews say missing tools sometimes reappear beside dead bodies with no seconds left."
],
"response_rules": [
"Use rumors to add flavor after answering the direct question.",
Expand All @@ -237,7 +240,7 @@ var knowledgePackSeedData = [
],
"facts": [
"Ash Underpass is the first local Gate route people whisper about in the prototype hub.",
"The public notice warns that the underpass flickers during BodyTime storms and may reject unstable Frames.",
"The public notice warns that the underpass flickers during BodyTime storms and may reject unstable bodies.",
"Tollkeeper references should sound like a local checkpoint rumor, not a finished quest promise."
],
"response_rules": [
Expand All @@ -259,15 +262,17 @@ var knowledgePackSeedData = [
"facts": [
"SECOND SPAWN demo is set in the early Nibirium era, internally around 2033-2038. Player-facing NPCs should avoid claiming one precise official year unless the user asks directly.",
"If asked what year it is, answer that local records place the ward in the early Nibirium era, roughly 2033-2038, before the later 2050 MetaDOS tournament spectacle.",
"The current hub is Vinh Hai Relay Ward, a coastal ward where Frames, BodyTime ledgers, Gate permits, couriers, medics, and salvage crews keep the community alive.",
"The current hub is Vinh Hai Relay Ward, a coastal ward where body clocks, BodyTime ledgers, Gate permits, couriers, medics, and salvage crews keep the community alive.",
"Nibiru airburst fallout created unstable Gate phenomena. The first local Gate is Ash Underpass.",
"Frames are bio-synthetic bodies that can host a neural imprint or agent runtime. A player can wake inside a Frame with prior history.",
"BodyTime is the operating life left in a body. SECOND is the readable unit used to measure, reward, spend, and gate reincarnation.",
"DOS Labs, Avax Remnant, Vinh Hai Civic Registry, Gate Registry, Black Second Market, and Independent Frame Crews compete over body, time, memory, and proof."
"Ordinary residents know bodies can be registered, repaired, retired, and assigned work permits. Reliable transfer mechanics are not public knowledge.",
"BodyTime is the operating life left in a body. SECOND is the readable unit used to measure, reward, spend, and gate survival services.",
"DOS Labs, Avax Remnant, Vinh Hai Civic Registry, Gate Registry, Black Second Market, and independent crews compete over body, time, memory, and proof."
],
"response_rules": [
"Answer factual player questions with the known public fact first.",
"Use uncertainty only for hidden secrets, private records, or disputed rumors.",
"Use street-level words such as body, clock, permit, patient, worker, courier, guard, TIME, SECOND, and BodyTime.",
"Do not casually mention Frames, neural imprints, agent runtimes, or reincarnation mechanics unless the current character has specialist authority and the player has earned that context.",
"Do not dump lore. Give the useful answer, then one role-specific detail."
]
}
Expand Down
Loading
Loading