Polar Games

A bubble sorting puzzle with 60 levels · 1.0.0

Snowmates

This guide explains how to install, customize and update the game. Pick your language at the top; screenshots stay in English.

Version 1.0.0 Edition Standalone buyer edition

This guide works without internet. Images, styles and scripts are already inside this file.

Contents
  1. Overview
  2. Quick installation by FTP
  3. Requirements and sound
  4. Controls and how the game works
  5. Screens and controls explained
  6. Map of the files
  7. Names you will find in the code
  8. Customizing texts, images and sounds
  9. Languages
  10. Local saves
  11. Optional development
  12. Updating and cache
  13. Licenses
  14. Troubleshooting
  15. Frequently asked questions
  16. Support

1 Overview

Snowmates is an HTML5 sorting puzzle game. Snow animals wait inside bubbles; the player taps one and it jumps to the top bubble that shows its kind. Three of a kind fill a top bubble and a new one arrives. An animal with no top bubble waits in the tray, which has only 5 spots. The game has 60 levels in 6 worlds (Pine Woods, Frozen Lake, Igloo Village, Aurora Night, Glacier Peaks and Crystal Cave) and 12 animals to collect.

Around the levels there is a daily level made from the date, an album with a card for each of the 12 animals, a snow village on the home screen with 6 spots to decorate, 3 helpers paid with snowflakes, a guided tutorial with a pointing hand on levels 1 and 2, and narration in English, Portuguese and Spanish. The interface has 14 languages.

The game runs in any modern browser on phones, tablets and computers. It is drawn as a portrait column; on a wide screen the column stays in the middle and the sides show the same background, blurred. It uses plain HTML, CSS and JavaScript modules: no framework, no build step to play, no server code, no ads, no store, no ranking and no accounts.

2 Quick installation by FTP

Installing takes a few minutes if you have FTP access or a file manager in your hosting panel.

  1. 1. Extract snowmates-static-1.0.0.zip on your computer.
  2. 2. Connect to your hosting by FTP or its file manager and open the folder where the game should live, for example public_html/games/snowmates/.
  3. 3. Upload only the contents of the game/ folder, so that index.html sits directly inside the target folder.
  4. 4. Keep assets/, src/, favicon.ico and the three style-*.css files beside index.html, with names and letter case exactly as extracted.
  5. 5. Open https://your-domain.example/games/snowmates/ in a modern browser.
Warning Do not upload the source/ folder, the documentation/ folder or the ZIP itself. Players need no Node.js, PHP, database or account.

