# Event System Analysis - Quick Reference

## Key Metrics

### Event Complexity
```
- Total event functions: 85+ (58 in events.py + 27 in dayEvents.py)
- Functions checked per tick: O(n) where n = 85
- Time complexity: HIGH - module re-import + dir() + getattr() every tick
- Event discovery pattern: Dynamic introspection (inefficient)
```

### Event Triggering Schedule
```
Hourly Tick (when minuteOfHour == 0):
  - checkDayEvents() - 27 functions checked
  - checkTutorialEvents() - variable
  - checkEvents() - 58 functions checked  
  - checkDilemmas() - max 1 result returned

Intra-day Tick (every minute):
  - getIntradayActivity() - parsed daily plans
```

### API Calls (OpenAI)
```
Type: GPT-3.5-turbo
Frequency: ~100 calls/player/day (at scale)
Timeout: 3.5s per message (with 3 retries = max 10.5s)
Cost: ~$50/day for 1000 concurrent players
Annual: ~$18,250-19,000
```

### Memory Usage
```
Conversations (unbounded):
- Per player: ~20 relationships × ~100 messages = 2000 messages
- Per message: ~500 bytes
- Per player: ~1 MB for conversation history
- 1000 players: ~1 GB of conversation data

Player objects:
- Per player: ~50 MB average
- 1000 players: ~50 GB total
```

### Scalability Analysis (1000 Concurrent Players)
```
Event Checking Overhead:
- Per minute: 170,000 checks (1000 players × 2 checks × 85 functions)
- Latency per check: ~500ns (dir + getattr + filter)
- Total overhead: 85ms per minute = 2+ hours per day of CPU time

AI API Calls:
- Daily: ~100,000 calls
- Hourly: ~4,167 calls
- Cost: $50/day + API rate limiting constraints

Database I/O:
- Weekly save: 1000 players × 50MB = 50GB/week
- Daily: ~7 GB writes to MySQL
```

## Critical Issues

### 1. SECURITY: eval() Code Execution (Line 559 of app.py)
```python
eval(event['type']+"(player,'answer',event['key'],event['message'])")
```
**Impact**: Arbitrary code execution - attacker can steal data, modify other players, delete database
**Severity**: CRITICAL - FIX IMMEDIATELY
**Fix**: Replace with function registry lookup

### 2. PERFORMANCE: O(n) Event Discovery
```python
def checkEvents(player,type):
    import events  # Re-imports every tick!
    for i in dir(events):  # Checks ALL items (85+)
        item = getattr(events,i)
        if callable(item) and ...:
            result = item(player,type)
```
**Impact**: 85+ function checks per game tick, 170,000+ per minute at scale
**Severity**: HIGH
**Fix**: Cache event function list at startup

### 3. COST: Unbounded API Calls
```
- Every conversation = API call
- Every character message = API call
- 1/101 random chance per character per day
- 1000 players × 100 API calls/day = $50/day
```
**Impact**: ~$18K/year API costs + rate limiting constraints
**Severity**: HIGH
**Fix**: Implement response caching + rate limiting

### 4. MEMORY: Unbounded Conversation Storage
```python
class conversationObj():
    self.conversation = []  # Never pruned, grows indefinitely
    
# Impact: 1GB+ per 1000 players after extended play
```
**Impact**: Linear memory growth with playtime
**Severity**: MEDIUM
**Fix**: Implement message pruning (keep last 50 messages)

## Event Processing Flow (Visual)

```
Game Tick Every gameSpeed increments:
│
├─ Minutely:
│  └─ getIntradayActivity() - Update location/stats
│
└─ Hourly (when minuteOfHour == 0):
   ├─ checkDayEvents() - 27 functions
   │  └─ Iterate dir(dayEvents), call each, return first match
   │
   ├─ checkTutorialEvents() - Variable
   │  └─ Import tutorial_events, check triggers
   │
   ├─ checkEvents() - 58 functions
   │  └─ Iterate dir(events), call each, return first match
   │
   ├─ checkDilemmas() - Active dilemmas
   │  └─ Random chance to advance dilemma state
   │
   └─ Daily checks:
      └─ Birthday events
      └─ Age progression
      └─ Death chance
      └─ Character messages (1/101) → OpenAI API call (3.5s timeout)
```

## Conversation API Call Chain

```
Player Opens Character:
│
├─ parseConversations(player, character)
│  └─ Gets globals(), finds all functions
│  └─ Calls each function with await
│  └─ Each function checks character eligibility
│
└─ Player Clicks Conversation Button:
   │
   ├─ conversationInit() 
   │  └─ Calls specific conversation function
   │
   ├─ getOpenAIResponse()
   │  ├─ Builds prompt with character description
   │  ├─ API call: openai.ChatCompletion.acreate()
   │  │  └─ Timeout: 3.5s
   │  │  └─ Retry: up to 3 times (max 10.5s)
   │  ├─ Parse sentiment (<<positive>>, <<negative>>, <<neutral>>)
   │  └─ Update character affinity based on sentiment
   │
   └─ Player Responds:
      └─ Call getOpenAIResponse() again (another API call)
```

## Event Deduplication Strategy

**Current Implementation:**
- `player.events[]` - One-time events that never trigger again
- `player.askedQuestions[]` - Questions already answered
- `fname not in player.events` checks in each event function

**Problem:** Still calls event function logic even if event won't trigger
- Example: `firstCrush()` checks age, looks up relationships, generates options, all before checking fname

## API Cost Model

```
Per Player Per Day:
├─ Character messages: ~0.88 calls (1/101 chance × 100 relationships)
├─ Player conversations: ~5-10 calls if player actively chats
└─ Total: ~6-11 API calls/player/day

At Scale (1000 players):
├─ Daily: ~6,000-11,000 calls
├─ Cost: ~$3-5.50/day
├─ Monthly: ~$90-165
└─ Annual: ~$1,095-2,000

Projected at 10,000 players:
├─ Daily: ~60,000-110,000 calls  
├─ Monthly: ~$1,800-3,300
└─ Annual: ~$21,900-39,600
```

## Recommended Priority Fixes

### 🔴 CRITICAL (Do First - Security)
1. Replace eval() with function registry lookup
2. Add whitelist validation for event type names
3. Sanitize all client input

### 🟠 HIGH (Do Next - Scalability)
4. Cache event function list at module load time
5. Implement API response caching
6. Add rate limiting to API calls
7. Implement conversation message pruning

### 🟡 MEDIUM (Do Soon - Performance)
8. Optimize event eligibility checks
9. Move character message generation off main loop
10. Add connection pooling for OpenAI

### 🔵 LOW (Do Later - Architecture)
11. Redesign with event registry pattern
12. Implement event eligibility cache
13. Add conversation archival system

