perf: 전투 시뮬레이터 시작 payload를 줄인다
권위 실행 context를 화면 진입 때 한 번 전달하고 준비 응답은 seed base만 반환한다. 반복별 seed 배열은 결정적 파생값으로 대체하되 구형 queue seed 우선순위와 고정 seed 동작을 보존한다.
This commit is contained in:
@@ -4,6 +4,7 @@ import type { BattleSimOptions, GeneralDraft } from '../../utils/battleSimulator
|
||||
|
||||
interface Props {
|
||||
options: BattleSimOptions;
|
||||
crewTypes: Array<{ id: number; name: string; armType: number }>;
|
||||
mode: 'attacker' | 'defender';
|
||||
title: string;
|
||||
canImportServer: boolean;
|
||||
@@ -175,7 +176,7 @@ const officerLevelOptions = [
|
||||
<label class="field">
|
||||
<span>병종</span>
|
||||
<select v-model.number="general.crewtype">
|
||||
<option v-for="crew in options.unitSet.crewTypes" :key="crew.id" :value="crew.id">
|
||||
<option v-for="crew in crewTypes" :key="crew.id" :value="crew.id">
|
||||
{{ crew.name }}
|
||||
</option>
|
||||
</select>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import type { UnitSetDefinition, WarEngineConfig } from '@sammo-ts/logic';
|
||||
|
||||
export type InheritBuff = {
|
||||
warAvoidRatio: number;
|
||||
warCriticalRatio: number;
|
||||
@@ -47,16 +49,9 @@ export type BattleSimOptions = {
|
||||
currentYear: number;
|
||||
currentMonth: number;
|
||||
};
|
||||
config: {
|
||||
maxTrainByWar: number;
|
||||
maxAtmosByWar: number;
|
||||
maxTrainByCommand: number;
|
||||
maxAtmosByCommand: number;
|
||||
};
|
||||
unitSet: {
|
||||
defaultCrewTypeId: number;
|
||||
crewTypes: Array<{ id: number; name: string; armType: number }>;
|
||||
};
|
||||
config: WarEngineConfig;
|
||||
unitSet: UnitSetDefinition;
|
||||
scenarioEffect: string | null;
|
||||
nationTypes: Array<{ key: string; name: string; info: string }>;
|
||||
eventDomesticTraits: Array<{ key: string; name: string; info: string }>;
|
||||
warTraits: Array<{ key: string; name: string; info: string }>;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue';
|
||||
import { computed, onBeforeUnmount, onMounted, reactive, ref, shallowRef } from 'vue';
|
||||
import type { BattleSimRequestPayload, BattleSimResultPayload } from '@sammo-ts/game-api';
|
||||
import PanelCard from '../components/ui/PanelCard.vue';
|
||||
import SkeletonLines from '../components/ui/SkeletonLines.vue';
|
||||
@@ -33,7 +33,8 @@ type GeneralMeResponse = Awaited<ReturnType<typeof trpc.general.me.query>>;
|
||||
|
||||
const loading = ref(true);
|
||||
const error = ref<string | null>(null);
|
||||
const options = ref<BattleSimOptions | null>(null);
|
||||
// Worker execution data must stay outside Vue's deep reactive proxy graph so it remains structured-cloneable.
|
||||
const options = shallowRef<BattleSimOptions | null>(null);
|
||||
const battleResult = ref<BattleSimResultPayload | null>(null);
|
||||
|
||||
const attackerNation = reactive({
|
||||
@@ -83,6 +84,16 @@ const generalListLoading = ref(false);
|
||||
const selectedGeneralId = ref<number | null>(null);
|
||||
const gameDefaults = ref<GeneralMeResponse>(null);
|
||||
|
||||
const availableCrewTypes = computed(() => {
|
||||
const context = options.value;
|
||||
if (!context) {
|
||||
return [];
|
||||
}
|
||||
return (context.unitSet.crewTypes ?? [])
|
||||
.filter((crewType) => crewType.armType !== context.config.armTypes.castle)
|
||||
.map((crewType) => ({ id: crewType.id, name: crewType.name, armType: crewType.armType }));
|
||||
});
|
||||
|
||||
let generalIdSeed = 0;
|
||||
|
||||
const createInheritBuff = (): InheritBuff => ({
|
||||
@@ -125,7 +136,7 @@ const resolveGeneralNo = (preferred: number | null, excludeId?: string): number
|
||||
};
|
||||
|
||||
const createGeneralDraft = (overrides?: Partial<GeneralDraft>): GeneralDraft => {
|
||||
const baseCrew = options.value?.unitSet.defaultCrewTypeId ?? options.value?.unitSet.crewTypes[0]?.id ?? 1;
|
||||
const baseCrew = options.value?.unitSet.defaultCrewTypeId ?? availableCrewTypes.value[0]?.id ?? 1;
|
||||
const draft: GeneralDraft = {
|
||||
id: nextGeneralId(),
|
||||
no: 0,
|
||||
@@ -219,7 +230,7 @@ const applyGeneralExport = (target: GeneralDraft, data: GeneralExport) => {
|
||||
target.killcrew = data.killcrew;
|
||||
target.inheritBuff = data.inheritBuff ? { ...data.inheritBuff } : createInheritBuff();
|
||||
if (target.crewtype <= 0) {
|
||||
target.crewtype = options.value?.unitSet.defaultCrewTypeId ?? options.value?.unitSet.crewTypes[0]?.id ?? 1;
|
||||
target.crewtype = options.value?.unitSet.defaultCrewTypeId ?? availableCrewTypes.value[0]?.id ?? 1;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -590,8 +601,19 @@ const runSimulation = async (action: BattleSimRequestPayload['action']) => {
|
||||
|
||||
try {
|
||||
const payload = buildBattlePayload(action);
|
||||
const preparedPayload = await trpc.battle.prepareSimulation.mutate(payload);
|
||||
const result = await simulationWorker.run(preparedPayload);
|
||||
const preparation = await trpc.battle.prepareSimulation.mutate(payload);
|
||||
const result = await simulationWorker.run({
|
||||
...payload,
|
||||
...(preparation.seedBase ? { seedBase: preparation.seedBase } : {}),
|
||||
unitSet: options.value.unitSet,
|
||||
config: options.value.config,
|
||||
time: {
|
||||
year: payload.year,
|
||||
month: payload.month,
|
||||
startYear: options.value.world.startYear,
|
||||
},
|
||||
scenarioEffect: options.value.scenarioEffect,
|
||||
});
|
||||
|
||||
if (!result.result) {
|
||||
error.value = result.reason || 'battle_failed';
|
||||
@@ -1106,6 +1128,7 @@ const shouldShowUI = computed(() => !loading.value && !!options.value);
|
||||
v-model:general="attackerGeneral"
|
||||
data-parity-id="attacker-general"
|
||||
:options="options!"
|
||||
:crew-types="availableCrewTypes"
|
||||
mode="attacker"
|
||||
title="출병자 설정"
|
||||
:can-import-server="hasGameGeneral"
|
||||
@@ -1192,6 +1215,7 @@ const shouldShowUI = computed(() => !loading.value && !!options.value);
|
||||
v-model:general="defenders[index]"
|
||||
:data-parity-id="index === 0 ? 'defender-general' : `defender-general-${index + 1}`"
|
||||
:options="options!"
|
||||
:crew-types="availableCrewTypes"
|
||||
mode="defender"
|
||||
title="수비자 설정"
|
||||
:can-import-server="hasGameGeneral"
|
||||
|
||||
Reference in New Issue
Block a user