A Beginner's Guide To SFC2 Campaign Customization and Running Your Own Server

This document is intended to give people a good introduction/overview to the process of setting up and customizing their own campaigns in StarFleetCommand2 (SFC2) :Empires at War (EAW). It covers both single-player campaigns and D2 servers. I'm sure much of the information also applies verbatim to Orion Pirates (OP), but I'm also sure there are some changes required for OP - hopefully I'll get the chance to add those in the near future.

What you need:

This document is forever under revision and expansion, so FEEDBACK IS IMPORTANT!! If you spot anything that's incorrect (or just plain dumb) please let me know - my email address is dwessels@telus.net. I'm sure I've also overlooked a few things, please point them out! Many thanks!

As with my mission scripting documentation, it's been damn interesting putting this document together. Again I'm sure it's got lots of mistakes, those are my fault! For examples, corrections, and explanations I owe many many many thanks to the people who have been running servers and deciphering settings in the .gf files - some of the ones who spring to mind are Poland, MaxTorps, carrie, SkullnBonez, Rook, Articfires, BBJones, jdmckinney, kosh2000, Mog, all the other indie server admins, and a whole slew of others who have posted problems and solutions. And of course big thanks to Taldren for creating this great game, Khoros and Magnumman for their ongoing heroics, and everyone out there who plays it!

Dave (Nuclear) Wessels


Important: Starfleet Command, Empires at War, and Orion Pirates are copyrights of Interplay Productions, while Star Trek and all related material are copyright of Paramount Pictures. The API code itself is a copyright of Taldren.

