fix(event-catalog): update camera setting for laughing event and refine narrative logic
- Set camera property to false for the laughing event in the event catalog - Update documentation for StoryDecisionIntentLive to clarify intent handling - Refactor narrative exposure ledger to improve combat and consequence management - Enhance interest feeds to prevent premature relationship milestone publishing - Adjust narrative story store limits for runtime events and characters
This commit is contained in:
parent
c9000531fc
commit
4becf1c5dc
7 changed files with 178 additions and 62 deletions
|
|
@ -166,6 +166,7 @@ public static partial class EventCatalog
|
||||||
|| s.Contains("fireworks")
|
|| s.Contains("fireworks")
|
||||||
|| s.Contains("put_out_fire")
|
|| s.Contains("put_out_fire")
|
||||||
|| s.Contains("burn_tumors")
|
|| s.Contains("burn_tumors")
|
||||||
|
|| s.Contains("sexual_reproduction")
|
||||||
|| s.Contains("asexual_reproduction")
|
|| s.Contains("asexual_reproduction")
|
||||||
|| s.Contains("take_city_item")
|
|| s.Contains("take_city_item")
|
||||||
|| s.Contains("try_to_steal")
|
|| s.Contains("try_to_steal")
|
||||||
|
|
|
||||||
|
|
@ -683,6 +683,17 @@ public static class InterestFeeds
|
||||||
|
|
||||||
long sid = SafeId(subject);
|
long sid = SafeId(subject);
|
||||||
long rid = SafeId(related);
|
long rid = SafeId(related);
|
||||||
|
bool relationshipMilestone =
|
||||||
|
milestoneKey.Equals("milestone_friend", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| milestoneKey.Equals("milestone_lover", StringComparison.OrdinalIgnoreCase);
|
||||||
|
// Chronicle rebuilds can observe one side of a relationship before the partner has
|
||||||
|
// finished loading. Do not publish a two-person sentence until both visual owners exist.
|
||||||
|
if (relationshipMilestone
|
||||||
|
&& (related == null || !related.isAlive() || rid == 0))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
string cameraLabel = label ?? milestoneKey;
|
string cameraLabel = label ?? milestoneKey;
|
||||||
if (milestoneKey.Equals("milestone_kill", StringComparison.OrdinalIgnoreCase))
|
if (milestoneKey.Equals("milestone_kill", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2801,7 +2801,8 @@ internal static class HarnessScenarios
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Live DeferredInterestFeed EmitDecision path cools intent class (not only harness inject).
|
/// Reproduction intent is not a story beat. The live DeferredInterestFeed path must
|
||||||
|
/// reject it before registry intake and leave the camera free for confirmed outcomes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static List<HarnessCommand> StoryDecisionIntentLive()
|
private static List<HarnessCommand> StoryDecisionIntentLive()
|
||||||
{
|
{
|
||||||
|
|
@ -2820,20 +2821,11 @@ internal static class HarnessScenarios
|
||||||
Step("sdl9", "interest_end_session"),
|
Step("sdl9", "interest_end_session"),
|
||||||
Step("sdl10", "interest_variety_clear"),
|
Step("sdl10", "interest_variety_clear"),
|
||||||
Step("sdl11", "interest_story_clear"),
|
Step("sdl11", "interest_story_clear"),
|
||||||
Step("sdl20", "decision_emit", expect: "sexual_reproduction_try"),
|
Step("sdl20", "assert", expect: "decision_worthy",
|
||||||
Step("sdl21", "director_run", wait: 1.2f),
|
value: "sexual_reproduction_try", label: "false"),
|
||||||
Step("sdl22", "assert", expect: "tip_contains", value: "try to reproduce"),
|
Step("sdl21", "decision_emit", expect: "sexual_reproduction_try"),
|
||||||
Step("sdl23", "assert", expect: "beat_cooled", value: "sexual_reproduction_try"),
|
Step("sdl22", "director_run", wait: 1.2f),
|
||||||
Step("sdl24", "assert", expect: "beat_cooled", value: "decision_find_lover"),
|
Step("sdl23", "assert", expect: "tip_not_contains", value: "reproduce"),
|
||||||
Step("sdl25", "interest_end_session"),
|
|
||||||
Step("sdl26", "interest_story_clear"),
|
|
||||||
Step("sdl30", "decision_emit", expect: "find_lover"),
|
|
||||||
Step("sdl31", "interest_inject", asset: "human", label: "ClearPeer", tier: "Action",
|
|
||||||
expect: "sdl_peer", value: "lead=event;evt=70;char=5;force=false;ttl=60"),
|
|
||||||
Step("sdl32", "director_run", wait: 1.2f),
|
|
||||||
Step("sdl33", "assert", expect: "tip_contains", value: "ClearPeer"),
|
|
||||||
Step("sdl34", "assert", expect: "tip_not_contains", value: "reproduce"),
|
|
||||||
Step("sdl35", "assert", expect: "tip_not_contains", value: "find a lover"),
|
|
||||||
Step("sdl90", "fast_timing", value: "false"),
|
Step("sdl90", "fast_timing", value: "false"),
|
||||||
Step("sdl99", "snapshot"),
|
Step("sdl99", "snapshot"),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,13 @@ public static class NarrativeExposureLedger
|
||||||
new Dictionary<long, Exposure>();
|
new Dictionary<long, Exposure>();
|
||||||
private static readonly Dictionary<string, Exposure> Threads =
|
private static readonly Dictionary<string, Exposure> Threads =
|
||||||
new Dictionary<string, Exposure>(StringComparer.Ordinal);
|
new Dictionary<string, Exposure>(StringComparer.Ordinal);
|
||||||
private static readonly List<bool> PresentedCuts = new List<bool>(6);
|
private static readonly List<bool> PresentedCuts = new List<bool>(9);
|
||||||
private static int _maxCharacterCuts;
|
private static int _maxCharacterCuts;
|
||||||
private static int _maxThreadCuts;
|
private static int _maxThreadCuts;
|
||||||
private static int _combatRun;
|
private static int _combatRun;
|
||||||
private const int PresentedWindow = 6;
|
private const int PresentedWindow = 9;
|
||||||
private const int CombatWindowBudget = 2;
|
private const int CombatWindowBudget = 3;
|
||||||
private const int CombatRunBudget = 2;
|
private const int CombatRunBudget = 3;
|
||||||
|
|
||||||
public static void Clear()
|
public static void Clear()
|
||||||
{
|
{
|
||||||
|
|
@ -90,9 +90,10 @@ public static class NarrativeExposureLedger
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Two combat cuts may establish and escalate a conflict; another story family must
|
/// Three combat cuts may establish, escalate, and resolve a conflict; another story
|
||||||
/// then receive space. Criticality affects which combat cut wins, not whether combat
|
/// family must then receive space. The rolling window also holds combat to one third
|
||||||
/// may exceed the global story-first exposure budget.
|
/// of authored cuts. Criticality affects which combat cut wins, not whether combat may
|
||||||
|
/// exceed the global story-first exposure budget.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool MayPresent(InterestCandidate candidate)
|
public static bool MayPresent(InterestCandidate candidate)
|
||||||
{
|
{
|
||||||
|
|
@ -150,20 +151,34 @@ public static class NarrativeExposureLedger
|
||||||
};
|
};
|
||||||
NotePresented(combat);
|
NotePresented(combat);
|
||||||
NotePresented(combat);
|
NotePresented(combat);
|
||||||
|
NotePresented(combat);
|
||||||
bool routineBlocked = !MayPresent(combat);
|
bool routineBlocked = !MayPresent(combat);
|
||||||
bool criticalBounded = !MayPresent(criticalCombat);
|
bool criticalBounded = !MayPresent(criticalCombat);
|
||||||
for (int i = 0; i < 5; i++) NotePresented(family);
|
for (int i = 0; i < PresentedWindow; i++) NotePresented(family);
|
||||||
bool routineReopened = MayPresent(combat);
|
bool routineReopened = MayPresent(combat);
|
||||||
|
Clear();
|
||||||
|
var activityCombat = new InterestCandidate
|
||||||
|
{
|
||||||
|
Completion = InterestCompletionKind.ActivityActive,
|
||||||
|
Category = "Combat",
|
||||||
|
Label = "Aro is fighting Bex",
|
||||||
|
EventStrength = 70f
|
||||||
|
};
|
||||||
|
NotePresented(activityCombat);
|
||||||
|
NotePresented(activityCombat);
|
||||||
|
NotePresented(activityCombat);
|
||||||
|
bool activityCombatBounded = !MayPresent(activityCombat);
|
||||||
bool ok = underCovered > prolific
|
bool ok = underCovered > prolific
|
||||||
&& repetition > 0f
|
&& repetition > 0f
|
||||||
&& diverse == 0f
|
&& diverse == 0f
|
||||||
&& routineBlocked
|
&& routineBlocked
|
||||||
&& criticalBounded
|
&& criticalBounded
|
||||||
&& routineReopened;
|
&& routineReopened
|
||||||
|
&& activityCombatBounded;
|
||||||
detail = "debt=" + underCovered.ToString("0.0") + "/" + prolific.ToString("0.0")
|
detail = "debt=" + underCovered.ToString("0.0") + "/" + prolific.ToString("0.0")
|
||||||
+ " repetition=" + repetition.ToString("0.0") + "/" + diverse.ToString("0.0")
|
+ " repetition=" + repetition.ToString("0.0") + "/" + diverse.ToString("0.0")
|
||||||
+ " combat=" + routineBlocked + "/" + criticalBounded
|
+ " combat=" + routineBlocked + "/" + criticalBounded
|
||||||
+ "/" + routineReopened
|
+ "/" + routineReopened + "/" + activityCombatBounded
|
||||||
+ " pass=" + ok;
|
+ " pass=" + ok;
|
||||||
Clear();
|
Clear();
|
||||||
return ok;
|
return ok;
|
||||||
|
|
@ -196,18 +211,33 @@ public static class NarrativeExposureLedger
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsCombat(InterestCandidate candidate)
|
internal static bool IsCombat(InterestCandidate candidate)
|
||||||
{
|
{
|
||||||
return candidate != null
|
if (candidate == null)
|
||||||
&& (candidate.Completion == InterestCompletionKind.CombatActive
|
{
|
||||||
|| candidate.Completion == InterestCompletionKind.WarFront
|
return false;
|
||||||
|| string.Equals(
|
}
|
||||||
candidate.AssetId,
|
|
||||||
"live_combat",
|
if (candidate.Completion == InterestCompletionKind.CombatActive
|
||||||
StringComparison.OrdinalIgnoreCase)
|
|| candidate.Completion == InterestCompletionKind.WarFront
|
||||||
|| string.Equals(
|
|| string.Equals(candidate.Category, "Combat", StringComparison.OrdinalIgnoreCase)
|
||||||
candidate.AssetId,
|
|| string.Equals(candidate.AssetId, "live_combat", StringComparison.OrdinalIgnoreCase)
|
||||||
"live_battle",
|
|| string.Equals(candidate.AssetId, "live_battle", StringComparison.OrdinalIgnoreCase)
|
||||||
StringComparison.OrdinalIgnoreCase));
|
|| (!string.IsNullOrEmpty(candidate.Verb)
|
||||||
|
&& candidate.Verb.IndexOf("fight", StringComparison.OrdinalIgnoreCase) >= 0))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
string label = candidate.Label ?? "";
|
||||||
|
return label.StartsWith("Duel", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| label.StartsWith("Skirmish", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| label.StartsWith("Battle", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| label.StartsWith("Mass", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| label.IndexOf(" fighting ", StringComparison.OrdinalIgnoreCase) >= 0
|
||||||
|
|| label.IndexOf(" in a fight", StringComparison.OrdinalIgnoreCase) >= 0
|
||||||
|
|| (label.IndexOf(" vs ", StringComparison.OrdinalIgnoreCase) >= 0
|
||||||
|
&& !label.StartsWith("War -", StringComparison.OrdinalIgnoreCase)
|
||||||
|
&& !label.StartsWith("Plot -", StringComparison.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,15 @@ public static class NarrativeStoryStore
|
||||||
private const int DevelopmentsPerThread = 16;
|
private const int DevelopmentsPerThread = 16;
|
||||||
private const int MaxRuntimeEvents = 2200;
|
private const int MaxRuntimeEvents = 2200;
|
||||||
private const int MaxRuntimeDevelopments = 2000;
|
private const int MaxRuntimeDevelopments = 2000;
|
||||||
private const int MaxRuntimeThreads = 650;
|
private const int MaxRuntimeThreads = 512;
|
||||||
private const int MaxRuntimeConsequences = 1200;
|
private const int MaxRuntimeConsequences = 1200;
|
||||||
private const int MaxRuntimeCharacters = 2000;
|
private const int MaxRuntimeCharacters = 2000;
|
||||||
|
// Saga/episode consequences are retained independently. Anonymous history competes
|
||||||
|
// for this smaller editorial budget so it cannot pin one character per world event.
|
||||||
|
private const int MaxAmbientRuntimeConsequences = 192;
|
||||||
|
// Character states referenced by retained story material are always kept. Beyond
|
||||||
|
// those, retain only a small bench of strong emerging challengers.
|
||||||
|
private const int MaxEmergingRuntimeCharacters = 64;
|
||||||
private const float RuntimeCompactionIntervalSeconds = 60f;
|
private const float RuntimeCompactionIntervalSeconds = 60f;
|
||||||
internal const int SchedulerCandidateLimit = 96;
|
internal const int SchedulerCandidateLimit = 96;
|
||||||
internal const int SchedulerCopyLimit = 128;
|
internal const int SchedulerCopyLimit = 128;
|
||||||
|
|
@ -736,6 +742,10 @@ public static class NarrativeStoryStore
|
||||||
AddExistingIds(state.OpenThreadIds, Threads, retainedThreadIds);
|
AddExistingIds(state.OpenThreadIds, Threads, retainedThreadIds);
|
||||||
AddExistingIds(state.ResolvedThreadIds, Threads, retainedThreadIds);
|
AddExistingIds(state.ResolvedThreadIds, Threads, retainedThreadIds);
|
||||||
}
|
}
|
||||||
|
// Snapshot the authored spine before ambient challengers fill the runtime budget.
|
||||||
|
// Consequences belonging to these threads remain lossless.
|
||||||
|
var protectedThreadIds =
|
||||||
|
new HashSet<string>(retainedThreadIds, StringComparer.Ordinal);
|
||||||
|
|
||||||
ThreadScratch.Clear();
|
ThreadScratch.Clear();
|
||||||
foreach (NarrativeThread thread in Threads.Values)
|
foreach (NarrativeThread thread in Threads.Values)
|
||||||
|
|
@ -775,8 +785,10 @@ public static class NarrativeStoryStore
|
||||||
var rankedConsequences = new List<CharacterConsequence>(Consequences.Values);
|
var rankedConsequences = new List<CharacterConsequence>(Consequences.Values);
|
||||||
rankedConsequences.Sort((a, b) =>
|
rankedConsequences.Sort((a, b) =>
|
||||||
{
|
{
|
||||||
bool aProtected = a != null && protectedCharacters.Contains(a.CharacterId);
|
bool aProtected = IsProtectedConsequence(
|
||||||
bool bProtected = b != null && protectedCharacters.Contains(b.CharacterId);
|
a, protectedCharacters, protectedThreadIds);
|
||||||
|
bool bProtected = IsProtectedConsequence(
|
||||||
|
b, protectedCharacters, protectedThreadIds);
|
||||||
if (aProtected != bProtected) return aProtected ? -1 : 1;
|
if (aProtected != bProtected) return aProtected ? -1 : 1;
|
||||||
int importance = (b?.Importance ?? float.MinValue).CompareTo(
|
int importance = (b?.Importance ?? float.MinValue).CompareTo(
|
||||||
a?.Importance ?? float.MinValue);
|
a?.Importance ?? float.MinValue);
|
||||||
|
|
@ -786,26 +798,38 @@ public static class NarrativeStoryStore
|
||||||
});
|
});
|
||||||
|
|
||||||
var retainedConsequenceIds = new HashSet<string>(StringComparer.Ordinal);
|
var retainedConsequenceIds = new HashSet<string>(StringComparer.Ordinal);
|
||||||
|
int protectedConsequences = 0;
|
||||||
|
int ambientConsequences = 0;
|
||||||
for (int i = 0;
|
for (int i = 0;
|
||||||
i < rankedConsequences.Count
|
i < rankedConsequences.Count
|
||||||
&& retainedConsequenceIds.Count < MaxRuntimeConsequences;
|
&& retainedConsequenceIds.Count < MaxRuntimeConsequences;
|
||||||
i++)
|
i++)
|
||||||
{
|
{
|
||||||
CharacterConsequence consequence = rankedConsequences[i];
|
CharacterConsequence consequence = rankedConsequences[i];
|
||||||
if (consequence == null || string.IsNullOrEmpty(consequence.Id)
|
bool protectedConsequence = IsProtectedConsequence(
|
||||||
|| string.IsNullOrEmpty(consequence.DevelopmentId)
|
consequence, protectedCharacters, protectedThreadIds);
|
||||||
|| !Developments.ContainsKey(consequence.DevelopmentId))
|
if (!protectedConsequence
|
||||||
{
|
&& ambientConsequences >= MaxAmbientRuntimeConsequences)
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!retainedDevelopmentIds.Contains(consequence.DevelopmentId)
|
|
||||||
&& retainedDevelopmentIds.Count >= MaxRuntimeDevelopments)
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
retainedDevelopmentIds.Add(consequence.DevelopmentId);
|
if (!TryRetainConsequence(
|
||||||
retainedConsequenceIds.Add(consequence.Id);
|
consequence,
|
||||||
|
retainedDevelopmentIds,
|
||||||
|
retainedConsequenceIds))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (protectedConsequence)
|
||||||
|
{
|
||||||
|
protectedConsequences++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ambientConsequences++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var rankedDevelopments = new List<NarrativeDevelopment>(Developments.Values);
|
var rankedDevelopments = new List<NarrativeDevelopment>(Developments.Values);
|
||||||
|
|
@ -875,11 +899,6 @@ public static class NarrativeStoryStore
|
||||||
{
|
{
|
||||||
if (consequence == null) continue;
|
if (consequence == null) continue;
|
||||||
if (consequence.CharacterId != 0) retainedCharacterIds.Add(consequence.CharacterId);
|
if (consequence.CharacterId != 0) retainedCharacterIds.Add(consequence.CharacterId);
|
||||||
if (consequence.OtherId != 0
|
|
||||||
&& retainedCharacterIds.Count < MaxRuntimeCharacters)
|
|
||||||
{
|
|
||||||
retainedCharacterIds.Add(consequence.OtherId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var rankedCharacters = new List<CharacterStoryState>(Characters.Values);
|
var rankedCharacters = new List<CharacterStoryState>(Characters.Values);
|
||||||
|
|
@ -892,9 +911,12 @@ public static class NarrativeStoryStore
|
||||||
return (b?.LastMeaningfulChangeAt ?? float.MinValue).CompareTo(
|
return (b?.LastMeaningfulChangeAt ?? float.MinValue).CompareTo(
|
||||||
a?.LastMeaningfulChangeAt ?? float.MinValue);
|
a?.LastMeaningfulChangeAt ?? float.MinValue);
|
||||||
});
|
});
|
||||||
|
int emergingLimit = Math.Min(
|
||||||
|
MaxRuntimeCharacters,
|
||||||
|
retainedCharacterIds.Count + MaxEmergingRuntimeCharacters);
|
||||||
for (int i = 0;
|
for (int i = 0;
|
||||||
i < rankedCharacters.Count
|
i < rankedCharacters.Count
|
||||||
&& retainedCharacterIds.Count < MaxRuntimeCharacters;
|
&& retainedCharacterIds.Count < emergingLimit;
|
||||||
i++)
|
i++)
|
||||||
{
|
{
|
||||||
CharacterStoryState state = rankedCharacters[i];
|
CharacterStoryState state = rankedCharacters[i];
|
||||||
|
|
@ -918,6 +940,7 @@ public static class NarrativeStoryStore
|
||||||
+ " developments=" + beforeDevelopments + "->" + Developments.Count
|
+ " developments=" + beforeDevelopments + "->" + Developments.Count
|
||||||
+ " threads=" + beforeThreads + "->" + Threads.Count
|
+ " threads=" + beforeThreads + "->" + Threads.Count
|
||||||
+ " consequences=" + beforeConsequences + "->" + Consequences.Count
|
+ " consequences=" + beforeConsequences + "->" + Consequences.Count
|
||||||
|
+ " consequenceMix=" + protectedConsequences + "/" + ambientConsequences
|
||||||
+ " characters=" + beforeCharacters + "->" + Characters.Count
|
+ " characters=" + beforeCharacters + "->" + Characters.Count
|
||||||
+ " ms=" + LastCompactionMs.ToString("0.0"));
|
+ " ms=" + LastCompactionMs.ToString("0.0"));
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -954,6 +977,45 @@ public static class NarrativeStoryStore
|
||||||
+ development.Confidence * 5f;
|
+ development.Confidence * 5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool IsProtectedConsequence(
|
||||||
|
CharacterConsequence consequence,
|
||||||
|
HashSet<long> protectedCharacters,
|
||||||
|
HashSet<string> protectedThreadIds)
|
||||||
|
{
|
||||||
|
if (consequence == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (protectedCharacters != null
|
||||||
|
&& (protectedCharacters.Contains(consequence.CharacterId)
|
||||||
|
|| (consequence.OtherId != 0
|
||||||
|
&& protectedCharacters.Contains(consequence.OtherId))))
|
||||||
|
|| (protectedThreadIds != null
|
||||||
|
&& !string.IsNullOrEmpty(consequence.ThreadId)
|
||||||
|
&& protectedThreadIds.Contains(consequence.ThreadId));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryRetainConsequence(
|
||||||
|
CharacterConsequence consequence,
|
||||||
|
HashSet<string> retainedDevelopmentIds,
|
||||||
|
HashSet<string> retainedConsequenceIds)
|
||||||
|
{
|
||||||
|
if (consequence == null
|
||||||
|
|| string.IsNullOrEmpty(consequence.Id)
|
||||||
|
|| string.IsNullOrEmpty(consequence.DevelopmentId)
|
||||||
|
|| !Developments.ContainsKey(consequence.DevelopmentId)
|
||||||
|
|| (!retainedDevelopmentIds.Contains(consequence.DevelopmentId)
|
||||||
|
&& retainedDevelopmentIds.Count >= MaxRuntimeDevelopments))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
retainedDevelopmentIds.Add(consequence.DevelopmentId);
|
||||||
|
retainedConsequenceIds.Add(consequence.Id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private static void AddExistingId<T>(
|
private static void AddExistingId<T>(
|
||||||
string id,
|
string id,
|
||||||
Dictionary<string, T> source,
|
Dictionary<string, T> source,
|
||||||
|
|
@ -1212,6 +1274,7 @@ public static class NarrativeStoryStore
|
||||||
|
|
||||||
const int importedDevelopments = 2300;
|
const int importedDevelopments = 2300;
|
||||||
const int importedThreads = 900;
|
const int importedThreads = 900;
|
||||||
|
const int importedConsequences = 1300;
|
||||||
for (int i = 0; i < importedDevelopments; i++)
|
for (int i = 0; i < importedDevelopments; i++)
|
||||||
{
|
{
|
||||||
string developmentId = "probe:compact:development:" + i;
|
string developmentId = "probe:compact:development:" + i;
|
||||||
|
|
@ -1259,6 +1322,18 @@ public static class NarrativeStoryStore
|
||||||
thread.AddCast(i + 1, "protagonist");
|
thread.AddCast(i + 1, "protagonist");
|
||||||
ImportThread(thread);
|
ImportThread(thread);
|
||||||
}
|
}
|
||||||
|
if (i < importedConsequences)
|
||||||
|
{
|
||||||
|
ImportConsequence(new CharacterConsequence
|
||||||
|
{
|
||||||
|
Id = "probe:compact:consequence:" + i,
|
||||||
|
CharacterId = i + 1,
|
||||||
|
DevelopmentId = developmentId,
|
||||||
|
Kind = CharacterConsequenceKind.FoundHome,
|
||||||
|
OccurredAt = i + 1,
|
||||||
|
Importance = 50f
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compacted = CompactRuntimeGraph(force: true);
|
bool compacted = CompactRuntimeGraph(force: true);
|
||||||
|
|
@ -1278,13 +1353,23 @@ public static class NarrativeStoryStore
|
||||||
&& Threads.Count <= MaxRuntimeThreads
|
&& Threads.Count <= MaxRuntimeThreads
|
||||||
&& Consequences.Count <= MaxRuntimeConsequences
|
&& Consequences.Count <= MaxRuntimeConsequences
|
||||||
&& Characters.Count <= MaxRuntimeCharacters;
|
&& Characters.Count <= MaxRuntimeCharacters;
|
||||||
|
bool leanCharacters =
|
||||||
|
Characters.Count <= MaxRuntimeThreads
|
||||||
|
+ MaxAmbientRuntimeConsequences
|
||||||
|
+ MaxEmergingRuntimeCharacters;
|
||||||
|
bool leanConsequences =
|
||||||
|
Consequences.Count <= MaxAmbientRuntimeConsequences;
|
||||||
bool ok = ambientGraphDeferred && authoredBirthProjected && authoredHomeProjected
|
bool ok = ambientGraphDeferred && authoredBirthProjected && authoredHomeProjected
|
||||||
&& compacted && bounded && graphClosed && newestThreadKept;
|
&& compacted && bounded && leanCharacters && leanConsequences
|
||||||
|
&& graphClosed && newestThreadKept;
|
||||||
detail = "events=" + NarrativeEventStore.Count + "/" + MaxRuntimeEvents
|
detail = "events=" + NarrativeEventStore.Count + "/" + MaxRuntimeEvents
|
||||||
+ " developments=" + Developments.Count + "/" + MaxRuntimeDevelopments
|
+ " developments=" + Developments.Count + "/" + MaxRuntimeDevelopments
|
||||||
+ " threads=" + Threads.Count + "/" + MaxRuntimeThreads
|
+ " threads=" + Threads.Count + "/" + MaxRuntimeThreads
|
||||||
+ " consequences=" + Consequences.Count + "/" + MaxRuntimeConsequences
|
+ " consequences=" + Consequences.Count + "/" + MaxRuntimeConsequences
|
||||||
|
+ " ambientBudget=" + MaxAmbientRuntimeConsequences
|
||||||
+ " characters=" + Characters.Count + "/" + MaxRuntimeCharacters
|
+ " characters=" + Characters.Count + "/" + MaxRuntimeCharacters
|
||||||
|
+ " leanCharacters=" + leanCharacters
|
||||||
|
+ " leanConsequences=" + leanConsequences
|
||||||
+ " newest=" + newestThreadKept
|
+ " newest=" + newestThreadKept
|
||||||
+ " closed=" + graphClosed
|
+ " closed=" + graphClosed
|
||||||
+ " deferred=" + ambientGraphDeferred
|
+ " deferred=" + ambientGraphDeferred
|
||||||
|
|
|
||||||
|
|
@ -574,10 +574,7 @@ public static class StoryScheduler
|
||||||
|
|
||||||
private static bool IsCombatShot(InterestCandidate candidate)
|
private static bool IsCombatShot(InterestCandidate candidate)
|
||||||
{
|
{
|
||||||
return candidate != null
|
return NarrativeExposureLedger.IsCombat(candidate);
|
||||||
&& (candidate.Completion == InterestCompletionKind.CombatActive
|
|
||||||
|| string.Equals(candidate.AssetId, "live_combat", System.StringComparison.OrdinalIgnoreCase)
|
|
||||||
|| string.Equals(candidate.AssetId, "live_battle", System.StringComparison.OrdinalIgnoreCase));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static string SemanticFamily(InterestCandidate candidate)
|
internal static string SemanticFamily(InterestCandidate candidate)
|
||||||
|
|
|
||||||
|
|
@ -1824,7 +1824,7 @@
|
||||||
"id": "laughing",
|
"id": "laughing",
|
||||||
"strength": 34,
|
"strength": 34,
|
||||||
"category": "StatusAmbient",
|
"category": "StatusAmbient",
|
||||||
"camera": true,
|
"camera": false,
|
||||||
"extendsGrief": false
|
"extendsGrief": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue