Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ npx skills add decentraland/sdk-skills
| `deploy-scene` | Deploy scenes to Genesis City (LAND-based). |
| `deploy-worlds` | Deploy scenes to Worlds (personal 3D spaces). |
| `game-design` | Game design patterns, scene limits, performance budgets. |
| `game-mechanics` | Reusable game-mechanic systems — wave spawning, turn/grid, economy/upgrades, status effects, combat AI, UI game systems (quiz/cards/dialogue), game-feel feedback. |
| `lighting-environment` | Dynamic lighting, shadows, skybox, fog, environment settings. |
| `migrate-sdk6-to-sdk7` | Port legacy SDK6 scenes (decentraland-ecs) to SDK7 — ECS conceptual shift, API mapping, worked 2048 example. |
| `multiplayer-sync` | Peer-to-peer multiplayer using CRDT networking. |
Expand All @@ -62,6 +63,10 @@ npx skills add decentraland/sdk-skills

Skills are markdown files that give AI coding assistants the context they need to write correct code for specific frameworks and platforms. They're installed using the [Vercel Skills CLI](https://github.com/vercel/skills) and work with any AI tool that supports `.cursor/skills`, `.claude/skills`, or similar conventions.

## Acknowledgments

The `game-mechanics` skill's taxonomy of reusable game systems was inspired by the [OpenGame project](https://github.com/leigest519/OpenGame) (Apache-2.0). All code and text in this repository are original and Decentraland SDK7-native.

## Contributing

