How to Build an Energy Feature

Author
Jason Louro
Jason LouroCo-Founder, Trophy
14 min readSummarize:OpenAIClaudeMistral AIGoogle GeminiGitHub CopilotPerplexity

Your team wants to add an energy system. Users consume energy for actions. Energy regenerates over time. Cap it at a maximum. Seems like simple arithmetic. Three weeks later, you're debugging regeneration timing, handling edge cases around maximum caps, and dealing with race conditions when users perform rapid actions.

Energy systems appear straightforward until you implement them at scale. The core concept (limited resource that regenerates) hides complexity. When does regeneration happen? What if users act while at zero energy? How do you handle time zones for regeneration timing? What prevents users from gaming the system?

Trophy handles energy systems including regeneration, consumption, and metering. The complete implementation guide walks through the full process. Integration takes 1 day to 1 week. But understanding what building from scratch involves helps you make informed build versus buy decisions.

Build It Yourself vs. Use an Energy API

Most teams don't need to build energy systems from scratch. The decision comes down to two questions: how unusual are your mechanics, and how much engineering time can you spare?

DimensionBuild It YourselfUse an Energy API (Trophy)
Time to ship3–6 months (7+ weeks of core engineering, plus ongoing work)2-3 days
Regeneration and timezone handlingYou implement regeneration logic, handle DST transitions, and store per-user timezones yourselfConfigured in the dashboard; Trophy handles timezone math server-side
Concurrency and race conditionsYou design locking or optimistic concurrency to prevent double-spend bugsHandled at the API layer with atomic operations
Anti-abuse and server-side validationYou build server-side checks to prevent client-side clock manipulationServer-side by default; client timestamps are ignored
Ongoing maintenance and tuningYour team owns schema migrations, rate adjustments, and scaling as usage growsConfiguration changes in the dashboard; infrastructure scales automatically

Building in-house is the right call when your mechanics are so unusual that no API covers them and you want to keep dependencies minimal. However even at small scale, using Trophy makes sense since it's free up to 1,000 monthly active users.

Key Points

  • Technical challenges in energy system implementation
  • Regeneration patterns and timing considerations
  • Consumption triggers and usage metering
  • Integration examples with Trophy's API
  • Build versus buy considerations for energy features

How to Build an Energy System

Define the Energy Model

Energy is a metered, capped resource where each action costs a fixed number of units and the balance cannot exceed a maximum cap.

Your energy model needs three values: a maximum cap (the ceiling a user can hold), a starting balance (often equal to the cap), and a unit cost per action. When a user performs an action, you deduct the cost from their balance. When the balance hits zero, block or defer the action until energy regenerates.

Think of it like a rechargeable battery with a fixed capacity. Users spend units, hit a floor, wait for a recharge, and spend again. The cap creates scarcity; the cost per action controls how fast users burn through it.

Regeneration

Energy regenerates by granting a fixed number of units at a set interval, up to but never exceeding the maximum cap.

You have two design choices. First, how much and how often: grant 1 unit every 10 minutes, or 5 units every hour, or full energy once per day. Second, when to calculate it:

  • Lazy regeneration computes the new balance on demand, when the user next checks or spends. Simpler to implement; no background jobs.
  • Scheduled regeneration runs a cron or queue job that updates balances at fixed times. More predictable for users who want to know exactly when energy returns.

Both approaches must respect the cap. If a user has 8/10 energy and a grant of 5 fires, they end up at 10, not 13.

Consumption Rules

Each action deducts a fixed or variable amount from the user's energy balance, and the system blocks or defers the action when the balance is insufficient.

Fixed-cost actions are simplest: every message costs 1 energy, every generation costs 5. Variable-cost actions scale with intensity: a 500-word generation costs 2, a 2,000-word generation costs 8. Some systems allow partial completion or queue the request until enough energy accumulates.

Decide what happens at zero:

  • Hard block: the action fails immediately.
  • Soft defer: the action queues and executes when energy regenerates.
  • Partial refund: if an action fails mid-execution, return the unused portion.

Persistence and Anti-Abuse

Energy must be stored and regenerated server-side to prevent clock-tampering, race conditions, and replay attacks.

If you calculate energy on the client, users can change their device clock and grant themselves infinite resources. Server-authoritative storage closes that hole: the server owns the balance, computes regeneration, and validates every spend.

Handle concurrency with optimistic locking or atomic transactions. Two requests hitting the server at the same millisecond should not both succeed if only one unit remains. Store the balance and last-updated timestamp together so lazy regeneration can compute elapsed time without a separate job.

Timezones matter for daily grants. Decide whether "daily" means calendar day in the user's local time, UTC midnight, or 24 hours since last grant, and document the choice so users understand when their energy resets.

A Minimal DIY Energy Implementation

Here is a self-contained skeleton for a basic energy system. It covers the model, regeneration, consumption, and anti-abuse checks.

// 1. Energy model
interface EnergyState {
  balance: number;
  maxCap: number;
  lastRegenAt: number; // Unix timestamp (ms)
  regenRatePerMs: number; // e.g., 1 energy per 60000ms = 1 per minute
}

// 2. Regeneration (lazy, computed on read)
function computeCurrentEnergy(state: EnergyState, now: number): number {
  const elapsed = now - state.lastRegenAt;
  const regenerated = Math.floor(elapsed * state.regenRatePerMs);
  return Math.min(state.balance + regenerated, state.maxCap);
}

// 3. Consumption (check then deduct)
function consumeEnergy(
  state: EnergyState,
  cost: number,
  now: number
): { success: boolean; newState: EnergyState } {
  const current = computeCurrentEnergy(state, now);
  if (current < cost) {
    return { success: false, newState: state };
  }
  return {
    success: true,
    newState: {
      ...state,
      balance: current - cost,
      lastRegenAt: now,
    },
  };
}

// 4. Anti-abuse: always compute on the server
// Never trust a timestamp sent from the client.
function handleEnergyRequest(state: EnergyState, cost: number) {
  const serverNow = Date.now(); // Use server clock, not client-supplied time
  return consumeEnergy(state, cost, serverNow);
}

This is the minimum. The real cost is the edge cases (concurrency, persistence, tuning) the section above described. That's why many teams reach for an API instead.

Server-Side Regeneration, Clock-Tampering, and Timezones

Trophy computes energy balances on the server. Every regeneration tick and every consumption event runs server-side, with results stored in Trophy's backend. The client never calculates energy. It only reads the current balance from the API.

Changing the device clock is the obvious cheat. A user can set their phone forward by four hours and watch their energy refill instantly. If your regeneration logic runs on the client or trusts client timestamps, you have no defense. The only fix is computing regeneration from server time. Trophy processes all regeneration math on the backend, so device clock manipulation has zero effect on the actual balance.

Lazy regeneration keeps the math simple. Instead of running a cron job every few seconds, Trophy calculates the correct balance at read time using the server clock. Here's the formula:

energy = min(cap, stored_energy + floor((server_now - last_updated) / regen_interval) * regen_amount)

server_now is the current UTC timestamp from Trophy's servers. last_updated is the UTC timestamp of the last consumption or explicit update. regen_interval is how often one unit regenerates (for example, 1800 seconds for 30 minutes). regen_amount is how many units regenerate per interval. The result is clamped to cap so energy never exceeds the maximum.

Timezones matter for daily resets. If your energy refills at midnight, "midnight" needs to match the user's local time. Trophy stores a timezone identifier per user and computes reset boundaries server-side. A player in Tokyo gets their daily energy at 00:00 JST while a player in London gets theirs at 00:00 GMT. No client input required. For a deeper look at timezone handling in gamification, see Handling Time Zones in Gamification.

Multi-device sync comes free. Because the balance lives on Trophy's servers, the same energy total appears on a user's phone, tablet, and web browser. Open the app on your iPad after playing on your phone and your energy is already correct. There's no per-device state to reconcile, no conflict resolution, no drift. One source of truth, accessible from anywhere.

Implementation Estimate

Here's realistic timeline for building energy systems in-house:

Week 1-2: Basic implementation. Track energy balance. Deduct for actions. Display totals. Works in development with simple cases.

Week 3-4: Regeneration logic. Implement time-based regeneration with scheduled jobs. Handle maximum caps. Make regeneration work across user sessions and time zones. Test edge cases around timing.