I have no objections to people using any of my material as long as it is not for profit (though I'd certainly appreciate due credit) but you must respect the rights of the game developers, owners, and publishers.


Document structure

0. A short introduction to the world of D2 servers
0.1 The pieces of an online campaign
0.2 What happens when you connect to a server?
0.3 What happens when you accept a mission online?
0.4 Players and the AI: what ships are out there?
0.5 What can the server dudes do to customize a campaign?
0.6 What can SQL add to an online campaign?
0.7 What can be done to customize missions for a campaign?
1. Initial setup
1.1 Single player campaigns
1.2 Online servers
2. Selecting missions for a campaign
2.1 Storing the mission scripts
2.2 Editing the campaign mission-control file (.mct)
(which races, which map, which missions, what difficult level, and which era)
3. Selecting the campaign map
3.1 Selecting which base map to use
3.2 Customizing (editing) a map
4. Selecting the ship and fighter lists
4.1 Changes that do NOT require a player download
5. Controlling the cost and availability of ships and supplies
5.1 Determining ship construction rates
5.2 Determining ship prices
5.3 Determining supply and repair costs
5.4 Setting rates of "free" repair and resupply
6. Controlling mission offerings
6.1 Weighting mission factors
6.2 Weighting terrain factors
6.3 Weighting political factors
6.4 Weighting ship/fleet strength factors
6.5 Determining the strength of the opposition
7. Controlling time and time-dependent events
7.1 Determining the starting year/era
7.2 Determining the number of turns per year
7.3 Determining the length of a turn
7.4 Determining how often the economy runs
7.5 Determining how often the campaign is saved
7.6 Determining time delays on movement, drafting, etc
8. Controlling player careers
8.1 Determining the starting ship and prestige
8.2 Matching ranks and prestige levels (and bonuses)
8.3 Controlling a player's glicko calculation
9.0 Controlling hex values and changes
9.1 Setting the initial hex levels
9.2 Setting the impact of missions on hex levels
9.3 Setting the flip points and new values of hexes
9.4 Determining the impact of bases on nearby hexes
10. Determining political tensions
10.1 Determining initial tensions and alliances
10.2 Determining how tensions change during the campaign
11. Controlling AI ships in the campaign
11.1 Determining how frequently AI ships are generated and destroyed
11.2 Determining how frequently AI-only battles are fought
11.3 Directing the movement of AI ships
11.4 Controlling pirate and monster populations
12. Controlling access to a campaign
12.1 Creating invite-only servers
12.2 Preventing the use of unauthorized shiplists and mission scripts
12.3 Limiting the number of players on the server
13. Using custom names
13.1 Custom ship names
13.2 Custom captain names
13.3 Custom race names
13.4 Custom rank names
14. Controlling the news
15.0 The Mysteries of the Metaverse
15.1 Specifying valid mission locations
16.0 Editing the hex database

And into the fray ...

0. A short introduction to the world of D2 servers

This is meant to give a non-technical overview to the different systems involved in an online D2 campaign. Sections 1 through 15 of the document will then give the "how-to" details for achieving the different effects described here.

For those of you who just want to customize your single player campaign 90% of this applies verbatim, the only changes are:

0.1 The pieces of an online campaign

There are three key components involved in an online campaign:

(Note that servers are just computers running appropriate software to provide options to collections of other users - the software needed to use an ordinary PC as a D2 server is provided as part of the D2 server kit described elsewhere.)

How all these components work together is described below.

0.2 What happens when you connect to a server?

  1. When you fire up the game and go to multiplayer/dynaverse/login, your PC establishes a communication connection to the Gamespy server.

    This is done automatically, and works fine as long as your connection is ok, you aren't running a firewall (or have performed any necessary technical voodoo to prevent it from interfering with SFC2), and Gamespy's machine is actually up and running.

  2. The Gamespy server is also in communication with all the different D2 servers that are currently up and running, and acts like a matchmaker - Gamespy passes the server descriptions, player loads etc on to you, and you tell Gamespy which server you wish to connect with.

  3. When you pick a server, Gamespy helps establish a link between you and the server (that lag time while you're waiting to get on the server, impatiently tapping your fingers and hoping you get through).

  4. Once the connection is established, Gamespy bows out, leaving you in communication with the server.
    Before
    ======
    One D2 Server
    	\
    	GamespyServer-----Your PC
    	/
    Another D2 Server
    
    After
    =====
    Player 1's PC
    	\
    	Selected D2 Server-----Your PC
    	/
    Player 2's PC
    

  5. The D2 server keeps track of all the universe details - where all the ships in the galaxy are, what the map looks like, what the state of the economy is, what ships are in the shipyards, and which ships are currently involved in missions

    The first time you connect to the server you are asked to choose a race, and when you do so it creates a character for you (name, starting ship, prestige, etc) and adds all that stuff to the list of things it has to keep track of.

    After that (and every subsequent time you connect to the server) the server takes a few moments to tell your PC everything it needs to know about the current state of the universe. This includes the list of players currently logged on and an up-to-date copy of the map. The delay you experience waiting for the map to appear is part of this process - at first the server has to tell your PC a lot about the universe. Once that's done it only needs to let you know when things change.

    From that point on, as long as you aren't actually in a mission, the D2 server and your machine are constantly keeping each other informed about what's going on:

    • when players log on or off, or go into or come out of missions, the server passes word along to your PC so it can update the player list
    • when players move into or out of the hexes immediately around your ship, the server passes word along so the ship symbol appears/disappears on your map
    • when a hex flips, or its value changes, the server passes word along so your PC can update its map
    • when people type something in chat the server passes word along, etc etc

    The most interesting (and most complicated) set of circumstances comes about when you move from one hex into another, so we'll start a separate step to look at that.

0.3 What happens when you accept a mission online?

When you move from one hex to another, it causes a whole chain of events to occur:

  1. First, your PC sends word to the D2 server that you want to move from your current hex to a target hex.

    You then sit around and wait until the D2 server acknowledges that yes, it knows your moving and your move is ok.

    You get delays here for two reasons, (i) the server admin can specify how much to deliberately slow people down when moving, (ii) if the server is busy it can take a few seconds before it gets around to acknowledging you

  2. When you move from one hex to another the server has to decide what kind of an impact that has on mission offerings, so (as far as I can tell) the following things take place:

    • The server looks at the hex you've moved into and looks at every type of mission on the server, and decides which mission(s) to offer you (if any).

      To do this, the factors it considers are:

      • the type of terrain (asteroids, shipping lane, etc)
      • the presence or absence of planets and bases
      • who owns the hex
      • which other ships are in draft radius, and the size and race of each of those ships

      The server compares those factors to the set of recommendations the mission script contains, and decides which missions you should be offered.

    • The server displays a set of available missions to you, and you may or may not choose one of them. (Or, you may get drafted by someone before you get the chance.)

    • When you select a mission, the server has to go through another sequence of steps:
      • Pick what kind of map you'll be using,
      • Pick which nearby ships to draft from the dynaverse,
      • Inform all the players that they've been drafted, and give them time to accept or forfeit
      • Generate AI ships to fill in for teams that weren't drafted

      • GET ALL THE INVOLVED PLAYERS' PCS TO HOOK UP WITH EACH OTHER TO RUN THE MISSION

        This is important, in that at this point the D2 server steps out of the loop for awhile.

        The player who did the drafting starts off as the mission "host" - it is that player's PC that directs the running of the mission and keeps the other players' PCs informed about what's going on.

        Communication problems between the players' PCs cause the infamous lag and drop problems.

        If communication between the host and another player is broken, you get the "host left" message, and one of the remaining players' PCs takes on the duties of hosting the mission.

        Once the mission completes, everyone hooks back up with the D2 server, and the host PC informs the server what the results were.

        This is what explains many of the weird things that happen when players drop. If the communication link between two players is broken, then both may see it as if the other player dropped, both players' PCs start acting as host, and both communicate results to the D2 server. Since both players may have finished their missions against AI opponents, their reported results may be very different.

        This is also the reason that you can complete a mission long after the server has actually gone down - you don't find out the server is down until the mission is over and your PC tries to re-establish its connection to tell the server what the results were.

      I may insert more piccies here, 
      showing the separation of the D2 server from the players 
         while the mission is taking place.
      

0.4 Players and the AI: what ships are out there?

Ships in the dynaverse come in three flavours:

  1. Ships that belong to players, and as such are a permanent part of the dynaverse (well, permanent until they're destroyed or traded in)

  2. Ships that are controlled by the AI but are a permanent part of the dynaverse - the number of these, the way they move through the dynaverse, and the way they take on missions in the dynaverse are all controlled or influenced through configuration files maintained by the administrators of the D2 server.

  3. Ships that are generated and eliminated on a mission-by-mission basis. Each mission has certain roles, or teams, that must be filled (e.g. the freighters in a convoy mission). If the needed ships are not drafted from the dynaverse (which they often are not) then they are created out of thin air at the start of the mission and evaporate again at the end of the mission.

    These ships are the cause of a lot of the "unreality" in the dynaverse, in that there is an infinite supply of such ships for every empire - they are created and destroyed at will to flesh out the mission requirements.

0.5 What can the server dudes do to customize a campaign?

The primary technical control that a server administrator has over the dynaverse is through editing a set of configuration files, essentially setting the options for the campaign.

These configuration files are plain text files (you can edit them with thing like Notepad) with the extensions .gf or .mct

The specifics of editing these files forms the bulk of this document, but here's a quick sketch of the possibilities they present:

The other big technical control the admin has is on the map itself - the server kit includes a tool for editing the hex maps, establishing which races start with with hexes, where the planets are, what the economic and defensive values are, etc etc.

The tool is useful, but is rather cumbersome for large maps - kudos to those who take the time to customize large detailed maps for us!

0.6 What can SQL add to an online campaign?

SQL is software designed to allow someone to manipulate large or complex data sets, such as the mass of data that represents the current state of the universe in a D2 server.

At a basic level, the only thing a server administrator can do to customize a campaign is change the settings in the configuration files. This does not allow for very much customization of the campaign once it's in motion.

To date, the only way for server administrators to "alter the state of the universe" (e.g. fix peoples accounts) is to figure out where the appropriate data exists in the data files and manually (well, using a tool) edit them. This is a difficult and time consuming task.

SQL would give the admins the abilities to manipulate the database (the state of the universe) by issuing SQL queries --- this is a much more flexible and admin-friendly way of doing things.

The specifics of what SQL can do for the D2 servers is, I'm afraid, something I'm not qualified to answer (I ain't a DB guy). Articfires is the go-to guy on this matter, and he'll keep us informed as he discovers (and creates) more and more opportunities.

0.7 What can be done to customize missions for a campaign?

In creating new missions, the scripter in some ways almost unlimited freedom to make anything they want happen during the mission.

Unfortunately, there are some very important limitations on what can currently be done.

In the interests of not stifling suggestions from people, perhaps what I'll do here is provide a list of what's "almost impossible", and let people come up with suggestions on other things they'd like tried.

The "nearly impossible to script" list:

Note: I'm having a mental block at the moment,
      there are many other things "we just canna do Cap'n"
      but I'll have to add them as they occur to me ;-)

1. Initial setup

We'll split this in two parts: 1.1 covers setup if you want to customize a single-player campaign, while 1.2 covers all the basic setup to get an online server up and running.

First things first:

1.1 Single player campaigns

For single-player campaigns installing the game takes care of most of the setup for you.

If you want to create a new campaign, without wiping out any of the existing campaigns, go through the following steps:

  1. Go to folder Starfleet Command II\Assets\Scripts\Campaigns, and copy one of the existing .mct files into a file for your new campaign, e.g. copy ISC-Lyran.mct into MyNewCampaign.mct
  2. Now open the file (Notepad will do fine) and change the Name and Description fields to describe the campaign. E.g.
    Name="My new campaign"
    Description="A test campaign"
    
    These fields are the names and descriptions that will come up in the single-player campaign selection screen.

As far as the rest of the customization goes, there are a handful of folders containing the relevant files, each of which is discussed in detail in later sections.

1.2 Online servers

You do NOT need to have SFC2 installed on the machine you will use as a server, but you do need to download and install (unzip) the server kit.

Once you have done so, open an MS-DOS window (i.e. select Start | Programs | MS-DOS Prompt and type serverplatform.exe -install

When you do so, it will attempt to detemine the IP address for the server, and display it to you. It also tells you that if the address is incorrect then you need to set the correct address by creating a CentralSwitchAddress=xxx.xxx.xxx.xxx entry in the file SFC2Server\Assets\ServerProfiles\MyCampaign\ServersSetup.gf (replacing the xxx's with the correct IP address).

After that, to start your server up and running all you need to do is type serverplatform then select option 1 (or whichever campaign you specify) and hit enter.

To shut a server down later, just hit ENTER then select option 1.

To restart the same campaign, just fire up serverplatform.exe again and select 1.

To wipe out a campaign you need to remove the saved campaign history (i.e. the files in folder SFC2Server\Assets\db).

If you want to create a new campaign, without wiping out any of the existing campaigns, go through the following steps:

  1. Go to folder SFC2Server\Assets\Scripts\Campaigns, and copy one of the existing .mct files into a file for your new campaign, e.g. copy MyCampaign.mct into MyNewCampaign.mct
  2. Now open the file (Notepad will do fine) and change the Name and Description fields to describe the campaign. E.g.
    Name="My new campaign"
    Description="A test campaign"
    
    These fields are the names and descriptions that will come up in the metaverse server-selection screen that players see when they log on.
  3. Go to the file SFC2Server\Assets\ServerProfiles\MyCampaign\ServersSetup.gf and insert the appropriate campaign file name (the one you just created) in the CampaignFile field, e.g. CampaignFile = "MyNewCampaign.mct"

As far as the rest of the customization goes, there are a handful of folders containing the relevant files, each of which is discussed in detail in later sections. If you apply any of the customizations listed below you will need to wipe out and restart the campaign to get them to take effect, so generally speaking you want to get the settings right and test them out a bit before you officially start a campaign.

2. Selecting missions for a campaign

In this section we'll focus on creating the total list of possible missions, then in section 6 we'll show how to control which missions appear where/when.

2.1 Storing the mission scripts

For each mission we want available, we need a copy of the mission script (a .scr file) in the Scripts folder. The stock missions (from Taldren) should already be there, any additional (custom) missions you create or download must be copied into that folder.

For single-player campaigns, this is folder Starfleet Command II\Assets\Scripts.

For online servers, this is folder SFC2Server\Assets\Scripts.
Also, for online servers, every player who uses your server must have a current copy of the script for each mission which can occur in the campaign. I.e. for custom scripts they must download a copy of the script from the same place you did, and they must place it in their Starfleet Command II\Assets\Scripts folder.

The creation of mission scripts is wayyyy beyond the scope of this document, check out my mission scripting guide if you're interested in that area.

2.2 Editing the campaign mission-control file (.mct)

Now we can control specifically which missions are available in a campaign. For instance, the monster missions bug me, so I usually remove them from my own campaigns.

Open the .mct file you created for the current campaign (from step 1.1 or 1.2), and you'll fields which allow you to do the following

Then you'll see a long list of numbers and file names - these identify all the missions which can appear in the current campaign. If you want to add new missions you need to add them to this list, and if you want to get rid of missions you need to delete them from this list.

You should also make sure you go through and renumber the revised mission list appropriately (zero to whatever).

Finally, you'll see a list of numbers under a [Races] heading at the bottom. This controls which races can be played by humans in the campaign, and what order those races are offered in the startup list. (The first number is the position, the second is the race.) Add the following lines (or delete the undesired lines) for the following possibilities:

// version 1, the default order        
0=0 // means the Federation is playable
1=1 // means the Klingons are playable
2=2 // means the Romulans are playable
3=3 // means the Lyrans are playable
4=4 // means the Hydrans are playable
5=5 // means the Gorn are playable
6=6 // means the ISC are playable
7=7 // means the Mirak are playable

// version 2, an ordering putting the lesser-played
//    races earlier in the list
0=3 // Lyrans offered first
1=5 // Gorn offered second
2=4 // Hydrans offered third
3=6 // ISC offered fourth
4=2 // Romulans offered fifth
5=7 // Mirak offered sixth
6=1 // Klingon offered seventh
7=0 // Federation offered last
Actually, this may be a useful point to mention how to set the game speed. This is controlled in MissionMatching.gf with the GameSpeed setting:
[Game]
GameSpeed							=7 	//default meta game speed

3. Selecting the campaign map

The campaign map chosen says a lot about your campaign: small maps lead to more PvP, but may lead to short-lived campaigns for some races if accompanied by low hex defensive values.

Conversely, large maps (especially if accompanied by high hex values) can lead to long term campaigns, but with relatively little PvP in the early stages. Large maps are also slower to load and update as the number of players increases, so you want to balance player limits and map size based on the performance of your server.

3.1 Selecting which base map to use

As mentioned in section 2.2, the .mct file controls which map is selected based on the era.

There are a number of stock maps available, you can select whichever one you want, for whichever era you want, by setting the EarlyMapName="xxx.mvm", MidMapName="xxx.mvm", LateMapName="xxx.mvm" fields in the .mct file.

The pre-made maps available to you are:

3.2 Customizing (editing) a map

If you downloaded the server kit, you'll find it contains a tool that allows you to customize the maps. Simply copy the map you want to use as a starting point and give the copy a new name, then fire up Artifex.exe (from folder SFC2Server\Map Editor), select File | Open and browse to the folder containing your new map (set file types to *.mvm) and select the file you want to edit.

Artifex allows you to edit each hex (or select many at once). Click the little hexagon on the toolbar, then select the feature you want to adjust from the drop-down menu, and select the value for the feature from the adjacent menu. Then click on a hex, and the value will be set.

The features you can set for each hex are:

Artifex only comes with the server kit, so even if you only plan on customizing your single-player campaign I'd advise downloading the server kit just to get Artifex.

4. Selecting the ship and fighter lists

The ship list and fighter list totally define the available ships in the game - all the weaponry, power, hull, etc etc etc for each.

Modifying these files allows you to completely change the nature of the ships and the game, but everyone playing a mission together must have similar files. You can make any changes to the files you like, as long as everyone downloads the modified versions and stores them in the folders listed below. If you don't want to require custom downloads, there are more limited changes you can make, listed in section 4.1 below.

To play the game, copies of these files must be located in two folders Starfleet Command II\Assets\specs and Starfleet Command II\MetaAssetsin files shiplist.txt and ftrlist.txt.

For an online server, the server must also have the files in folders SFC2Server\Assets\Spec and SFC2Server\Assets\ValidatedClientFiles.

These are both tab-delimited plain text files, best edited using either Excel or Ship Edit.

4.1 Changes that do NOT require a custom download

If you don't want to force your players to download a custom shiplist, there are still quite a number of changes you can make.

Make these changes to the files in the Spec server folder, not the ValidatedClientFiles one.

The changes mostly control the availability, price, and default options for ships and fighters.

Here are columns you can safely edit in the shiplist.txt file:

Similarly, in the ftrlist.txt file, you can change the years in which a fighter is available, and the BPV of the fighter (First Year Avail, Last Year Avail, BPV).

5. Controlling the cost and availability of ships and supplies

Price is one of the big factors everyone has an opinion on, and one of the first things many players adjust when they customize their own campaign.

It is also, of course, one of the things players complain about most vocally for online servers...

5.1 Determining ship construction rates

We can, to a degree, control which kinds of ships appear and how frequently during the course of a campaign.

This is done by going to the economy.gf file and setting a probability level for each size of ship. Each time the economy is run (discussed later) this specifies the chance a ship is built.

First, there is a table of build rates which indicate the basic chance a ship can be built when the economy is run. The scale goes from 0 up, and the larger the number the less likely a ship will be built.

Freighter = 0.10
Frigate = 0.02
Destroyer = 0.08
LightCruiser = 0.01
WarDestroyer = 0.1
HeavyCruiser = 0.15
NewHeavyCruiser = 0.15
HeavyBattlecruiser = 0.15
Carrier = 0.45
Dreadnought = 1.5
Battleship = 2.0
BaseStation = 0.90
BattleStation = 0.90
StarBase = 2.0
When it is time to try and produce a new round of ships, the computer goes through this list from small ships up and determines how many of each kind of ship it will build.

As it does so, it subtracts the cost of the ship from that race's available economy, and when the race runs out of money obviously no more ships are built - thus even though there is a chance at building bigger ships your race might spend all its money on smaller ones before it gets there.

There are further catches: ships classed as special or restricted in the shiplist.txt file have their own sets of restrictions. I believe (still have to get confirmation) that "specials" will never be built (not for players or AI) whereas restricted ships will not be available in shipyards but may still be encountered as AI opposition.

There are two "economic threshold" settings, that determine which of the different races are allowed to build bases and/or big ships.

// How healthy an empire has to be to try to build a base
BuildBaseEconomicThreshold = 0

// How healthy an empire has to be to try to build a big ship
BuildBigShipEconomicThreshold = 0
Here's the way these settings work:

We can control how frequently (in turns) all the races check to see if they can build a base and/or big ship, these are determined by the following settings:

// How often bases try to get built (in turns)
BuildBaseFrequency = 10

// how often the computer tries to big big ships DN, BB, CV
BuildBigShipFrequency = 10
Thus each race can check every 10 turns to see if it can build a base or big ship (using the probability values we established at the very beginning of this section).

We can determine how long (in turns) a newly-constructed ship remains available for purchase through the MaximumAge setting.

Once a player makes a bid on a ship, we can also control how long they have to wait before getting it. This is set using the TurnsUntilClose setting

5.2 Determining ship prices

Of course, one of the big campaign factors is how much everything should cost (in terms of prestige points).

For ships, this is set in three parts (also in economy.gf):

  • We can also determine how much of the ship price you get back when you go to sell it, using the Tradein field (under [Cost/Ship/SupplyDock])

    5.3 Determining supply and repair costs

    Similarly, we can determine how much supply items cost, e.g.:

    // This is the cost of supplies in spacedock.
    // note that MinimumBidFactor is similar to TradeIn
    [Cost/Ship/SupplyDock]
    Repair	= 3.0 // base multiplier for how much repairs cost when done in spacedock
    TradeIn	= 3.0 // how much of your purchase price you get back 
                      // when you trade the used ship in
    Missiles	= 9.0 // multiplier for drone cost
    Fighters	= 6.0
    Shuttles	= 12.0
    Marines	= 15.0
    Mines		= 18.0
    SpareParts	= 30.0
    

    5.4 Setting rates of "free" repair and resupply

    Between missions, a certain amount of repair and resupply can be allocated to players for free. These values are set in Score.gf, using the following fields:

    [Base]
    PostBattleMinimumRepair		=1
    PostBattleRepairRatio		=0.25 // Maximum percentage of remaining damage to repair on a base after a battle - PostBattleMinimumRepair
    PostBattleMinimumResupply	=1
    PostBattleResupplyRatio		=0.60	// Maximum percentage of missing stores to resupply a base after a battle - PostBattleMinimumResupply
    

    6. Controlling mission offerings

    Earlier, we discussed how to include all the necessary .scr files, and edit the .mct file to determine which missions are available in a campaign.

    Now, we will determine the conditions under which missions are offered during the campaign.

    The way this works is as follows:

    • The mission developer includes in each mission a number of settings indicating the conditions under which the mission should be offered
    • In the MissionMatching.gf file we set values which essentially specify how much value we will place on those recommendations, or how much we'll ignore them and just offer the mission regardless of the scripter's recommendations.
    • When a player moves into a new hex during the campaign, the game engine looks at all the missions in the .mct file, and looks at the current conditions around the player's new hex. It then looks at the mission script recommendations, and the mission-matching weightings, and decides which missions it would be appropriate to offer.

    The recommendations and weightings are divided into a number of areas, including terrain conditions, ships in the area, political considerations, etc. We will consider the weights for each of those separately in the sections below.

    The maximum number of missions which can be offered is set using the Move field in MissionMatching.gf

    
    [MissionProfiles]
    //...
    Move			=2 // used to be 2, appears to be the max #missions offered
    
    If the player accepts a mission, the draft radius for eligible players is also set in MissionMatching.gf:
    [Environment]
    RadiusForMatching		=0		// range in hexes for a battle to take place (0=current hex, 1=current hex + 6 surrounding, etc.)
       
    If a player forfeits a mission, the penalties are set in MissionMatching.gf:
    [ForfeitModifiers]
    ForfeitModifyVictoryLevel		=4    // modifier to loss level
    ForfeitModifyRegularPrestige		=-100 //prestige lost if forfeit
        

    6.1 Weighting mission factors

    First, we can specify how much weight, in general, we will attach to each different kind of recommendation. These weights range from 0 (ignore) to 1 (treat as important), e.g.:

    // weights of categories
    [ScoringWeights]
    WeightMissionsLastPlayed			=0.2
    WeightPoliticsScore				=1.0
    WeightTerrainScore				=1.0
    WeightFleetScore					=1.0
    
    Second, we can specify how far away the required conditions can be:
    RadiusForMatching = 0 // the conditions must be in this hex
    
    If we had set the value to 1 then the mission could be offered as long as it was adjacent to (within 1 hex of) a hex with the right conditions.

    6.2 Weighting terrain factors

    Then, for the terrain conditions, we can weight different factors:

    //weight to missions matching based on terrain
    [TerrainScoring]
    PlanetTypeScoreForMatching			=6000  
    BaseTypeScoreForMatching			=4000
    TerrainTypeScoreForMatching			=2000
    
    A mission is more likely to be offered if the type of planet/base/terrain in the hex exactly matches what the mission requests.

    6.3 Weighting political factors

    The mission scripter specifies what kind of territory a mission should be run in, e.g. the player race's territory, enemy territory, allied territory, or neutral territory.

    We can then give higher priority to a mission in hexes more closely matching those specifications, e.g.

    //weight to missions matching based on political tensions
    //   NOTE THE MINUS SIGNS IN THE -10000's!
    [PoliticsScoring]
    BonusForExactPoliticalMatch			=2000
    LookingForOwnHexInOwn				=2000
    LookingForOwnHexInAlly				=-10000
    LookingForOwnHexInNeutral			=-10000
    LookingForOwnHexInEnemy				=-10000
    LookingForEnemyHexInOwn				=-10000
    LookingForEnemyHexInAlly			=-10000
    LookingForEnemyHexInNeutral			=-10000
    LookingForEnemyHexInEnemy			=2000
    LookingForAllyHexInOwn				=-10000
    LookingForAllyHexInAlly				=2000
    LookingForAllyHexInNeutral			=-10000
    LookingForAllyHexInEnemy			=-10000
    
    [RelationshipScoring]
    MaxRelationShipScore				=1000
    PoorEnemyOfScore					=0
    PoorAllyOfScore					=0
    DecentWorstEnemyScore				=100
    DecentAllyOfScore					=100
    

    6.4 Weighting ship/fleet strength factors

    Similarly, we can check how closely the size and strength of the available ships matches up to the script's specifications:

    //weight to missions matching based on ships available
    [FleetScoring]
    GoodBPVScore					=1000
    TooWeakBPVScore					=0
    TooStrongBPV					=0
    GoodShipCountScore				=1000
    TooFewShipCountScore				=0
    TooManyShipCountScore				=0
    PlaceBaseMissionScore				=50000
    BaseScoreBonus					=10000
    

    6.5 Determining the strength of the opposition

    We can also adjust the strength of the opposition that will be drafted, based on the current difficulty setting for the campaign:

    //modifier based difficulty setting
    [Diff]
    CaptainDiff							=0.85
    CommodoreDiff						=1.0
    AdmiralDiff							=1.15
    
    The Metamap.gf file also contains some settings which control the strength of the opposition:
    StandardAIBPV						=100 //Default AI BPV
    MaxAIEcoBonusBPV					=2.0 // Higher number will make bigger AI ships for losing empires
    MinFuzzAIBPV						=0.3 //Minimum random AI bpv level 0.3 = 30% less
    MaxFuzzAIBPV						=3.0 //Maximum random AI bpv level 2.0 = twice base
    ChanceForTwoShips					=0.2 //This is the chance for 2 ships for an AI
    ChanceForThreeShips					=0.05 //This is the chance for 3 ships for an AI
    
    I have, in fact, left out a handful of available variables simply because (so far) I haven't figured out what they do!

    7. Controlling time and time-dependent events

    The time settings are scattered across a number of .gf files, I'll try to catch them all here.

    Remember that the length of a turn, the number of turns between economy runs, and the number of turns before a player recieves a ship will all influence the frequency with which players can acquire new ships.

    Also remember that the length of a turn, multiplied by the number of turns in a year, will determine how quickly your campaign moves from one year to another (and hence how long before specific ships become available), and from one era to another.

    7.1 Determining the starting year/era

    As discussed earlier, the era is set in the campaign's .mct file. The starting year and the number of years per era are set in the Time.gf file:

    [Clock/StartingDate]
    BaseYear	= 2263
    0			= 0
    1			= 10
    2			= 20
    

    7.2 Determining the number of turns per year

    This is set in the Time.gf file:

    TurnsPerYear			= 144		// (144) (1 day/year)
    

    7.3 Determining the length of a turn

    In the Time.gf file we also determine how long a turn is (in milliseconds).

    Suppose we want each year of the game to take one day of real time, and we have decided on 365 turns per year (i.e. each turn sorta corresponds to one day of game time). The number of milliseconds in a day is 86,400,000 so the length of each turn would need to be 1/365th of that, say about 237000

    MilliSecondsPerTurn		= 237000	// (600000) (10 minutes)
    TimeStopWhenInTactical	= 0			// (0) ALWAYS 0 for Server!
    
    If the "timestop" value is set to 1, then every time a player goes into a mission the time stops ticking. This is ok for single player, but makes no sense for a multiplayer campaign (hence the ALWAYS comment). Some related values are also set in the Metamap.gf file.
    [General]
    // This is how often the map gets updated 1=1 time a turn
    
    TurnFrequency		= 3 //This is set to 1 to cause the player to create a turn break by moving.
    CauseTurnBreakOnMove 	= 0 // This setting must be 0 on server side!
    
    Note that if the CauseTurnBreakOnMove is set to 1, then every time a player moves it ends a turn.

    7.4 Determining how often the economy runs

    This is set in Economy.gf

    // This is how often the economy gets run. 10 = 10 turns
    TurnFrequency                           = 5 //(2)
    

    7.5 Determining how often the campaign is saved

    This is determined in the Database.gf file:

    AutoSaveFrequency = 10	//(1) How many turns will pass before auto-saving
    

    7.6 Determining time delays on movement, drafting, etc

    The two countdowns during drafting for online servers are set in MissionMatching.gf:

    // Time to wait for missions selection in milliseconds
    [SetupProtocol]
    ResponseWait						=120000 // 2 minutes
    ReadyWait							=60000  // 1 minute
    
    The time delay for moving between hexes (on servers) is set in MetaMap.gf:
    MovementDelayInMilliseconds=15000		// This is how long it take to move 1 space on the map in milliseconds
    

    8. Controlling player careers

    In this section we focus on getting the player a starting ship, some starting prestige (spending money), and an initial rank. We also determine how much prestige they need over the course of time to increase in rank, and any bonuses that come along with that.

    8.1 Determining the starting ship and prestige

    The starting prestige is controlled in the Character.gf file

    //This is a character's starting prestige
    StartingPrestige	= 50
    

    The BPV range for starting ship is fixed for all races in Ship.gf, but then tweaks are added for individual races. The selected ship will be (I think) the lowest BPV ship which exceeds the MinBPV + EmpireDelta.

    [StartingShip/Misc]
    MinBPV				= 65
    MaxBPV				= 75
    EmpireEconomicBonus	= 0
    
    [StartingShip/EmpireDeltas]
    Federation	= 6
    Gorn		= -9
    Hydran		= -4
    ISC			= 1
    Klingon		= 6
    Lyran		= -2
    Mirak		= -3
    Romulan		= 5
    Orion		= 0
    Monster		= 0
    
    This file also controls the range of valid ship sizes, and the ship replacement process (and penalty) if a player ship is destroyed:
    [AssignShips]
    PrestigeModiferOnShipGrant	= -100
    EmpireStrengthBonusOrdinal	= 0.85
    MinimumClassTypeSize		= 3
    MaximumClassTypeSize		= 11
    DeathShipBPVPenalty			= .75
    NumberOfShipsReplaced		= 1
    

    8.2 Matching ranks and prestige levels (and bonuses)

    The prestige required for promotion from one rank to another, and the prestige bonus the player receives upon promotion, are set in the Score.gf file:

    [Rank]
    //Total lifetime prestige needed to gain rank
    Ensign					=0
    Lieutenant				=500
    LieutenantCommander		=2000
    Captain					=6000
    Commodore               =12000
    RearAdmiral             =16000
    Admiral                 =25000
    FleetAdmiral            =36000
    
    [RankBonusPrestige]
    //This is the bonus prestige gets when they reach a new level
    
    Ensign				=0
    Lieutenant				=100
    LieutenantCommander		=150
    Captain				=250
    Commodore				=400
    RearAdmiral				=700
    Admiral				=1500
    FleetAdmiral			=3000
    

    8.3 Controlling a player's glicko calculation

    For online players, their "glicko" rating is recorded - comparing their cumulative success in battle to the strength of the opposition they have faced. Basically this rating goes up as you win missions, and down as you lose them. The amount it increases or decreases after each battle depends on how convincingly you win, and how much stronger or weaker your opponent was.

    The settings controlling this are located in the Score.gf file:

    [Rating]
    FermiTemp				=1.0
    StartingHumanRating		=1500
    StartingAIRating			=1200
    StartingAIRatingRange		=500
    MaximumGain				=32
    

    9.0 Controlling hex values and changes

    Aside from terrain, planets, and bases, each hex in the dynaverse has X,Y coordinates, a current racial alliance (neutral or a specific race) an economic strength, a current defensive strength, and a maxmimum defensive strength. The maximum defensive strength is the only "hidden" value, and is equal to the defensive strength the hex had at the start of the campaign.

    The defensive strength of a hex can be raised or lowered as a result of combat, and if lowered sufficiently it will first change alliance to "neutral" and then eventually flip in favour of another race.

    The sections below outline how the defensive strength of a hex can be controlled, to a degree, through server settings.

    9.1 Setting the initial hex levels

    The initial hex levels are set in the campaign map, as discussed earlier, but the meanings of the settings can be adjusted (I think) in the HexValues.gf file.

    9.2 Setting the impact of missions on hex levels We can determine how much the hex value changes by on each mission, based on the difficulty of the campaign:
    [VictoryPointModifier]
    Easy=35 // victory changes hex defense value by 35 in Captain mode
    Med=15  // victory changes hex defense value by 15 in Commodore mode
    Hard=5  // victory changes hex defense value by 5 in Admiral mode
    PureAI=0.2 // change due to pure AI battle is negligible
    

    9.3 Setting the flip points and new values of hexes

    We can control the point at which a hex flips, as a fraction of it's original setting. I think this is done using the settings below in the MetaMap.gf file:

    [Battle]
    MinVictoryPointsForPlayerVictory=0.2 // flips at 20% for player wins
    MinVictoryPointsForAIVictory=0.1 // flips at 10% for ai wins
    
    We can certainly control the value the hex flips to:
    HexHealthResetRatio=0.5
    

    9.4 Determining the impact of bases on nearby hexes

    Planting bases raises the defense value of their hex and surrounding hexes, and we can define how strong this effect is, using the Score.gf file:

    [Base/Transition]
    MinimumVictoryPoints		=1	// The minimum number of victory points a hex will have after a base transition
    [StarBase/Transition/VictoryPoints]
    Primary				=20	// 20 points added if the a StarBase is added or 20 points removed if StarBase is removed.  For the hex the StarBase is placed on
    Secondary				=7	// 7 "" "" but for "secondary" hexes.  Like the one right next to the primary hex
    [BattleStation/Transition/VictoryPoints]
    Primary				=14
    Secondary				=4
    [BaseStation/Transition/VictoryPoints]
    Primary				=10
    Secondary				=2
    [ListeningPost/Transition/VictoryPoints]
    Primary				=2
    Secondary				=0
    

    10. Determining political tensions

    In the beginning of the campaign, we set up the tensions (alliances and enemies) between all the different races. We can then also set things up so that combat during the campaign gradually changes these tensions.

    10.1 Determining initial tensions and alliances

    For each and every race, we can set how they feel about each other race. This is done using a number from 0 (best buds) to 1000 (hated enemies), set in MetaMap.h. The example below sets up some values for the Federation:

    [PoliticalTension/StartingTensions/Federation]
    Federation=0
    Klingon=1000
    Romulan=900
    Lyran=800
    Hydran=0
    Gorn=0
    ISC=500
    Mirak=200
    Orion=400
    Monster=200
    
    Notes: there seem to be "issues" if each race doesn't have at least one favoured ally and at least one distinct enemy, but experiment away!

    10.2 Determining how tensions change during the campaign

    The settings above determine the starting tensions and alliances for the campaign, but we can also have those gradually change over time - depending on who fights who, how often, etc.

    The settings to do this are also in MetaMap.gf:

    [PoliticalTensionInc]
    // This is the numbered added every time a battle is fought
    // Some races like the Federation are slower to anger
    Federation=5
    Klingon=20
    Romulan=10
    Lyran=15
    Hydran=10
    Gorn=15
    ISC=25
    Mirak=20
    
    //This is the number subtracted when political tension is asked to be decreased.
    //The federation is more likley to forgive than other races
    [PoliticalTensionDec]
    Federation=75
    Klingon=15
    Romulan=30
    Lyran=30
    Hydran=45
    Gorn=30
    ISC=10
    Mirak=20
    

    11. Controlling AI ships in the campaign

    Of course, one of the big bugaboos of the dynaverse is the number of AI ships floating around, and what they're doing out there. We can, to a degree, control the number of ships generated (initially and later on) and direct (to a degree) where on the map they migrate.

    11.1 Determining how frequently AI ships are generated and destroyed

    In MetaMap.gf, we can control the generation of AI ships. Most campaigns want smaller databases (for greater stability) and fewer dynaverse generated AI (as opposed to the AI which are generated on the fly for compatibility with a specific mission). To do so, reduce all the settings in the segment below, from MetaMap.gf:

    AttemptsToCreateAIInHomeHex			=10 // Maximum AI to create in 1 turn
    MaxAIsToCreatePerTurn				=3 //How many AIs to try to create before giving up
    CreateAIFrequency					=2 // How many AIs to create a second, untill goal level reached
    InitalAILevel						=400 // How many AI's to create before game starts
    MaxAIsPerEmpire						= -1 // ( -1 ) Create a fixed number of AIs per empire. -1 means not to use a fixed number.
    
    If you set MaxAIsperEmpire to some value greater than 0, then once those AI ships are destroyed no more dynaverse AI ships are created - just the usual collection of temporary mission-generated ships.

    If you want to adjust the strength of the opposition faced, see section 6.5.

    11.2 Determining how frequently AI-only battles are fought

    Also in MetaMap.gf, we can control the rate of AI-only battles:

    // try setting MaxAIsToKillPerTurn, and MaxBattlesPerTurn to 0 to reduce player-independent map activity
    MaxAIsToKillPerTurn					=0 // (10) Maximum AIs to be killed in 1 turn before ending phase
    AITurnOverRate						=0 // (1)
    MaxBattlesPerTurn					=10 //Maximum number AI battles in a turn before ending phase
    KillAIFrequency						=2 // How many AIs to kill a second, untill goal level reached
    

    11.3 Directing the movement of AI ships

    Yet again in MetaMap.gf we can direct the movement of AI ships around the map, in effect pulling them towards hexes that have specific properties:

    [AIMovement]
    
    NumTriesToGetACandidate				=5 //Number of tries to find a target hex to move to
    NumCandidateHexes					=7 //Number of hexes to choose from
    FriendlyEmpireScore					=100 // (?) weight movement toward Friendly hexes
    GoodEconomyScore					=75 // (?) weight movment towards high point value hexes
    EnemyDefenseScore					=10.0 // (?) weight movement towards strong hexes?
    WeakHexScore						=100 // (?) Weight movement towards weak hexes
    HighRelativeTensionScore			=75 // weight movement towards hostile territory?
    SupplyLineBonus						=10 //Extra points for every hex that the race owns that touches the dest hex
    
    // use this to turn on/off the following behaviors 1=on 0=off
    AttractionToEconomy=1
    AttractionToOwnEmpire=1
    AttractionToWeakHexes=1
    FearEnemyHexesByStrength=1
    AttractionToEnemyHexesByTension=1
    AttractionToSupplyLines=1
    

    11.4 Controlling pirate and monster populations
    We can control the population of Orions and Monsters in the dynaverse with two settings in the MetaMap.gf file:
    OrionPopulationRatio				=0.1 // (0.1) This is the population ratio for orion pirates.
    MonsterPopulationRatio				=0.025 // (0.025) This is the poplation ratio of Monsters.
    
    Unfortunately, the monster and pirate missions are often still determined to be valid for the terrain, and so temporary monster and pirate missions get generated with "fabricated" monster/pirate enemies, which disappear again once the mission ends.

    If you truly want to get monsters out of a campaign, the only real way to do it is to remove the monster mission from your campaign's .mct file (see section 2.2).

    12. Controlling access to a campaign

    For online servers, there is a folder called SFC2Server\Assets\ValidatedClientFiles.

    Every player who wants to connect to the server MUST have the exact same versions of each file listed in this folder.

    The error message displayed if someone fails this check is set in Assets.gf (you may want to alter it to tell people where to get valid copies, etc)

    SecurityCheckFailureMessage	="This server has detected that one or more of the necessary files required to connect is either missing or incompatible.  List of offending files: "
    

    12.1 Creating invite-only servers

    The easiest way to do this is just to create some small simple text file (e.g. containing the server rules) and placing a copy in the validation folder.

    Then every player you want to invite must download a copy of this file and place it in their Scripts folder (along with all the mission scripts).

    Anyone without the file will automatically be denied access to the server.

    12.2 Preventing the use of unauthorized shiplists and mission scripts

    You should put copies of the shiplist.txt, ftrlist.txt, and all the campaign .scr files in your validation folder. This will ensure that everyone playing on your server is using copies of the same file - not modified versions!

    12.3 Limiting the number of players on the server

    This is done in the Character.gf file:

    // maximum number of human characters in the campaign
    PlayersMax			= 3000
    
    // maximum number of players logged on simultaneously
    PlayersLoggedOnMax	= 64
    
    // number of days between log-ons before a player's character is deleted from the campaign
    PlayerMaximumInactivity	= 30
    

    13. Using custom names

    If you're bored and imaginative, you can set up custom names for ships, races, player ranks, and AI captains.

    13.1 Custom ship names

    The default ship names are listed in ShipNames.gf, e.g.:

    [Federation]
    0="USS Antares"
    1="USS Vega"
    2="USS Pollux"
    3="USS Delta"
    4="USS Antares"
    5="USS Eminiar"
    ... etc
    

    13.2 Custom captain names

    The default captain names for each race are set in Character.gf, e.g.

    //These are the names of Federation AI's
    [Create/Federation]
    
    0="Kirk"
    1="Sulu"
    2="Morris"
    3="Bethke"
    ...  etc 
    

    13.3 Custom race names

    The full empire names are set in MetaMap.gf, and can be adjusted if desired:

    [FullEmpireNames]
    Federation="United Federation of Planets"
    Klingon="Klingon Empire" 
    Romulan="Romulan Star Empire" 
    Lyran="Lyran Star Empire" 
    Hydran="Hydran Kingdom" 
    Gorn="Gorn Confederacy" 
    ISC="Interstellar Concordium"
    Mirak="Mirak Star League"
    Orion="Orion Pirate Cartels"
    NeutralRace="Contested Sector"
      

    13.4 Custom rank names

    In the Score.gf file we can control the rank names which appear in the news. I'm not sure if they appear anywhere but the news, so I'm tempted to change things like "Fleet Admiral" to "Total Nutter", just so the news articles reflect the campaign a little better ;-)

    [RankNames]
    //Rank names
    Ensign				="Ensign"
    Lieutenant				="Lieutenant"
    LieutenantCommander		="LieutenantCommander"
    Captain				="Captain"
    Commodore				="Commodore"
    RearAdmiral				="RearAdmiral"
    Admiral				="Admiral"
    FleetAdmiral			="FleetAdmiral"
    

    14. Controlling the news

    In MetaMap.gf we can control how frequently news is generated, including the economic reports summarizing empire status:

    [RandomNews]
    Interval=100						// Every "Interval" turns the random generator is run for news (heartbeat of news background is ONCE a SECOND!)
    Chance=10						// 0-100 Chance at this interval that news will be generated
    [EconomicReport]
    Interval=1						// Every "Interval" years the report is produced in the news
    

    The News.gf file allows you to customize the rest of the news, including the removal of old news and a limit on the volume of news.

    [General]
    TurnFrequency					= 1		// Currently controls how often old news gets removed from the database
    MaximumItemsAtOnce				= 20 	// The maximum number of news items to send a client when it connects for the first time per second
    
    It also lets you change the colour schemes for news items, if there are things you really want to highlight or lowlight.

    15.0 The Mysteries of the Metaverse

    Ok, here's the way I understand things working in the Dynaverse. It's highly likely I've got some of that wrong, so please take it all with a grain of salt. Anything here that's actually correct should be credited to clintk, who has done a great job of trying to research this stuff.

    General sequence of events
    1. The D2 engine examines each hex on the map and generates AI ships based on the settings in the server .gf files.
    2. For each hex, the D2 engine determines if missions are required in the hex.
      To do this, it must examine each of the available mission scripts, and determine which ones are appropriate. Within each script, it appears to look at a lot of information and settings:
      • The mission criteria you establish in mScriptSpecs:
        • Valid hex terrain for the script
        • Valid hex ownership for the script
        • Valid races for the (drafting) player team
        • Valid time period for the mission
        • Valid fleet compositions for the mission (BPV, number and size of ships)
      • It also looks at the maps provided in the mission, to determine which are most suitable for the hex and mission.
      In hexes where all the required criteria are met, the appropriate missions are offered to human players. (With the maximum number offered, draft radius etc controlled by settings in our .gf files.)
    3. The player selects whichever mission they want (or forfeits, in which case our .gf-selected forfeit penalty is applied).
    4. The D2 engine drafts other players to fill any appropriate team slots, and (if applicable) creates AI teams to fill some or all of the remaining team slots. (Again, the draft radius is specified in our .gf files.) At this point the appropriate mission map is also selected.
    5. The mission happily chugs away, with mission endpoints and results controlled for each team by the mission script.

    15.1 Specifying valid mission locations Now that I've got both a test server and a collection of custom scripts up and running, I've finally been able to experiment with why the hell missions get offered the way they do.

    Here's the scoop:

    PART I In the mission script, the scripter gets to set restrictions on where/when a mission should be offered, including:

    • valid years
    • valid BPV ranges
    • valid fleet strenghts
    • valid fleet sizes
    • valid racial territory (e.g. own, enemy, neutral, allied)
    • valid terrain (empty space, asteroids, nebula, etc)
    • required bases
    • required planets
    • how far away (in hexes) the specified conditions can exist (e.g offer this mission within 2 hexes of an enemy hex with a black hole in it)

    As a mission scripter I thought that was all worthless or buggy, because the missions would appear in all sorts of invalid places anyway. This brings us to:

    PART II

    The server only treats those rules as advice, not as rules!

    The settings in MissionMatching.gf control how much weight the server attaches to each different "area" of script recommendations.

    Of course, the .gf settings don't break down into exactly the same categories as the scripter provides, but they're pretty close.

    Furthermore, the default settings in that file are utter rubbish - leading to the rules laid down in the mission script being largely bypassed. It looks like they were set up to give a maximum randomness of missions encountered, without real concern as to the implications.

    After a helluva lot of fiddling, here are the relevant MissionMatching.gf settings I changed to try to get missions to appear exactly where their scripts say they should. Mostly this is aimed at trying to discourage missions from popping up where they shouldn't (hence the -20000's whereever something isn't ideal). The three that you might still want to play with are the relative values for planets, bases, and terrain.

    //weight to missions matching based on terrain
    [TerrainScoring]
    PlanetTypeScoreForMatching=10000 // 5000  
    BaseTypeScoreForMatching=5000 // 2500
    TerrainTypeScoreForMatching=2500 // 100
    
    //weight to missions matching based on political tensions
    [PoliticsScoring]
    // NOTE THE NEGATIVE SIGNS IN THE -20000's
    //    It's important!  ;)
    BonusForExactPoliticalMatch=500 
    LookingForOwnHexInOwn=500 
    LookingForOwnHexInAlly=-20000 
    LookingForOwnHexInNeutral=-20000 
    LookingForOwnHexInEnemy=-20000
    LookingForEnemyHexInOwn=-20000
    LookingForEnemyHexInAlly=-20000
    LookingForEnemyHexInNeutral=-20000 
    LookingForEnemyHexInEnemy=500
    LookingForAllyHexInOwn=-20000 
    LookingForAllyHexInAlly=500
    LookingForAllyHexInNeutral=-20000 
    LookingForAllyHexInEnemy=-20000
    
    //weight to missions matching based on ships available
    [FleetScoring]
    GoodBPVScore=500
    TooWeakBPVScore=-20000
    TooStrongBPV=-20000
    GoodShipCountScore=500
    TooFewShipCountScore=-20000
    TooManyShipCountScore=-20000
    PlaceBaseMissionScore=50000
    BaseScoreBonus=10000
    
    // weights of categories
    [ScoringWeights]
    WeightMissionsLastPlayed=0.2
    WeightPoliticsScore=1.0
    WeightTerrainScore=1.0
    WeightFleetScore=1.0 
    
    [RelationshipScoring]
    MaxRelationShipScore=500
    PoorEnemyOfScore=-25000
    PoorAllyOfScore=-25000
    DecentWorstEnemyScore=0 
    DecentAllyOfScore=0
    
    What it all means

    At the very least this means we can now prepare custom missions and get them to appear where they are needed and expected.

    It does, however, mean that if you apply this to a stock server then somewhat fewer missions are offered (since it doesn't give all the "wrong" mission opportunities it used to).

    This may also turn out to have an important side effect, in that I suspect some of our weird-hex-effects come in as a result of poor misson offering (e.g. a script intended to run in a player's own territory instead gets run in their allies territory, and updates the DV incorrectly as a result). That's still pretty speculative however.

    It appears that the relative weighting of planets, bases, terrain, and politics is critical. If bases and planets, or terrain and bases, are too closely weighted then you start getting base or planet missions cropping up in empty space.

    16.0 Editing the hex database

    Once a campaign is begun, most of the information is stored within a huge single database file, found in folder Starfleet Command II\MetaAssets\DB for single player campaigns and in folder SFC2Server\Assets\DB for servers.

    To edit this file you will need a hex editor, such as HexEdit This one is shareware, 30 day free trial, then $15 for single user, single machine, and this download copy is hosted by Evolution (kosh2000 and the gang from The Triangle).

    Theoretically, with enough editing you can change anything and everything about the campaign - just take the server down, alter the database, and bring the server back up. Some of the things you can do include creating, deleting, or altering player accounts, adjusting racial tensions, changing the current state of the map, etc.

    Of course, to do so, you need to know exactly where all the information exists within the database. Fortunately, kosh2000/js (of The Triangle server) has put together a partial layout of the database, available as an Excel download.