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 🙏

© 2026 – Pkg Stats / Ryan Hefner

tactica

v0.0.1

Published

A mobile-first, browser-based 2D game engine built with TypeScript. Zero external runtime dependencies, pure Web APIs.

Readme

Tactica

A mobile-first, browser-based 2D game engine built with TypeScript. Designed for touch-enabled devices with a focus on performance, accessibility, and developer experience.

Features

  • Mobile-First Input - Touch gestures, multi-touch, haptic feedback, virtual joystick, action buttons
  • Canvas Rendering - Hardware-accelerated 2D graphics with camera, sprites, tilemaps, layer management
  • Camera Effects - Shake, flash, fade, zoom effects for visual polish
  • Entity System - Flexible entity-component architecture
  • Scene Management - Multiple scenes with smooth transitions (fade, slide, zoom, wipe)
  • Physics & Collision - Simple physics with spatial partitioning
  • Particle System - Particle emitters with configurable behaviors
  • Tweening - Smooth animations with 30+ easing functions
  • UI Components - Canvas-based UI: buttons, sliders, panels, progress bars, toasts, modals, tooltips
  • Audio System - Sound playback, volume control, crossfade
  • State Management - Reactive stores with undo/redo support
  • Persistence - LocalStorage and IndexedDB backends with data migrations
  • Timer System - Game-time-aware timers with pause/resume support
  • Performance - Frame budget tracking, debug overlay, screenshot capture
  • PWA Support - Installable, offline-capable
  • Accessibility - Screen reader announcements, reduced motion support

Installation

npm install tactica

Quick Start

import {
	createEngine,
	createScene,
	createEntity,
	createInputSystem,
} from 'tactica'

// Create canvas
const canvas = document.getElementById('game') as HTMLCanvasElement

// Initialize engine
const engine = createEngine({
	canvas,
	width: 480,
	height: 800,
	backgroundColor: '#1a1a2e',
})

// Create input system
const input = createInputSystem(canvas)

// Create a scene
const gameScene = createScene({ name: 'game' })

// Create player entity
const player = createEntity({
	id: 'player',
	x: 240,
	y: 700,
	width: 40,
	height: 40,
})

gameScene.addEntity(player)

// Handle touch input
input.onTap((x, y) => {
	player.setPosition(x, y)
})

// Start game loop
engine.onBeforeUpdate((deltaTime) => {
	gameScene.update(deltaTime)
})

engine.onBeforeRender((ctx) => {
	gameScene.render(ctx)
})

engine.start()

Documentation

For comprehensive documentation, see the Tactica Guide.

Development

# Clone repository
git clone https://github.com/mikesaintsg/tactica.git
cd tactica

# Install dependencies
npm install

# Start development server
npm run dev

# Run type checking
npm run check

# Run tests
npm test

# Build library
npm run build

# Build showcase
npm run show

Factory Functions

Core Engine

| Function | Description | |--------------------------------------------------|-------------------------------------------| | createEngine(options) | Create game engine with canvas | | createScene(options) | Create a game scene | | createSceneManager(options) | Manage multiple scenes | | createEntity(options) | Create game entities | | createTimerManager(options) | Game-time timers |

Rendering

| Function | Description | |--------------------------------------------------|-------------------------------------------| | createCamera(options) | Create camera with follow/shake | | createCameraEffects(camera) | Camera effects (shake, flash, fade, zoom) | | createRenderer(context, options) | Create renderer with batching | | createViewport(options) | Viewport with scaling modes | | createSpriteSheet(options) | Sprite sheet for animations | | createAnimationPlayer(options) | Animation playback controller | | createTilemap(options) | Tile-based level rendering | | createLayerManager(options) | Render layer management | | createSpriteBatch(context, assets, options) | Batched sprite rendering | | createTrailRenderer(options) | Visual trails behind objects | | createShapeRenderer(options) | Geometric primitive drawing | | createPostProcessManager(options) | Screen-wide visual effects | | createCullingSystem(options) | Frustum/distance culling | | createLODSystem(options) | Level of detail management | | createTransitionManager(sceneManager, options) | Screen transitions |

Input

