Build the Squeek Wars Testnet website on this project's live contracts and host it on IPFS, named squeek-wars. A static web app with no server, indexer or keys: it reads Sepolia from the browser through public RPCs, and the player's own wallet signs every action. English, pixel-art hamster village style (warm wood, straw and stone tones, chunky pixel buttons and icons), phone and desktop.

Live contracts on Sepolia (11155111), deployed in block 12060202: Villages 0x68dcfbff8b40429be1effaa63e82ea5200c87aec, Army 0x3cba4215e531ee3c4c3daa045d15803505d282e0, Clans 0xb789d7a3c8bb07ca1bd8811f10ee47f270d93fe1, SeedLedger 0x11d4a8126b7911bda323e4c6dc8b137bf01ba2b9, GameRules 0xfbe6911fbaa2fdfd91ef91887f30b0d3ba8f9d15. Villages is the canonical game: pass its address as the game in every Army, Clans and SeedLedger read and event filter, never mixing other namespaces. Squeekchain reads: SqueekCore 0x980b4424c007caf7a1f3670b48c8eaef7ebc3d44 state().cumulativeWork and the Squeek ERC-721 0xcb98349c134ab983da5bfd80527dfe2552bdb70f balanceOf. Read events with eth_getLogs in chunks from block 12060202, cache them in the browser, and fall back between at least two public Sepolia RPCs.

Pages:

  • Landing: what the game is, that SEED comes from the real work of Squeekchain's hamster, how a day works (04:00 UTC checkpoint); Rules and FAQ pages written from docs/ECONOMY.md.
  • Enter: Testnet (active) and Mainnet (disabled, "opens after the official Squeek mint"). Testnet connects an injected wallet, asks to switch to Sepolia, then founds a village with a name (3-16 letters, digits or underscore, checked with nameOwner before sending). A wallet that has a village goes straight in.
  • Players always appear as name + short address (0x1a2b...9f3c).
  • Village: the four resources ticking up live from on-chain rates, storage caps and Vault protection, SEED balance, the 8 fields and building plots with level, upgrade cost and time from GameRules quotes (including the Squeek speed bonus), the two build slots with countdowns, Finish and Cancel (80% refund) buttons, shield timer.
  • Map: the 100x100 grid with every village (from Founded events) and the 200 wild camps, own village highlighted, zoom and pan; tap a tile for its owner, troops, Walls and stock, then Attack, Scout or Support (clanmates only) with the travel time.
  • Army: train units with queue and Finish, home troops, room used, movements in flight with countdowns and a Resolve button once arrived (anyone may resolve), and Reports of battles, scouting and loot from Battle, Scouted and MovementResolved events.
  • Academy: the five research tiers with cost, time, unlocks and Finish.
  • Market and treasury: exchange 100 of a resource or SEED for another resource; output boost, peace shield, banner.
  • Champion: level, XP, free points, and allocation to Might, attack, defense and carry.
  • Clan: found (Clan Hall 3), invite, join (Clan Hall 1 plus an invitation), leave, members, support sent and received.
  • Ranking: season and weekly tabs for Overall (build + research + min(build, (attack + defense)/200), with the three parts shown), Attack, Defense and Loot, plus clans by summed Overall, from the Clans counters of every founded village.
  • Squeektoshi panel, always visible: game day, last checkpoint's work, SEED per village per day (work/10), Wheelhouse bonus, the player's Squeeks held and build speed bonus, time to the next 04:00 UTC.
  • Daily buttons: Checkpoint (anyone, once per game day, shown while today has none) and Claim SEED (when unclaimed).

Every write shows its state: waiting for the wallet, pending, confirmed, or reverted with the custom error explained in plain English. A Contracts page lists the addresses with Sepolia Etherscan links. No owner or admin controls, no test or cheat controls, no other services or analytics.

Published · Site

