The Smoke on Damage plugin provides visual feedback when aircraft are damaged, emitting black smoke and simulating engine failures for enhanced realism.
Overview
When an aircraft’s health drops below a threshold, it begins emitting black smoke and suffers engine damage that disables the afterburner and prevents missile firing.
This plugin is implemented as a module (folder-based plugin) and serves as an example for creating more complex plugins that need multiple files.
Configuration
Configure smoke behavior in config.py:
# Enable planes smoking on low life
# If true, planes on life < SMOKE_LIFE will emit black smoke
# They will also have an engine breakdown, not being able to turn
# on afterburner. Also they won't be able to fire missiles
SMOKE_PLANE = True
# Planes smoking minimum life
SMOKE_LIFE = 5
Settings Explained
| Setting | Type | Description |
|---|
SMOKE_PLANE | Boolean | Enable/disable the entire smoke system |
SMOKE_LIFE | Integer | Health threshold below which smoke appears |
Setting SMOKE_LIFE too high (e.g., 50) will cause aircraft to smoke even with minor damage. Setting it too low (e.g., 1) means only critically damaged aircraft will smoke.
How It Works
Smoke Activation
The plugin monitors flight data packets and checks aircraft health:
def on_flight_data(self, data, player, message_to_client, message_to_server):
"""After the initial incoming flight packet, check whether
the health is below the threshold, if so add smoke"""
if SMOKE_PLANE and player.aircraft.life < SMOKE_LIFE:
# Add smoke to the plane
smoke_packet = FSNETCMD_AIRPLANESTATE(data).smoke()
# Forward it on to the server
message_to_server.append(smoke_packet)
if not player.aircraft.damage_engine_warn_sent:
player.aircraft.damage_engine_warn_sent = True
# Warn the player
message = "Your engine has been damaged! You can't turn on your afterburner!"
message_to_client.append(FSNETCMD_TEXTMESSAGE.encode(message, True))
message_to_client.append(FSNETCMD_AIRCMD.set_afterburner(player.aircraft.id, False, True))
return False
else:
return True
Engine Damage Effects
When health drops below SMOKE_LIFE:
- Black smoke emission - Visual indicator of damage
- Afterburner disabled - Cannot engage afterburner
- Warning message sent - Player notified once
- Weapon restrictions - Cannot fire missiles
The warning message is only sent once per damage session to avoid spam. The flag damage_engine_warn_sent tracks this.
Repair and Recovery
Weapon Config Hook
When a player repairs or changes loadout:
def on_weapon_config(self, data, player, message_to_client, message_to_server):
if ENABLED:
player.aircraft.just_repaired = True
if player.aircraft.get_initial_config_value("AFTBURNR") == "TRUE":
message_to_client.append(FSNETCMD_AIRCMD.set_afterburner(player.aircraft.id, True, True))
return True
Recovery process:
- Weapon config change detected (repair)
just_repaired flag set (important for anti-cheat)
- If aircraft has afterburner capability, it’s re-enabled
- Damage warning flag reset
Player Experience
Visual Feedback
Players and observers will see:
- Black smoke trail from damaged aircraft
- Smoke intensity remains constant below threshold
- Smoke stops when aircraft is repaired or health recovers
Warning Message
On first damage below threshold:
Your engine has been damaged! You can't turn on your afterburner!
Example Configurations
High Realism (Strict)
SMOKE_PLANE = True
SMOKE_LIFE = 10
Aircraft smoke with even moderate damage, emphasizing careful flying.
Balanced Gameplay
SMOKE_PLANE = True
SMOKE_LIFE = 5
Default setting - smoke appears when critically damaged.
Critical Damage Only
SMOKE_PLANE = True
SMOKE_LIFE = 2
Only severely damaged aircraft smoke, allowing aggressive combat.
Disabled
Disabling smoke doesn’t affect other damage mechanics - aircraft still take damage normally.
Technical Implementation
Plugin Structure
This is a folder-based plugin:
plugins/smoke_on_damage/
├── __init__.py
└── Plugin.py
Registered Hooks
def register(self, plugin_manager):
self.plugin_manager = plugin_manager
self.plugin_manager.register_hook('on_flight_data', self.on_flight_data)
self.plugin_manager.register_hook('on_weapon_config', self.on_weapon_config)
Hooks used:
on_flight_data - Monitor health and emit smoke
on_weapon_config - Handle repairs and restore afterburner
Smoke Packet Generation
The smoke effect is generated by modifying the flight state packet:
smoke_packet = FSNETCMD_AIRPLANESTATE(data).smoke()
This creates a modified packet that includes smoke emission data.
Integration with Other Features
Anti-Cheat System
The just_repaired flag is critical for the anti-cheat system:
if player.aircraft.prev_life < player.aircraft.life and player.aircraft.prev_life != -1 and not player.aircraft.just_repaired:
# Health hack detection
This prevents false positives when players repair legitimately.
G-Force Limiter
Combines well with the G-Limiter:
- G-limiter causes damage
- Smoke plugin provides visual feedback
- Creates immersive damage progression
Troubleshooting
Smoke not appearing?
- Check
SMOKE_PLANE = True in config.py
- Verify health is actually below
SMOKE_LIFE threshold
- Enable DEBUG logging to see plugin activity
- Ensure plugin is loaded (check startup logs)
Creating Similar Plugins
This plugin demonstrates:
- Folder-based plugin structure
- Multiple hook registration
- State tracking across packets
- Client-specific messaging
- Packet modification and forwarding
Use it as a template for your own complex plugins!