| Function | Description | |--------------------------------------------------|-------------------------------------------| | createInputSystem(canvas, options) | Touch/mouse input handling | | createKeyboardManager(options) | Keyboard input with combos | | createGamepadManager(options) | Controller input support | | createInputActionSystem(options) | Unified input with rebinding | | createVirtualJoystick(options) | Virtual joystick for mobile | | createActionButton(options) | Touch action button with cooldown |

Audio

| Function | Description | |--------------------------------------------------|-------------------------------------------| | createAudioManager(options) | Sound playback | | createMusicPlaylist(options) | Sequential music playback | | createSoundVariantPool(options) | Random sound variations | | createAudioZoneManager(options) | Spatial audio zones |

Physics & Animation

| Function | Description | |--------------------------------------------------|-------------------------------------------| | createPhysicsWorld(options) | Physics simulation | | createCollisionSystem() | Collision detection | | createTweenManager(options) | Animation tweens | | createParticleSystem(options) | Particle effects |

UI Components

| Function | Description | |--------------------------------------------------|-------------------------------------------| | createUIManager(options) | Canvas-based UI components | | createToastManager(options) | Toast notifications | | createModal(options) | Individual modal dialog | | createModalManager(options) | Modal dialogs (alert/confirm/prompt) | | createTooltipManager(options) | Tooltip system | | createTextInput(options) | Text input field | | createRadialMenu(options) | Circular selection menu | | createMinimap(options) | World overview minimap | | createNotificationManager(options) | In-game notifications |

Storage & State

| Function | Description | |--------------------------------------------------|-------------------------------------------| | createStore(options) | Reactive state management | | createComputed(compute) | Derived state values | | createDatabase(config) | IndexedDB database wrapper | | createStateManager(config) | Game state with save/load | | createSchema(options) | Data validation schema | | createLocalStorageBackend(options) | localStorage persistence | | createIndexedDBBackend(options) | IndexedDB persistence | | createMigrationRunner(options) | Data migrations | | createTabSyncManager(channelName) | Cross-tab synchronization |

Platform & Assets

| Function | Description | |--------------------------------------------------|-------------------------------------------| | createAssetManager(options) | Asset loading | | createMobileManager(options) | Mobile device features | | createAccessibilityManager(options) | Accessibility support | | createPWAManager(options) | PWA install/update | | createNetworkManager(options) | Network/multiplayer client |

Debug & Performance

| Function | Description | |--------------------------------------------------|-------------------------------------------| | createPerformanceMonitor(options) | FPS and metrics | | createDebugTools() | Debug logging | | createDebugOverlay(options) | Visual debug overlay | | createFrameBudget(options) | Frame timing budget | | createScreenshotManager(canvas) | Screenshot capture | | createEntityInspector(options) | Entity property inspector | | createCommandConsole(options) | Developer command console |

Game Systems

| Function | Description | |--------------------------------------------------|-------------------------------------------| | createBuffSystem(options) | Stackable buffs/debuffs with duration | | createHealthSystem(options) | Entity health, damage, invincibility | | createFloatingTextSystem(options) | Animated damage/pickup text | | createCollectibleSystem(options) | Pickups with drop tables and magnetism | | createSpawnerSystem(options) | Entity spawning with zones and waves | | createEffectZoneSystem(options) | Areas that trigger effects on entry | | createExperienceSystem(options) | XP tracking and level progression | | createStatisticsSystem(options) | Game stats and milestone tracking | | createObjectiveSystem(options) | Goals and progress tracking | | createStateMachine(options) | State transitions for game flow | | createBackgroundSystem(options) | Layered backgrounds with parallax | | createCrosshairSystem(options) | Desktop aiming cursor | | createEntityRendererRegistry() | Procedural entity rendering registry | | createInventorySystem(options) | Item and equipment management | | createDialogueSystem(options) | Conversation trees with branching | | createQuestSystem(options) | Quest tracking with objectives | | createCraftingSystem(options) | Item crafting with recipes |

Helper Functions

Tactica includes a comprehensive set of helper functions for game development:

Type Guards

