Getting started with modding Transcendence! (2025 Edition)

This is a moderated forum that collects tutorials, guides, and references for creating Transcendence extensions and scripts.
Post Reply
User avatar
Aury
Fleet Admiral
Fleet Admiral
Posts: 5510
Joined: Tue Feb 05, 2008 1:10 am
Location: At the VSS Shipyards in the frontier, designing new ships.

This is a new tutorial for getting started with the basics of modding, meant to be a bit more up to date than the previous getting-starting tutorials from 15+ years ago!

It covers getting your mod development environment setup, and creating an extremely basic mod. See the end of this post for links to tutorials covering more advanced topics, like modules, adventures, libraries, and making ship sprites with blender!

Introduction
  • This tutorial assumes you are using a windows PC. If you are using Linux, it is assumed that you have already gotten the game to run on Linux, and that converting over the basic windows cmd instructions to sh or bash commands should be easy enough for you.
  • It is recommended to try out this tutorial in challenge mode (just click on the difficulty setting in the new game menu until it says 'challenge'), because it will make it easier to feel the difference of this early game weapon. Story & Normal mode provide significant damage buffs to the player, which causes them to one-shot most earlygame enemies and it can be hard to notice the difference.
  • The discord is the best place to get help with modding
  • This tutorial is designed to be followed with the Stable release of Transcendence from the kronosaur website (non-steam), but it should generally work with other releases. Some steps may be slightly different for them.
  • If you want to be able to see the source game data, you will need a copy of transcendence that includes transdata.exe (The Steam version DOES NOT contain this program)
    * Stable release (feature parity with the steam version): https://downloads.kronosaur.com/Transcendence.zip + https://downloads.kronosaur.com/TransData.zip
    * Alpha/Beta/RC release (may contain newer modding features than the stable release - check announcements threads for details, supports multiverse integration): https://downloads.kronosaur.com/TranscendenceNext.zip + ( https://downloads.kronosaur.com/TransDataNext.zip OR if the previous link doesnt work, https://downloads.kronosaur.com/TransData.zip )
    * Preview release (contains bleeding edge modding features, may have substantial bugs or balance problems. Not recommended for new modders unless the feature you want to play with is only available in a preview release. Has no multiverse access, but you can copy over your multiverse collection into the preview release. Also, you will have to manually update these, they have no automatic update feature): (Check announcement threads for details)
  • You will need an xml-friendly text editor of some sort. Some suggestions:
    * VScode (most modern, feature rich)
    * Jedit (has a transcendence xml specific plugin, if you can still find it)
    * Notepad++ (ultra lightweight)
  • Before publishing your mod, you will need to register an UNID prefix. The UNID prefix prevents the IDs of the content you create from overlapping with other people's content, which can cause unpredictable behavior in either mod, or even complete crashes.
Initial Setup

This portion of the tutorial explains how to get your mod development environment set up for the first time.
  • 1. Install your text editor
    2. Create a new folder inside of the Transcendence folder (ie: in the same folder as Transcendence.exe) called Extensions
    3. Create a new folder inside of the Extensions folder called MyFirstModTutorial (It can be any valid folder name as long as it does NOT start with an underscore - because transcendence deliberately ignores loading any file or folder starting with an underscore). Having a descriptive name means that you will know what mod is inside of it!
    4. If you are using windows, make sure that windows file explorer is set to show known file extensions: https://support.microsoft.com/en-us/win ... dbbc75cb01
    5. Create a new text file. If the default name of this file is something like "New Text Document" instead of something like "New Text Document.txt" which has a ".txt" at the end, go back to step 4 because you need that .txt there so that you can delete it and replace it with .xml instead - if you dont do step 4 and just try adding a ".xml" to it, then you will have a secret ".txt" after it, which transcendence will ignore and not load. Now, rename it to "MyFirstModTutorial_Extension.xml"
    6. Open up this new text file with your editor
    7. Add in the following boilerplate code: (You can type it in manually if you like, but making a typo can result in very non-obvious errors. If Steps 8=-0 do not work, try pasting it in. There also is an explanation about this code in the following section.)

    Code: Select all

    <?xml version="1.0" encoding="utf-8"?>
    
    <!DOCTYPE TranscendenceExtension
    	[
    	<!ENTITY MFMT_unidExtension					    "0xEEEF0000">
    
    ]>
    
    <TranscendenceExtension
    	name="My First Mod - Tutorial"
    	credits="Insert your name here!"
    	UNID="&MFMT_unidExtension;"
    	release="1"
    	version="1.0.0.0"
    	apiVersion="53">
    	
    	<!-- Libraries -->
    	<Library unid="&unidCoreTypesLibrary;"/>
    	<Library unid="&unidRPGLibrary;"/>
    	<Library unid="&unidGalaxyLibrary;"/>
    	<Library unid="&unidHumanSpaceLibrary;"/>
    	
    	<!-- Content -->
    
    </TranscendenceExtension>
    
    8. Load up this copy of transcendence.exe
    9. It should load just fine to the main menu
    10. If you click on the 'New Game' button, you should see "My First Mod - Tutorial" show up in there as a selectable mod!
    11. Congratulations, you are now setup and ready to begin making your first mod!