Week 5-6: Consumption triggers. Build system for deducting energy based on different actions. Implement variable consumption amounts. Handle insufficient energy cases gracefully.

Week 7: Concurrency and edge cases. Prevent race conditions. Handle rapid actions correctly. Test regeneration at scale. Fix performance issues.

Ongoing: Maintenance and tuning. As usage patterns change, regeneration rates need adjustment. New actions need consumption rules. This work continues indefinitely.

That's 7+ weeks of engineering time plus ongoing maintenance. Trophy's infrastructure eliminates this timeline, reducing implementation to 1 day to 1 week of integration work.

Building with Trophy

Trophy's integration is faster because energy infrastructure already exists. Here's what implementation looks like.

Step 1: Create Energy System

In Trophy's dashboard, create a points system called "Energy" (or your preferred name). Configure the maximum energy cap users can have. Trophy supports any maximum up to your requirements.

Energy systems are just points systems with specific regeneration and consumption rules. Trophy's flexible points infrastructure supports both XP-style accumulation and energy-style metering.

Step 2: Configure Regeneration Triggers

Set up how users gain energy over time. In Trophy's dashboard, create time-based triggers:

Hourly regeneration: Grant X energy every N hours

  • Award 1 energy every hour
  • Award 10 energy every 6 hours
  • Maximum caps prevent energy exceeding limits

Daily regeneration: Grant energy once per day

  • Award 20 energy at midnight user time
  • Award 50 energy every 24 hours
  • Trophy handles timezone timing automatically

Trophy's trigger system grants energy automatically based on your configuration. Users receive energy without manual processing.

Step 3: Configure Consumption Triggers

Set up how users spend energy. Create negative-value triggers for actions that consume energy:

Action-based consumption: Deduct energy when users perform specific actions

  • Deduct 1 energy per lesson viewed
  • Deduct 5 energy per workout started
  • Deduct 10 energy per premium feature access

Configure these through Trophy's dashboard as negative point awards. When users perform tracked actions, Trophy automatically deducts configured energy amounts.

Step 4: Track Energy-Consuming Actions

Send events for actions that consume energy:

import { TrophyApiClient } from '@trophyso/node';

const trophy = new TrophyApiClient(process.env.TROPHY_API_KEY);

// When user views a lesson (consumes 1 energy)
const response = await trophy.metrics.event('lesson_viewed', {
  user: {
    id: 'user-123'
  },
  value: 1 // 1 lesson viewed
});

// Check remaining energy
if (response.points?.energy) {
  const remaining = response.points.energy.total;
  const consumed = Math.abs(response.points.energy.added); // Will be negative
  console.log(`Consumed ${consumed} energy. ${remaining} remaining.`);
}

Trophy processes the event and automatically deducts energy based on trigger configuration. The response includes updated energy balance for immediate display.

Changes to energy consumption logic can be made in the Trophy dashboard, preventing back and forth code changes.

Step 5: Check Energy Before Actions

Before allowing energy-consuming actions, check if user has sufficient energy:

// Check user's current energy
const energy = await trophy.users.points('user-123', 'energy');

if (energy.total > 0) {
  // User has energy, allow action
  await performAction();
  
  // Track the action (consumes energy)
  await trophy.metrics.event('lesson_viewed', {
    user: { id: 'user-123' },
    value: 1
  });
} else {
  // User has no energy, prevent action or show paywall
  showInsufficientEnergyMessage();
}

This pattern prevents users from attempting actions they can't afford. The energy check happens before action processing, providing clear feedback.

Step 6: Display Energy Status

Show users their current energy and when it regenerates:

// Get detailed energy information
const energy = await trophy.users.points('user-123', 'energy', {
  awards: 5  // Last 5 energy changes
});

console.log({
  current: energy.total,
  maximum: energy.maximum,
  recentChanges: energy.awards.map(award => ({
    amount: award.points,
    trigger: award.trigger.name,
    time: award.timestamp
  }))
});

Trophy returns current energy, maximum cap, and recent energy changes. Use this data for UI showing energy status and regeneration timing. The points API documentation covers all available fields.

Regeneration Strategies

Different regeneration patterns serve different product goals.

Constant regeneration grants energy at fixed intervals regardless of usage. Users get 1 energy per hour even if they're at maximum. Simple but can waste potential energy when users hit caps.

Regeneration until cap stops when users reach maximum. Trophy's default behavior. Users don't waste regeneration but might feel pressure to spend energy before hitting cap.

Overflow to storage lets excess regeneration accumulate in separate pool. Complex but prevents waste. Trophy supports this through secondary points systems that have different caps.

Activity-based regeneration grants energy for specific actions beyond time. Complete a challenge, gain energy. This creates positive feedback loops where engagement grants resources for more engagement.

Trophy's time-based triggers handle first two patterns natively. Configure in dashboard without code. More complex patterns use multiple points systems or custom trigger logic.

Consumption Patterns

How you consume energy affects gameplay and user psychology.

Fixed consumption deducts the same amount for all instances of an action. 1 energy per lesson. Simple and predictable. Users understand cost clearly.

Variable consumption charges different amounts for different actions or contexts. 1 energy for basic lesson, 5 energy for advanced lesson. Creates strategic choice about energy spending.

Scaling consumption increases cost based on usage. First 5 lessons cost 1 energy each, next 5 cost 2 each. Encourages moderation and prevents grinding. Trophy implements through threshold-based triggers.

Partial refunds return energy if actions don't complete. User starts lesson (spends energy) but quits (refunds energy). Requires custom logic to track partial completions and issue refunds as positive point awards.

Trophy's trigger flexibility supports all these patterns. Configure consumption amounts through dashboard. Adjust based on player behavior without code changes.

Preventing Energy Gaming

Energy systems create incentives to game. Design prevents exploitation.

Maximum caps prevent infinite accumulation. Trophy's configurable maximum prevents users from stockpiling unlimited energy for later use. Choose caps based on intended session length.

Rate limiting beyond energy. If users can refresh energy artificially (time zone changes, system clock manipulation), add detection and rate limits. Trophy's server-side processing prevents client-side time manipulation.

Consumption verification ensures actions actually completed before deducting energy. Deduct energy only after verifying action succeeded. Trophy's event-based model supports this through proper event sequencing.

Account-level tracking prevents multi-account farming. If users create multiple accounts to bypass energy limits, implement account-level detection. Trophy tracks per-user; your authentication layer handles account limits.

Display and Communication

How you present energy affects user experience.

Clear cost indicators before actions. "This will cost 5 energy" prevents surprise when users can't afford actions. Trophy's balance checking enables this.

Regeneration timing transparency. "Energy regenerates in 2 hours" or "Full energy at 8 PM" gives users planning information. Trophy's time-based triggers have predictable schedules you can communicate.

Friendly empty states. "You're out of energy! It regenerates 1 per hour." explains situation without being punitive. Frame energy as pacing mechanic, not punishment.

Progress toward regeneration. "Energy: 3/10 (regenerating...)" shows both current state and that progress continues. Trophy's balance provides current amount; you track maximum for display.

Economic Tuning

Energy systems need careful tuning to feel fair without killing engagement.

Regeneration rate determines session frequency. Fast regeneration (hourly) encourages frequent short sessions. Slow regeneration (daily) encourages longer, less frequent sessions. Trophy makes rate adjustments through dashboard configuration.

Maximum cap determines session length. Cap of 10 with consumption of 1 per action allows 10 actions per session. Cap of 100 allows longer sessions but slower regeneration to full. Trophy's configurable cap lets you test different values.

Consumption amounts relative to regeneration define gameplay pace. If regeneration grants 20 energy daily and average session consumes 15, users can play daily with buffer. Trophy's analytics show consumption patterns informing tuning.

Monitor average energy levels across users. If most users sit at maximum constantly, regeneration is too generous or consumption too low. If most users sit at zero, consumption is too high or regeneration too slow. Trophy's analytics dashboard shows energy distribution.

Analytics and Optimization

Trophy provides analytics for energy system health.

Distribution curves show how energy spreads across users. Clustering at maximum suggests regeneration exceeds consumption. Clustering at zero suggests opposite problem.

Consumption patterns show which actions consume most energy. If one action dominates consumption, it might need rebalancing. Trophy's trigger analytics show consumption by trigger type.

Regeneration effectiveness shows how much granted energy gets used versus wasted. High waste (users constantly at cap) suggests tuning opportunities.

Session length correlation reveals whether energy gates usage appropriately. Do users stop playing because they're out of energy or for other reasons? Trophy's data combined with your session analytics answers this.

Use these insights to tune regeneration rates, consumption amounts, and maximum caps. Trophy's dashboard configuration makes adjustments quick without code changes.

Common Implementation Mistakes

Teams integrating Trophy make predictable errors.

Blocking critical paths on energy. Don't prevent onboarding or core value delivery with energy gates. Use energy for optional features or advanced content, not basic functionality.

Insufficient energy for meaningful sessions. If regeneration grants enough energy for 2 minutes of play, users can't engage meaningfully. Trophy's configurable caps let you test session lengths.

Unclear regeneration timing. Users should understand when energy returns. Trophy's time-based triggers have predictable schedules. Communicate these in your UI.

No emergency energy sources. Some products offer energy purchase or alternative earning. This creates escape valve for engaged users. Implement through your monetization layer; Trophy tracks the energy you grant.

Forgetting timezone impacts. Daily regeneration at midnight means different times for different users. Trophy handles this, but your UI should show user-local times.

FAQ

How long does Trophy integration take for energy?

Basic energy tracking with regeneration and consumption: 1-2 days including trigger configuration and event tracking. Advanced features like variable consumption and complex metering: 3-5 days. Compare this to 2-3 months building in-house.

Can we adjust energy rates after launch?

Yes. Trophy's dashboard configuration means changing regeneration rates or consumption amounts requires no code deployment. Adjust trigger values and new events use new amounts.

How does Trophy prevent energy gaming?

Trophy's server-side processing prevents client-side time manipulation. Maximum caps prevent infinite accumulation. Your authentication layer handles multi-account detection. Trophy tracks per-user, not per-device.

What if we want different energy rates for different users?

Trophy's user attributes enable segment-specific triggers. Grant or consume different energy amounts based on subscription tier, user level, or other attributes. Configure through Trophy's dashboard.

Can users purchase energy?

Trophy tracks energy totals. Implementing purchases happens in your application through your payment provider. Grant purchased energy as positive point awards through Trophy's API.

How do we test energy changes without affecting real users?

Trophy supports multiple environments (staging, production). Test trigger configurations in staging before deploying to production. Trophy's deterministic processing means staging tests predict production behavior.

What happens if users are at maximum when regeneration fires?

Trophy's default behavior stops regeneration at maximum. Users don't exceed the cap. Alternative patterns (overflow to storage) require multiple points systems configured through Trophy's dashboard.

Can I add an energy system without long-term maintenance?

Building in-house means indefinite maintenance: tuning regeneration rates, adding consumption rules for every new action, and fixing edge cases as they surface. A managed energy system moves that work to dashboard configuration, where product teams can adjust settings without code changes. Compared to 7+ weeks of engineering plus ongoing upkeep, a managed API takes 1 day to 1 week to integrate with minimal long-term overhead.

Do I need a backend to build an energy feature?

A production energy system needs server-authoritative state to prevent client-side clock manipulation and race conditions. If you build it yourself, yes, you need a backend. Trophy's API handles server-side processing and automatic time-zone handling, so you can add energy to your app without building or running that infrastructure.

How is an energy system different from rate limiting?

Rate limiting is an infrastructure guardrail. It caps requests per time window, runs invisibly in the background, and protects your systems from abuse (for example, 100 API calls per minute). An energy system is a user-facing pacing mechanic. It shows users a visible, regenerating resource that shapes session length and engagement (for example, 5 lives that refill every 30 minutes).

Author
Jason Louro
Jason LouroCo-Founder, Trophy

Get the latest on gamification

Product updates, best practices, and insights on retention and engagement — delivered straight to your inbox.

The gamification layer for consumer apps

Drop-in gamification features you can ship this sprint. Increase retention and user engagement without sacrificing your roadmap.

How to Build an Energy Feature