Skip to content

Instantly share code, notes, and snippets.

@daverave1212
Last active May 26, 2026 21:14
Show Gist options
  • Select an option

  • Save daverave1212/7d33bfcb67292ddb210d235d763341d7 to your computer and use it in GitHub Desktop.

Select an option

Save daverave1212/7d33bfcb67292ddb210d235d763341d7 to your computer and use it in GitHub Desktop.
A Python script for dragging camera in RTS games that don't have that feature (e.g. Age of Empires 2)
'''
What This Is
This is a python script that enables you to drag-move the camera with the middle mouse button.
How To Install (Windows)
1. Install python (https://www.python.org/ and go to Downloads and Download for Windows)
2. Open windows search, search for Command Prompt. Right click it > Run as administrator > Yes
3. Type the following command:
pip install mouse keyboard
How To Run (Windows)
1. Save this script in C:/
2. Open windows search, search for Command Prompt. Right click it > Run as administrator > Yes
3. Type the following commands:
cd C:/
python .\camera_drag.py
You can run the script while the game is running or before.
To end the script, press the End key on your keyboard, or close the Command Prompt.
IMPORTANT: For any game you play, make sure you have ENABLED ARROW KEYS to move the camera, and the MIDDLE MOUSE BUTTON is NOT set to anything else!
In your game's settings, you can also change the arrows scroll speed if the camera drag moves too slowly or too fast for you.
How It Works
It detects your middle mouse clicks and does some simple math to press the arrow keys as long as you drag the camera.
If It Doesn't Work
If this doesn't work, check the Command Prompt for any errors. Copy all the code and paste it to ChatGPT or your favorite AI, and tell him what error you got in the console. It will help you fix it.
'''
import time
import threading
import ctypes
import keyboard
import mouse
# =========================
# SETTINGS
# =========================
SCROLL_SPEED = 10000 # camera units per second (tune this)
DEADZONE = 2
LOOP_SLEEP = 1 / 60 # 60 loops per second
VK_MBUTTON = 0x04
# =========================
running = True
dragging = False
last_pressed = False
start_x = 0
start_y = 0
cam_x = 0.0
cam_y = 0.0
def current_milli_time():
return round(time.time() * 1000)
def is_middle_down():
return ctypes.windll.user32.GetAsyncKeyState(VK_MBUTTON) & 0x8000 != 0
def release_all():
keyboard.release("left")
keyboard.release("right")
keyboard.release("up")
keyboard.release("down")
def press_only(x, y):
# horizontal
if x > DEADZONE:
keyboard.press("left")
keyboard.release("right")
elif x < -DEADZONE:
keyboard.press("right")
keyboard.release("left")
else:
keyboard.release("left")
keyboard.release("right")
# vertical
if y > DEADZONE:
keyboard.press("up")
keyboard.release("down")
elif y < -DEADZONE:
keyboard.press("down")
keyboard.release("up")
else:
keyboard.release("up")
keyboard.release("down")
last_frame_timestamp = current_milli_time()
def loop():
global dragging, last_pressed
global start_x, start_y
global cam_x, cam_y
global last_frame_timestamp
while running:
this_frame_timestamp = current_milli_time()
pressed = is_middle_down()
# --- start drag ---
if pressed and not last_pressed:
dragging = True
start_x, start_y = mouse.get_position()
cam_x = 0
cam_y = 0
# --- end drag ---
if not pressed and last_pressed:
dragging = False
release_all()
last_pressed = pressed
# --- main logic ---
if dragging:
mx, my = mouse.get_position()
# desired offset from start
target_x = mx - start_x
target_y = my - start_y
# remaining distance we still need to "consume"
diff_x = target_x - cam_x
diff_y = target_y - cam_y
# step toward target based on speed
step = SCROLL_SPEED * (this_frame_timestamp - last_frame_timestamp) / 1000
# clamp step so we don't overshoot
if abs(diff_x) < step:
cam_x = target_x
else:
cam_x += step if diff_x > 0 else -step
if abs(diff_y) < step:
cam_y = target_y
else:
cam_y += step if diff_y > 0 else -step
press_only(diff_x, diff_y)
last_frame_timestamp = this_frame_timestamp
time.sleep(LOOP_SLEEP)
thread = threading.Thread(target=loop, daemon=True)
thread.start()
print("Drag-scroll running. You can now enter the game.")
print("Hold MIDDLE MOUSE and drag.")
print("Press END to exit.")
keyboard.wait("end")
running = False
release_all()
print("Stopped cleanly.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment