refactor(runtime): expose canonical gameplay state
Move character options and movement skills into the Runtime-owned character graph, expose borrowed inventory, character, and social views, and route retained UI state commands through generation-gated typed Runtime contracts. Preserve the existing synchronous wire path while deleting the App-owned option and skill mirrors and extending normalized parity checkpoints. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
9d0d9b07e0
commit
dcb61efb5a
34 changed files with 2076 additions and 103 deletions
|
|
@ -1,5 +1,6 @@
|
|||
using AcDream.App.UI;
|
||||
using AcDream.Core.Chat;
|
||||
using AcDream.Core.Items;
|
||||
using AcDream.Core.Net.Messages;
|
||||
using AcDream.Runtime.Session;
|
||||
using AcDream.UI.Abstractions;
|
||||
|
|
@ -15,8 +16,64 @@ internal sealed record LiveSessionCommandBindings(
|
|||
Action<string, string> SendTell,
|
||||
Action<uint, string> SendChannel,
|
||||
Action<uint, uint, uint, uint, string, uint> SendTurbineChat,
|
||||
Action<ShortcutEntry> AddShortcut,
|
||||
Action<uint> RemoveShortcut,
|
||||
Action<uint, int, int> AddFavorite,
|
||||
Action<uint, int> RemoveFavorite,
|
||||
Action<uint> SetSpellbookFilter,
|
||||
Action<uint> ForgetSpell,
|
||||
Action<uint, uint> SetDesiredComponent,
|
||||
Action ClearDesiredComponents,
|
||||
Action<uint, ulong> RaiseAttribute,
|
||||
Action<uint, ulong> RaiseVital,
|
||||
Action<uint, ulong> RaiseSkill,
|
||||
Action<uint, uint> TrainSkill,
|
||||
Action<uint> SetCharacterOptions,
|
||||
Action<string> AddFriend,
|
||||
Action<uint> RemoveFriend,
|
||||
Action ClearFriends,
|
||||
Action RequestLegacyFriends,
|
||||
Action<bool, uint, string, uint> ModifyCharacterSquelch,
|
||||
Action<bool, string> ModifyAccountSquelch,
|
||||
Action<bool, uint> ModifyGlobalSquelch,
|
||||
Action<string>? Log = null);
|
||||
|
||||
internal readonly record struct AddShortcutRuntimeCmd(ShortcutEntry Entry);
|
||||
internal readonly record struct RemoveShortcutRuntimeCmd(uint Index);
|
||||
internal readonly record struct AddFavoriteRuntimeCmd(
|
||||
uint SpellId,
|
||||
int Position,
|
||||
int TabIndex);
|
||||
internal readonly record struct RemoveFavoriteRuntimeCmd(
|
||||
uint SpellId,
|
||||
int TabIndex);
|
||||
internal readonly record struct SetSpellbookFilterRuntimeCmd(uint Filters);
|
||||
internal readonly record struct ForgetSpellRuntimeCmd(uint SpellId);
|
||||
internal readonly record struct SetDesiredComponentRuntimeCmd(
|
||||
uint ComponentId,
|
||||
uint Amount);
|
||||
internal readonly record struct ClearDesiredComponentsRuntimeCmd;
|
||||
internal readonly record struct RaiseAttributeRuntimeCmd(uint StatId, ulong Cost);
|
||||
internal readonly record struct RaiseVitalRuntimeCmd(uint StatId, ulong Cost);
|
||||
internal readonly record struct RaiseSkillRuntimeCmd(uint StatId, ulong Cost);
|
||||
internal readonly record struct TrainSkillRuntimeCmd(uint StatId, uint Cost);
|
||||
internal readonly record struct SetCharacterOptionsRuntimeCmd(uint Options);
|
||||
internal readonly record struct AddFriendRuntimeCmd(string Name);
|
||||
internal readonly record struct RemoveFriendRuntimeCmd(uint CharacterId);
|
||||
internal readonly record struct ClearFriendsRuntimeCmd;
|
||||
internal readonly record struct RequestLegacyFriendsRuntimeCmd;
|
||||
internal readonly record struct ModifyCharacterSquelchRuntimeCmd(
|
||||
bool Add,
|
||||
uint CharacterId,
|
||||
string Name,
|
||||
uint MessageType);
|
||||
internal readonly record struct ModifyAccountSquelchRuntimeCmd(
|
||||
bool Add,
|
||||
string Name);
|
||||
internal readonly record struct ModifyGlobalSquelchRuntimeCmd(
|
||||
bool Add,
|
||||
uint MessageType);
|
||||
|
||||
/// <summary>
|
||||
/// Owns the command surface for one exact live-session generation. The router
|
||||
/// itself is the published bus, so a retained reference becomes inert before
|
||||
|
|
@ -52,6 +109,68 @@ internal sealed class LiveSessionCommandRouter : ILiveSessionCommandRouting
|
|||
SendIfActive(() => bindings.SendTalk(command.Text));
|
||||
});
|
||||
commands.Register<SendChatCmd>(command => RouteChat(bindings, command));
|
||||
commands.Register<AddShortcutRuntimeCmd>(
|
||||
command => SendIfActive(() => bindings.AddShortcut(command.Entry)));
|
||||
commands.Register<RemoveShortcutRuntimeCmd>(
|
||||
command => SendIfActive(() => bindings.RemoveShortcut(command.Index)));
|
||||
commands.Register<AddFavoriteRuntimeCmd>(
|
||||
command => SendIfActive(() => bindings.AddFavorite(
|
||||
command.SpellId,
|
||||
command.Position,
|
||||
command.TabIndex)));
|
||||
commands.Register<RemoveFavoriteRuntimeCmd>(
|
||||
command => SendIfActive(() => bindings.RemoveFavorite(
|
||||
command.SpellId,
|
||||
command.TabIndex)));
|
||||
commands.Register<SetSpellbookFilterRuntimeCmd>(
|
||||
command => SendIfActive(() =>
|
||||
bindings.SetSpellbookFilter(command.Filters)));
|
||||
commands.Register<ForgetSpellRuntimeCmd>(
|
||||
command => SendIfActive(() => bindings.ForgetSpell(command.SpellId)));
|
||||
commands.Register<SetDesiredComponentRuntimeCmd>(
|
||||
command => SendIfActive(() => bindings.SetDesiredComponent(
|
||||
command.ComponentId,
|
||||
command.Amount)));
|
||||
commands.Register<ClearDesiredComponentsRuntimeCmd>(
|
||||
_ => SendIfActive(bindings.ClearDesiredComponents));
|
||||
commands.Register<RaiseAttributeRuntimeCmd>(
|
||||
command => SendIfActive(() =>
|
||||
bindings.RaiseAttribute(command.StatId, command.Cost)));
|
||||
commands.Register<RaiseVitalRuntimeCmd>(
|
||||
command => SendIfActive(() =>
|
||||
bindings.RaiseVital(command.StatId, command.Cost)));
|
||||
commands.Register<RaiseSkillRuntimeCmd>(
|
||||
command => SendIfActive(() =>
|
||||
bindings.RaiseSkill(command.StatId, command.Cost)));
|
||||
commands.Register<TrainSkillRuntimeCmd>(
|
||||
command => SendIfActive(() =>
|
||||
bindings.TrainSkill(command.StatId, command.Cost)));
|
||||
commands.Register<SetCharacterOptionsRuntimeCmd>(
|
||||
command => SendIfActive(() =>
|
||||
bindings.SetCharacterOptions(command.Options)));
|
||||
commands.Register<AddFriendRuntimeCmd>(
|
||||
command => SendIfActive(() => bindings.AddFriend(command.Name)));
|
||||
commands.Register<RemoveFriendRuntimeCmd>(
|
||||
command => SendIfActive(() =>
|
||||
bindings.RemoveFriend(command.CharacterId)));
|
||||
commands.Register<ClearFriendsRuntimeCmd>(
|
||||
_ => SendIfActive(bindings.ClearFriends));
|
||||
commands.Register<RequestLegacyFriendsRuntimeCmd>(
|
||||
_ => SendIfActive(bindings.RequestLegacyFriends));
|
||||
commands.Register<ModifyCharacterSquelchRuntimeCmd>(
|
||||
command => SendIfActive(() => bindings.ModifyCharacterSquelch(
|
||||
command.Add,
|
||||
command.CharacterId,
|
||||
command.Name,
|
||||
command.MessageType)));
|
||||
commands.Register<ModifyAccountSquelchRuntimeCmd>(
|
||||
command => SendIfActive(() => bindings.ModifyAccountSquelch(
|
||||
command.Add,
|
||||
command.Name)));
|
||||
commands.Register<ModifyGlobalSquelchRuntimeCmd>(
|
||||
command => SendIfActive(() => bindings.ModifyGlobalSquelch(
|
||||
command.Add,
|
||||
command.MessageType)));
|
||||
_commands = commands;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,9 +36,7 @@ namespace AcDream.App.Net;
|
|||
internal sealed record LiveSessionPlayerRuntime(
|
||||
LocalPlayerIdentityState Identity,
|
||||
LocalPlayerControllerSlot Controller,
|
||||
LocalPlayerSkillState Skills,
|
||||
LiveWorldOriginState WorldOrigin,
|
||||
PlayerCharacterOptionsState CharacterOptions);
|
||||
LiveWorldOriginState WorldOrigin);
|
||||
|
||||
internal sealed record LiveSessionDomainRuntime(
|
||||
RuntimeEntityObjectLifetime EntityObjects,
|
||||
|
|
@ -215,8 +213,8 @@ internal sealed class LiveSessionRuntimeFactory
|
|||
_domain.Communication.ResetChatIdentity();
|
||||
EntityVanishProbe.PlayerGuid = 0u;
|
||||
_interaction.Settings.ResetActiveCharacterKey();
|
||||
_player.CharacterOptions.Reset();
|
||||
_player.Skills.ResetSession();
|
||||
_domain.Character.Options.ResetSession();
|
||||
_domain.Character.MovementSkills.ResetSession();
|
||||
_world.NetworkUpdates.ResetSessionState();
|
||||
_world.Hydration.ResetSessionState();
|
||||
_domain.Inventory.ResetPlayerSnapshots();
|
||||
|
|
@ -282,27 +280,22 @@ internal sealed class LiveSessionRuntimeFactory
|
|||
ResolveSkillFormulaBonus: skillCreditResolver.Resolve,
|
||||
OnSkillsUpdated: (runSkill, jumpSkill) =>
|
||||
{
|
||||
_player.Skills.Update(
|
||||
runSkill,
|
||||
jumpSkill,
|
||||
_player.Controller.Controller);
|
||||
if (_player.Skills.IsComplete
|
||||
&& _player.Controller.Controller is not null)
|
||||
if (LocalPlayerSkillProjection.ApplyTo(
|
||||
_domain.Character.MovementSkills,
|
||||
_player.Controller.Controller))
|
||||
{
|
||||
RuntimeMovementSkillSnapshot snapshot =
|
||||
_domain.Character.MovementSkills.Snapshot;
|
||||
_log(
|
||||
$"player: applied server skills " +
|
||||
$"run={_player.Skills.RunSkill} " +
|
||||
$"jump={_player.Skills.JumpSkill}");
|
||||
$"run={snapshot.RunSkill} " +
|
||||
$"jump={snapshot.JumpSkill}");
|
||||
}
|
||||
},
|
||||
OnConfirmationRequest: request =>
|
||||
_ui.RetailUi?.HandleConfirmationRequest(request),
|
||||
OnConfirmationDone: done =>
|
||||
_ui.RetailUi?.HandleConfirmationDone(done),
|
||||
OnCharacterOptions: (options1, _) =>
|
||||
_player.CharacterOptions.Options =
|
||||
(Core.Net.Messages.PlayerDescriptionParser.CharacterOptions1)
|
||||
options1,
|
||||
ClientTime: ClientTimerNow);
|
||||
}
|
||||
|
||||
|
|
@ -391,6 +384,26 @@ internal sealed class LiveSessionRuntimeFactory
|
|||
senderGuid,
|
||||
text,
|
||||
cookie),
|
||||
AddShortcut: session.SendAddShortcut,
|
||||
RemoveShortcut: session.SendRemoveShortcut,
|
||||
AddFavorite: session.SendAddSpellFavorite,
|
||||
RemoveFavorite: session.SendRemoveSpellFavorite,
|
||||
SetSpellbookFilter: session.SendSpellbookFilter,
|
||||
ForgetSpell: session.SendRemoveSpell,
|
||||
SetDesiredComponent: session.SendSetDesiredComponentLevel,
|
||||
ClearDesiredComponents: session.SendClearDesiredComponents,
|
||||
RaiseAttribute: session.SendRaiseAttribute,
|
||||
RaiseVital: session.SendRaiseVital,
|
||||
RaiseSkill: session.SendRaiseSkill,
|
||||
TrainSkill: session.SendTrainSkill,
|
||||
SetCharacterOptions: session.SendSetCharacterOptions,
|
||||
AddFriend: session.SendAddFriend,
|
||||
RemoveFriend: session.SendRemoveFriend,
|
||||
ClearFriends: session.SendClearFriends,
|
||||
RequestLegacyFriends: session.SendLegacyFriendsListRequest,
|
||||
ModifyCharacterSquelch: session.SendModifyCharacterSquelch,
|
||||
ModifyAccountSquelch: session.SendModifyAccountSquelch,
|
||||
ModifyGlobalSquelch: session.SendModifyGlobalSquelch,
|
||||
Log: _log);
|
||||
|
||||
private static double ClientTimerNow() =>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue