CCFish replaced its manual, error-prone event scheduling system with a fully automated in-game event calendar powered by Cloudflare Workers and D1. The result: a 42% increase in daily active users during event windows, a 28% boost in IAP revenue, and zero missed event launches over the first three months of production.

The Problem

CCFish, a Cocos Creator 2.4.15 mobile fishing game with over 500,000 registered players, relied on manual event scheduling administered through a bespoke admin panel. Community managers would log in, toggle event flags, set timer values in the game config, and pray nothing broke. This fragile process produced three chronic pain points:

- **Inconsistent scheduling**: Events started late, ended early, or overlapped with each other because human operators could not juggle multiple concurrent time windows without errors.

- **Missed revenue**: Seasonal events like the Lunar New Year Fishing Tournament or the Summer Coral Challenge required developer intervention to configure — if the engineering team was busy with a release, the event simply didn't happen.

- **No recurring patterns**: Daily login streaks, weekly leaderboards, and hourly fishing frenzy windows all had to be configured from scratch each time. There was no concept of a repeating event template.

Internal metrics from Q4 2025 showed that 18% of scheduled events had timing errors, and an estimated $12,000 in monthly IAP revenue was being lost to missed or poorly timed events.

The Solution

The automated event calendar was designed around three core principles:

1. **Declarative scheduling** — events are defined once in a database, and the system handles time-based activation and deactivation automatically.

2. **Recurring templates** — common event types (daily login bonus, weekly tournament, hourly frenzy) are first-class templates that can be instantiated with parameter overrides.

3. **Serverless triggers** — Cloudflare Workers cron triggers wake up every minute, evaluate which events should be active, and sync the game state via the CCFish SDK without any human touch.

The event calendar lives in-game as a dedicated UI screen accessible from the main lobby. Players see a day-by-day grid showing upcoming, active, and expired events with countdown timers, reward previews, and direct "Participate" buttons.

Architecture Overview

The system spans three layers:

**Cloudflare Workers (scheduler + API)** — A Workers script running on a `*/1 * * * *` cron trigger polls the D1 database for all events whose start time has arrived or end time has passed. It computes a snapshot of currently-active event IDs and writes them to a small KV cache (TTL: 60 seconds). A companion API endpoint (`/api/events/active`) serves this snapshot to the CCFish game client.

**Cloudflare D1 (persistence)** — All event definitions, recurrence rules, reward configurations, and player participation records live in a D1 database. Schema is normalized across `events`, `event_templates`, `event_rewards`, and `player_event_state` tables.

**CCFish SDK integration** — The game client, built on Cocos Creator 2.4.15, polls the Workers API endpoint on scene transitions and at five-minute intervals during active play. The SDK layer maps returned event IDs to in-game assets (banners, reward items, leaderboard panels) via a local asset manifest.

```yaml

wrangler.toml configuration

trriggers = { crons = ["*/1 * * * *"] }

[vars]

API_VERSION = "v1"

MAX_ACTIVE_EVENTS = 10

DEFAULT_TTL_SECONDS = 60

```

Data flow: Cron Worker → evaluate all events → write active set to KV → game client polls `/api/events/active` → SDK renders event UI.

Implementation

The database schema centers on the `events` table:

```sql

CREATE TABLE events (

id TEXT PRIMARY KEY,

template_id TEXT NOT NULL,

title TEXT NOT NULL,

description TEXT,

starts_at INTEGER NOT NULL, -- Unix timestamp

ends_at INTEGER NOT NULL, -- Unix timestamp

recurrence_rule TEXT, -- RRULE or NULL for one-off

reward_config TEXT, -- JSON blob

asset_bundle TEXT, -- referenced asset pack

max_participants INTEGER,

status TEXT DEFAULT 'draft' -- draft | scheduled | active | ended | cancelled

);

CREATE TABLE event_templates (

id TEXT PRIMARY KEY,

name TEXT NOT NULL,

default_reward_config TEXT,

default_duration_minutes INTEGER,

category TEXT -- daily | weekly | hourly | seasonal | tournament

);

CREATE TABLE player_event_state (

player_id TEXT NOT NULL,

event_id TEXT NOT NULL,

score INTEGER DEFAULT 0,

joined_at INTEGER,

claimed_rewards TEXT, -- JSON array of claimed reward IDs

PRIMARY KEY (player_id, event_id)

);

```

To create a recurring weekly tournament, an operator inserts a single row:

```sql

INSERT INTO events (id, template_id, title, starts_at, ends_at, recurrence_rule, reward_config, status)

VALUES (

'weekly-tournament-001',

'weekly-tournament',

'Weekend Fishing Showdown',

1748649600, -- Sunday 00:00 UTC

1748908800, -- Tuesday 00:00 UTC

'FREQ=WEEKLY;BYDAY=SU,MO;INTERVAL=1',

'{"currency":"gold","base_amount":500,"tier_multiplier":[1,2,3]}',

'scheduled'

);

```

The Worker scheduler evaluates recurrence rules using a lightweight RRULE parser (the `rrule` npm package) and expands occurrences into virtual instances. Only the base event is stored; the scheduler dynamically computes which occurrence window the current time falls within.

Results

After three months of production operation:

- **42% increase in DAU** during event windows compared to the manual scheduling era.

- **28% lift in IAP revenue** — attributed to time-limited offers and tournament entry fees being reliably available.

- **100% on-time launch rate** — zero missed or delayed event starts across 87 scheduled events.

- **72% reduction in community management overhead** — CMs no longer toggle event flags; they only approve reward configurations.

- **34% of players** interacted with the event calendar UI in their first week of seeing it, suggesting strong discoverability.

- Average session length during events increased by 11 minutes (from 22 to 33 minutes).

Player feedback via in-game surveys showed a Net Promoter Score of +48 for the event calendar feature specifically. Common sentiment: "I can finally see what's coming up and plan my play sessions."

Key Takeaways

1. **Automated event scheduling is a high-leverage investment** for mobile games — the DAU and revenue gains paid back the development cost in under six weeks.

2. **Serverless architecture (Workers + D1)** is a natural fit for event scheduling workloads: the compute is bursty (one evaluation per minute), the data is relational (event definitions with joins), and the latency requirements are relaxed (seconds, not milliseconds).

3. **Recurrence rules (RRULE)** are surprisingly powerful — a single database row can represent an infinite series of weekly tournaments, daily login bonuses, or hourly fishing frenzies.

4. **The Cocos Creator SDK integration** was the trickiest part — asset loading from dynamically-determined event bundles required careful async lifecycle management. A recommended pattern: preload event assets on scene load and swap UI panels in-place rather than reloading scenes.

5. **Start with three template types** (daily, weekly, seasonal) and expand. Building more than that before seeing player behavior data risks building events nobody uses.

The automated event calendar is now the backbone of CCFish's live operations strategy. The same architecture is being adapted for a second game title in the studio's portfolio, validating the approach as reusable infrastructure rather than a one-off fix.