Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Subjective

ASecurity

First-person code — the "I" shifts based on who is speaking

56 stars
0 votes
0 copies
0 views
Added 10/6/2026
developmentjavascriptpythongojava

Security Analysis

A100/100

Pro scans all 5 files and shows the line behind each finding

Scanned 10/6/2026

$npx -y skills add SimHacker/moollm --skill subjective --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Subjective?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Subjective
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/simhacker-subjective/badge)](https://www.skillsdirectory.com/skills/simhacker-subjective)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: subjective
description: First-person code — the "I" shifts based on who is speaking
allowed-tools:
  - read_file
  - write_file
tier: 1
protocol: SUBJECTIVE-ORIENTED
tags: [moollm, programming, perspective, first-person, context]
related: [context, runtime, object, character]
adversary: third-person-coupling
---

# Subjective-Oriented Programming

> *"i_have('key') reads naturally. 'Does the world have a key?' does not."*
> — The Gezelligheid Grotto Design Principles

---

## What Is It?

**Subjective-oriented programming** uses `i_` prefixed functions that speak from the current subject's perspective. The "I" shifts based on context:

| Context | Who is "I"? |
|---------|-------------|
| Player action | The player character |
| Object simulate() | The object |
| NPC dialogue | The NPC |
| Room description | The room |

---

## The Problem with `world.`

```javascript
// Third-person: "Does the world have a key?"
if (world.has("key")) ...

// But who has the key? The world? The player? Confusing!
```

## The Solution: `i_`

```javascript
// First-person: "Do I have a key?"
if (i_have("key")) ...

// Clear! The current subject is asking about themselves.
```

---

## Core `i_` Functions

### Inventory

```javascript
i_have("key")           // Do I have this item?
i_give("key")           // Give item to current target
i_take("key")           // Take item from current target
i_drop("key")           // Drop item in current room
i_has_tag("weapon")     // Do I have any item with this tag?
i_find_by_tag("food")   // Find all my items with this tag
```

### State

```javascript
i_am("lit")             // Am I in this state? (object.state.lit)
i_am_not("broken")      // Am I NOT in this state?
i_set("lit", true)      // Set my state
i_get("fuel")           // Get my state value
```

### Buffs

```javascript
i_have_buff("strength")     // Do I have this buff?
i_add_buff(buff)            // Apply buff to myself
i_remove_buff("strength")   // Remove buff from myself
```

### Flags

```javascript
i_flag("door_unlocked")     // Is this flag set?
i_set_flag("door_unlocked") // Set this flag
```

### Location

```javascript
i_am_in("pub/")             // Am I in this room?
i_can_see("treasure")       // Can I see this object?
i_go("north")               // Move in direction
```

### Communication

```javascript
i_say("Hello!")             // Emit dialogue
i_emote("grins widely")     // Emit emote
i_think("This is odd...")   // Emit internal thought
```

---

## Context Shifting

The meaning of `i_` changes based on who is "speaking":

### Player Context

```yaml
# In player action handlers
effect: |
  if i_have("key"):
    i_say("I found the key!")
    i_drop("key")  # Drop in current room
```

### Object Context (simulate)

```yaml
# In object's simulate field
simulate: |
  if i_am("lit"):
    i_set("fuel", i_get("fuel") - 1)
    if i_get("fuel") <= 0:
      i_set("lit", false)
      i_emit("The lamp dies!")
```

### NPC Context

```yaml
# In NPC dialogue/behavior
behavior: |
  if i_have("gold") and i_can_see("beggar"):
    i_give("gold")
    i_say("For you, friend.")
```

### Room Context

```yaml
# In room description/behavior
describe: |
  if i_am("dark"):
    i_emit("You can't see anything.")
  else:
    i_emit("A cozy room with a fireplace.")
```

---

## Implementation

The `i_` functions are bound to the current subject:

```javascript
class World {
  // The current subject ("I")
  get subject() {
    return this.object || this.npc || this.player;
  }
  
  // === INVENTORY (subjective) ===
  
  i_have(itemId) {
    const inv = this.subject.inventory || [];
    return inv.includes(itemId);
  }
  
  i_give(itemId) {
    const inv = this.subject.inventory || [];
    const idx = inv.indexOf(itemId);
    if (idx > -1) {
      inv.splice(idx, 1);
      (this.target.inventory ??= []).push(itemId);
    }
  }
  
  i_take(itemId) {
    const targetInv = this.target.inventory || [];
    const idx = targetInv.indexOf(itemId);
    if (idx > -1) {
      targetInv.splice(idx, 1);
      (this.subject.inventory ??= []).push(itemId);
    }
  }
  
  i_drop(itemId) {
    const inv = this.subject.inventory || [];
    const idx = inv.indexOf(itemId);
    if (idx > -1) {
      inv.splice(idx, 1);
      (this.room.objects ??= []).push({ id: itemId });
    }
  }
  
  i_has_tag(tag) {
    const inv = this.subject.inventory || [];
    for (const itemId of inv) {
      const item = this.getObject(itemId);
      if (item && (item.tags || []).includes(tag)) {
        return true;
      }
    }
    return false;
  }
  
  // === STATE (subjective) ===
  
  i_am(stateKey) {
    return this.subject.state?.[stateKey] === true;
  }
  
  i_am_not(stateKey) {
    return !this.i_am(stateKey);
  }
  
  i_get(stateKey) {
    return this.subject.state?.[stateKey];
  }
  
  i_set(stateKey, value) {
    this.subject.state ??= {};
    this.subject.state[stateKey] = value;
  }
  
  // === BUFFS (subjective) ===
  
  i_have_buff(buffId) {
    const buffs = this.subject.buffs || [];
    return buffs.some(b => b.id === buffId);
  }
  
  i_add_buff(buff) {
    this.subject.buffs ??= [];
    this.subject.buffs.push(buff);
  }
  
  i_remove_buff(buffId) {
    const buffs = this.subject.buffs || [];
    this.subject.buffs = buffs.filter(b => b.id !== buffId);
  }
  
  // === LOCATION (subjective) ===
  
  i_am_in(roomPath) {
    return this.subject.location === roomPath ||
           this.room?.path === roomPath;
  }
  
  i_can_see(objectId) {
    const objects = this.room?.objects || [];
    return objects.some(o => o.id === objectId);
  }
  
  i_go(direction) {
    this._pendingNavigation = direction;
  }
  
  // === COMMUNICATION (subjective) ===
  
  i_say(message) {
    this.emit(`${this.subject.name}: "${message}"`);
  }
  
  i_emote(action) {
    this.emit(`${this.subject.name} ${action}`);
  }
  
  i_think(thought) {
    this.emit(`(${this.subject.name} thinks: "${thought}")`);
  }
  
  i_emit(message) {
    this.emit(message);
  }
}
```

### Python Equivalent

```python
class World:
    @property
    def subject(self):
        """The current 'I' — object, NPC, or player."""
        return self.object or self.npc or self.player
    
    def i_have(self, item_id: str) -> bool:
        inv = self.subject.get('inventory', [])
        return item_id in inv
    
    def i_am(self, state_key: str) -> bool:
        return self.subject.get('state', {}).get(state_key) == True
    
    def i_get(self, state_key: str):
        return self.subject.get('state', {}).get(state_key)
    
    def i_set(self, state_key: str, value):
        state = self.subject.setdefault('state', {})
        state[state_key] = value
    
    def i_say(self, message: str):
        self.emit(f"{self.subject.get('name')}: \"{message}\"")
    
    def i_emit(self, message: str):
        self.emit(message)
    
    # ... etc
```

---

## Natural Language Compilation

The LLM compiles natural language to `i_` calls:

```yaml
# Natural language
guard: "I have the key and I am not cursed"

# Compiled
guard_js: (world) => world.i_have("key") && !world.i_have_buff("cursed")
guard_py: lambda world: world.i_have("key") and not world.i_have_buff("cursed")
```

```yaml
# Natural language (object context)
simulate: |
  if I am lit and fuel > 0:
    consume 1 fuel
    if fuel reaches 0:
      I am no longer lit
      say "The lamp dies!"

# Compiled
simulate_js: (world) => {
  if (world.i_am("lit") && world.i_get("fuel") > 0) {
    world.i_set("fuel", world.i_get("fuel") - 1);
    if (world.i_get("fuel") <= 0) {
      world.i_set("lit", false);
      world.i_emit("The lamp dies!");
    }
  }
}
```

---

## The `i_` vs `world.` Split

| Use `i_` when... | Use `world.` when... |
|------------------|----------------------|
| Acting as current subject | Accessing global state |
| Checking own inventory | Checking adventure flags |
| Modifying own state | Navigating rooms |
| Speaking in first person | Managing party |

```javascript
// Mixed example
if (i_have("key") && world.flag("door_visible")) {
  i_say("I can unlock this door!");
  world.set_flag("door_unlocked", true);
}
```

---

## Benefits

1. **Readable** — `i_have("key")` reads like English
2. **Context-aware** — "I" shifts naturally
3. **Object-oriented** — Objects think for themselves
4. **Compilable** — LLM can translate natural language easily
5. **Debuggable** — Clear who is speaking in logs

---

## Protocol Symbol

```
SUBJECTIVE-ORIENTED — The "I" shifts based on who is speaking
```

Attribution

SimHackerSimHacker
View sourceSee grades on GitHubMore from SimHacker →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Clean Code

Pragmatic coding standards - concise, direct, no over-engineering, no unnecessary comments

304955 votes

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

286712 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2222 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Writing Plans

Use when you have a spec or requirements for a multi-step task, before touching code

2927051 votes
View all in development →