F50's Modding tutorial
Part 1: Your first mod.
http://neurohack.com/transcendence/foru ... 29&start=0
This tutorial assumes that you have taken a look at the link above and have decompiled the source xml files. It may also help to have taken a look at the xelarus modsite, linked to below. It contains many mods to play and learn from.
The easiest way to mod is to simply steal someone else's code, and put it into your own xml file. The two main sources to steal from are the decompiled source xml files, and the mods on xelarus.
So, down to modding. To mod you will need a WYSIWYG editor like notepad. A word processor like Microsoft Word will mess up your mod. Create a file and rename it to "FOO.xml" where 'FOO' is a name of your choice. Before we can actually make a ship, we have to make mod declarations. Here is the most basic mod (it doesn't actually *do* anything, just compiles ):
Code: Select all
1. <?xml version="1.0" ?> 2. 3. <!DOCTYPE TranscendenceExtension 4. [ 5. ]> 6. 7. <TranscendenceExtension UNID="0xD1110000" version="0.98d"> 8. 9.</TranscendenceExtension>
The mod actually begins on line 7 with the declaration of the Transcendence Extension itself. Our greatest interest here is: "UNID='0xD1110000". This UNiquely IDentifies your mod. By convention, the first three (hex) digits after the 'D' (currently are 1's) represent the identity of the modder, and the rest represent the identity of the mod and entities within the mod. Before you release a mod to the community (at xelarus), you should post the three digits that you will be using as your identity at the link below. After that is posted, ALWAYS use those same three digits for the UNID of your mod. Remember that since these digits are in hexadecimal, you can use anything from 0-9 and A-F (inclusive).
http://neurohack.com/transcendence/foru ... 59&start=0
This does exactly the same thing:
Code: Select all
1. <?xml version="1.0" ?> 2. 3. <!DOCTYPE TranscendenceExtension 4. [<!ENTITY extUNID "0xD1110000"> 5. ]> 6. 7. <TranscendenceExtension UNID="&extUNID;" version="0.98d"> 8. 9.</TranscendenceExtension>
<!ENTITY FOO "BAR">
where FOO is the name you want to use in place of the UNID and BAR is the UNID itself.
Now that is done, lets go ahead and create a ship. Put the declaration code above into the file you created. Then, look at CharonPirates.xml (its one of the source xml files) and copy the corsair-class Gunship into line 8 of your file.
Now you have lots of code in those lines. I have added comments to the code below to explain what each line does. Comments in xml code are set off by <!-- and are closed by -->
Code: Select all
<?xml version="1.0" ?> <!DOCTYPE TranscendenceExtension [ ]> <TranscendenceExtension UNID="0xD1110000" version="0.98d"> <!--Remember to change the 1's to something meaningful!--> <!-- Corsair-class Gunship --> <!--This tag states the defining features of the ship class. --> <ShipClass UNID="&scCorsair;" manufacturer= "Charon Pirates" class= "Corsair" type= "gunship" score= "25" techOrder= "mech" mass= "45" cargoSpace= "5" thrust= "250" maneuver= "4" maxSpeed= "25" leavesWreck= "20" > <!-- Note that I cannot put comments before the '>' character as that is technically within a tag--> <!-- manufacturer: Useless, to my knowledge class: Dictates the name of the ship type for when you are killed by this kind of ship or when you target a ship pf this type type: Dictates the class of this ship for when you are killed by this kind of ship or when you target a ship pf this type score: The amount of points you get for vanquishing a ship of this type techOrder: Useless, to my knowledge mass: How heavy the ship is. This effects how easy it is to move the ship with weapons fire, how fast the ship goes, and how well the ship maneuvers cargoSpace: How much cargo the ship can hold. Generally only useful for playerships thrust: How fast the ship accelerates maneuver: How well the ship maneuvers. (Note: the lower the better) maxSpeed: How fast the ship can go leavesWreck: The percent chance of this ship leaving a wreak when it is destroyed. Feel free to mess around with these values! --> <Armor> <ArmorSection start="270" span="180" armorID="&itLightTitaniumPlate;" areaSet="0,2,3,7" /> <ArmorSection start="90" span="180" armorID="&itLightTitaniumPlate;" areaSet="1,4" /> </Armor> <!-- The <Armor> tag defines the armor of the ship armorID: The UNID of the type of armor of an armor section, in this case "&itLightTitaniumPLate;". start: the start angle of the armor section in degrees. span: the magnitude, in degrees, of the angle the section of armor covers. --> <Devices> <Device deviceID="&itLaserCannon;"/> </Devices> <!-- The Devices tag describes the devices installed on the ship. Each devices is listed in the form: '<Device deviceID="FOO"/>' where FOO is the unid of the device. More on this tag in part 2 --> <Image imageID="&rsMediumShips1;" imageX="288" imageY="0" imageWidth="48" imageHeight="48" rotationOffset="-10" imageFrameCount="0" imageTicksPerFrame="0"/> <!-- This is various image information that I don't understand--> <AISettings fireRateAdj= "40" fireAccuracy= "75" perception= "4" /> <!--This determines some AI behavior. fireRateAdj: how fast the ship fires in relation to the fireing rate of the weapons installed. fireRateAdj= "10" will cause the AI to fire at the firing rate of the weapon. fireRateAdj= "1" will cause the AI to fire at an insane rate (much greater than that of the weapons it wields). fireAccuracy: How close the AI has to be to hitting to fire. perception: Determines how close you need to be before the ship notices you. I am unsure of the relationship between Transcendence's unit if distance, lightseconds (abbreviated ls), and the perception value. --> <DriveImages> <NozzleImage imageID="&rsDriveExhaust;" imageX="48" imageY="0" imageWidth="48" imageHeight="48" imageFrameCount="0" imageTicksPerFrame="0"/> <NozzlePos x="-30" y="-7"/> <NozzlePos x="-30" y="7"/> </DriveImages> <!--Drive image information that I don't understand--> </ShipClass>
Unfortunately, this code does about as much as the simple 9 lines that we wrote previously. Its time to change that.
Try replacing the <Armor> tag with this:
Code: Select all
<Armor> <ArmorSection start="270" span="180" armorID="&itLightTitaniumPlate;" areaSet="0,2,3,7" nonCritical="general"/> <ArmorSection start="90" span="180" armorID="&itLightTitaniumPlate;" areaSet="1,4" nonCritical="general"/> <ArmorSection start="270" span="180" armorID="&itLightTitaniumPlate;" areaSet="0,2,3,7" nonCritical="general"/> <ArmorSection start="90" span="180" armorID="&itLightTitaniumPlate;" areaSet="1,4" nonCritical="general"/> <ArmorSection start="270" span="180" armorID="&itLightTitaniumPlate;" areaSet="0,2,3,7"/> <ArmorSection start="90" span="180" armorID="&itLightTitaniumPlate;" areaSet="1,4"/> </Armor>
added before the end of each <ArmorSection /> tag. This option allows a segment of armor to be destroyed without destroying the ship. In this case, we used it to make the armor of the corsair about 3 times stronger.nonCritical="general"
This is good, but not much has happened yet. Try messing around with a few more values:
inside the ShipClass tag:
When you are destroyed by this ship, instead of "Corsair-class gunship", it will be called "Corsair-class modship".type= "modship"
Now lets change the weapon it uses. If you go into stdWeapons.xml, you will find a weapon called &itMakayevLauncher; Replace the laser cannon with this weapon.
Code: Select all
<Devices> <Device deviceID="&itMakayevLauncher;"/> </Devices>
Code: Select all
<Items> <Item count="100d100" item="&itStrelkaWhite;"/> </Items>
Go and be pwnd!
After you've had some fun with that, you will realize that the maneuverability of the Corsair modship has suffered. You can fix this by changing the cargoSpace option in the ShipClass tag from
Any other sufficiently large value will work (the value given is probably overkill).cargoSpace= "50000"
Mess around with this until you feel comfortable or bored. Then copy another ship from the source, add it to your mod, and mess around with those values. You'll discover a few new options, feel free to ask on the forums what they do.
Part 2: Modding stations.
Modding stations is pretty much the same as modding ships. Go into CharonPirates.xml and copy the Charon Pirate Cache into your mod.
Here is some code with comments to explain.
Code: Select all
<StationType UNID="&stCharonPirateOutpost;" name= "Charon Pirate Cache" sovereign= "&svPirates;" abandonedScreen= "&dsAbandonedStation;" dockScreen= "&dsAbandonedStation;" dockingPorts= "8" canAttack= "true" armorID= "&itLightTitaniumPlate;" maxHitPoints= "50" hitPoints= "50" fireRateAdj= "80" ejectaType= "&vtWreckEjecta;" attributes= "pirates,enemy,envAir,envEarth,envFire,envWater,populated" levelFrequency= "cuv-- ----- ------ ----- -----" locationCriteria= "-planet,-void" > <!-- name: Dictates the name of the station type for when you are killed by or target this kind of station abandonedScreen: Describes the dockscreen that is shown when the station is destroyed. Usually: "&dsAbandonedStation;" dockScreen: Describes the dockscreen that is shown when the station is alive. If none, then it should be "&dsAbandonedStation;" by convention. dockingPorts: Describes the number of docking ports. canAttack: Generally = "true". I assume that if it is false then the station cannot attack. armorID: Describes the resistances of the station by referring to the UNID of a certain armor type. maxHitPoints: Describes the hit points of the station. hitPoints: Describes the starting hit points of the station. fireRateAdj: how fast the station fires in relation to the firing rate of the weapons installed. " fireRateAdj= "10" " will cause the AI to fire at the firing rate of the weapon. "fireRateAdj= "1" " will cause the AI to fire at an insane rate (much greater than that of the weapons it wields). ejectaType: Describes the effect when you hit the station. attributes: This is important if you wish to distinguish the item from others or wish it to be sold (or not to be sold) in certain stations. See Periculi's post later in the thread. levelFrequency: Describes how often you will see this kind of station. The value is always of the form: "----- ----- ------ ----- -----" where each non-space character represents a level of system (Eridani being a level 1 system and St. K. being the first level 4 system). A dash means that station will not appear at that level, 'c' means very common, 'u' means uncommon, 'r' means rare, and 'v' means very rare. locationCriteria: Describes where in a system a planet can be located. --> <Image imageID="&rsStations1;" imageX="0" imageY="512" imageWidth="156" imageHeight="156"/> <!--Same as with ships--> <Devices> <Device deviceID="&itLaserCannon;" omnidirectional="true"/> </Devices> <!--This tag, as I went over in part 1, describes the devices that this object can use. The only difference here is that stations cannot use any kind of shields. :( However, I left out a very important detail illustrated in the above devices tag. Additional arguments can be added after the UNID such as omnidirectional="true" which change the way the weapon behaves. The most frequent are listed below: omnidirectional: This may be true or false, default is false. When true this causes the weapon to act as if it were omnidirectional secondaryWeapon: This may be true or false, default is false. When true this allows the weapon to be fired concurrently with the main weapon. posAngle: This may be a number from 0 to 360 (potentially more, but anything above that is useless), I don't know what the default is. This determines the polar angle coordinate to the position of the weapon posRadius: This may be a number from 0 to 360 (potentially more, but anything above that is useless), I don't know what the default is. This determines the polar radius coordinate to the position of the weapon minFireArc: This may be an number from 0 to 360, I don't know the default value. This determines the minimum angle at which the device (probably just weapons, I don't think it would effect an ICX) can fire. Incompatible with Omnidirectional minFireArc: This may be an number from 0 to 360, I don't know the default value. This determines the maximum angle at which the device can fire. Incompatible with Omnidirectional --> <Ships> <Table> <Ship chance="85" count="1d4" class="&scCorsair;" orders="guard"/> <Group chance="10"> <Ship count="1" class="&scCorsair;" orders="guard"/> <Ship count="1" class="&scViking;" orders="guard"/> </Group> <Ship chance="5" count="1d2" class="&scViking;" orders="guard"/> </Table> </Ships> <!--More on the <Ships> tag later--> <Items> <Table> <Lookup chance="40" count="1" table="&trConsumables2;"/> <Lookup chance="40" count="1" table="&trMinorItem2;"/> <Lookup chance="20" count="1" table="&trMajorItem2;"/> </Table> </Items> <!--This looks up some items. Chance describes the percent chance of that item, (in this case lookup item) or other entity actually being present. Remember that all tags with the same name share the same properties. If they are valid for both stations and ships they are no difference between placing them on stations or on ships. The <items> tag works the same here as it did for the strelka missiles.--> <Encounters frequency="common"> <Table> <Ship chance="75" count="1d3" class="&scCorsair;" orders="attack" /> <Ship chance="25" count="1" class="&scViking;" orders="attack" /> </Table> </Encounters> <!--This creates bee-line attack ships at a frequency of "common" for every station of this type. If there are lots of stations, then expect LOTS of these encounters. Other values for frequency are "uncommon", "rare", and "very rare"--> </StationType>
The <Encounters> and <Ships> tags both have very similar formats, if you copy the inside of one to the other, it will work without error. The format is:
Code: Select all
<Ship count="dice/range/number" class="UNID" orders="string" sovereign="UNID"> <Escorts> <Ship count="dice/range/number" class="UNID" orders="escort"/> </Escorts> </Ship>
class: The UNID (unique identifier) of the type of ship to be created. Remember the ship we modified? The UNID of a ship can be found in the first line of the ship definition. For example: <ShipClass UNID="&scCorsair;"
orders: This tells the AI what it should do. The most common values are "attack" which will send ships after the player, "patrol" which will send the ship circling around a point in space (usually the station), and "guard", which will cause the ship to sit still and wait for the player. Another interesting value is "wander" which will send the ship wandering around the system. If "patrol" is given as an order, you may add another option patrolDist="FOO" where foo is the range in lightseconds that the ship will circle at.
sovereign: The UNID of the sovereign that the ship belongs to. This should be OMITTED if this is inside a <ships> tag, but is NECESSARY if this is inside a <Encounters> tag. This is the major difference between the <encounters> and the <ships> tags.
Note that ships inside <Escorts> tags always have the orders "escort" which causes them to follow lead ship. If the count of the lead ship is greater than one, each ship will have its own escort. You may place as many ships inside an escort tag as you wish.
Notice that the escort tag is not necessary. If escorts are not used, a slightly different shorthand may be substituted:
Code: Select all
<Ship count="dice/range/number" class="UNID" orders="string" sovereign="UNID" />
The <table> tag picks things out of a list. For example:
Code: Select all
<Table> <Ship chance="75" count="1d3" class="&scCorsair;" orders="attack" /> <Ship chance="25" count="1" class="&scViking;" orders="attack" /> </Table>
This works identically with items.
There is one more feature of the <table> tag I need to mention.
Code: Select all
<Table count="1d4"> <!-- A list of stuff--> </Table>
So there it is. Explore, experiment, and most of all, have fun!
Part 3: All sorts of cool weaponry.
First, a quick run-down of the format of a weapon:
Code: Select all
<!-- Turbolaser Cannon --> <ItemType UNID="&itTurbolaserCannon;" name= "turbolaser cannon" level= "3" value= "1500" mass= "1500" frequency= "common" modifiers= "EnergyWeapon; MajorItem" description= "One of the most popular designs by the Earth Industries Conglomerate, the turbolaser cannon is a cheap, powerful, and reliable weapon." > <!-- name: The name of the item. level: The "level" of the weapon. Lower-level weapons are found in earlier systems and higher-level weapons are found in more advanced systems. The player will often use the level of the weapon to determine it's relative strength. value: How much a station will buy/sell it for mass: The weight of the weapon for purposes of calculating acceleration and turning speed. frequency: How often a weapon is likely to appear as random loot. Some missions use this as criteria for accepting items (Dvalin). modifiers: see Periculi's post below. MajorItem should be on all weapons and EngergyWeapon allows Longhzu spheres to be used on it. description: displayed along with the weapon's name. Helps the player understand the purpose of the weapon and sometimes furnishes the weapon with backstory. --> <Image imageID="&rsItems1;" imageX="96" imageY="0" imageWidth="96" imageHeight="96"/> <Weapon type= "beam" damage= "laser:2d4+1" fireRate= "15" lifetime= "30" powerUse= "50" beamType= "laser" primaryColor= "0x5f, 0xf1, 0x2a" secondaryColor= "0x00, 0xff, 0x00" sound= "&snLaserCannon;" > <!-- type: I have to ask Periculi damage: Determines the damage of a weapon, more on this later. fireRate: How fast the weapon fires. 1 is extremely fast, 100 is extremely slow. lifetime: How long the weaponsfire lasts (in ticks, I believe). Helps to determine the range of the weapon powerUse: the amount of power usage, in tenths of a MW, that the weapon uses when firing. The rest are beam-specific and I'll need to ask Periculi about them. --> </Weapon> </ItemType>
Damage is expressed in TYPE:NUMBER where type is the damage type of the weapon, and number can be a constant, range, or dice formula. Damage type can be any one of the list below. Betelguse made an attempt at giving "weights" to each damage type which is given in brackets after the damage type to help give you a rough idea of how good each damage type is.
dark acid (244.14)
dark steel* (244.14)
dark lightning* (610.35)
dark fire* (610.35)
*not currently used to my knowledge in the vanilla (unmodded) game
Each armour, shield, and anything else that can be damaged has a "resistance value" to each damage type which is then multiplied by the damage number to produce the final damage result (certain exceptions apply, but they are outside of the scope of this tutorial).
THIS IS NO LONGER MAINTAINED, and is available under the WTFPL, reproduced below:
Code: Select all
DO WHAT THE @#$! YOU WANT TO PUBLIC LICENSE Version 2, December 2004 Copyright (C) 2004 Sam Hocevar <[email protected]> Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. DO WHAT THE @#$! YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. You just DO WHAT THE @#$! YOU WANT TO.