Skip to content

Interface for Counter-Strike 1.6 game state

License

Notifications You must be signed in to change notification settings

cainky/CounterStrikeInterface

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

121 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Counter-Strike 1.6 Interface

Counter-Strike Logo

A Python interface layer for communicating with Counter-Strike 1.6 servers.

Quick Start (Windows)

First-time setup (downloads HLDS + AMX Mod X):

# Run in PowerShell as Administrator
.\scripts\setup_hlds_windows.ps1

Start the server:

poetry run python -m scripts.start_server

This automatically starts:

  • Redis (via Docker)
  • HLDS dedicated server (de_dust2, 12 players)
  • File bridge (connects game to Python)

Connect your CS 1.6 client to localhost:27015

After connecting, verify the plugin is working in your CS 1.6 console (~ key):

csif_ping         # Should respond with "PONG!"
csif_status       # Shows plugin status
csif_start        # Start exporting observations
csif_dump_once    # Create single observation file
csif_stop         # Stop exporting

Server Configs

The server is scrim-ready by default (MR15 competitive settings). Use these configs:

Config Purpose Command
scrim.cfg Competitive MR15 (default) exec scrim.cfg
pub.cfg Casual/pub play exec pub.cfg
knife.cfg Knife round for side pick exec knife.cfg
live.cfg Go live after knife (3 restarts) exec live.cfg
overtime.cfg MR3 $10k overtime exec overtime.cfg

Scrim workflow:

exec knife.cfg     # Knife for sides
exec live.cfg      # Go live after knife
exec overtime.cfg  # If tied at 15-15

Configuration

Edit config/server.yaml to customize:

  • Map, max players, server name
  • RCON password
  • Round settings
  • Session ID for Redis

Quick Start (Mock Server)

Test your code without CS 1.6:

docker compose up

This runs a mock CS server at 100Hz. Great for developing your agent.

What is this?

This is the interface layer - it handles communication between Python and CS 1.6 game servers:

  • Observation schemas (ObsV1) - Structured game state data
  • Action schemas (ActionV1) - Structured player commands
  • Redis IPC client - Pub/sub communication at 100 Hz
  • Geometry utilities - Coordinate transforms, visibility checks

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    CS 1.6 DEDICATED SERVER                   β”‚
β”‚                                                              β”‚
β”‚  HLDS ──▢ Metamod ──▢ AMX Mod X ──▢ cs_interface.amxx       β”‚
β”‚                                              β”‚               β”‚
β”‚                                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚                                   β”‚  File IPC (JSON)    β”‚   β”‚
β”‚                                   β”‚  cs_interface_*.jsonβ”‚   β”‚
β”‚                                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                               β”‚
                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                          β”‚              REDIS                   β”‚
                          β”‚  cs:obs:{session}  β†’  Observations   β”‚
                          β”‚  cs:act:{session}  ←  Actions        β”‚
                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–²β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                               β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                 THIS REPO (Interface Layer)                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚   Schemas    β”‚  β”‚ CSInterface  β”‚  β”‚     Geometry     β”‚   β”‚
β”‚  β”‚ ObsV1/Action β”‚  β”‚    Client    β”‚  β”‚     Utilities    β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                               β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚               YOUR REPO (Agent Development)                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚   Gymnasium  β”‚  β”‚   Training   β”‚  β”‚   Your Agent     β”‚   β”‚
β”‚  β”‚     Env      β”‚  β”‚    Loop      β”‚  β”‚     Policy       β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Installation (Development)

git clone https://github.com/cainky/CounterStrikeInterface.git
cd CounterStrikeInterface
poetry install

Usage

Python Interface Client

from src.interface import CSInterfaceClient, CSInterfaceConfig, ActionBuilder

# Connect to server
config = CSInterfaceConfig(
    redis_host="localhost",
    session_id="training",
)
client = CSInterfaceClient(config)
client.connect()

# Receive observations
obs = client.get_observation()
print(f"Tick: {obs.tick}")
print(f"Position: {obs.self_state.position}")
print(f"Health: {obs.self_state.health:.0%}")

# Send actions
action_builder = ActionBuilder()
action = action_builder.build(
    tick=obs.tick,
    forward=1.0,
    yaw_delta=5.0,
    fire=True,
)
next_obs = client.step(action)

Mock Client (for testing without server)

from src.interface import CSInterfaceConfig, MockCSInterfaceClient

config = CSInterfaceConfig(session_id="test")
client = MockCSInterfaceClient(config)

# Generates synthetic observations
obs = client.get_observation()

Observation Schema (ObsV1)

