Skip to content

Commit e6928a7

Browse files
author
web3blind
committed
Persist marketplace state for checkpoints
1 parent 89ede05 commit e6928a7

4 files changed

Lines changed: 40 additions & 17 deletions

File tree

app/index.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137
<script src="js/protocols/market-protocol.js"></script>
138138

139139
<!-- Game data -->
140-
<script src="js/data/creatures.js?v=20260621i"></script>
140+
<script src="js/data/creatures.js?v=20260621j"></script>
141141
<script src="js/data/spells.js"></script>
142142
<script src="js/data/recipes.js"></script>
143143
<script src="js/data/regions.js"></script>
@@ -154,7 +154,7 @@
154154
<script src="js/engine/validator.js"></script>
155155
<script src="js/engine/guild.js?v=20260621d"></script>
156156
<script src="js/engine/territory.js"></script>
157-
<script src="js/engine/crafting.js?v=20260621i"></script>
157+
<script src="js/engine/crafting.js?v=20260621j"></script>
158158
<script src="js/engine/enchanting.js"></script>
159159
<script src="js/engine/marketplace.js"></script>
160160
<script src="js/engine/checkpoint.js"></script>
@@ -164,7 +164,7 @@
164164
<script src="js/engine/quest-system.js?v=20260621e"></script>
165165
<script src="js/engine/loci.js"></script>
166166
<script src="js/engine/npc-framework.js"></script>
167-
<script src="js/engine/state-engine.js?v=20260621i"></script>
167+
<script src="js/engine/state-engine.js?v=20260621j"></script>
168168
<script src="js/engine/daily-leaderboard-storage.js"></script>
169169
<script src="js/engine/daily-leaderboard.js"></script>
170170

@@ -190,7 +190,7 @@
190190
<script src="js/ui/screens/guild.js?v=20260621d"></script>
191191
<script src="js/ui/screens/map.js?v=20260621h"></script>
192192
<script src="js/ui/screens/marketplace.js"></script>
193-
<script src="js/ui/screens/crafting.js?v=20260621i"></script>
193+
<script src="js/ui/screens/crafting.js?v=20260621j"></script>
194194
<script src="js/ui/screens/quests.js?v=20260621e"></script>
195195
<script src="js/ui/screens/world-boss.js"></script>
196196
<script src="js/ui/screens/settings.js"></script>

app/js/engine/state-engine.js

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,10 @@ var StateEngine = (function() {
142142
}
143143

144144
// Expire marketplace listings
145+
_ensureMarketplace();
145146
if (typeof MarketplaceEngine !== 'undefined') {
146147
MarketplaceEngine.expireListings(blockNum);
148+
_syncMarketplaceState();
147149
}
148150

149151
// Register crafted item templates if needed
@@ -903,6 +905,8 @@ var StateEngine = (function() {
903905
return [];
904906
}
905907

908+
_syncMarketplaceState();
909+
906910
return [{
907911
type: 'market_listed',
908912
account: sender,
@@ -922,6 +926,8 @@ var StateEngine = (function() {
922926
return [];
923927
}
924928

929+
_syncMarketplaceState();
930+
925931
return [{
926932
type: 'market_cancelled',
927933
account: sender,
@@ -938,6 +944,8 @@ var StateEngine = (function() {
938944
return [];
939945
}
940946

947+
_syncMarketplaceState();
948+
941949
return [{
942950
type: 'market_sold',
943951
buyer: sender,
@@ -970,19 +978,24 @@ var StateEngine = (function() {
970978
* Ensure marketplace state is initialized
971979
*/
972980
function _ensureMarketplace() {
973-
if (!worldState.marketplace) {
974-
worldState.marketplace = {};
981+
if (!worldState.marketplace || !worldState.marketplace.listings) {
982+
worldState.marketplace = {
983+
listings: {},
984+
history: [],
985+
priceHistory: {}
986+
};
975987
}
976988
if (typeof MarketplaceEngine !== 'undefined') {
977-
// Sync marketplace state from world state if needed
978-
var mState = MarketplaceEngine.getMarketState();
979-
if (!mState.listings) {
980-
MarketplaceEngine.setMarketState({
981-
listings: {},
982-
history: [],
983-
priceHistory: {}
984-
});
985-
}
989+
// Keep the replay/checkpoint world state and the marketplace module
990+
// on the same object so listings survive save/load and buy/cancel
991+
// handlers do not mutate a detached in-memory marketplace.
992+
MarketplaceEngine.setMarketState(worldState.marketplace);
993+
}
994+
}
995+
996+
function _syncMarketplaceState() {
997+
if (typeof MarketplaceEngine !== 'undefined') {
998+
worldState.marketplace = MarketplaceEngine.getMarketState();
986999
}
9871000
}
9881001

app/sw.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Viz Magic — Service Worker
2-
var CACHE_NAME = 'viz-magic-v22';
2+
var CACHE_NAME = 'viz-magic-v23';
33
var ASSETS = [
44
'/',
55
'/index.html',

tests/player-bug-regressions.test.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ test('crafting replay consumes the selected material ids only once', function ()
116116
assert.ok(/CraftingSystem\.craftWithMaterialIds/.test(stateEngineJs), 'state-engine craft replay should use exact material ids');
117117
});
118118

119+
test('marketplace state is mirrored into world state for checkpoints', function () {
120+
const stateEngine = read('app/js/engine/state-engine.js');
121+
assert.ok(/function _syncMarketplaceState\(\)/.test(stateEngine), 'state engine should expose marketplace checkpoint sync helper');
122+
assert.ok(/MarketplaceEngine\.setMarketState\(worldState\.marketplace\)/.test(stateEngine), 'marketplace engine should replay from checkpoint world state');
123+
assert.ok(/worldState\.marketplace = MarketplaceEngine\.getMarketState\(\)/.test(stateEngine), 'marketplace mutations should be mirrored back into world state');
124+
assert.ok(/_handleMarketList[\s\S]*_syncMarketplaceState\(\)/.test(stateEngine), 'market list should sync after successful mutation');
125+
assert.ok(/_handleMarketCancel[\s\S]*_syncMarketplaceState\(\)/.test(stateEngine), 'market cancel should sync after successful mutation');
126+
assert.ok(/_handleMarketBuy[\s\S]*_syncMarketplaceState\(\)/.test(stateEngine), 'market buy should sync after successful mutation');
127+
});
128+
119129
test('crafting recipes have templates and obtainable materials', function () {
120130
const context = { console, VizMagicConfig: { RARITY: { COMMON: 0, UNCOMMON: 1, RARE: 2, EPIC: 3, LEGENDARY: 4 } } };
121131
vm.createContext(context);
@@ -229,7 +239,7 @@ test('high-traffic UI narration and inventory stat labels are translated', funct
229239

230240
test('service worker updates quickly and keeps navigations network-first', function () {
231241
const swJs = read('app/sw.js');
232-
assert.ok(/viz-magic-v22/.test(swJs), 'service worker cache version should be bumped');
242+
assert.ok(/viz-magic-v23/.test(swJs), 'service worker cache version should be bumped');
233243
assert.ok(/self\.skipWaiting\(\)/.test(swJs), 'service worker should activate new cache without waiting for all tabs to close');
234244
assert.ok(/self\.clients\.claim\(\)/.test(swJs), 'service worker should claim clients after activation');
235245
assert.ok(/event\.request\.mode === 'navigate'[\s\S]*fetch\(event\.request\)/.test(swJs), 'navigation requests should prefer network to avoid stale cached index');

0 commit comments

Comments
 (0)