forked from profectus/Profectus
Fix NaN detection
Also removes the proxy around player and cleaned up types
This commit is contained in:
parent
8c8f7f7904
commit
f5a25b2c2d
9 changed files with 130 additions and 158 deletions
|
@ -14,9 +14,12 @@
|
|||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<a :href="discordLink" class="nan-modal-discord-link">
|
||||
<a
|
||||
:href="discordLink || 'https://discord.gg/WzejVAx'"
|
||||
class="nan-modal-discord-link"
|
||||
>
|
||||
<span class="material-icons nan-modal-discord">discord</span>
|
||||
{{ discordName }}
|
||||
{{ discordName || "The Paper Pilot Community" }}
|
||||
</a>
|
||||
</div>
|
||||
<br />
|
||||
|
@ -50,49 +53,51 @@ import state from "game/state";
|
|||
import type { DecimalSource } from "util/bignum";
|
||||
import Decimal, { format } from "util/bignum";
|
||||
import type { ComponentPublicInstance } from "vue";
|
||||
import { computed, ref, toRef } from "vue";
|
||||
import { computed, ref, toRef, watch } from "vue";
|
||||
import Toggle from "./fields/Toggle.vue";
|
||||
import SavesManager from "./SavesManager.vue";
|
||||
|
||||
const { discordName, discordLink } = projInfo;
|
||||
const autosave = toRef(player, "autosave");
|
||||
const autosave = ref(true);
|
||||
const isPaused = ref(true);
|
||||
const hasNaN = toRef(state, "hasNaN");
|
||||
const savesManager = ref<ComponentPublicInstance<typeof SavesManager> | null>(null);
|
||||
|
||||
const path = computed(() => state.NaNPath?.join("."));
|
||||
const property = computed(() => state.NaNPath?.slice(-1)[0]);
|
||||
const previous = computed<DecimalSource | null>(() => {
|
||||
if (state.NaNReceiver && property.value != null) {
|
||||
return state.NaNReceiver[property.value] as DecimalSource;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
const isPaused = computed({
|
||||
get() {
|
||||
return player.devSpeed === 0;
|
||||
},
|
||||
set(value: boolean) {
|
||||
player.devSpeed = value ? null : 0;
|
||||
watch(hasNaN, hasNaN => {
|
||||
if (hasNaN) {
|
||||
autosave.value = player.autosave;
|
||||
isPaused.value = player.devSpeed === 0;
|
||||
} else {
|
||||
player.autosave = autosave.value;
|
||||
player.devSpeed = isPaused.value ? 0 : null;
|
||||
}
|
||||
});
|
||||
|
||||
const path = computed(() => state.NaNPath?.join("."));
|
||||
const previous = computed<DecimalSource | null>(() => {
|
||||
if (state.NaNPersistent != null) {
|
||||
return state.NaNPersistent.value;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
function setZero() {
|
||||
if (state.NaNReceiver && property.value != null) {
|
||||
state.NaNReceiver[property.value] = new Decimal(0);
|
||||
if (state.NaNPersistent != null) {
|
||||
state.NaNPersistent.value = new Decimal(0);
|
||||
state.hasNaN = false;
|
||||
}
|
||||
}
|
||||
|
||||
function setOne() {
|
||||
if (state.NaNReceiver && property.value != null) {
|
||||
state.NaNReceiver[property.value] = new Decimal(1);
|
||||
if (state.NaNPersistent) {
|
||||
state.NaNPersistent.value = new Decimal(1);
|
||||
state.hasNaN = false;
|
||||
}
|
||||
}
|
||||
|
||||
function ignore() {
|
||||
if (state.NaNReceiver && property.value != null) {
|
||||
state.NaNReceiver[property.value] = new Decimal(NaN);
|
||||
if (state.NaNPersistent) {
|
||||
state.NaNPersistent.value = new Decimal(NaN);
|
||||
state.hasNaN = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,11 +59,10 @@
|
|||
<script setup lang="ts">
|
||||
import Modal from "components/Modal.vue";
|
||||
import projInfo from "data/projInfo.json";
|
||||
import type { PlayerData } from "game/player";
|
||||
import type { Player } from "game/player";
|
||||
import player, { stringifySave } from "game/player";
|
||||
import settings from "game/settings";
|
||||
import LZString from "lz-string";
|
||||
import { ProxyState } from "util/proxies";
|
||||
import { getUniqueID, loadSave, newSave, save } from "util/save";
|
||||
import type { ComponentPublicInstance } from "vue";
|
||||
import { computed, nextTick, ref, shallowReactive, watch } from "vue";
|
||||
|
@ -72,7 +71,7 @@ import Select from "./fields/Select.vue";
|
|||
import Text from "./fields/Text.vue";
|
||||
import Save from "./Save.vue";
|
||||
|
||||
export type LoadablePlayerData = Omit<Partial<PlayerData>, "id"> & { id: string; error?: unknown };
|
||||
export type LoadablePlayerData = Omit<Partial<Player>, "id"> & { id: string; error?: unknown };
|
||||
|
||||
const isOpen = ref(false);
|
||||
const modal = ref<ComponentPublicInstance<typeof Modal> | null>(null);
|
||||
|
@ -195,7 +194,7 @@ const saves = computed(() =>
|
|||
function exportSave(id: string) {
|
||||
let saveToExport;
|
||||
if (player.id === id) {
|
||||
saveToExport = stringifySave(player[ProxyState]);
|
||||
saveToExport = stringifySave(player);
|
||||
} else {
|
||||
saveToExport = JSON.stringify(saves.value[id]);
|
||||
}
|
||||
|
@ -228,7 +227,7 @@ function duplicateSave(id: string) {
|
|||
}
|
||||
|
||||
const playerData = { ...saves.value[id], id: getUniqueID() };
|
||||
save(playerData as PlayerData);
|
||||
save(playerData as Player);
|
||||
|
||||
settings.saves.push(playerData.id);
|
||||
}
|
||||
|
@ -272,7 +271,7 @@ function newFromPreset(preset: string) {
|
|||
}
|
||||
const playerData = JSON.parse(preset);
|
||||
playerData.id = getUniqueID();
|
||||
save(playerData as PlayerData);
|
||||
save(playerData as Player);
|
||||
|
||||
settings.saves.push(playerData.id);
|
||||
|
||||
|
@ -287,7 +286,7 @@ function editSave(id: string, newName: string) {
|
|||
player.name = newName;
|
||||
save();
|
||||
} else {
|
||||
save(currSave as PlayerData);
|
||||
save(currSave as Player);
|
||||
cachedSaves[id] = undefined;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import { branchedResetPropagation, createTree } from "features/trees/tree";
|
|||
import { globalBus } from "game/events";
|
||||
import type { BaseLayer, GenericLayer } from "game/layers";
|
||||
import { createLayer } from "game/layers";
|
||||
import type { PlayerData } from "game/player";
|
||||
import type { Player } from "game/player";
|
||||
import player from "game/player";
|
||||
import type { DecimalSource } from "util/bignum";
|
||||
import Decimal, { format, formatTime } from "util/bignum";
|
||||
|
@ -79,7 +79,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
|||
*/
|
||||
export const getInitialLayers = (
|
||||
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
|
||||
player: Partial<PlayerData>
|
||||
player: Partial<Player>
|
||||
): Array<GenericLayer> => [main, prestige];
|
||||
|
||||
/**
|
||||
|
@ -97,7 +97,7 @@ export const hasWon = computed(() => {
|
|||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
export function fixOldSave(
|
||||
oldVersion: string | undefined,
|
||||
player: Partial<PlayerData>
|
||||
player: Partial<Player>
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
): void {}
|
||||
/* eslint-enable @typescript-eslint/no-unused-vars */
|
||||
|
|
|
@ -7,6 +7,8 @@ import Decimal from "util/bignum";
|
|||
import { ProxyState } from "util/proxies";
|
||||
import type { Ref, WritableComputedRef } from "vue";
|
||||
import { computed, isReactive, isRef, ref } from "vue";
|
||||
import player from "./player";
|
||||
import state from "./state";
|
||||
|
||||
/**
|
||||
* A symbol used in {@link Persistent} objects.
|
||||
|
@ -56,6 +58,7 @@ export type State =
|
|||
* A {@link Ref} that has been augmented with properties to allow it to be saved and loaded within the player save data object.
|
||||
*/
|
||||
export type Persistent<T extends State = State> = Ref<T> & {
|
||||
value: T;
|
||||
/** A flag that this is a persistent property. Typically a circular reference. */
|
||||
[PersistentState]: Ref<T>;
|
||||
/** The value the ref should be set to in a fresh save, or when updating an old save to the current version. */
|
||||
|
@ -89,31 +92,65 @@ function getStackTrace() {
|
|||
);
|
||||
}
|
||||
|
||||
function checkNaNAndWrite<T extends State>(persistent: Persistent<T>, value: T) {
|
||||
// Decimal is smart enough to return false on things that aren't supposed to be numbers
|
||||
if (Decimal.isNaN(value as DecimalSource)) {
|
||||
if (!state.hasNaN) {
|
||||
player.autosave = false;
|
||||
state.hasNaN = true;
|
||||
state.NaNPath = persistent[SaveDataPath];
|
||||
state.NaNPersistent = persistent as Persistent<DecimalSource>;
|
||||
}
|
||||
console.error(
|
||||
`Attempted to save NaN value to`,
|
||||
persistent[SaveDataPath]?.join("."),
|
||||
persistent
|
||||
);
|
||||
throw "Attempted to set NaN value. See above for details";
|
||||
}
|
||||
persistent[PersistentState].value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a persistent ref, which can be saved and loaded.
|
||||
* All (non-deleted) persistent refs must be included somewhere within the layer object returned by that layer's options func.
|
||||
* @param defaultValue The value the persistent ref should start at on fresh saves or when reset.
|
||||
*/
|
||||
export function persistent<T extends State>(defaultValue: T | Ref<T>): Persistent<T> {
|
||||
const persistent = (
|
||||
isRef(defaultValue) ? defaultValue : (ref<T>(defaultValue) as unknown)
|
||||
) as Persistent<T>;
|
||||
const persistentState: Ref<T> = isRef(defaultValue)
|
||||
? defaultValue
|
||||
: (ref<T>(defaultValue) as Ref<T>);
|
||||
|
||||
persistent[PersistentState] = persistent;
|
||||
persistent[DefaultValue] = isRef(defaultValue) ? defaultValue.value : defaultValue;
|
||||
persistent[StackTrace] = getStackTrace();
|
||||
persistent[Deleted] = false;
|
||||
const nonPersistent: Partial<NonPersistent<T>> = computed({
|
||||
if (isRef(defaultValue)) {
|
||||
defaultValue = defaultValue.value;
|
||||
}
|
||||
|
||||
const nonPersistent = computed({
|
||||
get() {
|
||||
return persistent.value;
|
||||
return persistentState.value;
|
||||
},
|
||||
set(value) {
|
||||
persistent.value = value;
|
||||
checkNaNAndWrite(persistent, value);
|
||||
}
|
||||
});
|
||||
nonPersistent[DefaultValue] = persistent[DefaultValue];
|
||||
persistent[NonPersistent] = nonPersistent as NonPersistent<T>;
|
||||
persistent[SaveDataPath] = undefined;
|
||||
}) as NonPersistent<T>;
|
||||
nonPersistent[DefaultValue] = defaultValue;
|
||||
|
||||
// We're trying to mock a vue ref, which means the type expects a private [RefSymbol] property that we can't access, but the actual implementation of isRef just checks for `__v_isRef`
|
||||
const persistent = {
|
||||
get value() {
|
||||
return persistentState.value as T;
|
||||
},
|
||||
set value(value: T) {
|
||||
checkNaNAndWrite(persistent, value);
|
||||
},
|
||||
__v_isRef: true,
|
||||
[PersistentState]: persistentState,
|
||||
[DefaultValue]: defaultValue,
|
||||
[StackTrace]: getStackTrace(),
|
||||
[Deleted]: false,
|
||||
[NonPersistent]: nonPersistent,
|
||||
[SaveDataPath]: undefined
|
||||
} as unknown as Persistent<T>;
|
||||
|
||||
if (addingLayers.length === 0) {
|
||||
console.warn(
|
||||
|
@ -125,7 +162,7 @@ export function persistent<T extends State>(defaultValue: T | Ref<T>): Persisten
|
|||
persistentRefs[addingLayers[addingLayers.length - 1]].add(persistent);
|
||||
}
|
||||
|
||||
return persistent as Persistent<T>;
|
||||
return persistent;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
import { isPlainObject } from "is-plain-object";
|
||||
import Decimal from "util/bignum";
|
||||
import type { ProxiedWithState } from "util/proxies";
|
||||
import { ProxyPath, ProxyState } from "util/proxies";
|
||||
import { reactive, unref } from "vue";
|
||||
import type { Ref } from "vue";
|
||||
import transientState from "./state";
|
||||
import { reactive, unref } from "vue";
|
||||
|
||||
/** The player save data object. */
|
||||
export interface PlayerData {
|
||||
export interface Player {
|
||||
/** The ID of this save. */
|
||||
id: string;
|
||||
/** A multiplier for time passing. Set to 0 when the game is paused. */
|
||||
|
@ -36,9 +31,6 @@ export interface PlayerData {
|
|||
layers: Record<string, LayerData<unknown>>;
|
||||
}
|
||||
|
||||
/** The proxied player that is used to track NaN values. */
|
||||
export type Player = ProxiedWithState<PlayerData>;
|
||||
|
||||
/** A layer's save data. Automatically unwraps refs. */
|
||||
export type LayerData<T> = {
|
||||
[P in keyof T]?: T[P] extends (infer U)[]
|
||||
|
@ -52,7 +44,7 @@ export type LayerData<T> = {
|
|||
: T[P];
|
||||
};
|
||||
|
||||
const state = reactive<PlayerData>({
|
||||
const player = reactive<Player>({
|
||||
id: "",
|
||||
devSpeed: null,
|
||||
name: "",
|
||||
|
@ -68,90 +60,16 @@ const state = reactive<PlayerData>({
|
|||
layers: {}
|
||||
});
|
||||
|
||||
export default window.player = player;
|
||||
|
||||
/** Convert a player save data object into a JSON string. Unwraps refs. */
|
||||
export function stringifySave(player: PlayerData): string {
|
||||
export function stringifySave(player: Player): string {
|
||||
return JSON.stringify(player, (key, value) => unref(value));
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const playerHandler: ProxyHandler<Record<PropertyKey, any>> = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
get(target: Record<PropertyKey, any>, key: PropertyKey): any {
|
||||
if (key === ProxyState || key === ProxyPath) {
|
||||
return target[key];
|
||||
}
|
||||
|
||||
const value = target[ProxyState][key];
|
||||
if (key !== "value" && (isPlainObject(value) || Array.isArray(value))) {
|
||||
if (value !== target[key]?.[ProxyState]) {
|
||||
const path = [...target[ProxyPath], key];
|
||||
target[key] = new Proxy({ [ProxyState]: value, [ProxyPath]: path }, playerHandler);
|
||||
}
|
||||
return target[key];
|
||||
}
|
||||
|
||||
return value;
|
||||
},
|
||||
set(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
target: Record<PropertyKey, any>,
|
||||
property: PropertyKey,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
value: any,
|
||||
receiver: ProxyConstructor
|
||||
): boolean {
|
||||
if (
|
||||
!transientState.hasNaN &&
|
||||
((typeof value === "number" && isNaN(value)) ||
|
||||
(value instanceof Decimal &&
|
||||
(isNaN(value.sign) || isNaN(value.layer) || isNaN(value.mag))))
|
||||
) {
|
||||
const currentValue = target[ProxyState][property];
|
||||
if (
|
||||
!(
|
||||
(typeof currentValue === "number" && isNaN(currentValue)) ||
|
||||
(currentValue instanceof Decimal &&
|
||||
(isNaN(currentValue.sign) ||
|
||||
isNaN(currentValue.layer) ||
|
||||
isNaN(currentValue.mag)))
|
||||
)
|
||||
) {
|
||||
state.autosave = false;
|
||||
transientState.hasNaN = true;
|
||||
transientState.NaNPath = [...target[ProxyPath], property];
|
||||
transientState.NaNReceiver = receiver as unknown as Record<string, unknown>;
|
||||
console.error(
|
||||
`Attempted to set NaN value`,
|
||||
[...target[ProxyPath], property],
|
||||
target[ProxyState]
|
||||
);
|
||||
throw "Attempted to set NaN value. See above for details";
|
||||
}
|
||||
}
|
||||
target[ProxyState][property] = value;
|
||||
return true;
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
ownKeys(target: Record<PropertyKey, any>) {
|
||||
return Reflect.ownKeys(target[ProxyState]);
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
has(target: Record<PropertyKey, any>, key: string) {
|
||||
return Reflect.has(target[ProxyState], key);
|
||||
},
|
||||
getOwnPropertyDescriptor(target, key) {
|
||||
return Object.getOwnPropertyDescriptor(target[ProxyState], key);
|
||||
}
|
||||
};
|
||||
|
||||
declare global {
|
||||
/** Augment the window object so the player can be accessed from the console. */
|
||||
interface Window {
|
||||
player: Player;
|
||||
}
|
||||
}
|
||||
/** The player save data object. */
|
||||
export default window.player = new Proxy(
|
||||
{ [ProxyState]: state, [ProxyPath]: ["player"] },
|
||||
playerHandler
|
||||
) as Player;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import type { DecimalSource } from "util/bignum";
|
||||
import { shallowReactive } from "vue";
|
||||
import type { Persistent } from "./persistence";
|
||||
|
||||
/** An object of global data that is not persistent. */
|
||||
export interface Transient {
|
||||
|
@ -8,8 +10,8 @@ export interface Transient {
|
|||
hasNaN: boolean;
|
||||
/** The location within the player save data object of the NaN value. */
|
||||
NaNPath?: string[];
|
||||
/** The parent object of the NaN value. */
|
||||
NaNReceiver?: Record<string, unknown>;
|
||||
/** The ref that was being set to NaN. */
|
||||
NaNPersistent?: Persistent<DecimalSource>;
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import type { JSXFunction } from "features/feature";
|
||||
import { isFunction } from "util/common";
|
||||
import type { Ref } from "vue";
|
||||
import { computed } from "vue";
|
||||
import { isFunction } from "util/common";
|
||||
|
||||
export const DoNotCache = Symbol("DoNotCache");
|
||||
|
||||
|
@ -32,21 +33,22 @@ export function processComputable<T, S extends keyof ComputableKeysOf<T>>(
|
|||
key: S
|
||||
): asserts obj is T & { [K in S]: ProcessedComputable<UnwrapComputableType<T[S]>> } {
|
||||
const computable = obj[key];
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
if (isFunction(computable) && computable.length === 0 && !(computable as any)[DoNotCache]) {
|
||||
if (
|
||||
isFunction(computable) &&
|
||||
computable.length === 0 &&
|
||||
!(computable as unknown as JSXFunction)[DoNotCache]
|
||||
) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
obj[key] = computed(computable.bind(obj));
|
||||
} else if (isFunction(computable)) {
|
||||
obj[key] = computable.bind(obj) as unknown as T[S];
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(obj[key] as any)[DoNotCache] = true;
|
||||
(obj[key] as unknown as JSXFunction)[DoNotCache] = true;
|
||||
}
|
||||
}
|
||||
|
||||
export function convertComputable<T>(obj: Computable<T>): ProcessedComputable<T> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
if (isFunction(obj) && !(obj as any)[DoNotCache]) {
|
||||
if (isFunction(obj) && !(obj as unknown as JSXFunction)[DoNotCache]) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
obj = computed(obj);
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import type { Persistent } from "game/persistence";
|
||||
import { NonPersistent } from "game/persistence";
|
||||
import Decimal from "util/bignum";
|
||||
|
||||
export const ProxyState = Symbol("ProxyState");
|
||||
export const ProxyPath = Symbol("ProxyPath");
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export type ProxiedWithState<T> = NonNullable<T> extends Record<PropertyKey, any>
|
||||
export type ProxiedWithState<T> = NonNullable<T> extends Record<PropertyKey, unknown>
|
||||
? NonNullable<T> extends Decimal
|
||||
? T
|
||||
: {
|
||||
|
@ -16,6 +16,18 @@ export type ProxiedWithState<T> = NonNullable<T> extends Record<PropertyKey, any
|
|||
}
|
||||
: T;
|
||||
|
||||
export type Proxied<T> = NonNullable<T> extends Record<PropertyKey, unknown>
|
||||
? NonNullable<T> extends Persistent<infer S>
|
||||
? NonPersistent<S>
|
||||
: NonNullable<T> extends Decimal
|
||||
? T
|
||||
: {
|
||||
[K in keyof T]: Proxied<T[K]>;
|
||||
} & {
|
||||
[ProxyState]: T;
|
||||
}
|
||||
: T;
|
||||
|
||||
// Takes a function that returns an object and pretends to be that object
|
||||
// Note that the object is lazily calculated
|
||||
export function createLazyProxy<T extends object, S extends T>(
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import projInfo from "data/projInfo.json";
|
||||
import { globalBus } from "game/events";
|
||||
import type { Player, PlayerData } from "game/player";
|
||||
import type { Player } from "game/player";
|
||||
import player, { stringifySave } from "game/player";
|
||||
import settings, { loadSettings } from "game/settings";
|
||||
import LZString from "lz-string";
|
||||
import { ProxyState } from "util/proxies";
|
||||
import { ref } from "vue";
|
||||
|
||||
export function setupInitialStore(player: Partial<PlayerData> = {}): Player {
|
||||
export function setupInitialStore(player: Partial<Player> = {}): Player {
|
||||
return Object.assign(
|
||||
{
|
||||
id: `${projInfo.id}-0`,
|
||||
|
@ -27,11 +26,9 @@ export function setupInitialStore(player: Partial<PlayerData> = {}): Player {
|
|||
) as Player;
|
||||
}
|
||||
|
||||
export function save(playerData?: PlayerData): string {
|
||||
const stringifiedSave = LZString.compressToUTF16(
|
||||
stringifySave(playerData ?? player[ProxyState])
|
||||
);
|
||||
localStorage.setItem((playerData ?? player[ProxyState]).id, stringifiedSave);
|
||||
export function save(playerData?: Player): string {
|
||||
const stringifiedSave = LZString.compressToUTF16(stringifySave(playerData ?? player));
|
||||
localStorage.setItem((playerData ?? player).id, stringifiedSave);
|
||||
return stringifiedSave;
|
||||
}
|
||||
|
||||
|
@ -70,7 +67,7 @@ export async function load(): Promise<void> {
|
|||
}
|
||||
}
|
||||
|
||||
export function newSave(): PlayerData {
|
||||
export function newSave(): Player {
|
||||
const id = getUniqueID();
|
||||
const player = setupInitialStore({ id });
|
||||
save(player);
|
||||
|
@ -91,7 +88,7 @@ export function getUniqueID(): string {
|
|||
|
||||
export const loadingSave = ref(false);
|
||||
|
||||
export async function loadSave(playerObj: Partial<PlayerData>): Promise<void> {
|
||||
export async function loadSave(playerObj: Partial<Player>): Promise<void> {
|
||||
console.info("Loading save", playerObj);
|
||||
loadingSave.value = true;
|
||||
const { layers, removeLayer, addLayer } = await import("game/layers");
|
||||
|
|
Loading…
Reference in a new issue