Summary

Every game is built from parts — discrete elements that have attributes defining their current state and behaviours defining how they act and react. Sellers (Advanced Game Design, Ch. 8) provides a formal taxonomy of parts and attributes that underpins the systems thinking approach to game design: understanding how simple, locally defined parts interact to produce complex emergent behaviour.

The framework is complementary to the mda-framework (which operates at the experience level) and to game-atoms (which maps mechanics to player-perceptible elements). Where MDA asks what the designer intends and the player experiences, Sellers’ parts-and-attributes model asks how the underlying system is actually structured.

(Sellers, Advanced Game Design, see source-advanced-game-design)

Parts taxonomy

Sellers distinguishes three categories of game parts:

Physical parts

Objects that exist within the game world and can be directly interacted with. Examples include characters, enemies, terrain tiles, projectiles, items, buildings, and vehicles.

Physical parts have:

  • A location in the game space (coordinates, grid cell, or relative position)
  • Collision or interaction boundaries
  • Attributes describing their current state (health, speed, allegiance)

Non-physical parts

Structural elements of the game that exist as rules, states, or systems rather than as objects in space. Examples include score counters, turn trackers, phase markers, timers, and game rules themselves.

Non-physical parts are often invisible to the player but govern how physical parts behave and how the game progresses. A turn-counter is a non-physical part; the restriction “only one move per turn” is a non-physical behaviour.

Representational parts

The layer of presentation that maps game-world state to the player’s senses: visual sprites, 3D models, audio cues, UI elements, text, and particle effects. Representational parts do not change game state directly — they represent it.

The distinction between representational and non-representational parts matters for implementation: a health bar is a representational part whose value tracks the physical part’s health attribute. When the health attribute changes, the representation is updated — they are not the same thing. This separation underlies the unity-gamemanager-pattern pattern in Unity, where game state (non-physical) is owned centrally, and visual representations (MonoBehaviours) subscribe to it.

Attributes

An attribute is a named property of a part that holds a value. Attributes can be thought of as key-value pairs: name → value. Every meaningful property of a part — health, speed, allegiance, temperature, level — is an attribute.

Static vs. dynamic attributes

  • Static attributes do not change during gameplay (e.g. an enemy’s species name, a weapon’s model ID).
  • Dynamic attributes change as the game runs (e.g. current health, current position, current ammunition count).

Good systems design keeps static attributes as constants in data files and dynamic attributes in runtime state. This enables data-driven design (see below).

Attribute orders

Sellers introduces a hierarchy of attribute types based on what each attribute measures:

First-order attributes

First-order attributes measure amounts: the current state of a quantity.

Examples:

  • health = 40
  • ammunition = 12
  • coins = 350
  • position = (3, 7)

First-order attributes are the most common and most intuitive. They answer: how much of this is there right now?

Second-order attributes

Second-order attributes measure rates of change of first-order attributes — they describe how something is changing over time.

Examples:

  • healthRegen = 2 (health recovers at 2 points per second)
  • speed = 5 (position changes at 5 units per second)
  • incomeRate = 100 (coins increase by 100 per minute)

Second-order attributes add significant design depth without adding new systems: the same attribute can be modified by buffs, terrain, status effects, or equipment. A player who understands rates can make more strategic decisions — spending to increase income rate may outperform spending on direct health.

Third-order attributes

Third-order attributes measure rates of rates — acceleration, momentum, compounding growth. They are rare in games but produce the richest systemic behaviour when used intentionally.

Examples:

  • acceleration = 1.5 (speed increases by 1.5 units per second per second)
  • growthRate = 0.1 (income rate increases by 10% each level)
  • compoundInterest = 0.05 (a resource that generates more of itself over time)

Third-order attributes are the mechanism behind exponential growth in resource economies, accelerating difficulty curves, and snowball dynamics in strategy games. They must be managed carefully: an uncapped third-order attribute produces runaway positive feedback (see game-balance).

Attribute ranges

Attributes need ranges — defined minimum and maximum values — to behave predictably:

  • Integer vs. float: Integer ranges (0–100 health) are simpler for players to reason about; float ranges (0.0–1.0 for normalised values) offer more precision but less legibility.
  • Distribution shape: A uniformly random attribute produces flat distributions; a bell-curve distribution (sum of multiple dice rolls) clusters values around the mean and produces more predictable outcomes. The choice of distribution affects balance: bell curves make average outcomes more common, reducing the impact of outliers.

In practice, most player-facing attributes use integer ranges for readability. Internal simulation attributes (physics, AI weights) use floats.

Behaviours

