From BF2 Technical Information Wiki
Jump to navigation Jump to search


With the 16/32/64 player map modes from BF2, I was upset to see that BF2 didn't support dynamic scaling of the map size based on the number of players connected. I went ahead and threw something together to fix this issue. It also randomizes the map cycle. The randomization feature is currently hardcoded into the script.

What It Does

It gets its data from the server maplist file as defined in the server config file, defaulting to mods/bf2/settings/maplist.con, on every GameStatus.Playing event thrown, so you can change it on the fly and invalid maps are still handled by the normal maplist parsing that hapens when bf2 loads up. It also sets the next map on this Event so that attempts to get the next map using 'admin.nextLevel' will succeed. The size of the map, however, is decided on GameStatus.EndGame to ensure that the next map's size is set properly as close to the map change as possible.


  • Currently, if there's only one map in the maplist, a loop will start and never, ever stop. If nobody beats me to it, I'll fix it soon. --Dst 14:04, 28 Jul 2005 (MDT)
  • If someone would be so kind as to make my commented instructions more user-friendly, I'd be very grateful. --Dst 14:04, 28 Jul 2005 (MDT) Battlefield 2 automatic map changer/randomizer and maplist parser
 # Place in admin/standard_admin/
 # Add "import dc_automap" and "dc_automap.init()" to the file in that directory.
 # This works from the maps in your default maplist.con file. Please put more than one map in the file.
 # Set this to prevent maps being loaded if it played "n" number of maps ago, including the current map.
 maps_run_tracking = 3
 import host
 import bf2
 import random
 import re
 from bf2 import g_debug
 #init the maps_run list
 maps_run = []
 def init():
     if g_debug: print 'initializing Automatic Map Changer, Randomizer and Parser'
 def onGameStatusChanged(status):
     global next_map
     global maps_run_tracking
       if status == bf2.GameStatus.Playing:
         current_map = bf2.gameLogic.getMapName()
         match_pattern = re.compile(r'maplist.append "?(?P<map>.*?)"? "?gpm_[a-z]{2}"?( "?[0-9]{1,2}"?)?', re.I)
         map_list = []
         map_file = host.rcon_invoke('maplist.configFile')
         lines = 0
         for line in open(map_file.rstrip('\n')):
             match = match_pattern.match(line)
             lines += 1
         if lines < maps_run_tracking: maps_run_tracking = lines - 1
         maps_run.insert(0, current_map)
         if len(maps_run) > maps_run_tracking: maps_run.pop()
         next_map = current_map
         while next_map in maps_run:
             next_map = random.choice(map_list)
         host.rcon_invoke('maplist.append %s gpm_cq' % (next_map))
         host.rcon_invoke('admin.setnextlevel 0')
         if g_debug: print 'Next level set to %s, size will be determined on EndGame' % (next_map)
     if status == bf2.GameStatus.EndGame:
         numplayers = 0
         for p in bf2.playerManager.getPlayers():
               numplayers += 1
         if numplayers >= 40:
             map_size = 64
         if numplayers < 40:
               map_size = 32
         if numplayers < 20:
             map_size = 16
         host.rcon_invoke('maplist.append %s gpm_cq %d' % (next_map, map_size))
           host.rcon_invoke('admin.setnextlevel 0')
         if g_debug: print 'Next level set to %s (%d)' % (next_map, map_size)

Add these lines:

import dc_automap