Component Description
self_state Position, velocity, health, armor, weapons, inventory
players Visible/audible enemies with relative position and angle
sounds Recent sound events with direction and confidence
round_state Phase, time, scores, bomb status
map_context Map name, distance/angle to objectives

Human vs Oracle Mode

Feature Human Mode Oracle Mode
Enemy positions Only visible All enemies
Enemy health Unknown Exact value
Through-wall info None Full

Action Schema (ActionV1)

Component Type Description
movement Continuous forward/strafe [-1,1], jump, crouch, walk
view Continuous pitch/yaw deltas (degrees)
attack Binary fire, alt_fire, reload
utility Discrete use, weapon switch, buy

Project Structure

config/
└── server.yaml            # Server configuration (map, players, etc.)

src/
β”œβ”€β”€ schemas/               # Core data schemas
β”œβ”€β”€ interface/             # Redis IPC layer
└── utils/                 # Geometry, visibility utilities

scripts/
β”œβ”€β”€ start_server.py        # One-command server launcher
β”œβ”€β”€ setup_hlds_windows.ps1 # Windows HLDS installer
β”œβ”€β”€ mock_server.py         # Simulate CS server (100Hz)
β”œβ”€β”€ file_bridge.py         # Bridge AMX plugin to Redis
└── test_observability.py

server_plugin/
β”œβ”€β”€ cs_interface.sma       # AMX Mod X plugin source
└── README.md              # Server setup docs

For Agent Developers

This interface provides the low-level communication. To train an agent:

  1. Create a separate repo for your agent
  2. Import the interface: from cs_interface import CSInterfaceClient, ObsV1, ActionV1
  3. Build your Gymnasium env wrapping the client
  4. Define your reward function based on ObsV1 fields
  5. Train with your preferred RL library (stable-baselines3, cleanRL, etc.)

Requirements

  • Docker (for quick start)
  • Or: Python 3.10+, Redis, CS 1.6 dedicated server

Configuration Reference

Example config/server.yaml:

server:
  map: de_dust2
  maxplayers: 12
  hostname: "CS Training Server"
  rcon_password: "changeme"

redis:
  host: localhost
  port: 6379
  session_id: training

game:
  round_time: 3        # minutes
  freeze_time: 3       # seconds
  buy_time: 15         # seconds
  bot_quota: 10        # number of bots

Troubleshooting

Plugin not responding to commands

Symptom: csif_ping in console does nothing, or says "Unknown command"

Check:

  1. Verify AMX Mod X is loaded:

    meta list
    

    Should show AMX Mod X in the list.

  2. Verify plugin is loaded:

    amxx plugins
    

    Should show cs_interface.amxx with status running.

  3. If plugin shows error or bad load:

    • Check cstrike/addons/amxmodx/logs/ for error messages
    • Ensure cs_interface.amxx is in cstrike/addons/amxmodx/plugins/
    • Ensure it's listed in cstrike/addons/amxmodx/configs/plugins.ini

What success looks like:

] csif_ping
[CS Interface] PONG! Plugin v3 ready.

] csif_status
[CS Interface] Status: IDLE
[CS Interface] Session epoch: 42
[CS Interface] File IPC: ENABLED
[CS Interface] Last write: 0.003s ago

Agent connects but gets no observations

Symptom: client.get_observation() hangs or returns None

Check:

  1. Is Redis running?

    redis-cli ping

    Should return PONG.

  2. Is the file bridge running?

    poetry run python -m scripts.file_bridge

    Should show [Bridge] Connected to Redis, watching for snapshots...

  3. Is the plugin exporting?

    csif_start
    csif_status
    

    Status should show RUNNING, not IDLE.

  4. Check the snapshot file exists and is updating:

    ls -la C:/hlds_cs16/cstrike/addons/amxmodx/configs/csif_snapshot.json

    Timestamp should be updating every ~10ms.

Redis connection refused

Symptom: ConnectionRefusedError: [Errno 111] Connection refused

Fix:

# If using Docker:
docker run -d --name redis -p 6379:6379 redis:alpine

# Verify:
redis-cli ping  # Should return PONG

Server starts but bots don't spawn

Symptom: Server runs, you connect, but no bots appear

Fix:

# In CS console:
bot_quota 10
bot_add_ct
bot_add_t

Or ensure bot_quota is set in your server.yaml.

File IPC permission errors (Windows)

Symptom: Plugin fails to write JSON files

Fix: Run HLDS as Administrator, or ensure the cstrike/addons/amxmodx/configs/ folder has write permissions for all users.

License

GPL-3.0 License. See LICENSE for details.

About

Interface for Counter-Strike 1.6 game state

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published

Contributors 2

  •  
  •