A Python library for reading, writing, and updating .csf files from Command & Conquer: Red Alert 2 and Command & Conquer: Yuri's Revenge.
pip install ra2csfIf you find this project helpful, consider supporting me:
CSF (Command String File) files contain localized text strings used in Red Alert 2 and Yuri's Revenge. This library provides simple functions to load, dump, and update these files.
Load a CSF file and return a dictionary mapping string labels to their values.
Parameters:
file- Path to CSF file (str) or file-like object
Returns: dict[str, str] - Dictionary where keys are label names and values are the corresponding text strings.
Example:
import ra2csf
# Load from file path
strings = ra2csf.load("ra2.csf")
print(strings["NAME: Soviet War Factory"])
# Output: "Soviet War Factory"
# Load from file object
with open("ra2.csf", "rb") as f:
strings = ra2csf.load(f)Write a dictionary of strings to a CSF file.
Parameters:
strmap- Dictionary mapping label names (str) to text values (str)file- Output path (str) or writable file-like object
Example:
import ra2csf
new_strings = {
"NAME: Soviet War Factory": "Soviet War Factory",
"DESC: Soviet War Factory": "Produces heavy vehicles",
"NAME: Tesla Reactor": "Tesla Reactor",
}
ra2csf.dump(new_strings, "custom.csf")Update an existing CSF file with new or modified strings. Existing strings not in the update map remain unchanged.
Parameters:
file- Path to existing CSF file (str)strmap- Dictionary of label names and values to add or modify
Example:
import ra2csf
# Update specific strings
ra2csf.update("ra2.csf", {
"NAME: Soviet War Factory": "Soviet Tank Factory",
"NAME: New Unit": "Apocalypse Tank",
})import ra2csf
# Load original
strings = ra2csf.load("original.csf")
# Make modifications
strings["NAME: Tesla Coil"] = "Tesla Tower"
# Save to new file
ra2csf.dump(strings, "modified.csf")
# Or update in-place
ra2csf.update("original.csf", {
"NAME: Tesla Coil": "Tesla Tower"
})The load function handles both standard entries (with RTS label) and extra data entries (with WRTS label), but returns only the string values by default.
All functions accept either file paths or file-like objects:
import io
import ra2csf
# Using BytesIO
buffer = io.BytesIO()
ra2csf.dump({"LABEL": "Text"}, buffer)
buffer.seek(0)
loaded = ra2csf.load(buffer)The ra2csf CLI provides three main commands for working with CSF files.
ra2csf {dump,merge,update} [arguments]Convert a CSF file to human-readable JSON or YAML format.
ra2csf dump [--format json|yaml] <csf_file> <output_file>Aliases: d
Options:
-f, --format- Output format (jsonoryaml, default:json)
Examples:
# Export to JSON
ra2csf dump ra2.csf strings.json
# Export to YAML
ra2csf dump --format yaml ra2.csf strings.yaml
# Short form
ra2csf d -f yaml ra2.csf strings.yamlMerge JSON or YAML files into a new CSF file.
ra2csf merge <csf_file> <sources...>Aliases: m
Behavior: Creates a new CSF file (overwrites if exists).
Examples:
# Merge multiple JSON files into a CSF
ra2csf merge output.csf strings.json more_strings.json
# Merge YAML files
ra2csf merge output.csf translations.yaml
# Short form
ra2csf m output.csf data.jsonAdd or modify entries in an existing CSF file.
ra2csf update <csf_file> <sources...>Aliases: u
Behavior: Reads the existing CSF file, applies updates from source files, and saves back to the same file.
Examples:
# Update a CSF with new strings
ra2csf update ra2.csf new_strings.json
# Apply multiple update files
ra2csf update ra2.csf patch1.json patch2.yaml
# Short form
ra2csf u ra2.csf hotfix.jsonThe merge and update commands accept both JSON and YAML files. The format is auto-detected.
{
"NAME: Soviet War Factory": "Soviet War Factory",
"DESC: Soviet War Factory": "Produces heavy vehicles",
"NAME: Tesla Reactor": "Tesla Reactor"
}NAME: Soviet War Factory: Soviet War Factory
DESC: Soviet War Factory: Produces heavy vehicles
NAME: Tesla Reactor: Tesla Reactor# Dump to JSON for editing
ra2csf dump ra2.csf en_strings.json
# Or YAML for better readability
ra2csf dump -f yaml ra2.csf en_strings.yaml# 1. Edit the JSON file with translations
# 2. Apply updates to the original CSF
ra2csf update ra2.csf chinese_translations.json# Merge several JSON files into one CSF
ra2csf merge ra2.csf ra3_orig.csf units.json buildings.json# Apply multiple update patches in sequence
ra2csf update game.csf v1.1_strings.json
ra2csf update game.csf v1.2_strings.json
ra2csf update game.csf hotfix_strings.jsonThe CLI supports - as a placeholder for stdin/stdout:
# Dump to stdout (for piping)
ra2csf dump ra2.csf - | jq '.'# Install with dev dependencies
pip install ra2csf[dev]
# Run tests
pytest
# Format code
black ra2csf/