| Function | Description | |---------------------------|--------------------------------------| | isString(value) | Check if value is a string | | isNonEmptyString(value) | Check if value is a non-empty string | | isNumber(value) | Check if value is a number (not NaN) | | isFiniteNumber(value) | Check if value is a finite number | | isBoolean(value) | Check if value is a boolean | | isNullish(value) | Check if value is null or undefined | | isDefined(value) | Check if value is defined | | isObject(value) | Check if value is a plain object | | isArray(value) | Check if value is an array | | isNonEmptyArray(value) | Check if value is a non-empty array | | isFunction(value) | Check if value is a function | | isOk(result) | Check if result is successful | | isErr(result) | Check if result is an error |

Browser & Storage Guards

| Function | Description | |--------------------------------|---------------------------------------| | hasDeviceMemory(nav) | Check for deviceMemory API | | hasGetBattery(nav) | Check for Battery API | | hasNetworkConnection(nav) | Check for Network Information API | | hasVibrate(nav) | Check for Vibration API | | hasIndexedDB() | Check if IndexedDB is available | | isIDBValidKey(value) | Check if value is valid IndexedDB key | | hasId(obj) | Check if object has id property | | hasVersion(obj) | Check if object has version property | | hasTimestamp(obj) | Check if object has timestamp |

Distance & Vectors

| Function | Description | |-----------------------------------|---------------------------------------| | distance(x1, y1, x2, y2) | Calculate distance between two points | | distanceSquared(x1, y1, x2, y2) | Squared distance (faster, no sqrt) | | distanceVec(a, b) | Distance between two vectors | | distanceVecSquared(a, b) | Squared distance between two vectors | | normalize(x, y) | Normalize a vector to unit length | | normalizeVec(v) | Normalize a vector object | | magnitude(x, y) | Get the length of a vector | | magnitudeVec(v) | Get the length of a vector object | | angleBetween(x1, y1, x2, y2) | Angle between two points in radians | | angleOf(x, y) | Angle from origin to point | | fromAngle(angle, length) | Create vector from angle and length | | addVec(a, b) | Add two vectors | | subVec(a, b) | Subtract vector b from a | | scaleVec(v, scalar) | Scale a vector | | dotVec(a, b) | Dot product of two vectors | | crossVec(a, b) | Cross product (z-component) | | rotateVec(v, angle) | Rotate a vector by angle | | perpVec(v) | Get perpendicular vector | | reflectVec(v, normal) | Reflect vector off surface |

Interpolation & Easing

| Function | Description | |----------------------------------------------|--------------------------------------| | lerp(start, end, t) | Linear interpolation | | lerpVec(a, b, t) | Linear interpolation between vectors | | smoothstep(t) | Smooth step (ease in-out) | | smootherstep(t) | Ken Perlin's smoother step | | inverseLerp(a, b, value) | Find t given value between a and b | | remap(value, inMin, inMax, outMin, outMax) | Remap value between ranges | | approach(current, target, step) | Approach target by fixed step | | damp(current, target, smoothing, dt) | Damped approach (exponential decay) | | dampVec(current, target, smoothing, dt) | Damped approach for vectors |

Clamping & Bounds

| Function | Description | |--------------------------------------------------|-------------------------------------------| | clamp(value, min, max) | Clamp number between min and max | | clampToRectangle(x, y, minX, minY, maxX, maxY) | Clamp position to rectangle | | clampToWorld(x, y, entitySize, width, height) | Clamp position accounting for entity size | | wrap(value, min, max) | Wrap value within range | | wrapToWorld(x, y, width, height) | Wrap position within world bounds |

Random

| Function | Description | |-----------------------------------------------------|-----------------------------------| | randomRange(min, max) | Random float between min and max | | randomInt(min, max) | Random integer (inclusive) | | randomElement(array) | Random element from array | | randomPosition(minX, maxX, minY, maxY) | Random position in rectangle | | randomEdgePosition(width, height, margin, offset) | Random position on rectangle edge | | randomInCircle(cx, cy, radius) | Random point inside circle | | randomOnCircle(cx, cy, radius) | Random point on circle edge | | randomDirection() | Random unit vector | | randomSign() | Random -1 or 1 | | randomBool(probability) | Random boolean |

Collision Detection