The source of truth for these skills is maintained in the [sdk-skills](https://github.com/decentraland/sdk-skills) repository. To contribute improvements, please open a PR there.
Expand Down
3 changes: 3 additions & 0 deletions game-design/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ Ask: **What does the player DO?** The answer should be a single sentence:

## 11. Game Loop Archetypes

> **Implementations for these loops live in the `game-mechanics` skill** — wave spawners, turn/grid managers, economy/upgrades, status effects, combat AI, and quiz/card/battle UI. This section covers the design fit; go there for the code.

### Exploration
- **Core loop**: Discover locations, find hidden items, unlock areas.
- **DCL fit**: Excellent. The 3D world and spatial navigation are strengths.
Expand Down Expand Up @@ -282,6 +284,7 @@ Ask: **What does the player DO?** The answer should be a single sentence:

| Topic | Skill | When to Use |
|---|---|---|
| Reusable mechanic systems (waves, turns/grid, economy, status effects, combat AI, quiz/card/battle UI) | **game-mechanics** | Implementing the moving parts of a game after the design is set |
| Interactivity, input handling, raycasting | **add-interactivity** | Implementing click handlers, triggers, input |
| Multiplayer sync, server communication | **multiplayer-sync** | Networked game state, real-time sync |
| Screen UI, React-ECS, HUD elements | **build-ui** | Building menus, scoreboards, dialogs |
Expand Down
68 changes: 68 additions & 0 deletions game-mechanics/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
name: game-mechanics
description: Reusable, implementation-level game-mechanic systems for Decentraland SDK7 games. Covers wave spawning (enemy waves, path-following, between-wave countdowns), turn/grid systems (step/turn/realtime/freeform timing, board state, undo), economy and upgrades (currency, purchase/sell, upgrade tracks), status effects (timed modifiers as components), combat AI behaviors (patrol/chase/melee/ranged, targeting modes, projectile prediction, enemy FSM), UI game systems (quiz, cards, dialogue sequencing, turn-based battle flow built from React-ECS), and game-feel feedback (floating 3D text, combos). Use when the user is building the moving parts of a game — spawners, turn managers, currency, buffs/debuffs, enemy behavior, or menu-driven battle/quiz/card UI. Do NOT use for game planning, scene limits, or loop archetypes (see game-design); basic pointer/proximity/trigger input (see add-interactivity); NPC dialog toolkit (see npcs); networking primitives (see multiplayer-sync, authoritative-server); or general screen UI setup (see build-ui).
---

# Game Mechanics for Decentraland Scenes

Implementation-level building blocks for DCL games. This is the counterpart to **game-design** (which covers planning, loops, and limits): here you get concrete, verified SDK7 systems you can adapt. Every system is data-driven (define content as plain arrays/objects) and runs on `engine.addSystem` loops, custom components, or Tweens.

> This skill assumes the ECS mental model (entities as IDs, data-only components, systems as free functions). If that is unfamiliar, read **create-scene** and **game-design** first.

## System Taxonomy

| System | What it gives you | Reference |
| ------------------ | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| Wave spawning | Data-defined enemy waves, spawn pacing, between-wave countdowns, lifecycle callbacks, waypoint path-following | `{baseDir}/references/wave-spawner.md` |
| Turn & grid | Timing manager (step/turn/realtime/freeform), phase cycle with input-locking, 2D board state, undo | `{baseDir}/references/turn-and-grid-systems.md` |
| Economy & upgrades | Currency (afford/spend/earn), purchase + sell/refund, data-driven upgrade tracks | `{baseDir}/references/economy-and-upgrades.md` |
| Status effects | Timed modifiers as a custom component, refresh-don't-stack, auto-expiry, stat multipliers, visual tint | `{baseDir}/references/status-effects.md` |
| Combat behaviors | Composable patrol/chase/melee/ranged components, targeting modes, projectile lead prediction, enemy FSM | `{baseDir}/references/combat-behaviors.md` |
| UI game systems | Quiz/trivia, card hand/deck, dialogue sequencing, turn-based battle flow, all in React-ECS | `{baseDir}/references/ui-game-systems.md` |
| Game-feel feedback | Floating 3D damage/reward text, combo counters (in `ui-game-systems.md`) | `{baseDir}/references/ui-game-systems.md` |

## Genre Fit in Decentraland

DCL is a third or first-person, always-live, shared 3D world. Some genres map cleanly; others need adaptation.

| Genre | Fit | Why / adaptation |
| ------------------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Tower defense | Excellent | Click-to-place towers, path-following enemies, no player character needed. Pointer-only, so it works on mobile. See wave-spawner + combat-behaviors + economy. |
| Grid / board games (sokoban, tactics, match-3, puzzles) | Excellent | Discrete state, no physics, input locked during animations. Lay the board on the parcel floor as 3D entities, or drive it entirely through React-ECS UI. See turn-and-grid. |
| Arena / horde combat | Good (adapted) | The player is their own avatar, not a spawned sprite. Enemies chase `engine.PlayerEntity`, melee/ranged the avatar, apply knockback via **player-physics**. No respawn screen — design drop-in/drop-out. See combat-behaviors. |
| Card / quiz / narrative | Good | Built entirely in React-ECS UI (**build-ui**). Deck/hand/quiz/dialogue state lives in module variables or components. See ui-game-systems. |
| Twitch platformers | Good | Network latency make precise timing hard. Prefer having key interactions against the environment vs against other player's position |
| fast shooters | Weak | Network latency make precise timing hard. Prefer turn-based, timing-window, or placement mechanics (see game-design "Competitive"). |

## DCL Constraints That Shape These Mechanics

These are not optional — they change how every system above is written:

- **Always-live, no native title screen / no forced game-over.** There is no "press start" and no way to freeze the world or eject a player. A "round" is a state your systems track, not a scene boundary. Waves, turns, and battles must tolerate a player walking away mid-game.
- **Drop-in / drop-out players.** A player can arrive or leave at any moment. Per-player game state (economy, hand, current battle) must handle a player who appears mid-round or vanishes. Games might otherwise have a spectator mode before the next round starts.
- **Shared multiplayer space.** Multiple players are always potentially present, even in a "single-player" game. Every mechanic below has a multiplayer note: decide up front whether state is **local-only** (each client runs its own copy), **synced** for a shared game (`syncEntity` — see multiplayer-sync), or **server-validated** (see authoritative-server). Competitive/economy mechanics that matter should be server-validated.
- **Mobile, pointer-only input.** Do not build keyboard-dependent mechanics. Everything must be reachable with pointer clicks, on-screen React-ECS buttons, and at most the pointer, E (`IA_PRIMARY`) / F (`IA_SECONDARY`) action keys and 1, 2, 3 & 4. See add-interactivity and advanced-input.
- **Performance budget.** Spawners, projectiles, and per-frame AI must respect entity/triangle limits. Pool entities (never create/destroy per shot or per enemy) and throttle heavy systems. See optimize-scene.

## Conventions Used Across the References

- **Scheduling:** use `timers.setTimeout` / `timers.setInterval` from `@dcl/sdk/ecs` for delays and countdowns — never the native JS `setTimeout` globals (they are not bound to the scene engine). See scene-runtime.
- **Motion:** use `Tween` / `TweenSequence` for procedural movement (enemy paths, floating text) and `tweenSystem.tweenCompleted(entity)` to detect completion. See animations-tweens.
- **State:** small games use module-level variables; structured/queryable state uses custom components via `engine.defineComponent(name, { ...Schemas })`. Shared state uses `syncEntity`.
- **Pooling:** reuse entities for enemies/projectiles/floating text. See optimize-scene.

## Cross-References

| Topic | Skill | When |
| --------------------------------------------- | ------------------------ | --------------------------------------------------- |
| Game planning, loops, scene limits, MVP | **game-design** | Before implementing — decide the loop and budget |
| Pointer / proximity / trigger / raycast input | **add-interactivity** | Click-to-place, "press E", zone triggers |
| Held-key polling, cursor lock, action bar | **advanced-input** | Continuous input, custom action keys |
| Screen UI (menus, HUD, React-ECS primitives) | **build-ui** | Building the UI shell that ui-game-systems fills in |
| Shared game state, broadcast events | **multiplayer-sync** | Making a mechanic multiplayer without a server |
| Server validation, anti-cheat, persistence | **authoritative-server** | Competitive scores, real economy, leaderboards |
| NPC dialog toolkit, AvatarShape NPCs | **npcs** | Conversation NPCs (vs. combat enemies here) |
| Impulses, knockback, forces on the avatar | **player-physics** | Combat knockback against the player |
| Model animations, procedural tweens | **animations-tweens** | Enemy walk clips, path motion, text rise |
| Pooling, LOD, throttling, budgets | **optimize-scene** | Keeping spawners and projectiles within limits |
| 3D text, Billboard, materials | **advanced-rendering** | Floating text and tint feedback details |
Loading