Explaining the boilerplate

So, what was in that boilerplate mod that you pasted in step 7?
This is a foundational skeleton for a mod that will work in the base game. It is defined using an XML format. The indentation style is not mandatory, but is strongly recommended to keep your code consistent and easier to read. You will thank yourself later for having good indentation practices.
Here is a quick primer to the xml format that Transcendence uses:

This is an entity definition, containing an entity name and an entity value:
<!ENTITY MFMT_unidExtension "0xEEEF0000">
And this is how an entity is referenced:
&MFMT_unidExtension;
One of the first things that the game engine does before it actually converts your xml text into data that the game can use and make instances of objects, ships, etc out of, it has to replace all of the entity names with the text inside of the quotes in the entity value. It will complain if an entity is not defined in either the extension, or the library files that the extension imports. (Advanced hint: while you can defined entities inside of TranscendenceModule files, which are not covered in this tutorial, those entities can only be used inside of that one file. Entities defined in a TranscendencExtension or TranscendenceAdventure can be accessed in any module of that extension or adventure, and entities defined in a TranscendenceLibrary can be accessed in any module of that library, or by any extension, adventure, or library that uses that library). Entities are almost exclusively used for giving UNIDs a human-readable name. You can name an entity_name whatever alphanumeric text you like. Underscores are acceptable as well, though usually the main part of the entity name uses camelCase style text to differentiate words, with the underscore being used only to separate the mod's prefix. This will be explained in greater detail later.

This is an XML element, comprised of just one xml tag (the part in the <>) with no inner text:
<Type/>
That is equivalent to this, which is the same element, just expressed using 2 tags instead
<Type></Type>
This is an XML element using two tags, enclosing some inner text:
<Type>"this is inner text"</Type>
You can have tags inside of other tags too as inner text in order to nest your xml elements.
<Type><AnotherType/></Type>
The use of tags as your inner text is the most common use of inner text in transcendence. Non-tag text will be parsed as TLisp, the game's built-in scripting language. Keep in mind, that when you start working with TLisp and TLisp comments, you cannot put an XML element tag into a comment! You will need to use an <!-- XML comment --> instead, as that is the only safe way to encapsulate a tag.
Tags can also contain attributes:
<Type attribute="value"/>
In this case we have an attribute named "attribute", which is assigned a value of "value". Even if the value is an integer or a boolean (true/false value), they are always entered as quoted string text in transcendence, so a number like 10 would be entered as "10", and a boolean like True is entered as "true". Attributes can also reference entity names, for example, how UNID="&MFMT_unidExtension;" is used

Now, lets go over the actual content that you added into the file in Step 7:

This section simply tells the parser about the xml format that is used in this file. You can safely ignore it, but you always need to have it for Transcendence to read your file.

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
This is the Document Type Data (aka "DTD") of the XML file. Here, we define a replacement mapping of readable names ("UNID Names" or "Entities") to hexadecimal numbers ("UNIDs"). Currently, we only have a single UNID and its corresponding entity in here.

Code: Select all

<!DOCTYPE TranscendenceExtension
	[
	<!ENTITY MFMT_unidExtension					    "0xEEEF0000">

]>
If we look at the entity line, we can break it up into the two parts, the Entity and the UNID:
<!ENTITY MFMT_unidExtension "0xEEEF0000">
Our UNID is the hexadecimal number: 0xEEEF0000
Our Entity is: MFMT_unidExtension

Both of these can be broken into several parts - lets look at the UNID first:
It can be broken in 3 parts: 0x EEEF 0000
  • The "0x" at the beginning signifies that this is a hexidecimal number, where each digit can be one of the following numbers: 0, 1, 2, 3, 4, 5, 6, 7, 8 , 9, A (10), B (11), C (12), D (13), E (14), F (15)
  • The "EEEF" portion is the UNID range, it represents the first 16 bits of the UNID number, and is usually assigned to a single person or a collaborative project. The UNID ranges from D000 to EFFF are considered "unregistered" by the game (meaning they are available for any independent mod to go and use, but save games using them do not count for official high score lists), but you are still expected to go through the "registration process" (linked above, in the prerequisites section) before publishing your mod to avoid collisions. Mods using UNID ranges not assigned to the author will be removed.
  • The final "0000" portion is the last 16 bits of the UNID number, and simply denotes a unique identifying number for that "design type". Make sure that your design types each get their own UNID number! Defining multiple types with the same UNID number can cause unpredictable results, or even crashes.