site
squeek-wars-testnet-hamster-vill.imd.site
ipfs
bafybeicbsbt3225bkcajwkdbec73lfflxy5wq4h2e5a6zyuh7j4tb4qr3m · 1.4 MB
source
identity-md-launches/launch-2935-launch-squeek-wars-testnet · pull request

Work

  1. Posted17 minto the first attempt
  2. Build websiteAgent #184245 files changedsent back
    ran onclaude · claude-opus-5-5 · 53 turns · 16m 41s · 98 in · 85.8K out · 5.3M cached
    submissionafaf677d260565d2b1e326e8b4b4343555eedf239d322079cd9a1ffa9f4b44ca
    device0eca5d6d7ad6ddb47e81e2e533a069b9ec3a436b27ba5c360a4dda3013256c32
    started from4910a7bf7b3f27e8c1f1c5066274a4a79c030458
    bundleb4ae409f5e5a4092feabfabd74b572c9398c6ce1e85e542db2ca6f560dccdd55 · 568 KB
    verifiedrebuilt and matched · verifier 0.1.0 ·
    changed · 45 files
    dist/assets/ccip-CkjE6S3k.jsdist/assets/hooks.module-Dy7GlVeP.jsdist/assets/index-CJsOtaCx.jsdist/assets/index-CZEpwoPs.jsdist/assets/index-CidywgcH.jsdist/assets/index-pHdL576D.cssdist/assets/pixelify-sans-latin-500-normal-Bq6pAlou.woffdist/assets/pixelify-sans-latin-500-normal-DC052d-m.woff2dist/assets/pixelify-sans-latin-700-normal-BctWAS0u.woffdist/assets/pixelify-sans-latin-700-normal-D3Xxx3QE.woff2dist/favicon.svgdist/index.htmldist/og.pngweb/index.htmlweb/package-lock.jsonweb/package.jsonweb/public/favicon.svgweb/public/og.pngweb/scripts/make-og.mjsweb/src/App.tsxweb/src/abi/Army.jsonweb/src/abi/Clans.jsonweb/src/abi/GameRules.jsonweb/src/abi/SeedLedger.jsonweb/src/abi/Villages.jsonweb/src/chain.tsweb/src/config.tsweb/src/data.tsweb/src/errors.tsweb/src/game.tsweb/src/main.tsxweb/src/pages/Army.tsxweb/src/pages/Clan.tsxweb/src/pages/Enter.tsxweb/src/pages/Info.tsxweb/src/pages/Map.tsxweb/src/pages/More.tsxweb/src/pages/Ranking.tsxweb/src/pages/Village.tsxweb/src/styles.cssweb/src/tx.tsxweb/src/ui.tsxweb/src/wallet.tsxweb/tsconfig.jsonweb/vite.config.ts
  3. Design criticAgent #1110found 2 high, 6 medium
    AreaResult
    Requirements63 items: 55 met, 7 missing/partial, 0 faked, 1 after review
    Broken features5 bug findings
    First screen at 390pxUnverified; browsers failed to launch
    taste@1No checks measured; browser launch failed
    Copy1 finding
    Share cardAll 5 metadata checks present; image inspected

    Saved 8 findings: 2 high, 6 medium in .imd-findings.json. Application files are unchanged.

    The high findings are missing loot reports and custom errors displayed as raw signatures. Medium findings cover stale camp values, blocked Scout-only support, expired boost rates, false empty rankings, incomplete player identities, and incorrect Rules copy.

    Read-only simulations, source-render fixtures, and a query-cache test reproduced the relevant behavior. All five ABIs match the pinned deployment hashes. Signed transactions and browser layouts were not exercised.

    Squeek Wars is a village strategy game whose wood, straw and pixel hamster art carry the visual identity.

    “Met” below means supported by source inspection. “Missing” includes partial implementations with confirmed defects. Source paths are under web/src/ unless stated otherwise.

    Brief requirementStatusEvidence
    “host it on IPFS, named squeek-wars”After reviewPublishing and naming follow review
    “static web app with no server, indexer or keys”Metchain.ts; web/vite.config.ts
    Browser reads through public Sepolia RPCsMetconfig.ts; chain.ts
    Player’s wallet signs every actionMettx.tsx:32
    English; warm pixel art; chunky buttons and iconsMetstyles.css; ui.tsx
    Phone and desktopMetResponsive rules in styles.css:277; visually unverified
    Five specified live contracts on SepoliaMetconfig.ts:11; addresses match deployment
    Deployment block 12060202Metconfig.ts; chain.ts:35
    Canonical Villages namespace for helper reads and event filtersMetdata.ts; page queries
    SqueekCore state().cumulativeWorkMetconfig.ts; data.ts:25
    Squeek ERC-721 balanceOfMetdata.ts:79
    Chunked eth_getLogs from deployment; browser cacheMetchain.ts:32
    At least two public Sepolia RPC fallbacksMetThree configured in config.ts
    Landing explains game, real work, SEED and 04:00 UTCMetpages/Info.tsx
    Rules from docs/ECONOMY.mdMissingInfo.tsx:59 misstates champion and training rules
    FAQ from economy documentationMetpages/Info.tsx:66
    Active Testnet; disabled Mainnet with mint explanationMetpages/Enter.tsx:33
    Injected wallet and Sepolia switchMetwallet.tsx; Enter.tsx:37
    Founding name validation and nameOwner checkMetpages/Enter.tsx
    Existing village goes straight inMetpages/Enter.tsx:17
    Players always show name plus short addressMissingwallet.tsx:62; Village heading; map options
    Four resources ticking from on-chain ratesMissingdata.ts:115 retains expired boost rates
    Storage caps, Vault protection and SEED balanceMetpages/Village.tsx:81
    Eight fields and building plots with levelsMetpages/Village.tsx:120
    GameRules upgrade costs and times, including Squeek bonusMetpages/Village.tsx:11
    Two build slots, countdowns, Finish, Cancel and 80% refundMetpages/Village.tsx:101
    Shield timerMetpages/Village.tsx:80
    100×100 map, Founded villages and 200 campsMetpages/Map.tsx; data.ts:38
    Own village highlight, zoom and panMetpages/Map.tsx:127
    Tile owner, troops and WallsMetpages/Map.tsx:59
    Tile stockMissingCamp quantities are absent or stale in Map.tsx:34
    Attack, Scout and travel timeMetpages/Map.tsx:40
    Support for clanmatesMissingMap.tsx:96 bloc
    ran oncodex · gpt-6.1-sol · 7 turns · 12m 18s · 138.4K in · 28.4K out · 4.3M cached
    submissiona2033e2fe12d6b98c7f2a6f950cb2636d3d85f66879d4fe6d03a1a909b471416
    device88cc3b0a22556b9a90da99db62c80858a61a8cedb8ee5b01dc48814f69d024c2
    started fromb36abf4c00ba1b5933c6e50ffc47e41836f1e0f3
    bundlenone
    applied onc266a580bdb7a46d428aacfc63f200e389fed53b294503a3d78ce8fb16e74c31
    • highfidelity: completed battle reports omit all loot amountsweb/src/pages/Army.tsx:105

      Now: Reports renders Battle statistics and MovementResolved mode/arrival text, but never loads Army.report(game,id) or renders its loot array; completed movements are excluded from the only list that can display carried loot.

      Change to: Read the existing report for each battle in the canonical Villages namespace and show the four recorded resource amounts alongside its result, preserving them after the return resolves.

      Why: The brief explicitly requires Reports of battles, scouting and loot. MovementResolved contains no loot values, so displaying its mode alone does not satisfy loot reports.

      Widths: 390 and 1440.

      With a village that has won a looting raid, resolve the outbound movement and then its return; open Army > Reports.

      Expected: the battle report retains Wood/Food/Stone/Iron looted.

      Actual: the report shows only attack, defense, losses and movement modes.

      Source evidence: Army.tsx lines 60–65 read movement loot only for the active list; lines 101–105 render no loot; src/Army.sol report() exposes the persisted Report.

      No signature was sent during this review; this is a deterministic source-traced state reproduction.

      Executed source-render fixture: MovementSent id=1, decisive Battle id=1, MovementResolved mode=6, completed movement with no remaining units/loot.

      Reports rendered "Attack 400 vs defense 150 · Decisive · lost 10 / 100" and "Movement #1 resolved as Completed", with zero resource amounts and no report() read.

    • highbug: forwarded game errors are shown as raw signatures instead of plain Englishweb/src/tx.tsx:28

      Now: simulateContract uses only ABI[c]. Most player actions target Villages, whose ABI omits errors forwarded from Army, Clans and SeedLedger. explain() therefore receives no decoded errorName and returns viem's raw signature message, despite having the correct translations.

      Change to: Decode revert data against the union of the existing game-contract error definitions before passing the name to PLAIN; preserve the existing addresses, action arguments and wallet calls.

      Why: The brief requires every reverted write to explain its custom error in plain English. This fails across training, treasury, clan and champion actions.

      Widths: 390 and 1440 (shared write path).

      Use treasury(2,0) with under 1,000 SEED, or train with insufficient Burrow room, join an uninviting clan, or exceed a champion stat cap.

      A read-only viem simulateContract test using the committed Villages ABI and a custom transport returning each actual custom-error selector produced: treasury / InsufficientSeed / 0x03ca7e96 -> The contract function "treasury" reverted with the following signature: 0x03ca7e96; train / InsufficientBurrowRoom / 0xaad2176c, joinClan / NotInvited / 0x779a6f41, allocateChampion / StatCap / 0x4771317e likewise returned only signatures.

      Expected: the already-written PLAIN explanations for each.

      All four were executed locally without a wallet or transaction.

    • mediumbug: camp tiles show stored stock and outdated defense instead of current valuesweb/src/pages/Map.tsx:34

      Now: camp() returns storage at its last refresh, but TileInfo uses its stock verbatim and treats an initialized camp with regrowAt=0 as having fixed defense. Never-raided camps display a sentence instead of numeric stock.

      Change to: Derive current camp stock from lastStock and the documented daily rate integral, cap each resource at 24 hours of the current rate, and use campParameters defense whenever regrowAt is zero or expired; show numeric stock for untouched camps too.

      Why: Visitors need the current stock and defenses to choose raids; camp storage refreshes during raid resolution, not during the view read.

      Widths: 390 and 1440.

      1. Select size-1 camp #1 an hour after a decisive raid on season day 1, with stored stock zero, lastStock one hour ago and a future regrowAt. Expected: at least 22 of each resource grown during that hour, subject to day transitions; actual: stored zeroes persist.
      2. Select an initialized camp with regrowAt=0, saved defense=150 from season day 0, after season day 1 starts. Expected: campParameters defense 190; actual: 150.
      3. Select an untouched camp: Stock is a sentence rather than an amount. Evidence: Map.tsx 33–35, 73–75 versus src/Army.sol _refreshCamp and _campIntegral. Executed the actual TileInfo query function and rendered its result with combined read fixtures camp=[true,0,lastStock,150,[0,0,0,0]], campParameters=[190,22000000]: output was "Defense 150 Stock 0 Wood, 0 Food, 0 Stone, 0 Iron Growth 22 of each per hour". These are read fixtures, not claimed live chain observations.
    • mediumbug: the map blocks valid Scout-only support contingentsweb/src/pages/Map.tsx:96

      Now: Support is disabled whenever all selected units are Scouts, although Army.send permits Scouts in support mode and Scouts have defense.

      Change to: Remove the units[6] === total restriction from the existing Support disabled condition; retain the positive-unit and clanmate checks.

      Why: The map must let players support clanmates according to the live game rules. Only scouting mode restricts troop types; support has no Scout ban.

      Widths: 390 and 1440.

      With at least one home Scout and a clanmate on the map, select that clanmate and enter 1 Scout with every other unit at 0. d.same is true, total=1 and units[6]=1.

      Expected: Support enabled, preparing mode 3 with [0,0,0,0,0,0,1].

      Actual: the disabled expression evaluates true.

      Selecting one additional Spearman enables the same action. src/Army.sol send() checks allied status and no champion for mode 3; the i != 6 troop restriction applies only to mode 2.

      No signed transaction is required to reproduce the disabled control.

      Executed source-render fixture with same=true and units=[0,0,0,0,0,0,1] produced exactly Support.

    • mediumbug: resource rate labels retain the output boost after it expiresweb/src/data.ts:115

      Now: useRates computes whether boostUntil is in the future only inside its query function. Its key includes the fixed expiry timestamp but no active/expired state and it has no refetch interval. Crossing the expiry leaves the boosted rate cached while the Village page removes the boost countdown.

      Change to: Make the existing rate query update when the boost crosses its deadline, and integrate only the boosted part of each local interpolation interval.

      Why: The brief requires four resources ticking from on-chain rates; the economy ends a treasury boost exactly at its 24-hour deadline.

      Widths: 390 and 1440.

      Leave Village open across an output-boost expiry with two level-1 fields, no Wheelhouse and no upkeep for that resource.

      Before expiry useRates returns 36*1.25=45/h.

      After expiry all query-key entries remain identical (including boostUntil); useVillage refreshes stock but cannot invalidate this key.

      Expected: 36/h and post-expiry stock growth at 36/h.

      Actual: the cached label remains +45/h and interpolation keeps using 45/h between stock polls.

      Refocusing the window or changing a key entry can correct it, which is why keeping the page open is required.

      Executed the actual useRates query function with a TanStack QueryObserver, a fixed clock, fieldRate=18000000 and a boost ending one second later.

      Advanced the clock by two seconds and reapplied the same query key: cached rate was 45/h, recomputing the same function returned 36/h, and queryCalls stayed 1.

    • mediumbug: failed chain reads are presented as an empty leaderboardweb/src/pages/Ranking.tsx:49

      Now: Ranking handles rows.error but ignores players.error and g.error. When either prerequisite fails, the rows query stays disabled and data defaults to an empty array, triggering No villages yet. Found the first one.

      Change to: Check the existing prerequisite query error states before the empty-data branch; use Could not read the rankings. Retrying. until all required reads succeed. Reserve No villages yet for a successful empty Founded result.

      Why: Loading, failure and empty states must say only what the app knows; an RPC failure does not prove that no villages exist.

      Widths: 390 and 1440.

      Open Ranking with a fresh browser cache and make the Founded log request or a required useGlobal read fail on all fallback RPCs.

      After retries, players.error or g.error is set, the rows query is disabled, and rows.error is unset.

      Expected: a retry/error message.

      Actual: No villages yet.

      Found the first one.

      A source-render test with usePlayers={data:undefined,isLoading:false,error:Error("RPC unavailable")}, useGlobal in the same error state and a disabled ranking query reproduced that exact empty-state text.

      This reports the incorrect UI state, not third-party endpoint availability.

    • mediumfidelity: player identities are not consistently paired with their short addressweb/src/wallet.tsx:62

      Now: The connected-wallet button displays only a short address, the village heading displays only its name and coordinates, and the map selector options display only village names and coordinates. The existing Who component correctly pairs both elsewhere.

      Change to: Label the existing wallet button with the founded village name plus short(address), and append the short address to the existing village heading and map village options; preserve their actions and full identities.

      Why: The brief says players always appear as name + short address, so the same identity must be recognizable across the header, village, map and ranking.

      Widths: 390 and 1440.

      Connect a Sepolia wallet with a village named Nutmeg_Hollow and address 0x1111111111111111111111111111111111111111.

      Expected header identity: Nutmeg_Hollow 0x1111...1111.

      Actual source-rendered ConnectSheet button: 0x1111...1111.

      Open Village and Map > Go to tile: Village.tsx line 80 and Map.tsx line 162 render names and coordinates without the paired address.

      The wallet fixture was read-only; no real account was connected.

    • mediumfidelity: the Rules page misstates champion points and training speedweb/src/pages/Info.tsx:59

      Now: Rules says each champion level gives four points and all four allocations cap at 20; level 1 actually has zero free points and Might has no 20-point cap. It also says training is 10% faster per Barracks level, while level 1 has no reduction and later reductions compound.

      Change to: Replace the champion explanation with "Champion level is min(30, 1 + floor(√(XP ÷ 100))). Each level gained after level 1 grants four permanent points. Attack, defense and carry cap at 20 points each; Might can use the remaining points." Replace the training-speed clause with "Each Barracks level above 1 multiplies training time by 0.9."

      Why: The brief requires Rules written from docs/ECONOMY.md. These are decisions about permanent point allocation and build progression, and the published explanations must agree with the documented live rules.

      Widths: 390 and 1440.

      Open Rules > Champion and Troops and battle.

      The source-rendered champion paragraph says each level gives four points and (20 points each at most).

      Compare a new champion: Army.championLevel returns 1 and allocate allows 4*(1-1)=0 points; at level 30 allocate permits Might=116 with the other allocations 0.

      Only attack, defense and carry are checked against 20.

      For 1 Spearman at Barracks 1, GameRules.unitQuote duration is 900 seconds, exactly the 15-minute base, not 10% shorter.

      Barracks 3 is 900*0.9^2=729 seconds.

      Evidence: docs/ECONOMY.md Research, training, and champion; src/Army.sol allocate; src/GameRules.sol unitQuote.

  4. Build websiteAgent #312 files changed

    I fixed all eight findings in the source under web/src, but I couldn't build, typecheck or test anything. Every Bash call this session failed with "Sandbox is required but failed to initialize: Failed to create bridge sockets after 5 attempts", so dist/ is still the previous accepted build and doesn't contain these fixes. Someone has to run cd web && npm ci && npm run build before this revision reaches the live site.

    That's a broken runtime on this machine, not a question for you, so I didn't write .imd-blocked.json. I also didn't hand-edit the minified bundle: a patched bundle wouldn't match any real build.

    Fixes (each answered in .imd-responses.json; I confirmed every finding by reading the code against src/*.sol and docs/ECONOMY.md):

    • Loot in battle reports (Army.tsx): each battle now reads Army.report(GAME, id) and shows "Looted X Wood, Y Food, Z Stone, W Iron". The contract stores that report permanently, so it still shows after the return trip resolves.
    • Error messages (tx.tsx): the pre-send check and the after-revert check now know every error from all five game contracts. Errors that Villages passes on from Army, Clans or SeedLedger now get their plain-English text. The wallet request itself is unchanged.
    • Wild camps (Map.tsx): campNow() copies the contract's own camp-refresh math, so the tile shows current stock (capped at 24 hours of growth) and current defense. Untouched camps now show numbers, and a "Defense regrows in" line appears while regrowth is pending.
    • Scout-only support (Map.tsx): removed the rule that disabled Support when only Scouts were picked. The contract only limits troop types for scouting.
    • Output boost expiry (data.ts, Village.tsx): the stored rates no longer bake in the boost. The page applies the +25% only before the boost ends, so the /h label and the ticking stock both drop it on time.
    • Ranking errors (Ranking.tsx): a failed read now shows "Could not read the rankings. Retrying." "No villages yet" appears only after a successful read that finds none.
    • Name + short address (wallet.tsx, Village.tsx, Map.tsx, styles.css): the wallet button shows the village name above the short address, with the full address on hover. The village heading and the map's tile list also show both.
    • Rules text (Info.tsx): the champion and training wording now matches docs/ECONOMY.md and the contract. The Barracks note in game.ts had the same wrong "10% faster per level" claim, so I fixed it too.

    Docs: DESIGN.md didn't exist at the repo root and the README had no website section, though the acceptance criteria require both. I wrote DESIGN.md from the current source: tokens, the six type sizes, spacing, components, the 640px breakpoint, and do's and don'ts. I added a website section to README.md with install, typecheck, build, preview and dev commands, plus validation notes for this revision that state the limits above.

    Not done this round: the typecheck, the build, interaction tests, the taste.mjs design probe and any browser or screenshot checks. Nothing rendered was observed. In particular, nobody has checked whether the new two-line wallet button fits a 320px header.

    ran onclaude · claude-opus-5-5 · 97 turns · 8m 28s · 79 in · 41K out · 3.8M cached
    submission3d0aa19680c10ea1fb4e40384af9092c39f62abc8b164ff28d8f437f096975f9
    device401c4383398af47cbcb358b7bf27675cd481dbf39525cc93d1029da774972a60
    started fromb36abf4c00ba1b5933c6e50ffc47e41836f1e0f3
    bundlec266a580bdb7a46d428aacfc63f200e389fed53b294503a3d78ce8fb16e74c31 · 578 KB
    verifiedrebuilt and matched · verifier 0.1.0 ·
    changed · 12 files
    DESIGN.mdREADME.mdweb/src/data.tsweb/src/game.tsweb/src/pages/Army.tsxweb/src/pages/Info.tsxweb/src/pages/Map.tsxweb/src/pages/Ranking.tsxweb/src/pages/Village.tsxweb/src/styles.cssweb/src/tx.tsxweb/src/wallet.tsx
  5. Design criticAgent #1622found 1 medium
    AreaPrevious reportedThis review
    RequirementsFull count unavailable34 met, 1 missing, 0 faked, 1 after review
    Broken features5 bugs1 medium bug
    First screen at 390UnrecordedUnverified
    taste@1Unrecorded0/16 measured; browser blocked
    Copy findings10
    Share cardUnrecorded5/5 metadata fields present

    Seven of the eight previous findings are fixed. One medium defect remains, recorded in .imd-findings.json.

    bug: the revised wallet header truncates valid village names. At 390 and 1440 widths, the new .acct-name rule caps names at 162 px. The valid name WWWWWWWWWWWWWWWW requires 224.352 px in the shipped font. Remove the ellipsis and allow wrapping so the full identity remains readable. Evidence combines an executed source-render fixture with measurements from the committed font; browser screenshots were unavailable.

    Previous findingSettlement
    Completed battle reports omit lootFixed. Completed-return fixture retained “Looted 12 Wood, 23 Food, 34 Stone, 45 Iron” from report(GAME, id).
    Forwarded errors show raw signaturesFixed. Actual viem simulations decoded all four reported selectors into plain English.
    Camps show stale stock and defenseFixed. Growth, untouched camps, zero-regrow defense and day-boundary fixtures passed; 1,000 integral cases matched the contract formula.
    Scout-only support is blockedFixed. One-Scout fixture rendered Support enabled.
    Output rates retain expired boostsFixed. Rate changed from 45/h to 36/h at expiry; cross-expiry growth integrated correctly.
    Failed rankings appear emptyFixed. Prerequisite failures rendered retry text; successful empty results retained the empty state.
    Identities omit short addressesPartially fixed. Header, Village and Map now pair both, but the header clips valid names.
    Rules misstate champion points and trainingFixed. Rendered Rules and Barracks notes match the corrected formulas.

    The visual idea is a hamster strategy game presented through warm timber frames, straw surfaces and chunky pixel controls.

    The inventory below describes source implementation. Signed transactions and browser layout were not verified. Chromium could not launch, so taste@1, first-screen measurements and WebKit interaction checks remain unavailable. The tracked dist/ still contains the earlier export.

    RequirementStatusEvidence
    Static browser app; no server, indexer or keysMetmain.tsx, chain.ts
    Supplied Sepolia contracts, chain 11155111 and deployment block 12060202Metconfig.ts
    Canonical Villages namespace for helper reads and event filtersMetconfig.ts, data.ts, game pages
    SqueekCore cumulative work and Squeek ERC-721 balance readsMetconfig.ts, data.ts
    Chunked eth_getLogs, browser cache and multiple public RPC fallbacksMetchain.ts, config.ts
    English; warm pixel-art village style; phone and desktop layoutsMet in sourceindex.html, styles.css, ui.tsx
    IPFS hosting named squeek-warsAfter reviewHosting handoff
    Landing explains game, hamster work, SEED and 04:00 UTC daysMetpages/Info.tsx, Home
    Rules and FAQ based on docs/ECONOMY.mdMetpages/Info.tsx; corrected Rules fixture
    Active Testnet and disabled Mainnet with mint-opening explanationMetpages/Enter.tsx
    Injected-wallet connection and Sepolia switchingMetwallet.tsx, pages/Enter.tsx
    Founding with 3–16 permitted characters and nameOwner checkMetpages/Enter.tsx
    Existing village goes straight inMetpages/Enter.tsx redirect
    Players always display name plus short addressMissing in fullstyles.css:136 truncates names
    Four ticking resources,
    ran oncodex · gpt-6.1-sol · 6 turns · 10m 6s · 107.2K in · 25.4K out · 2.1M cached
    submissionf8128913258678f8a4843226cd7bbcf26ae1f4e748562847d8fcf25f2cbb28ae
    device76ce625b2d0c81713f61af714a9d7b5bffe886f004df35f284d4967a70923e11
    started from477feab56ed385755fba9180122664f8317bd9a2
    bundlenone
    applied onc266a580bdb7a46d428aacfc63f200e389fed53b294503a3d78ce8fb16e74c31
    • mediumbug: the revised wallet header truncates valid village namesweb/src/styles.css:136

      Now: The connected header pairs name and short address, but the new .acct-name rule clips the village name at 9em with an ellipsis, even on desktop. A legal 16-character name can exceed that limit; the button title contains only the address.

      Change to: Remove the name's overflow:hidden, text-overflow:ellipsis and white-space:nowrap; let the full name wrap (overflow-wrap:anywhere) within the identity button and let .top wrap its items when necessary at phone widths.

      Why: The identity finding asked to preserve full identities, and the brief says players always appear as name plus short address. Critical player names must remain readable rather than being shortened by layout.

      Widths: 390 and 1440.

      Use a connected Sepolia wallet 0x1111111111111111111111111111111111111111 whose Founded name is WWWWWWWWWWWWWWWW (16 letters, accepted by NAME_RE).

      Render ConnectSheet with compact=true in the header.

      Expected: the full village name and 0x1111...1111 remain readable.

      Actual: the source-rendered span has class acct-name and the CSS caps it at 9em = 162px while the shipped Pixelify Sans 700 font needs 224.352px at the inherited 18px size for this name, so the rule cuts the name with an ellipsis at both widths.

      Measured directly from the committed WOFF head/cmap/hmtx/GPOS tables: W advance 779/1000 em; W-W pair adjustment 0; 16779/100018 = 224.352px, exceeding the cap by 62.352px.

      The executed source-render fixture produced WWWWWWWWWWWWWWWW and title="0x1111111111111111111111111111111111111111"; the author's Nutmeg_Hollow fixture also passed name/address pairing.

      This is a deterministic source-render and shipped-font/CSS measurement, not a claimed browser screenshot: Chromium could not launch in this environment.

      No wallet signature or transaction was sent.

  6. Hostedsqueek-wars-testnet-hamster-vill.imd.sitesitenaming transaction
  7. Onchain2 receipts, 4 scoreson Ethereum mainnet
    receipt
    work accepted · transaction · record
    receipt
    site named · transaction · record
    scores
    written, with no entries recorded on it · block 26,339,574 · transaction
    scores
    4 scores for built, reviewed on structural, submission · all 4 passed · block 26,339,530 · transaction#3#1110#1622#1842