3 Requirements and sound

  • Any static web hosting with HTTPS (or HTTP). Opening index.html directly from the disk (file://) is not supported, because browsers block JavaScript modules that way.
  • A current browser: Chrome, Edge, Firefox or Safari, on desktop or mobile.
  • Browsers start sound only after a user gesture. The game opens on a tap-to-start screen and only then plays music, effects and voice lines.
  • When the page is hidden, the sound fades out over 30 seconds and everything pauses after 60 seconds; it comes back when the player returns.

4 Controls and how the game works

Tap or click an animal inside a bubble. If a top bubble shows its kind, it jumps there; 3 of a kind fill the top bubble, which leaves and makes room for the next one. If no top bubble fits, the animal waits in the tray and leaves by itself when its bubble arrives. The level is lost when the 5 tray spots are full and nothing fits; a second chance (5 snowflakes, once per level) empties the tray and adds a spot. Holding an animal calls every animal of the same kind in that bubble at once. Undo takes back the last tap if it went to the tray.

Stars depend on how full the tray got: 3 stars if it never held more than 3 animals, 2 stars with 4, and 1 star with 5 or after a second chance. Snowflakes are the only currency. The player starts with 6 and earns the stars of each win, plus 2 for a treasure chest emptied in time, 1 for a family trio (three animals from the same bubble), 1 for each Golden Ornament and 5 for the daily level. Helpers cost snowflakes: Sled (3) fills the fullest top bubble, Shovel (3) clears the tray and the animals come back when their bubble opens, and Blizzard (2) groups the animals by kind. They unlock on levels 3, 5 and 7, and the first use of each one is free.

New pieces are introduced one at a time with a one-sentence card: snow wreath (level 4), calling all animals of a kind (6), locked chest and key (7), free top bubble (8), Golden Ornament (9) and treasure chest (11). Levels 1 and 2 are guided: a hand points at the animal to tap and a caption at the bottom explains the goal and the tray. Every level has a solution that needs no helper and gives 3 stars; npm test proves it by playing all 60 levels.

Settings (the gear) has volume sliders for music, effects and voice, vibration, reduced motion and the language list. During a level the same panel also offers Resume, Restart and Home.

5 Screens and controls explained

Title screen: the first tap starts the game and unlocks sound.
Title screen: the first tap starts the game and unlocks sound.

Marks on the screenshot

  1. Tap to start
Home (My Snow Village): the play button with the next level, the snowflakes, the settings, the village with the
animals you found and the decorations, and the bar with Album, Journey and Daily.
Home (My Snow Village): the play button with the next level, the snowflakes, the settings, the village with the animals you found and the decorations, and the bar with Album, Journey and Daily.

Marks on the screenshot

  1. Play
  2. Snowflakes
  3. Settings
  4. Snow village and decorations
  5. Album, Journey and Daily
Journey: the 60 levels on one path. The ribbon shows the world and the counter shows the stars earned.
Journey: the 60 levels on one path. The ribbon shows the world and the counter shows the stars earned.

Marks on the screenshot

  1. Current level
  2. World name
  3. Stars earned
  4. Back
A level: the top bubbles with the kinds asked for, the bubbles with animals, the tray and the three helpers.
A level: the top bubbles with the kinds asked for, the bubbles with animals, the tray and the three helpers.

Marks on the screenshot

  1. Level number
  2. Snowflakes
  3. Pause
  4. Top bubbles
  5. Bubbles with animals
  6. Tray
  7. Helpers
Level 1: the hand points at the animal to tap and the caption explains the goal.
Level 1: the hand points at the animal to tap and the caption explains the goal.

Marks on the screenshot

  1. Guiding hand
  2. Tutorial caption
Win: stars, snowflakes earned and the buttons to go on.
Win: stars, snowflakes earned and the buttons to go on.

Marks on the screenshot

  1. Stars
  2. Snowflakes earned
  3. Next
Album: the 12 animals. An animal already found opens a card with its name, a fact and how many times it was
found.
Album: the 12 animals. An animal already found opens a card with its name, a fact and how many times it was found.

Marks on the screenshot

  1. Animal found
  2. Not found yet
  3. Animals found
Settings: volume of music, effects and voice, vibration, reduced motion and language.
Settings: volume of music, effects and voice, vibration, reduced motion and language.

Marks on the screenshot

  1. Volume sliders
  2. Vibration and reduced motion
  3. Language
Daily Flurry: one new level each day, worth 5 extra snowflakes.
Daily Flurry: one new level each day, worth 5 extra snowflakes.

Marks on the screenshot

  1. Today
  2. Play today

6 Map of the files

game/ is the ready-to-host game. source/ has the same editable files plus the tests, a local preview server, the level generator and the build command. Code comments are in Portuguese. The code keeps some internal names from an earlier theme (fish, pearls, kelp, reef and others): they are only names, and the section "Names you will find in the code" translates them.

game/                        upload these contents to your web host
  index.html                 entry page
  favicon.ico                browser tab icon
  style-1-base.css           styles, loaded in this order
  style-2-glass-panels.css
  style-3-polish.css
  src/main.js                start-up, resize, frame loop, test shortcuts
  src/ui.js                  screens and panels (DOM)
  src/game.js                one match: touch -> rules -> drawing -> sound
  src/sim/                   rules, simulated players, level builder
  src/levels.js              the 60-level curve and the daily level
  src/level-seeds.js         one seed per level (written by npm run levels)
  src/render/                canvas drawing, art loading, effects
  src/reef.js                home screen: found animals and decoration spots
  src/audio/sound.js         music, sound effects, narration
  src/locales.js             texts: English, Portuguese, Spanish
  src/locales-more.js        texts: the other 11 languages
  src/config.js              feel numbers, volumes, decorations, save key
  src/save.js, storage.js, i18n.js, viewport.js, fullscreen.js
  assets/art/                images (WebP)
  assets/fonts/              Fredoka font and its license
  assets/music/              reef.mp3, play-a.mp3, play-b.mp3
  assets/sfx/                11 recorded effects (MP3)
  assets/voice/en|pt|es/     narration, 19 files per language (MP3)
  DOCUMENTATION.txt          short note that points to this guide
source/                      the same editable files, plus:
  package.json               npm test, npm run build, serve, levels
  package-lock.json
  README.md, LEVELS.md
  test/                      node --test tests
  tools/build.mjs            copies the game into dist/
  tools/serve.mjs            local preview server
  tools/gen-levels.mjs       level generator
documentation/index.html     this guide (offline, 14 languages)
documentation/customization.html   step-by-step customization guide
documentation/img/           the screenshots of both guides
DOCUMENTATION.html           shortcut to this guide
CUSTOMIZATION.html           shortcut to the customization guide
START-HERE.txt, CHANGELOG.txt
THIRD-PARTY-LICENSES/        font license
  • src/config.js: game feel numbers in one place (FEEL: flight time, springs, shake, particles, hint delay, vibration), default volumes, decorations, lesson cards and the save key.
  • src/locales.js and src/locales-more.js: every interface text in the 14 languages; src/i18n.js picks the language.
  • src/sim/: the rules with no drawing (sim.js), the simulated players (bots.js) and the level builder (levelgen.js). src/levels.js holds the curve of the 60 levels and src/level-seeds.js holds one seed per level.
  • src/game.js runs a match, src/render/ draws it on the canvas (view.js, art.js, fx.js), src/reef.js draws the home screen with the animals you found and the decoration spots, src/ui.js builds the screens and panels, and src/main.js starts everything.
  • style-1-base.css, style-2-glass-panels.css and style-3-polish.css: the styles, loaded in this order. A rule in a later file overrides the same rule in an earlier one, so edit the last file that sets it.
  • assets/: images (art/, WebP), the font (fonts/), music (music/), sound effects (sfx/) and narration (voice/en, voice/pt, voice/es), all MP3.

7 Names you will find in the code

Snowmates was made from an earlier game, and the code and the art files keep some of its internal names. They are only names: the player never sees them. The list below shows what each one is in this game. Rename them only if you are comfortable changing the code that uses them.

# name in the code or file -> what it is in the game
# (one name per line, so the block also fits a phone screen)
fish, species, sp -> the animals (SPECIES lists the 12 art sets)
clown -> Maple, the fox
puffer -> Pip, the penguin (the mascot)
angel -> Polo, the polar bear
eel -> Luna, the narwhal
seahorse -> Pebble, the seal
star -> Wally, the walrus
crab -> Rudy, the reindeer
tang -> Fuzzy, the yeti
box -> Chilly, the snowman
banner -> Ruby, the cardinal
jelly -> Hops, the bunny
octo -> Flurry, the ice dragon
gold -> the Golden Ornament
pearls, pearl -> snowflakes (the only currency)
kelp -> the snow wreath that holds a bubble
clam-lock, padlock, key -> the locked chest, its lock and its key
oyster -> the treasure chest bubble
scoop, sweep, whirl -> the helpers Sled, Shovel and Blizzard
pelican, crab-broom, whirl (images) -> the pictures of the Sled, the Shovel and the Blizzard
shoal, callShoal -> all animals of one kind in a bubble (hold to call them)
reef, Reef, myReef -> the home screen: My Snow Village
turtle (image), deepmark -> the icicle badge on the last level of each world
coral, kelp, ship, glow, ice, deep -> the 6 worlds: Pine Woods, Frozen Lake, Igloo Village, Aurora Night,
  Glacier Peaks, Crystal Cave (bg-*.webp)
decor-amphora, -anchor, -arch, -boat, -castle, -chest, -helmet, -lighthouse, -tiki -> the 9 village
  decorations: gift pile, Christmas tree, ice arch, ice castle, signpost, lamp post, ice fountain, igloo,
  campfire (in this order)
reef.mp3, play-a.mp3, play-b.mp3 -> menu music, worlds 1 to 3, worlds 4 to 6
ui-btn-coral, ribbon-coral, ... -> red buttons and ribbons: "coral" is only a color name

8 Customizing texts, images and sounds

Note Not a programmer? The Customization Guide shows every change step by step, with numbered screenshots of the game. It is in English. Open CUSTOMIZATION.html in the main folder of the download, or documentation/customization.html.

Customization Guide (step by step, in English)

Texts: open src/locales.js (English, Portuguese and Spanish) or src/locales-more.js (the other 11 languages) and change the text after each key. Keep the keys and placeholders such as {n} unchanged; npm test checks that all 14 languages still have the same keys. The names of the 12 animals are in NAMES, in src/locales.js.

Images: replace a file in assets/art/ with another WebP of the same name and similar proportions. Each animal has five files, for example clown.webp (Maple the fox), clown-x0.webp, clown-blink.webp, clown-happy.webp and clown-worry.webp. Backgrounds are bg-home.webp and one per world (bg-coral.webp, bg-kelp.webp, bg-ship.webp, bg-glow.webp, bg-ice.webp, bg-deep.webp); decorations are decor-*.webp; the logo is logo.webp and the browser tab icon is favicon.ico. The old file names are explained in the section "Names you will find in the code".

Levels: params(n) in src/levels.js sets how many animals, kinds, bubbles and obstacles level n has. After changing it, run npm run levels to choose new seeds (it rewrites src/level-seeds.js and LEVELS.md) and npm test to confirm that every level can still be won. Helper prices are COST in src/sim/sim.js; the starting snowflakes, the levels that unlock helpers, the lesson cards and the decorations are in src/config.js.

Colors and sizes of the interface are in the three style-*.css files, measured in --u (1% of the width of the game column). The game title is in index.html and in assets/art/logo.webp; the line under the logo is the tagline text.

Music, sound effects and narration

Music: assets/music/reef.mp3 plays on the menus, play-a.mp3 in worlds 1 to 3 and play-b.mp3 in worlds 4 to 6. To change a track, replace the MP3 keeping the name. The game starts the next loop a few seconds before the end of the file, so that it blends with the fade-out; set those seconds per track in MUSIC_TAIL, in src/audio/sound.js. To remove the music, delete the files in assets/music/: the game notices the missing file once and stays silent. To avoid that request altogether, pass an empty name to the two startMusic(...) calls, in src/main.js and src/ui.js.

Sound effects: the short sounds of play (tap, tray, pop, buttons, the rising notes) are synthesized by the SYNTH table in src/audio/sound.js, so they have no file. The 11 recorded effects are the MP3 files in assets/sfx/ (win, fail, star, unlock, gold, scoop, sweep, whirl, oyster, chance, pearl), with their levels in the GAIN table. Replace a file keeping the name, or delete it and remove its entry from GAIN to silence that effect.

Narration: assets/voice/en/, assets/voice/pt/ and assets/voice/es/ each hold 19 MP3 files: intro (the welcome on level 1), g1a, g1b, g1c, g2a, g2b, g2c (the tutorial captions) and name_0 to name_11 (the album cards, in the order of NAMES). The other 11 languages show only the caption. To re-record a line, replace the file. To add narration for a language, record the 19 files in assets/voice/<code>/ and add the code to VOICE_LANGS in src/audio/sound.js. To remove narration, empty VOICE_LANGS (or remove one code) and delete the folders; the speaker button of the album card disappears by itself.

Players control the three volumes in Settings; the starting values are VOL in src/config.js. If you change the tutorial captions or the animal names, re-record or remove the matching narration files, because the voice says the original sentences.

Warning Keep the save key unchanged on a live site. A different key makes the game ignore existing progress and start a new save.

9 Languages

The game has 14 languages: English, Português (Brasil), Español, Français, Deutsch, Italiano, Nederlands, Polski, Türkçe, Русский, Bahasa Indonesia, 日本語, 한국어 and 简体中文. It follows the browser language on the first visit and the player can change it in Settings. Narration exists in English, Portuguese and Spanish. English, Portuguese and Spanish are the reference texts; the other 11 languages were not reviewed by native speakers, so a native review is recommended before a launch in those markets. The bundled font covers Latin letters; Russian, Japanese, Korean and Chinese use a font of the device.

To force a language, add ?lang=pt (or another code) to the game address.

To add a language, copy one of the blocks in src/locales-more.js, translate it, add it to MORE at the end of that file, and add its code and name to LANGS, HTML_LANG and NUMBER_LOCALE in src/locales.js. The language test in test/i18n.test.mjs expects 14 languages, so update that number too.

10 Local saves

  • Progress (level reached, stars, snowflakes, album, lesson cards already seen, decorations, daily results and settings) is saved in the browser localStorage of each device.
  • There are no accounts or cloud saves. Clearing site data resets the progress on that device.
  • The two keys are shown below. Their prefix is STORAGE_PREFIX in src/config.js.
snowmates.template.save.v1.progress
snowmates.template.save.v1.lang

11 Optional development

This section is only for changing the code. The game/ folder already contains the finished game, so installing it needs no Node.js. The game has no dependencies and no compile step: npm run build only copies the files into source/dist/, which is identical to game/.

1. Install Node.js. Open https://nodejs.org/en/download and choose the latest Node.js 26 LTS installer for your system (minimum 26.13). npm is included.

Windows: run the .msi installer, keep npm and Add to PATH enabled, finish the installation and reopen Command Prompt. macOS: run the official .pkg installer and reopen Terminal. Linux: follow the instructions on the official download page for your distribution, including npm.

2. Check the installation. Run node --version and npm --version separately. Both must print a version number, and Node.js must be 26.13 or newer. If a command is not found, reopen the terminal and check the installation.

node --version
npm --version

3. Extract the complete ZIP first and open its source/ folder, where package.json is. Windows: type cmd in the address bar of that folder in File Explorer. macOS and Linux: open Terminal and use cd with the folder path in quotes.

4. Run the commands below one by one. npm ci checks the lock file (nothing is downloaded, the project has no dependencies). npm test plays all 60 levels with a simulated player and checks the rules, the 14 languages and the save key; stop and fix any error before going on.

npm ci
npm test

5. Preview: npm run serve starts a local server; open http://localhost:5195/ in your browser, play a level, and stop the server with Ctrl+C.

npm run serve

6. Build: npm run build empties source/dist/ and copies index.html, favicon.ico, the three style-*.css files, src/ and assets/ into it. dist/ is what you publish; while the source is unchanged it matches game/ file by file.

npm run build

7. Publish: back up the game on your website, then upload the contents of dist/ in place of the old files, keeping the folders. If you deleted or renamed a file, delete the old one on the server yourself. Clear the browser cache to see the new version (see below).

Note Troubleshooting: ENOENT or a missing package.json means the terminal is in the wrong folder. EBADENGINE means Node.js is too old. If PowerShell blocks npm.ps1, use Command Prompt instead; do not change security settings.

Test shortcuts (local addresses only)

The shortcuts below work only when the page address is localhost, 127.x or a private network address (192.168.x). On any public address they are ignored, so players cannot use them. ?lang=pt (or another language code) is not a test shortcut and works on any address.

  • ?level=12 opens level 12 directly.
  • ?unlock unlocks all 60 levels.
  • ?screen=journey opens a screen directly (home, journey, album or daily).
  • ?reduced forces reduced motion.
  • ?qa adds a simulated player for automated tests: run __snowmates.auto(999, 350, 'good') in the browser console. The window.__snowmates object (the running game) also exists only on local addresses.
http://localhost:5195/?level=12&lang=es

12 Updating and cache

Clearing the cache without losing progress

Progress is stored in this browser, not on the server. Clearing cached images and files, or doing a hard reload, keeps your progress.

Computer: press Ctrl+F5 on Windows and Linux, or Cmd+Shift+R on macOS. Phone: in the browser settings, choose the option to clear cached images and files.

Do not choose cookies and site data, or clear site data, for the game's address. That deletes the local save.

13 Licenses

The game code and artwork are supplied under the license of the item you purchased. The music, sound effects and narration used by the game are included in the package and can be replaced or removed (see the customizing section).

The Fredoka font is used under the SIL Open Font License 1.1; its complete license text is in THIRD-PARTY-LICENSES/ and in game/assets/fonts/LICENSE-Fredoka-OFL.txt. The game has no third-party code and no npm dependencies.

14 Troubleshooting

  • Blank page: the game was opened from the disk or a file is missing. Use a web host and keep assets/, src/ and the three style-*.css files next to index.html.
  • No sound: tap the screen once; check the device is not silent and the volume sliders are up.
  • Old version after an update: clear the browser cache (see below).
  • Images missing after replacing art: check the file name, extension and letter case.
  • An address such as ?level=5 does nothing on your website: test shortcuts only work on local addresses (see the development section).

15 Frequently asked questions

Does the game work without internet?
The game calls no external services. It is not an installable offline app, so players need to reach your web address to load it.
Can I add ads, a store, cloud saves or a ranking?
Not in this edition. It has no ad, payment, sync or ranking code. Adding them is developer work that needs your own accounts.
Can I publish it on game portals or app stores?
Yes, within the terms of the license you purchased. Wrapping it as an app needs your own developer accounts and tools.
Do I need Node.js?
Only to run the tests or rebuild after editing. Installing and playing needs only a web host.
How do I reset the progress while testing?
Clear the site data for the game address in the browser, or run localStorage.clear() in the browser console. Settings has no reset button.

16 Support

Questions or problems: write to willian@polargames.com.br with your purchase code, the browser and a short description or screenshot.

Support request

When you write to support, include the browser and device, the game version, the page address, the steps that caused the problem, a screenshot and the first error shown in the browser console. Never send passwords, payment details or secret keys.