Now, lets look at the Entity:
It too can be broken into several parts: MFMT _ unid Extension
  • The "MFMT" part is the namespace, this is normally an acronym or abbreviation for the name of your mod, and aims to prevent collisions between different mods (or the base game) where the same entity name is used. Originally prefixes were not used, which has resulted in some embarrassing problems such as the official expansions Corporate Command and Eternity Port both trying to use the Entity "smTopology", but mapping it to different values, so anything including both of their libraries could run into problems unless it renamed them.
  • The "_" is just a spacer to delineate the namespace of the entity from the rest of the entity name
  • The "unid" portion is a code for the design type that this UNID is supposed to be assigned to. Generic types (such as basic <Type>s, Extensions, Adventures, and Libraries, just use "unid" as their entity type code. This way you can differentiate MFMT_scMyShip (an entity referring to a ShipClass) from MFMT_rsMyShip (an entity referring to an Image resource), for example, since they have to have different UNID numbers.
  • The "Extension" portion is just the name - ideally you want a sufficiently descriptive name here so you know what you are referring to. In this case, this is just "extension" because it refers to the extension of this mod.
There are a number of strategies to organizing your mod UNID numbers so that you can easily find things and not have to constantly check between mods to figure out what mod is using what UNID numbers, but that will be a topic for a more advanced post.


Last, but absolutely not least, we have the extension definition - this is the heart of your mod and what lets Transcendence actually load it up and connect it to the rest of the game.

Code: Select all

<TranscendenceExtension
	name="My First Mod - Tutorial"
	credits="Insert your name here!"
	UNID="&MFMT_unidExtension;"
	release="1"
	version="1.0.0.0"
	apiVersion="53">
	
	<!-- Libraries -->
	<Library unid="&unidCoreTypesLibrary;"/>
	<Library unid="&unidRPGLibrary;"/>
	<Library unid="&unidGalaxyLibrary;"/>
	<Library unid="&unidHumanSpaceLibrary;"/>
	
	<!-- Content -->

</TranscendenceExtension>
Most of the fields should be pretty self-explanatory, but lets go over a few of them.
Name: this is just the name of your mod. We can leave it as-is for this tutorial, but normally you will want to change this.
Credits: feel free to put your name there, so it shows up in the credits on the main menu under your mod's name
UNID: this must be a unique UNID number - no other extension, adventure, library, or normal design type should share the same number as your mod, otherwise transcendence will either fail to load your mod, or fail to load at all.
release: this is an author-defined field to keep track of incremental public releases of the mod. Increment it as you like.
version: this is the version string displayed to the user. the default one is set up for semantic versioning w/ an optional build number at the end: https://semver.org/
apiVersion: this is the transcendence api that this extension expects to use. Features from newer API versions will not be accessible, but you can't requires a higher API version than the game engine executing the extension code can support. For example, if the current release version of the game (1.9.2) only supports API 53, but you want to use the API 54 features from a preview build, you must set your apiVersion to 54, download the preview build and run your extension on that version of the game.

Things within the <!-- ... --> markers are xml comments. These are different from Tlisp comments, which will be explained in an advanced tutorial onTlisp.

The <Library...> section defines a bunch of default libraries that the game uses for mods that modify the base game (not DLCs or other mods) - doing that will be covered in an advanced tutorial on Libraries. For now, we will simply make an item that shows up in the free base game adventure: Stars of the Pilgrim.


Adding content

Lets start out by improving the base game sapphire - I think its a bit too weak, because it was designed back when you could not purchase new ships, and you had to stick with your starting ship for the entire game - the gimmick it relies on is being the most flexible and expandable, at the cost of earlygame performance, but that flexibility matters a lot less now, so lets improve its early game performance.

We will be modifying the base game sapphire with an Override type (different from completely overwriting it with a new ShipClass design type definition with the original UNID, which is more dangerous and prone to causing mod conflicts but sometimes necessary, as not everything can use Overrides), by making it faster, and giving it a stronger custom starting weapon.

Below the xml comment line that says "<!-- Content -->", add in the following xml:

Code: Select all

	<ShipClassOverride UNID="&scSapphireYacht;">
	</ShipClassOverride>
This is a special version of the ShipClass design type called an Override design type - any attributes or subelements that we add inside of it should be pasted on top of the original values. If they aren't, its possible there is a bug or oversight in the engine code, and you can report it on Ministry
scSapphireYacht is an Entity defined in the HumanSpaceLibrary, as seen in the <Library> declaration above, as a result, we don't need to manually add it ourselves in our own UNID-Entity list. If you go looking around in the HumanSpaceLibrary, you might have noticed already that the player actually starts with scSapphirePlayer, not scSapphireYacht! However, scSapphirePlayer (as well as all other playable and non-playable versions of the sapphire) inherits either directly or indirectly from scSapphireYacht, so we want to modify scSapphireYacht so that ALL of them get to use our new buffs, unless they individually overwrite the parts we are about to modify.

First, lets bump up the speed - at the default 0.2c, too many things can catch and kill it in early game, and it is the flimsiest of the 3 starting ships. Lets try setting it to 0.23c, fast enough it can outrun most things, and of the ships that are faster than it, it is unlikely to encounter them as enemies until it has a chance to get armor and weapon upgrades.
Inside of the <ShipClassOverride> xml element, you should paste in the following code:

Code: Select all

		<Drive
			maxSpeed=			"23"
			thrust=				"300"
			powerUse=			"20"
			/>
This will tell the game to change the sapphire's default engine stats to have a maximum speed of 0.23c now, while keeping the thrust and power draw the same as before. This means it accelerates the same, it can just reach a higher speed.

Go ahead and launch the game, load up the sapphire, and try it out now!

Maybe its not quite strong enough, and we want it to do even better in early game, so lets give it a more potent weapon to help kill anything that can catch it.
Lets start out by looking at its default weapon, the recoilless cannon. Here is the xml for this weapon:

Code: Select all

	<ItemType UNID="&itRecoillessCannon;"
			name=				"recoilless cannon"
			attributes=			"commonwealth, majorItem, NAMI"
			  
			level=				"1"
			frequency=			"uncommon"

			value=				"340"
			mass=				"2500"
			  
			description=		"Recoilless cannons are slower than the ubiquitous laser cannon but pack a bigger punch."
			>

		<Image imageID="&rsItemsNAMI1;" imageX="96" imageY="0" imageWidth="96" imageHeight="96"/>

		<Weapon
				type=				"missile"

				damage=				"kinetic:1d6+1; momentum1"
				fireRate=			"15"
				missileSpeed=		"40"
				lifetime=			"60"
				powerUse=			"10"
				
				effect=				"&efKineticBoltDefault;"
				sound=				"&snRecoillessCannon;"
				>
		</Weapon>
	</ItemType>
We can see that the <ItemType> element defines a lot of the actual item object stats (what you see in a shop, or in your inventory) while the <Weapon> subelement defines the actual combat stats. Normally, we want the items to be well-balanced (where their damage output increases by around 1.34x per level), but in this case, we want to be able to see our changes a bit better, so we will disregard conventional balance.
Paste the above xml into your mod below the <ShipClassOverride> for the base sapphire, and lets start changing it up.


First, we want to make this a NEW item type, so its custom to just the player's starting sapphire, and not something that a bunch of random NPCs using old ships are going to show up and destroy you with. To do so, we need to give it a new UNID number, which also means giving it a new UNID name/entity. Lets have the lore for this weapon be that Zubrin, the manufacturer of the Sapphire, wanted something stronger for their ship, so they made their own weapon.

Go up to your entity definitions and add in the following entity:

Code: Select all

	<!ENTITY MFMT_itZubrinRecoillessCannon					    "0xEEEF0001">
Note that the design type code is "it" instead of "unid", like the extension's entity. This is because "it" is the design type code for "ItemType".
Dont forget to change the EEEF part to whatever your own UNID range is, if you have gotten one allocated to yourself and want to extend this mod further into something you can publish.

Now, you can rename the <ItemType UNID="&itRecoillessCannon;" ... part to <ItemType UNID="&MFMT_itZubrinRecoillessCannon;" - this will tell the game to replace that entity name with the actual new UNID number when it loads it up, so it will see it as a unique weapon and not try to just overwrite the basic recoilless cannon.

Lets take care of the lore housekeeping first, and update the attributes list by replacing "NAMI" with "Zubrin" (this is a tag, which in this case, identifies who manufactured it). Since its a bespoke specialty weapon, lets change the frequency to "rare" so it is weighted to show up less frequently. We should also change the name "Zubrin Recoilless Cannon" and description to reflect this: "Zubrin, manufacturer of the popular Sapphire-class Yacht, wanted a premium weapon for their ship but were not satisfied with the offerings on the market, so they made their own weapon.".

Since we want it to be clear in this example tutorial that the weapon should feel significantly different, lets make it a level 3 weapon too. To do this, we go to our <ItemType ...> tag where the level attribute exists, and change it from having a value of "1" to "3" instead.

Ok, now we need to actually modify the weapon's performance characteristics. At level 3, it should be dealing around double the damage. Right now, you can see from the damage description of "kinetic:1d6+1; momentum1" that it is:
* dealing kinetic damage of 1d6+1, which means that it rolls a single six-sided dice, and then adds one to that value
* applying a special effect of momentum, at level 1 (out of 7)
Since we want the weapon strength to be 2x as powerful, we only need to modify the damage calculation here. We want it to be approximately 2x as strong as it currently is, so that it fits with other level 3 weapons, so lets keep it as a kinetic weapon, but give it 2x as much damage output. In this case, that is pretty easy to do. We can simply have it roll a twelve sided dice instead (so that its equally likely still to roll max, middle, or min damage, just as it used to be), and then add 2 - while we could also have it roll 2 six sided dice, that makes it more likely to roll in the middle - normally that is good, but for the sake of this demo I'm just trying to keep the feel of the original weapon, just scaled up by 2x.
Finally, since its a level 3 weapon, at least at the time of writing, those tend to use around 3x the power draw of a level 1 weapon, so lets change the powerUse to 30 instead of 10.

Now you can fire up the game and try out the changes! It should feel noticeably different from the basic sapphire's weapon when playing on challenge mode, simply because it is a lot stronger.

Experimentation
Feel free to experiment and try out changing more parts of the base game! If you ever get stuck, feel free to ask for help in the discord!
A helpful resource are the core game files, here are instructions on how to extract them:
  • 1. Download and extract TransData.zip/TransDataNext.zip (see the introduction section for the links) into their own directories too and copy the TransData.exe and TransCompiler.exe files from inside into the directory with Transcendence.exe. Don't put the files in a place that you need administrator permissions to access.
    2. Open up cmd (it should not need to be in administrator mode)
    3. Copy the directory path of the location where Transcendence.exe is from the folder name bar at the top of windows explorer. Here is where to click to get the path to show up:
    Transcendence_File_Path_Example.png
    Transcendence_File_Path_Example.png (60.23 KiB) Viewed 5944 times
    4. If the drive letter at the front of the path that you just copied (ex, "C:" or "D:") IS "C:", skip this step and go to Step 5 instead. OTHERWISE if it is NOT "C:", type in the different drive letter along with the colon into cmd. For example, if your path to the Transcendence executable is D:Downloads\Transcendence\Transcendence.exe, then you type in D:. It should look something like this once you do this step:

    Code: Select all

    C:\Users\MyUserAccount> D:
    
    D:>
    
    5. Given the previous path example from step 4, type in cd D:\Downloads\Transcendence - the part you type in after "cd" is determined by the portion of the path to Transcendence.exe after the drive letter & its color (so, in this case, "D:") up until you reach "\Transcendence.exe". When you complete this step, it should look something like this:

    Code: Select all

    D:>cd D:\Downloads\Transcendence
    
    D:\Downloads\Transcendence\>
    
    6. Next, type in transdata.exe /decompile and wait for the command to finish.

    Code: Select all

    D:\Downloads\Transcendence\>transdata.exe /decompile
    
    Transcendence_Source\Transcendence.xml
    Transcendence_Source\... (there will be a lot of lines of text here!)
    Transcendence_Source\Xenophobes.xml
    
    D:\Downloads\Transcendence\>
    
    If there were no errors, you should now have all of the game files in a folder called "transcendence_source" next to your transcendence.exe file. You can now browse it for references and inspiration!
There are some existing tutorials on things like adding new ships, but unfortunately most of those old ones are very out of date, and may not work correctly or don't show all the improved features you can use.

Further Reading:
(At the time of posting, not all of these tutorials have been written yet! Check back later for more content, or make a special request for a specific tutorial on discord!)

Organizing UNIDs:

Making a mod with modules:

Making an adventure mod:

Making and using a library:

Writing Tlisp script:

Making sprites in blender:

I want to make...
New items:
A ship:
A player ship:
A station:
A new currency:
New star systems:
A new faction:
A storyline:
A whole expansion!:
(shpOrder gPlayership 'barrelRoll)

<New tutorials, modding resources, and official extension stuff coming to this space soon!>
Post Reply