web reimplementation of Sigmar's Garden https://bits.ondrovo.com/sigmar/
Ondřej Hruška 6a0a233671
Merge branch 'recursive'
9 months ago
images improve board effects and design, add more accurate tile graphics 9 months ago
.gitignore improve board effects and design, add more accurate tile graphics 9 months ago
README.md update readme 9 months ago
index.html bump scripts 9 months ago
script.js remove old placer, change Try Again to do repeated retry (avoids the generation time) 9 months ago
style.css added new placement rules to make games more challenging 9 months ago

README.md

Sigmar's Garden

This project implements the Sigmar's Garden mini-game from Zachronics' Opus Magnum in HTML5, JavaScript, and SVG.

Play on-line at https://bits.ondrovo.com/sigmar.

The game is fully client-side and static, you can simply download it and open locally as well.

Tips

  • "Pretty graphics" are disabled by default to give new users a smoother experience. Tap the Effects button to see if you like it and it doesn't lag the browser too much.
  • Settings are saved in the browser.
  • There is a Undo button! Look top left. It's dimmed when there's nothing to undo.
  • You can copy the URL to share a particular board setup

Game rules

There are 55 marbles on the board, composed as follows:

  • 8 pieces of the four Elements: Air, Water, Fire, and Earth (total of 32)
  • 4 pieces of Salt
  • 5 metals and 1 Gold
  • 5 pieces of Mercury
  • 4 pairs of Vitae and Mors

Your goal is to clear the board. For a marble to be removed, it must be combined with another suitable marble. Further, it must have three or more contiguous free tiles around it.

Reaction rules:

  • Vitae reacts only with mors
  • Elements react with the same element kind, or with Salt
  • Salt reacts with elements or with itself
  • Metals react with mercury, but they unlock one by one, from the most common lead to gold (see below)
  • Gold is removed by itself as the last metal

Salt works as a wildcard of sorts, but don't be fooled - some boards require you to use it as a wildcard, some can be solved with salt matched only to salt, some might even require you to do so. When you match salt with an element, you naturally must use another salt with the same element elsewhere, they're all placed in pairs. Using salt as a wildcard (or alone choosing one of several available pairings) requires some forethought or luck.

The metals sequence is as follows:

  1. Lead + Mercury
  2. Tin + Mercury
  3. Iron + Mercury
  4. Copper + Mercury
  5. Silver + Mercury
  6. Gold

Here is a diagram from the original game (hosted on Steam Community)

Rules sheet

User Interface Explanation

The user interface contains a few buttons and toggles:

  • Randomize - start a new game with a random shape and marble placement
  • Try Again - reset the current game to its initial arrangement
  • Undo - reverts one game action (reaction of two marbles). There is no limit on how many steps you can undo.

The bottom left corner contains minor buttons and settings:

  • Help - links you to this page with the README file
  • Fullscreen - toggles fullscreen. This is useful on a phone to hide the annoying address bar.
  • Effects - enable graphic effects that look pretty but perform poorly on phones or browsers without hardware acceleration. Glow is replaced with a solid circle, for example.
  • Dim Blocked - highlight marbles that can be played by dimming the others. This makes the game much harder, but is more realistic.
  • Sloppy Gen - allow sloppy board filling. Use if building the board takes too long on your computer. May result in uglier and/or easier boards.

Settings

The game saves its persistent settings in your browser's localStorage.

Settings can be manipulated through the GUI, through some GET parameters, and via JavaScript API in dev tools. The function of interest is called game.setCfg({key: value, ...}).

Here's the settings object. Please refer to the source code, as this is internal API and may be extended or changed without updating this reference. Search for SettingsStorage.

{
  log: 'info', // default log level
  retryTemplate: 30,    // retry attempts within one template
  attemptTemplates: 50, // number of templates to try on failure
  svgEffects: false,    // fancy mode
  dimBlocked: true,     // highlight active marbles
}

GET Arguments

The game can be parametrised by GET arguments you add to the URL. This can be used for bookmarks or to share a particular board.

  • debug=1/0 - enable debug, or disable debug and trace logging levels
  • trace=1/0 - toggle trace logging level
  • log=level - select logging level: trace, debug, info, warn, error
  • seed=123 - set random seed, must be numeric. Share the current board by copying the URL
  • rnd=1 - don't put the seed in URL, so you can randomize by pressing Refresh (F5)
  • template=star - set board template (shape in which the marbles are arranged). See the source code for a list of templates. The currently used template is also printed to the debug console for convenience. Can be combined with 'rnd' or 'seed'.

Note that some templates are hard to fill, so the engine can give up and switch to a different random template.

Algorithm Quirks

Every board must be solvable, otherwise it wouldn't be much of a game. Generating a valid board turned out quite a bit more challenging than I thought. My algorithm is based in some heuristics and luck.

To make things more fun, besides the marble matching rules, the board must be laid out in one of several pre-defined shapes of exactly 55 tiles. The algorithm can sometimes get itself into a dead end while placing marbles on the board. After some experimentation I settled on a recursive algorithm with a heuristic and backtracking. There are configurable retry limits and max recursion / retry counter as a failsafe. If the given template fails many consecutive times, the algorithm opts to switch to a different template. Some templates are harder than others, and some random seeds just seem to have a problem.

I added a few extra rules to the generation algorithm to make the boards harder: Vitae and Mors should not appear as the first few marbles to remove, since they tend to eliminate any choice; and metals start a few levels deeper still. This gives the player a lot more room to make a mistake in the beginning. At least you can enjoy the Undo and Try Again buttons!

If you're curious about the inner workings, open dev tools and enable debug logging with the debug=1 GET parameter.