Game Gallery

All 6 games rendered simultaneously. Each instance is independent with its own canvas, state, and image cache.

View source
import './js/hex-controller-entry.js';

// Mount a map into any container — one line per game
const map = HexApp.createMapController(
  document.getElementById('my-container'),
  { game: 'nukes', seed: 'showcase', size: 4, players: 4, bgColor: '#1a2e1f' }
);

// Switch styles at runtime
map.setStyle('kenney');

// Each instance is fully independent — own canvas, state, image cache
const map2 = HexApp.createMapController(el2, { game: 'twilight', seed: 'showcase' });
// Destroying one does not affect the other

Programmatic Control

Seed-based reproducibility, hex editing, highlights, and live event stream.

View source
const map = HexApp.createMapController(container, {
  game: 'nukes', seed: 'hello-world', size: 4, players: 4
});

// Reproducible generation — same seed = same map every time
map.regenerate({ seed: 'new-seed' });

// Inspect hex data
const hex = map.getHexAt(1, -1);  // { id, q, r, type, label }
const all = map.getHexData();      // full hex array copy

// Edit individual hexes
map.setHexType(0, 0, 'water');

// Highlights (non-destructive overlays)
const waterHexes = all.filter(h => h.type === 'water');
map.highlightHexes(waterHexes, { color: '#00bcd4', opacity: 0.35 });
map.clearHighlights();

// Export
const svg = map.exportSVG();                          // SVG string
const blob = await map.exportPNG({ scale: 2 });       // PNG Blob

// Events
map.on('hexClick', ({ hex }) => console.log(hex));
map.on('regenerate', ({ hexes, seed }) => { });

Interactive Map

Hex Info

Click a hex to inspect

Event Log

Ready.

Map Data

Render Hooks

Custom rendering via tilePainter, overlayProvider, and afterRender hooks. Pass them in the options object at creation time.

Hook signatures
const map = HexApp.createMapController(container, {
  game: 'nukes',
  hooks: {
    // Replace default tile rendering entirely
    tilePainter: function(ctx, hex, { center, corners, hexSize }) {
      ctx.fillStyle = myGradient;
      ctx.fill();
      return true;  // return true = skip default rendering
    },

    // Add a translucent colour overlay per hex (non-destructive)
    overlayProvider: function(hex) {
      if (hex.type === 'water') return { color: '#00bcd4', opacity: 0.2 };
      return null;  // null = no overlay
    },

    // Draw on top of everything after the render pass completes
    afterRender: function(ctx, hexes, controller) {
      // Full canvas 2D context — draw tokens, labels, fog, anything
    }
  }
});

tilePainter

Gradient fills replacing default colours. Returned true prevents default rendering.

overlayProvider

Per-hex colour tinting based on terrain type. Non-destructive overlay.

afterRender

Drawing custom markers on top of rendered hexes. Full canvas context access.

Multi-Style Comparison

Same seed, same game, different visual styles side by side. Styles swap at runtime without regenerating.

View source
// Same seed produces identical terrain layout across all styles
['artistic', 'classic', 'kenney', 'realistic'].forEach(style => {
  HexApp.createMapController(container, {
    game: 'nukes', seed: 'compare', size: 3, players: 3, style
  });
});

// Or switch an existing map's style without regenerating
map.setStyle('kenney');  // re-renders with new tileset, same hexes