Skip to content
Back to skills

Smm Spatial Observation Encoding

ASecurity

Encode game state as a Super Mini Map (SMM) with separate binary channels for players, ball, and ownership, bit-packed for efficient transfer in RL training

  • 61 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 12, 2026
ai-agentspythongit

Works with

  • cli

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add wenmin-wu/ds-skills --skill smm-spatial-observation-encoding --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Smm Spatial Observation Encoding?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Smm Spatial Observation Encoding
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wenmin-wu-smm-spatial-observation-encoding/badge)](https://www.skillsdirectory.com/skills/wenmin-wu-smm-spatial-observation-encoding)

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

Download with Pro
SKILL.md
---
name: cv-smm-spatial-observation-encoding
description: Encode game state as a Super Mini Map (SMM) with separate binary channels for players, ball, and ownership, bit-packed for efficient transfer in RL training
---

# SMM Spatial Observation Encoding

## Overview

For RL agents in spatial games (football, RTS), raw observation vectors (player positions as floats) lose spatial relationships. The Super Mini Map (SMM) renders game state onto a small 2D grid with separate binary channels: one for left team positions, one for right team, one for ball, one for active player. This gives CNN policies a spatial inductive bias while staying compact via bit-packing.

## Quick Start

```python
import numpy as np
from collections import deque

def render_smm(obs, width=96, height=72):
    smm = np.zeros((height, width, 4), dtype=np.uint8)
    def plot(positions, channel):
        for x, y in positions:
            px = int((x + 1) / 2 * (width - 1))
            py = int((y + 0.42) / 0.84 * (height - 1))
            px, py = np.clip(px, 0, width-1), np.clip(py, 0, height-1)
            smm[py, px, channel] = 255
    plot(obs["left_team"], 0)
    plot(obs["right_team"], 1)
    plot([obs["ball"][:2]], 2)
    plot([obs["left_team"][obs["active"]]], 3)
    return smm

# Frame stacking with bit-packing
frames = deque(maxlen=4)
obs = render_smm(raw_obs)
frames.extend([obs] * 4)
stacked = np.concatenate(list(frames), axis=-1)
packed = np.packbits(stacked, axis=-1)
```

## Workflow

1. Define a small grid (72x96 or 48x64) matching the field's aspect ratio
2. Map normalized positions to pixel coordinates with boundary clipping
3. Render each entity type into a separate binary channel
4. Stack 4 consecutive frames for temporal context (16 channels total)
5. Bit-pack the binary arrays for 8x memory reduction during transfer
6. Feed to a CNN policy network (Conv2D → Dense → action logits)

## Key Decisions

- **Resolution**: 72x96 balances spatial precision vs. computation; lower res for faster training
- **Channels**: 4 base channels (left team, right team, ball, active player); add ownership, direction as needed
- **Frame stacking**: 4 frames captures velocity without explicit velocity channels
- **Bit-packing**: reduces observation size 8x for distributed RL data transfer; unpack before inference
- **vs. raw vectors**: SMM gives CNN spatial inductive bias; raw vectors are better for MLP policies

## References

- [GFootball - train SEED RL agent](https://www.kaggle.com/code/piotrstanczyk/gfootball-train-seed-rl-agent)
- [Convolutional Deep-Q learner](https://www.kaggle.com/code/garethjns/convolutional-deep-q-learner)

Attribution

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

Loading comments…