Behaviours are the rules that govern how parts act and react. A behaviour is triggered by a condition (an event, a state threshold, a timer) and produces an effect (changes one or more attribute values, creates or destroys other parts).

The behaviour locality principle

Sellers’ most important structural principle for designing game parts: each part’s behaviour should be defined locally and act generically.

  • Locally defined: a part’s behaviours are properties of that part, not of a central controlling system. The enemy part knows how to patrol, attack, and die; it does not require a global EnemyManager to tell it what to do at each step.
  • Generically acting: a part’s behaviours should not depend on the specific identity of other parts; they depend only on shared interfaces, tags, or attributes. An enemy that detects “anything tagged Player” is more robust than one detecting a specific PlayerController reference.

This principle has direct consequences for Unity architecture: it maps to the component model, where behaviours are MonoBehaviour scripts attached to individual GameObjects (see unity-getcomponent, unity-collider2d-and-triggers).

Why locality matters: Locally defined, generically acting behaviours are what enable emergence. When each part simply follows its own local rules, interactions between many such parts produce complex system-level behaviour that no individual part was programmed to produce.

Emergence from local rules

The classic examples of emergence from simple local behaviours:

Conway’s Game of Life: four simple rules governing cells on a grid (born, survive, die). No behaviour is programmed at the system level — yet the system produces gliders, oscillators, self-replicating structures, and Turing-complete computation.

Flocking (Craig Reynolds): three local rules per boid (separation, alignment, cohesion). The group appears to flock intelligently, though no individual boid has any representation of the group.

Slime Rancher: each slime type follows simple local eating, reproducing, and interacting rules. Player farms become complex ecological systems as different slime types interact in unexpected combinations — emergent gameplay that the designers could not fully predict.

The design lesson: invest effort in the quality of local rules, not in scripting system-level outcomes. A game with 20 well-designed local behaviours will produce more interesting play than a game with 200 hand-crafted scripted events.

(Sellers, Advanced Game Design, Ch. 8; see also second-order-design, systems-thinking)

Feedback and responsiveness

Game parts must communicate their state changes to the player through immediate, legible feedback. Sellers provides concrete guidance on feedback timing:

  • 100–250 milliseconds: the window for feedback that feels immediate to human perception. Responses to player actions should occur within this window to feel responsive rather than laggy.
  • Visual + auditory: the most effective feedback uses at least two sensory channels simultaneously. A hit that produces both a flash and a sound is registered more reliably than either alone.
  • Consistency: feedback signals must be consistent. If a red flash means “you are hit,” it must always mean that and nothing else. Inconsistent signals break the player’s mental model of the system.

These rules map directly to game feel (see game-feel) and to the ADSR response model (Attack-Decay-Sustain-Release) Swink uses to describe feel timing.

Data-driven design

When part attributes are numerous and subject to frequent adjustment during balancing, data-driven design separates attribute values from code:

  • Attribute tables are maintained in spreadsheets (.csv) or structured data files (.json)
  • Code reads these values at runtime; balancing requires changing a data file, not recompiling
  • Multiple iterations can be tested without rebuilding the game

In Unity, this pattern is often implemented using ScriptableObject assets as attribute containers: a WeaponData ScriptableObject holds all static weapon attributes, and a Weapon MonoBehaviour reads from it at runtime. This allows designers to duplicate, adjust, and version weapon data independently of code (see unity-scriptableobjects).

This is also the foundation for live-service games where attribute values are updated server-side without a client patch.

(Sellers, Advanced Game Design, Ch. 8; see also unity-gamemanager-pattern)

In practice

When designing a new game system, Sellers recommends working through the parts explicitly:

  1. List all parts the system requires (physical, non-physical, representational)
  2. Identify the attributes each part needs — start with first-order, then ask what rates matter (second-order), then whether any accelerations are needed (third-order)
  3. Define attribute ranges and distributions
  4. Write behaviours locally: each part’s rules as conditions → effects
  5. Separate data from code from the start: put numeric values in data files rather than hard-coding them
  6. Run and observe: the emergent behaviour of parts following local rules will often surprise you — that is the system working as intended

Open questions

  • At what scale does the locality principle become impractical? In very large systems (MMOs, city simulators), purely local behaviours may produce coherent but uncontrolled global states. How do designers introduce global constraints without abandoning locality?
  • Third-order attributes produce the richest dynamics but are also the hardest to balance by intuition. What analytical tools are most effective for managing compounding growth?
  • The representational layer is often treated as an afterthought in system design — but feedback timing (100–250ms) implies that the representational layer constrains the simulation tick rate. How should designers integrate simulation and representation requirements from the start?