npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@enigma-lake/tower-play-controller-sdk

v2.0.12

Published

A React component library for building gameplay interfaces

Downloads

714

Readme

TowerPlayController SDK

The TowerPlayController SDK provides a fully-configurable wager & play-control interface for Tower-style games.
It supports manual play, optional autoplay, optional risk selection, currency management, play amount input, and custom widgets.

Configuration is driven by the PlayControllerProps type, which supports two modes:

  • Full Mode (default) — risk & autoplay enabled (flag omitted or false)
  • Simplified Mode — risk & autoplay disabled when withoutRiskAndAutoplay: true

This keeps backwards compatibility with existing games (they don't need to pass the flag), and lets new games opt into a simpler controller by setting the flag.


🚀 Installation

npm install @enigma-lake/tower-play-controller-sdk

Import styles:

import "@enigma-lake/tower-play-controller-sdk/dist/style.css";

🧠 AutoManualPlayProvider

Wrap your game UI inside:

<AutoManualPlayProvider config={config}>
  {({ autoPlay, manual, mode }) => (
    // your UI
  )}
</AutoManualPlayProvider>

The provider manages all logic:

| Feature | Full Mode (default) | Simplified Mode (withoutRiskAndAutoplay: true) | |------------------------|------------------------------------------|--------------------------------------------------| | Autoplay | ✅ Enabled (requires onAutoPlay) | ❌ Disabled | | Risk Difficulty | ✅ Enabled (risks/currentRisk/onRiskChange) | ❌ Hidden | | Dropdown Risk Colors | ✅ Required | ❌ Not used | | Manual Play | ✅ Enabled | ✅ Enabled | | Play Amount | ✅ Enabled | ✅ Enabled |


🔧 Prop Structure

Below is an overview of the configuration props.


1. currencyOptions

{
  current: Currency;
  available: Currency[];
}

2. Styling (Conditional)

Panel

panel: {
  bottom?: string;
  bgColorHex: string;
  bgColorOpacity?: number;
}

Dropdown

Full Mode (default)
withoutRiskAndAutoplay omitted or false:

dropdown: {
  bgColorHex: string;
  riskColorConfig: {
    LOW: string;
    MEDIUM: string;
    HIGH: string;
  };
}

Simplified Mode
withoutRiskAndAutoplay: true:

dropdown: {
  bgColorHex: string;
}

3. Actions

Shared (both modes):

onPlay: () => void;
onCashout: () => void;

Only required in Full Mode (withoutRiskAndAutoplay omitted or false):

onAutoPlay: (selection: number[], next: () => void, stop: () => void) => void;
onAutoPlayStop?: () => void;

In Simplified Mode, onAutoPlay and onAutoPlayStop are not required and are effectively ignored.


4. Play Options (Conditional)

Full Mode (default)

playOptions: {
  isPlaying: boolean;
  canCashout: boolean;
  disabledController: boolean;
  displayController: boolean;

  // RISK SYSTEM
  risks: RiskTypes[];
  currentRisk: RiskTypes;
  onRiskChange(risk: RiskTypes): void;

  // AUTOPLAY SYSTEM
  autoPlayDelay?: number;
  showAutoPlayToast({ type, message }): void;

  disabledMenu: boolean;

  playHook(): {
    playLimits?: PlayLimits;
    playAmount: number;
    setPlayAmount(value: number): void;
  };

  totalBalance: number;
}

Simplified Mode

withoutRiskAndAutoplay: true:

playOptions: {
  isPlaying: boolean;
  canCashout: boolean;
  disabledController: boolean;
  displayController: boolean;

  disabledMenu: boolean;

  playHook(): {
    playLimits?: PlayLimits;
    playAmount: number;
    setPlayAmount(value: number): void;
  };

  totalBalance: number;
}

Risk/autoplay properties (risks, currentRisk, onRiskChange, autoPlayDelay, showAutoPlayToast) are not part of the simplified mode.


5. Widgets

leftWidgets: Widget[];
centerWidgets: Widget[];
rightWidgets: Widget[];

🎮 Example Usage

Example 1 — Full Mode (default: risk + autoplay enabled)

import {
  AutoManualPlayProvider,
} from "@enigma-lake/tower-play-controller-sdk";
import { Currency } from "@enigma-lake/zoot-platform-sdk";

const config = {
  // withoutRiskAndAutoplay omitted or false => FULL mode
  currencyOptions: {
    current: Currency.SWEEPS,
    available: [Currency.SWEEPS, Currency.GOLD],
  },

  onPlay: () => console.log("Play"),
  onAutoPlay: (selection, next, stop) => {
    console.log("Autoplay selection:", selection);
    next(); // continue to next round
  },
  onAutoPlayStop: () => console.log("Autoplay stopped"),
  onCashout: () => console.log("Cashout"),

  playOptions: {
    displayController: true,
    isPlaying: false,
    canCashout: false,
    disabledController: false,
    disableInput: false,

    // Risk controls
    risks: [RiskTypes.LOW, RiskTypes.MEDIUM, RiskTypes.HIGH],
    currentRisk: RiskTypes.LOW,
    onRiskChange: (risk) => console.log("Risk:", risk),

    // Autoplay
    autoPlayDelay: 1000,
    showAutoPlayToast: ({ type, message }) =>
      console.log(`${type}: ${message}`),

    disabledMenu: false,

    playHook: () => ({
      playLimits: { min: 1, max: 100 },
      playAmount: 10,
      setPlayAmount: (v) => console.log("Amount:", v),
    }),

    totalBalance: 100,
  },

  panel: {
    bottom: "60px",
    bgColorHex: "#08643F",
    bgColorOpacity: 0.8,
  },

  dropdown: {
    bgColorHex: "#123456",
    riskColorConfig: {
      LOW: "#1AE380",
      MEDIUM: "#FAEB78",
      HIGH: "#FF5646",
    },
  },

  leftWidgets: [],
  centerWidgets: [],
  rightWidgets: [],
};

export const GameExampleFull = () => (
  <AutoManualPlayProvider config={config}>
    {({ mode }) => (
      <div>Mode: {mode}</div>
    )}
  </AutoManualPlayProvider>
);

Example 2 — Simplified Mode (withoutRiskAndAutoplay: true)

import {
  AutoManualPlayProvider,
} from "@enigma-lake/tower-play-controller-sdk";
import { Currency } from "@enigma-lake/zoot-platform-sdk";

const config = {
  withoutRiskAndAutoplay: true, // simplified mode

  currencyOptions: {
    current: Currency.SWEEPS,
    available: [Currency.SWEEPS],
  },

  onPlay: () => console.log("Play"),
  onCashout: () => console.log("Cashout"),

  playOptions: {
    displayController: true,
    isPlaying: false,
    canCashout: false,
    disabledController: false,
    disableInput: false,
    disabledMenu: false,

    playHook: () => ({
      playLimits: { min: 1, max: 20 },
      playAmount: 5,
      setPlayAmount: (value) => console.log("New amount:", value),
    }),

    totalBalance: 50,
  },

  panel: {
    bgColorHex: "#0A3F2F",
  },

  dropdown: {
    bgColorHex: "#10243F", // no riskColorConfig here
  },

  leftWidgets: [],
  centerWidgets: [],
  rightWidgets: [],
};

export const GameExampleSimplified = () => (
  <AutoManualPlayProvider config={config}>
    {({ mode }) => (
      <div>Mode: {mode}</div>
    )}
  </AutoManualPlayProvider>
);

⭐ Features

  • Optional Risk System – enabled by default; disabled when withoutRiskAndAutoplay: true
  • Optional Autoplay – fully controlled via callbacks and delay (full mode only)
  • Dynamic Currency Management – multiple currencies supported
  • Wager Controls – validated against play limits
  • UI Widgets – customizable left/center/right areas
  • Flexible Styling – configurable colors, bottom positioning, and opacity
  • Responsive Layout – suitable for desktop and mobile

🛠 Development Notes

  • onAutoPlay / onAutoPlayStop are only required in full mode.
  • dropdown.riskColorConfig is only allowed/required in full mode.
  • Risk-related and autoplay-related fields in playOptions are removed in simplified mode.
  • Use withoutRiskAndAutoplay: true to explicitly opt into the simplified experience.