| Function | Description | |-----------------------------------------------------|---------------------------------------| | circlesOverlap(x1, y1, r1, x2, y2, r2) | Check if two circles overlap | | pointInCircle(px, py, cx, cy, radius) | Check if point is in circle | | pointInRectangle(px, py, rx, ry, rw, rh) | Check if point is in rectangle | | rectsOverlap(x1, y1, w1, h1, x2, y2, w2, h2) | Check if rectangles overlap | | circleRectangleOverlap(cx, cy, r, rx, ry, rw, rh) | Check if circle and rectangle overlap |

Angle Utilities

| Function | Description | |------------------------------------------|------------------------------------| | degToRad(degrees) | Convert degrees to radians | | radToDeg(radians) | Convert radians to degrees | | normalizeAngle(angle) | Normalize angle to [-π, π] | | angleDifference(from, to) | Shortest angular distance | | lerpAngle(from, to, t) | Interpolate angles (shortest path) | | rotateToward(current, target, maxStep) | Rotate toward target by max step |

Utility Functions

| Function | Description | |-------------------------------------------|-----------------------------------| | generateId() | Generate UUID v4 | | now() | Current timestamp in milliseconds | | deepClone(obj) | Deep clone object (JSON-safe) | | shallowEqual(a, b) | Shallow equality check | | debounce(fn, delay) | Debounce a function | | throttle(fn, limit) | Throttle a function | | createSpacing(value) | Create UI spacing object | | createError(path, message, code, value) | Create validation error | | validateField(field, value, path) | Validate field against definition |

Project Structure

tactica/
├── src/
│   ├── index.ts            # Public API exports
│   ├── factories.ts        # Factory functions
│   ├── types.ts            # Type definitions (source of truth)
│   ├── constants.ts        # Default values
│   ├── helpers.ts          # Utility functions
│   ├── core/
│   │   ├── engine/         # Engine, Scene, Entity, SceneManager, TimerManager, TransitionManager
│   │   ├── rendering/      # Camera, Renderer, Sprites, Tilemap, LayerManager, SpriteBatch, CameraEffects, TrailRenderer, ShapeRenderer, PostProcessManager, CullingSystem, LODSystem, Viewport
│   │   ├── input/          # InputSystem, KeyboardManager, GamepadManager, InputActionSystem
│   │   ├── audio/          # AudioManager, MusicPlaylist, SoundVariantPool, AudioZoneManager
│   │   ├── physics/        # PhysicsWorld, CollisionSystem, Quadtree, SpatialGrid
│   │   ├── animation/      # AnimationPlayer, TweenManager, ParticleSystem
│   │   ├── gameplay/       # BuffSystem, HealthSystem, FloatingTextSystem, CollectibleSystem, SpawnerSystem, EffectZoneSystem, BackgroundSystem, ExperienceSystem, StatisticsSystem, ObjectiveSystem, StateMachine, CrosshairSystem, EntityRendererRegistry, InventorySystem, DialogueSystem, QuestSystem, CraftingSystem
│   │   ├── ui/             # UIManager, Button, Slider, Panel, ProgressBar, Text, Checkbox, Toggle, UIImage, TextInput, ToastManager, Modal, ModalManager, TooltipManager, VirtualJoystick, ActionButton, RadialMenu, Minimap, NotificationManager
│   │   ├── storage/        # Store, Computed, StateManager, Database, Schema, TabSyncManager, LocalStorageBackend, IndexedDBBackend, MigrationRunner, Cache
│   │   ├── asset/          # AssetManager, ResourceManager, ObjectPool
│   │   ├── platform/       # MobileManager, AccessibilityManager, PWAManager
│   │   ├── debug/          # DebugTools, DebugOverlay, PerformanceMonitor, ScreenshotManager, FrameBudget, EntityInspector, CommandConsole
│   │   └── network/        # NetworkManager
│   └── schemas/            # State validation schemas (PlayerState, WorldState, InventoryState, SettingsState)
├── tests/                  # Unit tests (mirrors src/)
├── showcase/               # Demo game
├── configs/                # Build configs
└── guides/                 # Documentation

Development

# Type check
npm run check

# Lint and format
npm run format

# Run tests
npm test

# Build library
npm run build

# Development server (showcase)
npm run dev

# Build showcase to single HTML
npm run show

Browser Support

  • Chrome 80+
  • Firefox 78+
  • Safari 14+
  • Edge 80+

Mobile browsers with touch support are the primary target.

License

MIT