With the focus now shifting from TFTD back onto X-Com, I've started diving back into writing my own mod (it's still in the early design phase, don't hold your breath yet). So I've been going back over the rulesets to refresh my memory and learn some of the more in-depth stuff, but I still had a lot of questions and uncertainty with the documentation provided at
https://www.ufopaedia.org/index.php?title=OpenXcom. So after pouring over this forum looking for answers, I think I've caught onto most of it, but I'm still needing some clarifications on many things. So I've decided to post my rendition of a typical walkthrough down the mission chain, including along the way a few (of my many) questions, and I'm hoping the community will help answer them, as well as point out any grievous errors or omissions in my process.
So without further ado, let's create a mission:
missionScripts.rul
If firstMonth, LastMonth, conditionals, executionOdds, minDifficulty, researchTriggers, and maxRuns all pass, schedule a mission.
If mission-, race-, or regionWeights are specified, they override any values listed in the regions or alienMission rulesets. In our example, we'll say we're using those defaults.
Region is chosen based on weights given to each in their ruleset.
Mission is chosed based on that region's weighted odds for each appearing there.
Alien race is chosen based on the alienMission's weighted odds of that mission being carried out by each race.
Questions:
Labels: The documentation states that each label should be unique in the command list, which I originally took to mean within each script file. However, based on the arguments over claiming particular number ranges in this thread
https://openxcom.org/forum/index.php/topic,3782.15.html, I now understand that ALL labels have to be unique, including within any mods the player might be running.
startDelay: Mission scripts run at the beginning of the month (12 midnight on the 1st, I presume). Is this value the only thing stopping the mission from beginning immediately? Because I always thought that the mission was scheduled for some date/time during that month, but in either of those cases, I don't really see how startDelay ties in here, because the numbers I'm looking at being used for it are far too small to have any significant impact.
useTable: I read in the docs that missions are scheduled based on a deck pick. That is, it draws a mission from all possible choices, runs it once, and then never runs that same mission again until all other missions have been exhausted. It then puts them all back into the deck and reshuffles them. I'm assuming that this value tells the game whether or not this mission is drawn from that deck, or is an "extra" mission to run in addition to it?
So, we have our assigned mission, race, and region. Now we move on to:
alienMission.rul
Objective tells us what what happens if the mission is a success, whether it's (1) the country the ufo's land in leave the CFN, (2) a new base is constructed, (3) a special mission is created, (4) an X-Com base is searched for and attacked, or (5) a supply mission to an alien base. I'm guessing the 5 is needed to tell the ufo to go specifically to an alien base and not simply pick a random point in the mission zone?
spawnZone: Tells us the random area in which the creation of "something special" happens. 4 is used to determine where to place a base, whether it's a direct base mission or the side-effect of a successful alien infiltration. 3 is used for terror missions, but since there's no "area" within these zones, they happen on the only point available within the zone chosen, the city itself. The docs suggest that this is the only possible zone for terror missions, but what I read in this thread
https://openxcom.org/forum/index.php/topic,3811.msg49888.html#msg49888 tells me that it's really just the only vanilla zone that meets the necessary criteria, and that by creating new set of mission zones comprised of single points, there are more options for terror and other "special" missions to be generated. However, I also read in the docs that OXC only supports 6 sets of missionZones, and since vanilla uses 5 of them, that only leaves 1 for modders to play around with.
raceWeights: Although at this point in our hypothetical mission these weights have already been looked at and a race chosen, one thing to add here. They're listed by month, but only have listings on odd months, so my deductive reasoning tells me that the lower-month is used until a new entry is reached, or in other words, it uses whichever satisfies: this listing <= current month < next listing.
So we have our mission, and we know what we're doing with it. Enter the UFO's:
Waves (included in alienMissions.rul)
Number and type specified of ufo's are created for the first wave. The timer tells us how long until the next wave arrives, but does it start as soon as the ufo arrives? When it leaves? What if it's shot down before then?. In any case, am I correct in assuming that by this point in the mission (and indeed, well before it), success is pretty much automatic for the aliens? A base WILL be built. A country WILL be infiltrated. A terror site WILL be... Well, okay. For terror sites, shooting down the terror ship before it triggers the site will prevent it (assuming there is a terror ship GENERATED. for some special missions, this may not always be the case. More questions on this to follow later). But otherwise, shooting down any, and indeed all, of these ufos does nothing but to earn X-Com score, (potentially) deny the aliens same, and possibly increase the wave timer?
Trajectory: THIS is the reason that missionZone 5 is always UFO entry/egress points, 3 is always terror sites, 4 is always alien bases, etc. Because every trajectory says "Start and end at 5", "Go to (3/4) and do your thing." And just to be certain, since I've seen some inconsistent data from... somewhere, the speed and altitude are adjusted AFTER that waypoint is hit, not on the way TO it, yes? Not really sure why the final waypoint (egress) even needs them, but perhaps it's simply to avoid exceptions and that's the source of all my misunderstanding.
Objective: Why do supply ships need it? Is it just to say "insert the coordinates of an alien base into your trajectory and land there"? But my main issue with this one is this: Warboy says in the thread I mentioned above (
https://openxcom.org/forum/index.php/topic,3811.msg49888.html#msg49888) that this mission site may or may not have an associated ufo fly to it to create the mission. My question is, what makes that distinction? Is it by whether or not I provide a valid UFO for the objective wave, "If ufo: is a real ufo, have it fly there and generate this mission. Otherwise, just generate the mission anyways."?
Alright. We now have UFO's flying all around and doing stuff. Let's shoot one down and go in for a closer look:
globe.rul
First we look and see in what kind of environment this battle takes place. Each texture on the globe has an id which directly corresponds to a name, which will later reference the terrain to use. But before we do that... Here is the reason all cities have a constant -1 in their definition, and all (and only) terror sites generate in urban terrain. That -1 points to this entry in the textures definitions. I'm guessing the value is negative because there are no corresponding textures to display on the geoscape; it is a terrain that is only used for special mission sites that generate within this missionZone (which, again, as no area and thus cannot be landed in unless explicitly defined to). Also, since there is no UFO in terror sites, and consequently no corresponding alienDeployment to reference, we have to specify the deployment(s) we want to use for them, and the... percent chance of each one appearing? Or is that 100 just a weight?
So we know what the battlefield is, let's create it!
terrains.rul
name: This is a direct lookup from the name entry we just examined in globe.rul's texture definitions.
mapBlocks: lists all the blocks we'll use to generate this terrain
mapDataSets: lists all the tile information the aforementioned blocks will use.
Any listed civiliansTypes: will also be generated randomly once we know where we are, but first we need to find out where we are by running any scripts listed.
mapScripts.rul
Soooo many questions here. But they mostly deal with how to use each individual command, and do so effectively, so maybe they'd be more appropriate in another thread in which this script is more the focus, rather than just part of a general overview as in this one. So... Let's keep it simple for now.
We know we're at a UFO crash, so first we addUFO. That goes into ufo.rul, looks up what ufo we're invading, adds its mapBlocks and mapDataSets to our battlefield, then loads in the named UFO map files. This is where my questions start to get a bit more complex. Specifically, is it possible to include a (sub)script to THIS map (in ufo.rul)? I'd love to be able to randomly generate the layout of a UFO, perhaps by breaking it down into smaller chunks and having a bunch of different possible layouts for each one. But this would be even more difficult considering the smallest mapBlock it appears you can use is 10X10, which wouldn't permit me to, say, break a scout down into 4 5X5 quadrants and randomly generate a different section for each. But c'est la vie. Perhaps in the future...
So we have a UFO to head towards, now we need a drop point for ourselves, so we addCraft or addBlock for X-Com units to spawn in. Since this is a downed UFO, we addCraft for our dropship. We take a peek at crafts.rul and find data laid out in exactly the same format as our UFO, so we just drop it in with identical fashion.
Then for pretty much all terrains, we simply just color in the blank spots with fillArea. My issue here is, I'm totally lost on what the listed block indices are actually INDEXING. I thought at first that it was their order of appearance in terrains.rul, but that can't be it because there are gaps in the urban block set, and those gaps are reflected in the indices here in the script. So... does it take it from the number at the end of the block name? Or is that from somewhere deeper in the actual data files? And then there's the question of how it knows that block 20 means to use whatever map is assigned to that base facility in defense missions. [edit: Looking back now, I'd say the facilities are probably added in automatically, and that block 20 is just there to throw dirt in on top of the unused portions of the map.]
So now we have the terrain laid out. Let's fill it with aliens:
alienDeployments.rul
Now first off, I think I went out of order here, but I might have done so anyways even had I noticed, for the sake of clarity. If I'm not mistaken, this actually executes BEFORE any scripts, and possibly even before the terrain is loaded? I say this because I know from this thread (
https://openxcom.org/forum/index.php/topic,3138.msg38176.html#msg38176) that the map size is already known by the time the script runs, and that's determined by alienDeployments. So the aliens are already created, they just don't actually spawn, of course, until after all the aforementioned runs because they don't have any actual spawn points yet. But regardless, moving on...
We start by looking up the UFO we just shot down and using that to determine what the map size is, X, Y, and Z. Then for each alien rank listed, we spawn the minimum number of aliens based on difficulty, plus a random number of additionals based on dQty and/or extraQty, and determine whether they are inside or out of the UFO based on the percentages.
Next we give them gear by looking up the current month in alienItemLevels.rul, and assigning to each one the itemSets for whichever percentile that the RNG saw fit to give them.
But wait, we're not done with fleshing out the aliens just yet:
units.rul
By now, we know the race, rank, and quantities of all the aliens. So now all that's left is to give each one the stats and characteristics of his (or her) respective race/rank combination. Slap on some armor for appearance's sake, and you now have your very own invasion force perfect for conquering earth! Let the battle commence!