This document provides installation and configuration instructions for using the Foothold Checkpoint Tool as a DCSServerBot plugin.
The Foothold plugin integrates the Foothold Checkpoint Tool with DCSServerBot, providing Discord slash commands for managing campaign checkpoints directly from Discord.
- Discord Commands:
/foothold-checkpoint save,/restore,/list,/delete - Role-Based Permissions: Configure which Discord roles can execute each command
- Rich Embeds: Beautiful Discord embeds for command responses and notifications
- Auto-Backup: Automatic backup creation before restoring checkpoints
- Notifications: Configurable Discord notifications for checkpoint events
- Server Integration: Automatically detects Missions/Saves directory per DCS server
- Interactive UI: Discord buttons and dropdowns for better UX
This package includes comprehensive user documentation:
- PLUGIN_USER_MANUAL_EN.md - Complete user guide in English for Discord bot users
- PLUGIN_USER_MANUAL_FR.md - Guide utilisateur complet en français pour les utilisateurs du bot Discord
- This README - Technical documentation for server administrators
For end users: Share the user manual files with your Discord community to help them learn how to use the checkpoint commands.
- DCSServerBot already installed
- Python 3.10+ (should already be configured with DCSSB)
- All required dependencies are already in DCSSB's
requirements.txt:discord.py >= 2.6.4pydantic >= 2.12.5pyyaml(via ruamel-yaml)
Step 1: Download or Build the Plugin ZIP
Option A: Download pre-built ZIP (if available from releases)
- Download
foothold-checkpoint-plugin-vX.X.X.zipfrom GitHub releases
Option B: Build from source
cd D:\dev\_VEAF\VEAF-foothold-checkpoint-tool
python scripts\build_plugin.pyThis creates dist\foothold-checkpoint-plugin-vX.X.X.zip containing:
foothold-checkpoint/directory with all plugin codefoothold-checkpoint.yaml.examplecampaigns.yaml.exampleREADME.md(technical documentation for admins)PLUGIN_USER_MANUAL_EN.md(user guide in English)PLUGIN_USER_MANUAL_FR.md(user guide in French)
Step 2: Extract Plugin to DCSSB
Extract the ZIP file to your DCSSB plugins directory:
# Using PowerShell built-in extraction
cd D:\dev\_VEAF\VEAF-DCSServerBot\plugins
Expand-Archive -Path "path\to\foothold-checkpoint-plugin-vX.X.X.zip" -DestinationPath . -ForceOr manually extract the ZIP so that the foothold-checkpoint/ directory ends up in plugins/.
This creates the following structure:
DCSServerBot/plugins/foothold-checkpoint/
├── __init__.py # Plugin entry point (auto-generated)
├── py.typed # Type checking marker
├── commands.py # Discord slash commands
├── formatters.py # Discord embed formatting
├── listener.py # Event listeners
├── notifications.py # Discord notifications
├── permissions.py # Permission checks
├── ui.py # Interactive UI components
├── version.py
├── schemas/ # Pydantic config models
│ ├── __init__.py
│ └── plugin_config.py
└── core/ # Core checkpoint functionality
├── __init__.py
├── campaign.py
├── checkpoint.py
├── config.py
├── events.py
└── storage.py
Next: After installation, proceed to the Configuration section below to enable and configure the plugin.
Step 1: Clone Repository
cd D:\dev\_VEAF
git clone https://github.com/VEAF/VEAF-foothold-checkpoint-tool.gitStep 2: Copy Plugin Files
# Create plugin directory
cd D:\dev\_VEAF\VEAF-DCSServerBot\plugins
mkdir foothold-checkpoint
# Copy core module
xcopy /E /I D:\dev\_VEAF\VEAF-foothold-checkpoint-tool\src\foothold_checkpoint\core D:\dev\_VEAF\VEAF-DCSServerBot\plugins\foothold-checkpoint\core
# Copy plugin module files
xcopy /E /I D:\dev\_VEAF\VEAF-foothold-checkpoint-tool\src\foothold_checkpoint\plugin\*.py D:\dev\_VEAF\VEAF-DCSServerBot\plugins\foothold-checkpoint\
# Copy schemas
xcopy /E /I D:\dev\_VEAF\VEAF-foothold-checkpoint-tool\src\foothold_checkpoint\plugin\schemas D:\dev\_VEAF\VEAF-DCSServerBot\plugins\foothold-checkpoint\schemas
# Copy py.typed marker
copy D:\dev\_VEAF\VEAF-foothold-checkpoint-tool\src\foothold_checkpoint\py.typed D:\dev\_VEAF\VEAF-DCSServerBot\plugins\foothold-checkpoint\Next: After installation, proceed to the Configuration section below to enable and configure the plugin.
The Foothold Checkpoint plugin follows DCSServerBot's standard configuration pattern:
- Enable in main.yaml: Add plugin to
opt_pluginslist (required for loading) - Plugin Configuration:
config/plugins/foothold-checkpoint.yaml(configures the plugin behavior) - Campaigns Definition:
config/campaigns.yaml(defines all campaign file structures) - Bot Restart: Required after adding/modifying configuration
DCSServerBot uses a hierarchical configuration system:
- DEFAULT section: Base configuration applied to all servers
- Server-specific sections: Override DEFAULT settings for specific servers (server names must match
servers.yaml) - enabled: Set to
trueto activate the plugin for a server,falseto disable - opt_plugins: List in
main.yamlthat controls which optional plugins are loaded
This is the critical first step - without this, the plugin will not be loaded at all.
Edit config/main.yaml and add foothold-checkpoint to the opt_plugins list:
# config/main.yaml
guild_id: YOUR_GUILD_ID
autoupdate: false
# ... other settings ...
opt_plugins: # Optional plugins to load
- tacview
- discord
- restapi
- commands
- backup
- foothold-checkpoint # Add this lineImportant: The plugin name in
opt_pluginsmust befoothold-checkpoint(with hyphen), matching the directory name inplugins/.
Copy the example configuration:
cd D:\dev\_VEAF\VEAF-DCSServerBot
cp plugins\foothold-checkpoint\foothold-checkpoint.yaml.example config\plugins\foothold-checkpoint.yamlEdit config/plugins/foothold-checkpoint.yaml:
##############################################################
# Configuration for the Foothold Checkpoint plugin #
##############################################################
DEFAULT:
# Enable or disable the plugin
enabled: true
# Path to campaigns.yaml file (required)
campaigns_file: ./campaigns.yaml
# Directory where checkpoints are stored
checkpoints_dir: ./checkpoints
# Discord role-based permissions
permissions:
save:
- DCS Admin
- Mission Designer
restore:
- DCS Admin
list:
- DCS Admin
- Mission Designer
- Mission Controller
delete:
- DCS Admin
# Discord notifications
notifications:
# Discord channel ID where notifications will be sent
# To get ID: Right-click channel → Copy Channel ID (requires Developer Mode)
channel: 1234567890123456789 # Replace with your channel ID
on_save: true
on_restore: true
on_delete: true
on_error: true
# Per-server configuration (optional)
# Server names must match your servers.yaml
# Example: Disable for specific server
# DCS.release_server:
# enabled: false
# Example: Different permissions per server
# DCS.production_server:
# permissions:
# restore:
# - Admin # More restrictiveConfiguration Notes:
- enabled: Set to
falseto disable the plugin without removing it - campaigns_file: Path to campaigns configuration (see Step 3)
- checkpoints_dir: Where checkpoint ZIP files are stored
- notifications.channel: Replace
1234567890123456789with your actual Discord channel ID (integer) - Server sections: Add
DCS.your_server_name:sections to override defaults per server
Copy the campaigns example:
cp plugins\foothold-checkpoint\campaigns.yaml.example campaigns.yamlEdit campaigns.yaml to define your campaign file structures. See the included campaigns.yaml.example for complete examples with all DCS maps.
Example minimal configuration:
campaigns:
afghanistan:
display_name: "Afghanistan"
files:
persistence:
- "foothold_afghanistan.lua"
ctld_save:
files:
- "foothold_afghanistan_CTLD_Save.csv"
optional: true
ctld_farps:
files:
- "foothold_afghanistan_CTLD_FARPS.csv"
optional: true
storage:
files:
- "foothold_afghanistan_storage.csv"
optional: trueNote: The campaigns.yaml file defines file names and structures, not server paths. Server paths are configured in DCSServerBot's
servers.yamland accessed dynamically via theserverparameter.
After creating the configuration files, restart DCSServerBot to load the plugin:
# Stop DCSSB (Ctrl+C if running in terminal, or stop service)
# Then restart
cd D:\dev\_VEAF\VEAF-DCSServerBot
python run.pyOr if running as a service:
Restart-Service DCSServerBotFirst, verify the plugin was enabled in main.yaml:
- Confirm
foothold-checkpointappears in theopt_pluginslist - If not present, the plugin will not load at all
Then check Discord for slash commands:
The following slash commands should be available:
/foothold-checkpoint save- Save a checkpoint/foothold-checkpoint restore- Restore a checkpoint/foothold-checkpoint list- List available checkpoints/foothold-checkpoint delete- Delete a checkpoint
Note: Slash commands may take 1-2 minutes to sync with Discord after bot restart.
Check DCSSB logs for plugin loading confirmation:
Get-Content DCSServerBot\logs\bot.log -Tail 50Look for lines like:
[INFO] Loading extension plugins.foothold-checkpoint
[INFO] Extension plugins.foothold-checkpoint loaded successfully
All commands are under the /foothold-checkpoint group:
Save a checkpoint for campaign files using interactive selection.
Parameters:
server(required): DCS server name from DCSSB configuration- Determines which
Missions/Savesfolder to read from - Must match a server defined in
servers.yaml - Autocomplete: Type to filter available servers
- Determines which
Example:
/foothold-checkpoint save server:Afghanistan
How it works:
- Plugin accesses the server instance from DCSSB:
self.bot.servers[server_name] - Gets the DCS installation path:
server.instance.home - Constructs Missions/Saves path:
{home}/Missions/Saves/ - Detects campaigns: Scans files in Missions/Saves and matches them to campaign configurations
- Interactive selection: Shows detected campaigns in a selection menu
- Metadata modal: Optionally add custom name and comment to the checkpoint
- Reads campaign files from that directory based on
campaigns.yamldefinitions - Creates versioned ZIP checkpoint in
checkpoints_dir
Campaign Detection:
The plugin only shows campaigns that are actually present in the server's Missions/Saves directory. If a campaign is configured in campaigns.yaml but has no files in the server directory, it won't appear in the selection menu. This prevents saving empty checkpoints and provides accurate feedback about which campaigns are available on each server.
Required Role: Configured in permissions.save
Restore a checkpoint to a campaign using interactive selection.
Parameters:
server(required): DCS server name from DCSSB configuration- Determines which
Missions/Savesfolder to restore to - Must match a server defined in
servers.yaml - Autocomplete: Type to filter available servers
- Determines which
Example:
/foothold-checkpoint restore server:Afghanistan
Interactive Selection: The plugin displays a dropdown menu with all available checkpoints, showing:
- Checkpoint filename
- Campaign name
- Date and time
- File size
- Custom name and comment (if present)
Safety features:
- Automatic backup always created before restore for safety
- Files renamed to match current campaign file naming conventions
- Validation of checkpoint integrity before restore
- Confirmation dialog with full checkpoint details
- Server-specific restore to correct Missions/Saves directory
Required Role: Configured in permissions.restore
Browse all saved checkpoints with an interactive viewer.
Parameters: None
Example:
/foothold-checkpoint list
Interactive Browser:
- Dropdown menu to navigate between checkpoints
- Detailed view showing:
- Checkpoint filename
- Campaign name
- Date and time
- File size
- SHA-256 checksums
- Custom name and comment (if present)
- List of files in the checkpoint
Required Role: Configured in permissions.list
Delete a checkpoint file using interactive selection.
Parameters: None
Example:
/foothold-checkpoint delete
Interactive Selection: The plugin displays an interactive browser with:
- Dropdown menu to navigate between checkpoints
- Detailed view showing checkpoint information
- Delete button to request deletion
- Safety confirmation dialog before actual deletion
Checkpoint details shown:
- Checkpoint filename
- Campaign name
- Date and time
- File size
- Custom name and comment (if present)
Confirmation:
- Interactive button confirmation required after selection
- Shows full checkpoint details before deletion
- Option to cancel and return to browser
- 60-second timeout for confirmation
Warning: Deletion is permanent and cannot be undone!
Required Role: Configured in permissions.delete
The plugin integrates directly with DCSServerBot's server management:
When you run /foothold-checkpoint save server:Afghanistan:
- Server Validation: Plugin checks if
Afghanistanexists inself.bot.servers - Path Resolution: Accesses
self.bot.servers["Afghanistan"].instance.home - Directory Construction: Builds path
{home}/Missions/Saves/ - File Collection: Reads campaign files from that Missions/Saves directory
- Multi-Server Support: Each DCS server has its own Missions/Saves folder
- Dynamic Paths: No hardcoded paths in campaigns.yaml
- Automatic Detection: Plugin finds files automatically based on server instance
- Consistency: Server name in checkpoint metadata matches actual DCS server
If you have these DCSSB servers:
# servers.yaml
Afghanistan:
installation: "D:/DCS/Afghanistan"
Caucasus:
installation: "D:/DCS/Caucasus"The plugin automatically uses:
- Afghanistan saves from:
D:/DCS/Afghanistan/Missions/Saves/ - Caucasus saves from:
D:/DCS/Caucasus/Missions/Saves/
The plugin uses role-based access control. Users must have one of the configured roles for each operation, or have Discord Administrator permission.
Each operation has a list of Discord role names that have permission:
permissions:
save: ["DCS Admin", "Mission Designer"]
restore: ["Admin"]
list: ["@everyone"]
delete: ["Admin"]- save: Create new checkpoints
- restore: Restore checkpoints (most dangerous - can overwrite live data)
- list: View available checkpoints (read-only)
- delete: Delete checkpoints (permanent action)
permissions:
save: ["DCS Admin", "Mission Designer"]
restore: ["Admin"] # Most restrictive
list: [] # Empty = everyone can use
delete: ["Admin"]Empty array [] = everyone can use the command.
The plugin can send Discord notifications for checkpoint events to a configured channel.
Notifications use a simple on/off toggle per event type with a single channel:
notifications:
# Discord channel ID where all notifications are sent
# To get channel ID: Right-click channel → Copy Channel ID (Developer Mode required)
channel: 1234567890123456789
# Enable/disable notifications per event type
on_save: true # Notify when checkpoint saved
on_restore: true # Notify when checkpoint restored
on_delete: true # Notify when checkpoint deleted
on_error: true # Notify when operation fails- on_save: Checkpoint saved successfully (green embed with checkpoint details)
- on_restore: Checkpoint restored successfully (blue embed with restore details)
- on_delete: Checkpoint deleted (orange embed with warning)
- on_error: Operation failed (red embed with error message)
Use server-specific sections to override notification channels:
DEFAULT:
notifications:
channel: 1234567890123456789
on_save: true
on_restore: true
on_delete: true
on_error: true
# Production server uses different channel
DCS.production_server:
notifications:
channel: 9876543210987654321 # Production notifications channel
on_delete: true
on_error: true
on_save: false # Don't notify on routine saves
on_restore: false # Don't notify on routine restoresTo disable notifications, set all events to false:
notifications:
channel: 1234567890123456789
on_save: false
on_restore: false
on_delete: false
on_error: false # Still recommended to keep error notificationsEvents generate rich embeds with checkpoint details, user info, and timestamps.
After installation:
DCSServerBot/
├── plugins/
│ └── foothold-checkpoint/
│ ├── __init__.py
│ ├── commands.py # Slash command handlers
│ ├── formatters.py # Discord embed formatting
│ ├── listener.py # Event listeners
│ ├── notifications.py # Discord notifications
│ ├── permissions.py # Permission checks
│ ├── ui.py # Interactive UI components
│ ├── version.py
│ ├── schemas/ # Pydantic config models
│ └── core/ # Core checkpoint logic
├── config/
│ ├── plugins/
│ │ └── foothold-checkpoint.yaml # Plugin config
│ └── campaigns.yaml # Campaign definitions
└── checkpoints/ # Checkpoint storage (created automatically)
Cause: Server name doesn't match DCSSB servers.yaml
Fix: Use exact server name from servers.yaml, case-sensitive
Cause: Server installation path incorrect or Missions/Saves doesn't exist
Fix: Verify server installation path in servers.yaml and ensure DCS server has created the Missions/Saves folder
Cause: DCSSB server instance API mismatch
Fix: Check DCSSB version compatibility, ensure server.instance.home property exists
Cause: campaigns.yaml not configured or invalid
Fix: Verify config/campaigns.yaml exists and contains valid campaign definitions
For active development, you can create a symbolic link instead of copying files:
# Remove the copied directory (run PowerShell as Administrator)
cd D:\dev\_VEAF\VEAF-DCSServerBot\plugins
Remove-Item -Recurse foothold-checkpoint
# Create symbolic link to source
New-Item -ItemType SymbolicLink -Path foothold-checkpoint -Target D:\dev\_VEAF\VEAF-foothold-checkpoint-tool\src\foothold_checkpoint\pluginWith a symbolic link, changes to the source code take effect immediately after restarting DCSSB, without needing to re-copy files.
This is ideal for:
- Testing changes
- Debugging issues
- Contributing to development
Note: Symbolic links require administrator privileges in PowerShell.
# All tests
poetry run pytest
# With coverage
poetry run pytest --cov=foothold_checkpoint
# Specific test file
poetry run pytest tests/test_cli.pypython scripts/build_plugin.pyOutput: dist/foothold-checkpoint-plugin-vX.X.X.zip
After installation:
DCSServerBot/
├── plugins/
│ └── foothold-checkpoint/
│ ├── __init__.py
│ ├── commands.py # Slash command handlers
│ ├── formatters.py # Discord embed formatting
│ ├── listener.py # Event listeners
│ ├── notifications.py # Discord notifications
│ ├── permissions.py # Permission checks
│ ├── ui.py # Interactive UI components
│ ├── version.py
│ ├── schemas/ # Pydantic config models
│ └── core/ # Core checkpoint logic
├── config/
│ ├── plugins/
│ │ └── foothold-checkpoint.yaml # Plugin config
│ └── campaigns.yaml # Campaign definitions
└── checkpoints/ # Checkpoint storage (created automatically)
- User Manuals: See PLUGIN_USER_MANUAL_EN.md or PLUGIN_USER_MANUAL_FR.md for end-user documentation
- GitHub Issues: https://github.com/VEAF/VEAF-foothold-checkpoint-tool/issues
- General Usage: See USERS.md in main repository
- CLI Tool: See main README.md for standalone CLI usage
- 🏗️ ARCHITECTURE: Plugin now uses DCSServerBot's
Pluginbase class - 🎮 EVENT LISTENER: Integration with DCS events via
EventListener - ⚙️ AUTO-CONFIG: Configuration via
self.localsandself.get_config(server) - 📢 NOTIFICATIONS: Per-server channels with configurable toggles
- 📚 DOCUMENTATION: Comprehensive EN/FR user manuals
- 🗂️ EXTERNAL CAMPAIGNS: Support for shared
campaigns.yamlconfiguration - 📋 GROUPING: Visual separator between manual checkpoints and auto-backups
- 📅 SORTING: Chronological ordering (oldest first, newest last in dropdowns)
- ✨ Added server parameter integration with DCSSB
- 🎨 Improved list command with aligned table formatting
- 🔧 Dynamic Missions/Saves path resolution per server
- 📚 Enhanced documentation for server integration
- 🎉 Initial plugin release
- 💾 Save, restore, list, delete commands
- 🎯 Interactive UI components
- 🔐 Role-based permissions
- 📢 Discord notifications
Same as the main Foothold Checkpoint Tool project.