Skip to content

💾 战局存档:关掉浏览器不该从头再来 / Save & resume the war #6

Description

@longmaolab

💾 战局存档:关掉浏览器不该从头再来

问题

一局战争要打几十分钟。中途关掉浏览器 = 全部重来。只有生涯军衔(ironTideCareer)存了 localStorage,战局本身没存。结算画面还是直接 location.reload()

对玩耍时间被限制的小朋友来说,这个惩罚太重了。

一个关键设计决定

不要试图"重放"地图生成,要直接快照结果状态。

我们一开始想的是:把随机种子存下来,读档时重新跑一遍 buildTheater()。但这条路走不通,因为:

  • buildIsland() 里的 rx / rz / angle 是当场 Math.random() 摇出来的,而这三个值影响玩法(占领半径、行走边界、船体碰撞),不只是好看
  • 就算把生成过程种子化了,战争开打之后的随机(增援骰子、AI 建造、天气重摇)也没法重放

所以只存结果

const s={ v:1, mapIdx:currentMapIdx, money, sunk,
  weather:{type,tod,t,sea},
  fh:{x,z,hp,maxhp,up}, eh:{...},                       // 两个海港
  islands:islands.map(i=>({name,x,z,r,rx,rz,angle,owner,cap})),   // rx/rz/angle 一定要存
  units:landUnits.filter(u=>!u.dead).map(...),          // 所有地面单位
  shipId, hp, px, pz, hd,                               // 玩家的船
  guns:placed.map(p=>({id,x,y,z,free,ko})),             // 装了哪些炮、装在哪
  planes, tanks, gtanks, owned, eq, fbu, ebu, ground };

读档时用你现有的构造函数(buildIsland / buildHarbor / buildTurret / buildPlane / buildLand)把 3D 物体重建出来。buildIsland() 要加一个可选的 preset 参数,让它用存档里的 rx/rz/angle 而不是重新摇。

AI 舰队不用逐艘存——读档时按战场设定的强度重新生成就好。简单、可靠,也不会被玩家用来刷。

触发时机

  • 每 30 秒自动存一次(在主循环里累加 dt
  • beforeunloadvisibilitychange(页面隐藏)时存
  • 胜负分出后 clearSave()

菜单上放一个大按钮:▶ 继续上次战局——训练湾 · $6649

三个我们踩到的坑

  1. 地面坦克会丢:登陆战里买的坦克是 onDeck:false,既不在 landUnits 里也不在 tanks 过滤器里 → 读档后钱花了、坦克没了。要单独存一份 gtanks
  2. 甲板坦克的战损会丢:只存了车型 id,读档后 buildDeckTank 把血量重置成满血
  3. 登陆战读档会把人传送回指挥所deployLandCampaignStart() 总是把玩家放在指挥所旁边,把刚刚还原的 px/pz 覆盖掉了

参考实现

PR #15PR #18(后三个坑)


English summary: A war takes tens of minutes and nothing but the career record survives a page close. Snapshot the result state rather than trying to replay generation: island rx/rz/angle are rolled at build time and affect gameplay, and mid-war randomness (reinforcement dice, AI building, weather re-rolls) can't be replayed anyway. Store money/campaign/weather/both harbors/every island/all land units/ship + fitted guns + parked aircraft + tanks, rebuild the 3D objects through your existing constructors (buildIsland needs an optional preset for the saved footprint), and respawn AI fleets at the theater's authored strength. Autosave every 30s and on page hide; clear on victory/defeat. Watch out: ground-bought tanks live in neither landUnits nor the deck-tank list, deck tanks lose their damage on rebuild, and the land-campaign entry function overwrites the restored foot position.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions