Thor110 497 Posted January 1, 2019 (edited) [TUTORIAL] - KotOR Modding Tutorial Series These tutorials should be enough to get anybody started making levels for the game using the available resources and tutorials / tools etc IMPORTANT NOTE : A lot of the tools I use are outdated now that Holocron Toolset is out, however I still prefer working with each filetype as I am use to the programs that edit them directly that I use throughout this tutorial. So if you are using Holocron Toolset or KotOR Level Editor, things will be different, but the general idea should be the same. I suggest trying out Holocron Toolset if you want an all in one program for editing levels, it does everything KotOR Level Editor does and most of what all the tools I have below do, except perhaps findrefs, dencs, kotor gui editor, walkswitch, anicam, ptheditor and lip synch editor, but it does everything the rest of the programs do and it might even do some of the things from the programs I just mentioned, I am not sure! Available Source Material & Tools These are the tools I use for modding the game. Lots of source material is available on DeadlyStream as well as many tutorials, some old, some new and very detailed information on the filetypes and the game itself, so make sure to have a good look around. .nss scripts for every script I have been able to access from both games are available in the GitHub repositories for my project. Some scripts from KotOR1 require the files to be trimmed of some excess bytes, there is some information on it around here somewhere and I will post a link to it when I next find it, the scripts in question are some of those from Tatooine, Manaan, Kashyyyk and the Unknown World. Actually Decompiling Scripts Spoiler In order to decompile scripts you are going to need DeNCS and nwnnsscomp.exe which can be obtained via the downloads section of this site amongst the modding tools section. Then you can open the javascript runtime file which will launch the decompiler. From here as an example I am using ERFEdit to open a level from my project, which also contains the .nss scripts for every script which people are free to use to learn from and make their own mods with. Using ERFEdit or another method obtain the script you wish to decompile. Once you have done so, drag and drop it into the DeNCS window. Once you have dropped it into the programs window it will look like the image below. From here you can right click and select "View Decompiled Code" or you can the options to set the default directory to save the files to and then select File and Save As appropriately. If you view the decompiled code you can take a look and check out the script before you decide to save it, you can also decompile multiple scripts at a time as well as save them all at once. The log at the bottom of the window will notify you of any failed attempts at decompiling scripts, it will always give a warning about a partial issue recompiling the script. Hopefully that helps and will help anybody figuring out how to decompile scripts for the game. Feel free to use any of the source scripts available in any part of my project to learn from or create new mods with and please give credit appropriately if and where necessary. Steam KotOR Tool Issues Spoiler Some people often have trouble getting KotOR tool to work with Steam, this is down to not having the correct registry entries. You can use these registry files to update your registry accordingly. KotOR1.reg KotOR2.reg There are quite a few posts about this lying around the forums. KotOR2 Expanded Galaxy Thor110/Expanded-Galaxy-Main: Expanded Galaxy Main (github.com) KotOR1 in TSL Expanded Galaxy Thor110/Expanded-Galaxy-Port: Expanded Galaxy Port (github.com) Brotherhood of Shadow : Solomon's Revenge in TSL Expanded Galaxy Thor110/Expanded-Galaxy-Hood: Expanded Galaxy Hood (github.com) PLEASE do not redistribute the entire project anywhere without my express permission, but feel free to learn from the source material to make as many modifications to the game as you wish. If you wish to work on the project or contribute by offering or allowing your mod to be included with the project feel free to contact me on here or elsewhere. In future I might go beyond these basic scripting tutorials and add other types of tutorials such as texturing and modelling that are focused around KotOR2 TSL or working with others towards making a comprehensive KotOR modding guide. Most material I write will be aimed at KotOR 2 TSL, though a lot of the structure of the game is very similar between them both if not almost identical. For now here are some really basic written tutorials for getting setup with Blender and modding for KotOR or just messing around with the models from the game. I will continue to work on these providing screenshots and more as necessary. The first two blender tutorials here are a little outdated, there is a new version of KotORBlender for example which can import MDL files without the need for them to be converted to ASCII. I advise having a folder with all of the games model files ( mdl/mdx/wok/dwk/pwk ) and related files ( .lyt/.vis ) as well as textures ( swpc_tex_tpa/swpc_tex_gui ) And even all of the .gui files, this way you can use that folder to instantly import an entire level as well as properly display .gui files in the KotOR GUI Editor. Blender Tutorial 00 - Getting Blender Setup ( OUTDATED ) Spoiler Getting Setup I suggest using Blender 2.92 and the latest version of the kotorblender plugin. Blender 2.92 ( 3D Modelling Software ) https://www.blender.org/download/releases/2-92/ kotorblender ( \addons\kotorblender\plugin-files ) This plugin is used for blender and needs to be placed in C:\Users\your-user-name-here\AppData\Roaming\Blender Foundation\Blender\2.92\scripts\addons https://deadlystream.com/files/file/1853-kotorblender-for-blender-28/ NWN Model Viewer This can load all the models for quick / easy viewing provided you have the .mdl, .mdx & .tga files associated with the model in the folder. https://neverwintervault.org/project/nwn2/other/tool/simple-model-viewer-64-bit-patch Folder full of Assets Getting set up with a folder full of assets takes but a moment and a bit of space. Use KotOR Tool to extract the following archives. ( models.bif, textures.bif, lightmaps.bif, swpc_tex_gui.erf & swpc_tex_tpa.erf ) Then convert these using the batch tool from MDLEdit ( make sure it is set to the correct mode for whichever game you are converting files for, I have shown extracting K2 files above, but the process is almost identical for K1 ) After having converted them to ASCII and having converted all of the textures from .tpc to .tga you should have no problem getting them loaded up into Blender 2.92 using the kotorblender plugin. The following is a description of how I converted the textures from .tpc to .tga I used xoreos tools and the tpc2tga.bat that is available somewhere on the DeadlyStream Forums. Basically download xoreos tools and get the above mentioned batch file ( tpc2tga.bat ) and or find a similar method to convert all of the .tpc files to .tga files, you can then delete the remaining .tpc files, if you put them back into the game you might require the .txi data which will have to be extracted separately, they exist within the .tpc files, but not the .tga files. Below is a link to the relevant topic and solution mentioned by DarthParametric https://deadlystream.com/topic/6075-anyone-still-have-the-tpc-to-tga-executable/ From here it should be as simple as turning on the kotorblender and importing a model. Provided you put the files in the correct location you will be able to tick the box in the preferences menu. From here you will be able to import an ASCII model and the associated textures. I imported 3dgui.mdl From here it should be fairly straightforward to learn from all the existing in-game models from both games as examples to work from regarding how to structure assets. Assets are generally listed throughout the various 2DA files associated with the game. Blender Tutorial 01 - Asset Editing ( OUTDATED ) Spoiler In general I suggest learning to model in Blender from YouTube tutorial or other online resources, then using what you can to learn from the existing models of the game and make whatever you want using them as an example to work from. Opening and editing a level, character or asset from within the game. In order to do this you will need to first use KotOR Tool to extract all of the models and textures to a directory on your computer. The textures need to be in .tga format, which unfortunately means extracting them one at a time, or using some of the tools around to convert them all at once from .tpc to .tga You will also need to extract the lightmaps to that same directory if you are planning on working with the levels and the layout or .lyt files if you are planning to load an entire level at once into Blender. I also use the NWNModelViewer to quickly view the various models throughout the game using a directory full of it's binary file format models. You will then need to use MDLEdit to convert the model you want to an ASCII file format model. ( Or batch convert to convert lots of models at once ) NOTE : KotOR Blender now supports importing the binary models. From here you should easily be able to open any asset from within the game via the .mdl or .lyt files. Once you have modelled what you wanted and used click + shift drag to place it within the hierarchy of the asset You will then be able to select the asset and it's entire hierarchy and export it to .mdl Remember to select Export for TSL or Export for Xbox depending upon your circumstances. Blender Tutorial 02 - Creating A Placeable Spoiler In order to create a placeable I suggest importing a placeable to use as your template to work with. keeping the "lookathook" and using click + shift and drag to place your model within the correct heirarchy for the model. modelling the walkmesh area to match and moving the lookathook to where you want the player to be able to click on the placeable object. I kept the existing walkmesh ( PLC_*_pwk ) and renamed it to match the placeable I was making. Moved the lookathook to where I wanted it to be or where I want it to be for now. And selected then the object I had pasted over from the Ebon Hawk and held shift on the keyboard to add it to the heirarchy of the main object "PLC_baoplace" from here you will need to click on the placeable and make sure that the entire hierarchy is selected and export it to .mdl format ( ASCII ) then use MDLEdit to convert it back to binary. and add it to the placeables.2da in order to be able to place it somewhere in a level. Blender Tutorial 03 - Character Editing Spoiler As with all the above tutorials I suggest getting a folder full of all the models ( .mdl, .mdx, .wok, .pwk, .tga, .lyt ) as well as the .mdl.ascii files made by MDLEdit in order to quickly load any model you want into Blender and be able to edit it or alter it as necessary. From here editing any asset within the game shouldn't be too difficult as well as making new assets provided you are able to make use of existing materials, tutorials, resources and the tools available in order to achieve your goal. Sorry these tutorials are not very in-depth or detailed, I will work on them more in the future. For now getting assets loaded into Blender is often peoples first trouble step. As soon as I find the relevant links I will post about how to use Xoreos tools and the tpc2tga.bat file to convert all the textures for easily loading them up. When converting a character model make sure to have the relevant supermodel in the same folder as the model being converted. The supermodel can also be seen if you highlight or click on the header section of the model in MDLEdit at the bottom of the program. As shown for this the Supermodel is NULL meaning there isn't one. Hopefully this will help anybody get characters or other assets loaded into Blender for whatever they need them for. Blender Tutorial 04 - Level Editing Spoiler Since I have made quite a few level fixes lately, I might slowly fill this out with some tips and tricks I used to quickly edit levels. Currently this is just going to contain a few short videos until I write some more down about it in the future. This is the technique I use to line up level models from one part of a map to another, for example if they use the same geometry like shown in this example. I might post more, but it might require me to lay out a plan for what to demonstrate. Here I am just showcasing the way I take down two sets of co-ordinates, I then subtract the smaller number from the larger number ( I clip any negative values and just use the numbers ) which leaves me with a remainder or difference, which I can then use to move the rest of the model into the exact spot it should be in. Pretty sure there is a quicker way to do this, perhaps using the magnet tool, but something inside of me never trusts software to work the way I think it should or even the way it says it does and I tend to try and just work with raw values as much as possible so that I know things are as accurate as I can make them. Outdated Tutorials & Intro Spoiler Download : Downloads for my KotOR Modding Tutorial Series are available on the ModDB page. https://www.moddb.com/mods/kotor-ii-tsl-expanded-galaxy/downloads/kotor-modding-tutorial-series NOTE : I was writing / organising the tutorials differently when I started the document versions and so they are a little outdated / incomplete in comparison to what is here, but I still have plans to go back and cover some of the topics I planned to in the documents. ( DOWNLOADABLE VERSION IS OUTDATED FOR NOW ) Update : Please let me know how you get on with these tutorials, if you have any problems or suggestions for how I could improve anything even grammar / formatting I would really appreciate it, I hope to construct a tutorial series that covers modding of both the Expanded Galaxy Project and both KotOR games from basic modifications to Total Conversion Modifications set in the Old Republic Era of the Star Wars Universe, anything beyond this would require more work on your part, I believe it would be possible to make some interesting stories using the Odyssey engine for Point & Click type games or RPGs in general, but I believe it is better suited towards the Star Wars Universe, more specifically the Old Republic Era due to the abundance of content available in both games, but it could also be re-purposed for other Star Wars Stories from any time. https://www.moddb.com/mods/expanded-galaxy-project-kotor-12/downloads/kotor-modding-tutorial-series I will be posting my tutorials on ModDB as well, here is my first link which is a rough tutorial and overview of the future tutorials I have planned, both mods pages on ModDB will also have files to go alongside each mod and help streamline the process of creating levels for both games in the KotOR series and for the Expanded Galaxy Project. https://www.moddb.com/mods/kotor-ii-tsl-expanded-galaxy/tutorials/streamlining-module-creation Individually written and quite specific tutorials, mostly scripts and guidance towards achieving specific goals or tasks. 01 - [TUTORIAL] - Creating a Module for TSL using a KotOR Map! The first tutorial should be a great guide for porting a level from the first game into the second game as well as that it shouldn't be too difficult to work out how to do it the other way around from there on out! Spoiler Previous : This tutorial has been updated and I have released it as an .odt series on KotOR modding I am starting to write, I am going to be writing a lot more tutorials throughout the process of creating my mods, documenting the entire process and writing a tutorial for each individual element of the game that I learn to modify, change or add to in order to help others create great content for both of the KotOR games and the Expanded Galaxy Project. Tools Required Kotor Tool MDLEdit K-GFF Editor Bulk Rename Utility ( or Patience ) A copy of K1 & K2 ( Steam, GoG or original 4 CD version ) This tutorial will cover how to port the first module of the Endar Spire from K1 into K2, but the steps are very much the same for any module in the game. ( Open Spoilers to reveal images and instructions ) Layout Files - First open Kotor Tool, make sure your game directories are set, then open up BIF's>layouts.bif & extract "m01aa.lyt". Spoiler Extract "m01aa.lyt" to the override directory for your module" The Lightmaps Spoiler Extract "lightmaps.bif" ( not numbered, the first one ) to a folder, delete everything in the folder except m01aa, so click the first m01ab file and scroll to the bottom, then hold shift and click the last file to make this easier. Model Files Spoiler Then extract the entire "models.bif" directory ( this will save you a lot of time ) and delete everything except m01aa ( .mdl, .mdx and .wok files ) Module File Contents Spoiler Then open RIM's>Modules> and extract end_m01aa.rim & end_m01aa_s.rim directories. MDLEdit - Converting Map Files! Spoiler Open MDLEdit, set it to KOTOR1 mode, then batch > convert > to ascii, all of the models for m01aa. Make sure to set the mode for K1 before converting to ascii and then set the mode back to K2 when converting to binary. When it is complete, set the program to KOTOR2 mode, then batch > convert > to binary all the ascii files you just converted ( arrange by type to easily select the ascii files ) You will also need to extract the relevant texture pack you wish to use. Texture Packs, Loading Screen & Minimap. Spoiler Extract "swpc_text_tpa" ( these are the high resolution textures ) "tpb" & "tpc" are medium and low resolution versions of the same textures. if you want to individually single out which .tpc files you need for the module you are welcome to do so. At some point I will also write a short / easy and quick way to get just the .tga's necessary for an individual module. Minimap Loading Screen I have just extracted the three texture packs ( lightmaps, gui and tpa ) in their entirety in order to save singling out which files go to which modules because it is easier for the moment and suits the purpose of my project. Use K-GFF Editor to remove any references to scripts in the .are, .git and .ifo files. Change the Name String Reference to -1, right click and Add String, change this string to "Endar Spire - Above Taris" ( but you do not have to remove the entries for this module to work ) Spoiler Use K-GFF Editor to remove these references. Use Kotor Tool, click the ERF button, save the modules as "end_m01aa.mod"(make sure to include the .mod extension) set the dropdown to MOD and select add files, then add the .are, .ifo, .git, .pth and .utd files. Spoiler Use the ERF button and build the module. Make sure to delete the original maps and ascii conversions, as well as to rename all of the files using patience or I suggest Bulk Rename Utility and remove every reference of "-mdledit-mdledit" from the .mdl, .mdx and .wok files. ( you may also want the .dwk & .pwk files ) After creating the module copy it to your Modules folder and copy the rest of the files over to the override folder, you can then use the warp cheat to access the level "warp end_m01aa" Currently the stars and lasers / anything going on outside does not appear, if you wish to fix this just extract the missing contents from the texture packs. K1 & K2 : You should also be able to use this tutorial to make a module for both KotOR games as well as my Expanded Galaxy Mod, I will also update it so that completely custom areas can be made using parts already in the game allowing for much more diverse level creation. Note : It seems the process is the same for porting TSLmodules to KotOR, but for the moment I am unable to port the outside areas of Telos, Dxun or Dantooine due to foliage being spread across the map due to Vector Calculations being off during the conversion process. ( Noting that you need to be in K2 mode using MDLEdit when converting to ASCII then K1 mode when converting back to binary, exactly the same process I used for KotOR to TSL works in reverse ) Spoiler These are the current results, very similar to Telos Restoration Zone and Dantooine. I believe in order to get around this, you would have to delete the foliage geometry in a model editing program after converting them. These are some useful links that I have found around that might guide you towards making mods for the game. Useful Links for learning to mod TSL & KotOR Spoiler Links that I have found helpful My most recent attempts have lead me to this tutorial - Adding Planets To Galaxy Map in TSL https://web.archive.org/web/20130124075620/http://www.lucasforums.com/showthread.php?t=169825 I have also used this tutorial to name the module - Naming a custom module https://web.archive.org/web/20121204061936/http://www.lucasforums.com/showthread.php?t=194986 This tutorial helped me add loading screens to my modules - Custom Loadscreens https://web.archive.org/web/20150911045357/http://www.lucasforums.com/showthread.php?t=194903 Thanks to this next tutorial I was able to add custom music to my module - Adding Custom Music to KOTOR https://web.archive.org/web/20121016090124/http://www.lucasforums.com/showthread.php?t=180773 This tutorial I have not used yet but looks really well made and is for adding custom doors - Door Modelling Tutorial https://web.archive.org/web/20151120115337/http://www.lucasforums.com/showthread.php?t=186921&highlight=door A long series of video tutorials for modelling a new area - Modelling an new area! https://web.archive.org/web/20150912222837/http://www.lucasforums.com/showthread.php?t=195261 some of the tutorials link to downloads for the actual tutorial itself, luckily some if not most of the mediafire links are still active, you just have to edit out the wayback machine portion of the url after following the link. I have also come across these tutorials on youtube which others might find handy and I am noting down here for reference / credit to any tutorials that have helped me along my way. New Area in KotOR Part 1/3 - I haven't used any of these videos yet but they cover information I might need. https://www.youtube.com/watch?v=NvXEX1acl4I Modules Part 1 Overview - The uploader of this video also has lot's of other kotor related modding videos that look and sound useful. https://www.youtube.com/watch?v=ykvg3Bqohqs KotOR 1 & 2 Animated Texture Tutorial - This tutorial will definitely be helpful for making modifications to the game. https://www.youtube.com/watch?v=GBjWzNFdgg8 Using an example set by Effix in the Mod Requests section I have made a little more progress and managed to load the map correctly by including the .mdx, .wok and .lyt files. https://deadlystream.com/topic/6665-tsl-yavin-station/ More links! A detailed page about TXI file parameters. https://czerka-rd.fandom.com/wiki/TXI_Files A detailed page about .uti files for items. https://czerka-rd.fandom.com/wiki/.uti_(Item)_files A detailed post about .nss source scripts. https://czerka-rd.fandom.com/wiki/.nss_(source_script)_files A detailed post about .dlg dialogue files. https://czerka-rd.fandom.com/wiki/.dlg_(Dialogue)_files All pages available on the website from the above four links. https://czerka-rd.fandom.com/wiki/Special:AllPages Useful Tutorials & Information From DeadlyStream ( There are quite a few in the Tutorials Section worth reading ) https://deadlystream.com/topic/4748-lightmapping-an-area-model/ https://deadlystream.com/topic/4743-how-to-reskin-a-module/ https://deadlystream.com/topic/4034-setting-a-spawn-point-in-a-custom-module/ https://deadlystream.com/topic/524-conditional-scripts/ https://deadlystream.com/topic/4506-plot-usable-items-in-k2/ https://deadlystream.com/topic/9353-bump-mapping-tutorial-request-for-novices/ Thor110 In the following post in this topic are many more tutorials that I am working on to guide people through the process of making mods for KotOR. Edited Tuesday at 07:50 PM by Thor110 Blender Tutorial 04 4 1 Quote Share this post Link to post Share on other sites
Thor110 497 Posted January 11, 2019 (edited) 02 - [TUTORIAL] - Creating a Merchant - TSL Spoiler Merchants In order to add a merchant, you will need to first add a character to whatever module you want and create a .dlg (Dialog) file which is used by the .utc (Character) you will then need to add any relevant lines of dialog for your character to speak. Make sure to name the dialog file in the Conversation section of the utc file. From there you will need to link it to a script using a line of dialog. The following is an example of the script you will need to use to launch the merchants inventory window. void main() { object oStore = GetObjectByTag("merchant_file"); // this is the .utm file listing your merchants inventory if(!GetIsObjectValid(oStore)) oStore = CreateObject(OBJECT_TYPE_STORE, "merchant_file", GetLocation(OBJECT_SELF)); if(GetIsObjectValid(oStore)) DelayCommand(0.5, OpenStore(oStore, GetPCSpeaker())); } this script then needs to be compiled using the KotOR Scripting Tool. ( Make sure to set it to KotOR 2 Mode ) It will open the .utm (Merchant) file which contains a list of the items which are available for purchase. Another example is to use global variables as conditions to determine what stock your merchant has available. The next example is a script I am using for the Yavin Orbital Station, it determines which merchant script to load dependant on how many Jedi Masters the Exile has already encountered during their playthrough. ( Between 0 & 4 ) I have updated the script recently to make it a lot shorter and to use a function to create the store rather than a bunch of if/else statements and the same lines of code in each circumstance. // open_stores // this script opens a set of stores based on the string passed to it // intended for merchants that have a different store dependant upon game progression // updated 20/10/2024 void store(string oStoreName) { object oStore = GetObjectByTag(oStoreName); if(!GetIsObjectValid(oStore)) oStore = CreateObject(OBJECT_TYPE_STORE, oStoreName, GetLocation(OBJECT_SELF)); if(GetIsObjectValid(oStore)) DelayCommand(0.5, OpenStore(oStore, GetPCSpeaker())); } void main() { string sName = GetScriptStringParameter(); // pass the script the store name from a dialog file store(sName+IntToString(GetGlobalNumber("000_Jedi_Found"))); // call store function with the relevant string } This script is used in the same way as the previous script which has only one merchant file but it will require 5 merchant files. Some other script stuff. ( not sure why I put this here ) Using the source script from the games files “a_playpazaak” you can also start a game of pazaak using the same process. The following script will open a door on the map when you interact with a placeable, it could also be used in a dialog if you wish. void main() { object oDoor = GetObjectByTag("yav50_airlock"); ActionOpenDoor(oDoor); } In this example the placeable “yav_panel50x.utp” which is an invisible placeable loads the above script “yav_panel05” in the OnUsed section which can be found using the KGFF editor on a “.utp” (Placeable) file, the script then opens the door called “yav50_airlock”. Another useful property to note is the Static property of the doors, which can be used to determine whether or not the door can be selected by the player. 03 - [ADDITIONAL] - Using ERFEdit Spoiler ERFEdit is useful for extracting the contents of other module files, this can be handy to look up an example from another level. In order to make use of the following three examples, you will want to use ERFEdit to extract the contents of the module, you will also need DLGEdit & K-GFF Editor, extract the files and examine them to hopefully save others time from searching through the Characters, Placeables and Alien Voice Overs. You can also just spawn in each module and look around, each character or placeable will have their number references as their name. Characters 0-700 approx Placeables 0-400 approx Dialog 0-42 With all of these testing rooms I have still had the main three mods I am planning to provide compatibility for ( TSLRCM, M478EP & Jedi Temple ( Coruscant ) Mods ) installed to the game, so if you do not some of their appearances may be missing. 04 - [ADDITIONAL] - Picking an NPC to place in your level - TSL Spoiler I was dreading finding a specific NPC to place around any of the levels I am working on so I drafted up these test levels with every NPC from TSL in them. Using these modules you should have no trouble picking an NPC and identifying what number entry they are in the appearance.2da file. Testing Rooms.7z Screenshots Spoiler 099dia 199dia 299dia 399dia 499dia599dia699dia I hope this will be useful for others, I haven't made full use of it yet, but I can now roam around and pick out which NPC's I would like to place and not have to worry about finding their entry number, as well as having the ability to view nearly all of them at once. 05 - [ADDITIONAL] - Picking Placeables to fill your level with - TSL Spoiler I decided to do the same thing for placeables, so that I could not only look through them all at once but hopefully find it easier to populate the levels I am working on with placeables and NPC's. Testing Placeable Rooms.7z Screenshots Spoiler 699plc 799plc 899plc 999plc 06 - [ADDITIONAL] - Picking Alien Voice Over Dialog for your level - TSL Spoiler In the same style as the placeables and characters, but contains one character per alien in the "alienvo.2da" file and a dialog entry for each type of voice over they can use, excluding null entries. Alien VO Dialog Testing Room.7z The Rakata & I think a few others don't have voice files even though the 2da file states that they do, I will go through these at some point. Screenshots Spoiler 000voi 07 - [ADDITIONAL] - Placement & Rotation Spoiler The bearing of a placeable is it's rotation, characters have an X orientation and a Y orientation which also pertains to their rotation. The below co-ordinates are what I am using for making a placeable rotate to face any of the cardinal directions. I have seen that sometimes people over rotate from these numbers until they get to the right position, for example to face East can also be 4.5 approximately, but I have found the below values to be the best, if someone knows better please let me know. I generally use KotOR Toolset to locate an item in an existing module and record its co-ordinates then I edit its co-ordinates using K-GFF Editor, from there I tend to test the level over and over again until I get the placement just right. North -3.1415901184082 West -1.5707950592041 South 0 East 1.5707950592041 I realise they are using Radians or Pi, so this can be positive or negative accordingly, Pi itself is *3.14159265359 ( so that might be a more accurate value to use ) though I haven't used that just yet, but it will be such a minute change in rotation that it would be practically impossible to notice anyway. But I have noticed some things in the game over rotate to get to the correct position, so I thought this might be worth noting for other users, I used other objects in game to determine North & South and went from there. I also found the below example which is probably a lot more detailed, quoted from Lucas Forums by e-varmint Spoiler The "bearing" measurements for doors and placeables in the .git file use radians instead of degrees. Degrees Radians 15= 0.261799388 30= 0.523598776 45= 0.785398163 60= 1.047197551 75= 1.308996939 90= 1.570796327 105= 1.832595715 120= 2.094395102 135= 2.35619449 150= 2.617993878 165= 2.879793266 180= 3.141592654 195= 3.403392041 210= 3.665191429 225= 3.926990817 240= 4.188790205 255= 4.450589593 270= 4.71238898 285= 4.974188368 300= 5.235987756 315= 5.497787144 330= 5.759586532 345= 6.021385919 by e-varmint 08 - [TUTORIAL] - Waypoint Markers Spoiler Below is the documentation left within the blueprint waypoint files within the game, when I have actually placed some myself and am more familiar with the process I will try to write a step by step for it as well. "This is the default waypoint you may place to set a patrol path for a creature or NPC. 1. Create the creature and either use its current Tag or fill in a new one. 2. Place or make sure the WalkWayPoints() is within the body of the On Spawn script for the creature. 3. Place a series of waypoints along the route you wish the creature to walk. 4. Select all of the newly created waypoints and right click. Choose the Create Set option. ( The set will be defined by their numbers ) 5. The waypoint set will have a set name of "WP_" + NPC Tag. Thus if an NPC with the Tag "Guard" will have a waypoint set called "WP_Guard". Note that Tags are case sensitive." Bullet Point #1 Create your creature. ( .utc file which will be spawned using the .git file for the module ) Bullet Point #2 refers to what will be needed in the script. ( Example Scripts Below ) Bullet Point #3 Place your waypoints. ( placing the .utw files along a specified path using the .git file of the module ) Bullet Point #4 will be referring to the software they would have been using during development. Bullet Point #5 refers to naming the waypoint files. ( "WP_Guard_01.utc" etc ) I have three script examples so far for NPC's walking, but I haven't used any of them yet so cannot confirm they work until I start populating the areas I am working with. Continue Walking Waypoints - "walk_continue.nss" Spoiler #include "k_inc_generic" #include "k_inc_debug" #include "k_inc_treas_k2" void main() { // Force them to continue walking waypoints. onEndDialog GN_WalkWayPoints(); } Walk Around Randomly - "walk_random.nss" Spoiler void main() { // onHeartbeat AssignCommand(OBJECT_SELF,ActionRandomWalk()) } Walk Waypoints On Spawn - "walk_spawn.nss" Spoiler #include "k_inc_generic" #include "k_inc_debug" #include "k_inc_treas_k2" void main() { GN_SetDayNightPresence(AMBIENT_PRESENCE_ALWAYS_PRESENT); GN_SetListeningPatterns(); GN_WalkWayPoints(); } 09 - [TUTORIAL] - Scripting Basics Spoiler I will not cover much scripting, but when I am finished with the project all the source will be made available. You will need KotOR Scripting Tool & possibly DeNCS if you plan to use it ( it can be helpful to get examples from other scripts already in the game to see how they handle certain events and to get an idea of the common operators, functions and the syntax ) The script is saved as a .nss file and then compiled into a .ncs file, I use KotOR Scripting Tool but I think KotOR Tools Text Editor can also compile scripts. Remotely Opening A Door Spoiler void main() { object oDoor = GetObjectByTag("yav50_airlock"); ActionOpenDoor(oDoor); } The above script is called by an invisible placeable in front of the computer screens on the Yavin Orbital Station and the script itself is referenced in the OnUsed section of the associated .utp file, it is also getting the relevant door by its tag which is declared in the relevant doors .utd file. That's a very basic script, you can also scroll through the KotOR Scripting Tool to see all the available commands on the right hand side, I will be posting basic scripts in this section and hopefully they might be useful for others. Upon typing the command there is also a description shown in the bottom window of the program. If you have trouble compiling a script, make sure that "nwscript.nss" is located in the games override folder, also check that the tool is set to KotOR 1 or KotOR 2 accordingly, another possible problem is your relevant registry entry which can either be added back in manually, or just run the "swupdate.exe" and it will update the registry entry ( I had this problem as I was using two seperate installs of KotOR 2 for testing ) 10 - [EXAMPLE SCRIPT] - Spawning NPC's on Enter Spoiler Below is an example of an on Enter script spawning four NPC's via their utc file packaged with the .module but not placed in the levels git file. In order to do this you will also need to add a waypoint to the git file to point to where to spawn your NPC. This code can be used to spawn NPC's dependant on a Global Variable, it is also checking if the leader of the group already exists ( I should check if they all exist, but this works for the moment ) Spoiler void main() { if(GetGlobalNumber("SLE_FIREBLOODS") == 1) { if (!GetIsObjectValid(GetObjectByTag("rodian2", 0))) { CreateObject(1, "rodian2", GetLocation(GetObjectByTag("wp_rodian2", 0)), 0); CreateObject(1, "rodian1", GetLocation(GetObjectByTag("wp_rodian1", 0)), 0); CreateObject(1, "rodian3", GetLocation(GetObjectByTag("wp_rodian3", 0)), 0); CreateObject(1, "rodian4", GetLocation(GetObjectByTag("wp_rodian4", 0)), 0); } } } Hopefully this short example helps. 11 - [EXAMPLE SCRIPT] - Making NPC's Hostile! Spoiler The below code changes the above spawned NPC's to being hostile and changes the Global Number for the Variable storing the state of that questline / encounter. Spoiler void main() { object oRodian2 = GetObjectByTag("rodian2", 0); object oRodian1 = GetObjectByTag("rodian1", 0); object oRodian3 = GetObjectByTag("rodian3", 0); object oRodian4 = GetObjectByTag("rodian4", 0); ChangeToStandardFaction(oRodian2, 1); AssignCommand(oRodian2, ActionAttack(GetFirstPC(), 0)); ChangeToStandardFaction(oRodian1, 1); AssignCommand(oRodian1, ActionAttack(GetFirstPC(), 0)); ChangeToStandardFaction(oRodian3, 1); AssignCommand(oRodian3, ActionAttack(GetFirstPC(), 0)); ChangeToStandardFaction(oRodian4, 1); AssignCommand(oRodian4, ActionAttack(GetFirstPC(), 0)); SetAreaUnescapable(1); SetGlobalNumber("SLE_FIREBLOODS", 2); } 12 - [EXAMPLE SCRIPT] - Trigger talking to an NPC! Spoiler The below code requires a trigger to be placed in the level, on entering the trigger this script will fire. It starts a conversation with the lead Rodian from the above examples. Spoiler void main() { if(GetGlobalNumber("SLE_FIREBLOODS") == 1) { object oEntering = GetEnteringObject(); if ((!GetIsPartyLeader(oEntering))) { return; } object oRodian2 = GetObjectByTag("rodian2", 0); AssignCommand(oRodian2, ActionStartConversation(oEntering, "fireblood", 0, 0, 0, "", "", "", "", "", "", 0, 0xFFFFFFFF, 0xFFFFFFFF, 0)); DestroyObject(OBJECT_SELF, 0.0, 0, 0.0, 0); } } 13 - [EXAMPLE SCRIPT] - Make an NPC walk randomly Spoiler This script is assigned to the heartbeat function of the utc file for the NPC. Spoiler void main() { // onHeartbeat AssignCommand(OBJECT_SELF,ActionRandomWalk()); } 14 - [EXAMPLE SCRIPT] - Place a dead NPC Spoiler This script needs to be set in the spawn function for the NPC in the relevant .utc file. Spoiler void main() { effect efDeath = EffectDeath(0, 0, 1); ApplyEffectToObject(2, efDeath, OBJECT_SELF, 0.0); } 15 - [EXAMPLE SCRIPTS] - Starting Conditionals Spoiler This script is an example of a starting conditional that can be used to check what module the player is in, this could be used for companion dialogs to check you are in a specific area in order to engage in a certain dialog option. Spoiler int StartingConditional() { if ( ( GetModuleName() == "end_m01aa") || ( GetModuleName() == "end_m01ab") || ( GetModuleName() == "tar_m11ab")) { return TRUE; } return FALSE; } The example I have provided checks if it is any of the three named modules, if so it returns TRUE to the DLG, if not it returns FALSE. It can be modified to check as many modules as required, I included three as an example to either cut down or expand upon. c_has_feat.nss This checks if the player has a specific feat using the number of the row in the feat.2da file. Spoiler //Thor110 int StartingConditional() { int nParam1 = GetScriptParameter (1); if(GetHasFeat(nParam1,GetFirstPC()) == TRUE ) { return TRUE; } return FALSE; } c_modname_diff.nss This is essentially c_modname_comp.nss, but it returns False instead of True if you are inside the level in question and I fixed a typo in the header. Spoiler /* Returns TRUE if the passed in string parameter is equal to the current module name. Created by: Anthony Davis-OEI Modified (hardly) by: Thor110 */ int StartingConditional() { string modName = GetScriptStringParameter(); string currentMod = GetModuleName(); if(modName == currentMod) return FALSE; return TRUE; } That's it for now, but I will add any more conditional scripts I write here when I write them. 16 - [TUTORIAL] - Companion Vendor Spoiler I recently came up with an idea for a "Droid Companion Vendor" which will sell droids to the player to replace any lost or missed companions throughout the game. Also given that it demonstrates control of the party / companions, I thought I would work this into a tutorial. When I have completed the level / vendor itself, I will come back here to write a tutorial, provide the files and give examples on how this could be used to create a Total Conversion There are a total of 50-55 Droid Types, the plan is to have either all or a select set of the best droids as options. Maybe even spawning the droid next to the Vendor so that you can see them before buying them, or housing them in a store house with the droids you can purchase on display in the area. From here you will be able to purchase a new companion for any slot in the game. for anybody interested here is the code for the conditional script I wrote to check if a specific players companion slot is free. Spoiler #include "k_inc_debug" int StartingConditional() { int nComp = GetScriptParameter( 1 ); if ((IsAvailableCreature(nComp)) == FALSE) return TRUE; else return FALSE; } Here is a slightly different version that checks all companion slots at once. Spoiler #include "k_inc_debug" int StartingConditional() { if ((GetNPCSelectability(9)) == -1) return TRUE; else if ((GetNPCSelectability(8)) == -1) return TRUE; else if ((GetNPCSelectability(7)) == -1) return TRUE; else if ((GetNPCSelectability(6)) == -1) return TRUE; else if ((GetNPCSelectability(5)) == -1) return TRUE; else if ((GetNPCSelectability(4)) == -1) return TRUE; else if ((GetNPCSelectability(3)) == -1) return TRUE; else if ((GetNPCSelectability(2)) == -1) return TRUE; else if ((GetNPCSelectability(1)) == -1) return TRUE; else if ((GetNPCSelectability(0)) == -1) return TRUE; else return FALSE; } here is the code I use to preview the droid, spawning them at the location of the vendor. Spoiler void main() { string nDroid = GetScriptStringParameter(); CreateObject(1, nDroid, GetLocation(GetObjectByTag("blackmarket", 0)), 0); } this code is then used to destroy them, if you don't purchase them. Spoiler void main() { string nDroid = GetScriptStringParameter(); DelayCommand(0.1, DestroyObject(GetObjectByTag(nDroid), 0.0, 1, 0.0)); } and here is the code I used to make them join the party. Spoiler void main() { string nDroid = GetScriptStringParameter(); if ((IsAvailableCreature(9)) == FALSE) { AddAvailableNPCByTemplate(9, nDroid); ShowPartySelectionGUI("k_pend_reset", 9, 0xFFFFFFFF); } else if ((IsAvailableCreature(8)) == FALSE) { AddAvailableNPCByTemplate(8, nDroid); DelayCommand(0.1, ShowPartySelectionGUI("k_pend_reset", 8, 0xFFFFFFFF)); } else if ((IsAvailableCreature(7)) == FALSE) { AddAvailableNPCByTemplate(7, nDroid); DelayCommand(0.1, ShowPartySelectionGUI("k_pend_reset", 7, 0xFFFFFFFF)); } else if ((IsAvailableCreature(6)) == FALSE) { AddAvailableNPCByTemplate(6, nDroid); DelayCommand(0.1, ShowPartySelectionGUI("k_pend_reset", 6, 0xFFFFFFFF)); } else if ((IsAvailableCreature(5)) == FALSE) { AddAvailableNPCByTemplate(5, nDroid); DelayCommand(0.1, ShowPartySelectionGUI("k_pend_reset", 5, 0xFFFFFFFF)); } else if ((IsAvailableCreature(4)) == FALSE) { AddAvailableNPCByTemplate(4, nDroid); DelayCommand(0.1, ShowPartySelectionGUI("k_pend_reset", 4, 0xFFFFFFFF)); } else if ((IsAvailableCreature(3)) == FALSE) { AddAvailableNPCByTemplate(3, nDroid); DelayCommand(0.1, ShowPartySelectionGUI("k_pend_reset", 3, 0xFFFFFFFF)); } else if ((IsAvailableCreature(2)) == FALSE) { AddAvailableNPCByTemplate(2, nDroid); DelayCommand(0.1, ShowPartySelectionGUI("k_pend_reset", 2, 0xFFFFFFFF)); } else if ((IsAvailableCreature(1)) == FALSE) { AddAvailableNPCByTemplate(1, nDroid); DelayCommand(0.1, ShowPartySelectionGUI("k_pend_reset", 1, 0xFFFFFFFF)); } else if ((IsAvailableCreature(0)) == FALSE) { AddAvailableNPCByTemplate(0, nDroid); DelayCommand(0.1, ShowPartySelectionGUI("k_pend_reset", 0, 0xFFFFFFFF)); } } This checks if the companion is available, it then adds the NPC to the party and shows the selection screen making sure that the correct slot is selected. For now this is a very roughly written idea for a tutorial, but I have created the level and when it is finished I will upload it here as a tutorial for people to make use of. I plan to continue to expand upon this idea and fill the level with scripts and examples provided here for people to pull apart and make use of. Fow now there is a bug that means if you buy the same droid twice, they remain there because it tries to destroy the NPC in your Party, instead of the one being previewed, this is a side-effect of the fact I wanted to try and have all 55 available droids in the game as options, but it seems without using a global variable the best way to do this will be to individually select each droid for the list. ( there might still be a better way, I have yet to try again ) 000dia.mod Feel free to learn from this example, the idea itself I plan to use and release as either a stand-alone mod or as a part of the Expanded Galaxy Project. 17 - [TUTORIAL] - Upgradeable Items Spoiler Below is a list of the UpgradeLevel numbers that can be used in .uti files that I found posted by another user on DeadlyStream, I thought I would link through to it and repost it here. In order to make an item upgradeable the below entry needs editing in the associated .uti file to be in line with the numbers below by item type. Robes (Knight & Master) 1 Armored Robes (Zal Shey) 2 Light Armors 2 Medium Armors 3 Heavy Armors 4 Regular (Non-Powered) 1 Vibro Weapons (Powered) 2 Lightsabers (All Types) 3 Blasters (Scope Only) 1 Blasters (Scope,Chamber) 2 Blasters (All Upgrades) 3 Below is a link to the source from which I found this information. Source : https://deadlystream.com/topic/1488-question-on-making-an-item-upgradeable-in-game/ 18 - [ADDITIONAL] - Door Gallery Spoiler A recent request by another modder to make a similar room to my other testing rooms that displayed the available doors in the game. Doors are all numbered appropriately according to their 2da entry in genericdoors.2da to make them easier to find. They also autoclose after being opened if you are far enough away ( same script as jekk jekk tarr tunnels ) Door Gallery.7z 19 - [ADDITIONAL] - Main Menu Details Spoiler In-case anybody ever want's to modify the main menu for a Total Conversion or general mod, you can use the following details to help you do so and the following line of code in a script to change the relevant variable. SetGlobalNumber("GBL_MAIN_SITH_LORD",4); Keep in mind for total conversions and big mods that this variable exists by default in globalcat.2da as do some other variables that you might need to keep. The most recently loaded save determines which menu is shown on the main menu while in-game and I think it might be the auto-save when starting the game up, the number variable "GBL_MAIN_SITH_LORD" sets which is shown. 1 = mainmenu01.mdl = Darth Sion 2 = mainmenu03.mdl = Darth Nihilus 3 = mainmenu04.mdl = Kreia 4 = mainmenu05.mdl = Player The player can also be changed to other appearances in the main menu using disguises or when the player character is set to something else such as when playing as Bao-Dur's Remote on Malachor V. At some point in future I might work on a script that can change the players appearance based on another variable using either disguises or changing the active character under a fade-in / fade-out so that the number of main menus can be almost infinitely expanded or at least to the limit of number values. This could then be spoofed so that any appearance could be shown on the menu, for example it could show the last NPC you spoke to. However I am not sure how efficient this would be under a save/load fade-in/fade-out cover. But it's an interesting thought or idea none-the-less. 20 - [ADDITIONAL] - UI Customization Spoiler Where I have completely recoloured the GUI from green to blue for my port of the first game as well as helped out with a few other GUI changes I felt like I would write a short piece on how to quickly recolour the GUI files. First off you will need to collect all the original files needed or recolour those included in my release. For the TGA files, they can be quickly recoloured in GIMP using Color -> Colorisation and then picking a colour. The following five files differ between the Steam & 4CD versions of the game, so that is worth paying attention to. custpnl_p.gui equip_p.gui mainmenu8x6_p.gui optgraphics_p.gui saveload_p.gui For the Steam version of the game there are also a bunch of extra TGA files. This is the latest version of the K1 GUI for the Steam version of the game. K1 GUI.7z Lot's of details can be changed in the .gui files themselves, but for the most part it is the border, hilight and text colours you want to pay attention to. This can also be made easily viewable using the KotOR GUI Editor : Visual KotOR GUI Editor (KGE) - Modding Tools - Deadly Stream I have had trouble changing some elements of the .gui, as best as I can tell the problem is caused by a mixture if incorrectly applied masks and colour values and that some of the buttons text seems to have hardcoded colours ( though I could be wrong and have just not found where they are stored yet ) It seems as if in some instances the .tga files are supposed to act as masks while the colour values stored in the .gui files are supposed to colour those masks, however in some instances the .tga files themselves have been recoloured making it difficult to determine why the colour applied in the .gui file is wrong. 21 - [ADDITIONAL] - Recolouring Textures Spoiler This sort of thing can pretty much be done at the click of a single button in GIMP. Simply open the .tga file, follow the instructions here, then click File - > Overwrite original file. Colors -> Colorize -> Colorizer -> Color You can also use "Rotate Colors" after selecting an area of the image you are modifying. Colors -> Map -> Rotate Colors These two methods can allow you to quickly recolour an entire image or to manually select part of an image to recolour using the selection tools available. 22 - [ADDITIONAL] - Recolouring the .GUI Files and Textures Spoiler To continue from recolouring textures to recolouring the .gui files I have prepared a basic mask to demonstrate how you can quickly and easily recolour part of an image using a mask. First open the file and make the "Pasted Layer" visible with the eye icon button and then use the Fuzzy Select Tool to select the mask. Next hide the "Pasted Layer" and switch back to the main layer as the active layer by selecting it. From here go to Colors -> Colorize and select your profile or set one up. Now the image will change colour according to your selection. This technique can be used in a lot of different ways for a lot of different tasks. In order to create the mask in the first place I had to slowly select the area I chose to recolour by using the Fuzzy Select Tool with a tolerance that was adequate. The following two files contain the mask and controller image shown in the above images. cntrl_ps3_fre.xcf cntrl_xb360_eng.xcf There are five in total that were added to the game as of the Aspyr patch on Steam. To recolour the rest of the GUI in the game you will need to single out the images used as well as the .gui files that also contain various colour values. The KotOR GUI Editor is a fantastic tool and visual aid for doing this, if you set up a folder with all of the game's gui textures in a folder as well as the .gui files, it makes it quick and easy to view and recolour many of it's pieces. At some point in the future I will try to have a complete .gui recolour pack prepared for users that will make it easier to recolour the entire .gui quickly or you can find a version of the K1 recolour in the following tutorial from this series. #20 - [ADDITIONAL] - UI Customization I advise using that as a base to pick out the original files and recolour those instead of recolouring the K1 recolours to preserve their original looks as best as possible. The following is a list of files that the user interface uses, though I might have missed a few because I pulled this list from an old set of files. Spoiler Aspyr Patch cntrl_ps3_eng cntrl_ps3_fre cntrl_ps3_ger cntrl_ps3_ita cntrl_ps3_spa cntrl_xb360_eng cntrl_xb360_fre cntrl_xb360_ger cntrl_xb360_ita cntrl_xb360_spa cus_gpad_bg cus_gpad_fper cus_gpad_gen cus_gpad_hand cus_gpad_help cus_gpad_map cus_gpad_save cus_gpad_solo cus_gpad_solox cus_gpad_ste cus_gpad_ste3 Regular Game blackdot friendlyarrow lbl_force_neg lbl_force_pos lbl_icn_msg lbl_mibox00 lbl_micombat lbl_micomeff02 lbl_miscroll_f lbl_miscroll_f2 lbl_miscroll_open_f mm_barrow mm_barrow_p uibit_abi_arrow uibit_abi_back uibit_arrowneg_p uibit_arrowneg_x uibit_arrowpos_p uibit_arrowpos_x uibit_arrow_l uibit_arrow_r uibit_brdr_16bct uibit_brdr_16bet uibit_brdr_16gc uibit_brdr_16ge uibit_brdr_16oc uibit_brdr_16oe uibit_brdr_16wc uibit_brdr_16wct uibit_brdr_16we uibit_brdr_16wet uibit_brdr_c3d_p uibit_brdr_c3d_x uibit_brdr_chr1 uibit_brdr_chr1p uibit_brdr_chr2 uibit_brdr_chr2p uibit_brdr_chr3p uibit_brdr_chr4p uibit_brdr_map_p uibit_brdr_map_x uibit_brdr_port uibit_brdr_portp uibit_checkbxoff uibit_checkbxon uibit_eqp_cnfg uibit_eqp_cnfg_p uibit_eqp_itm1 uibit_eqp_itm2 uibit_eqp_itm3 uibit_eqp_shld uibit_eqp_shld_p uibit_fb_arrow uibit_fb_arrow_x uibit_fill_16b uibit_fill_16g uibit_fill_16gd uibit_fill_16o uibit_fill_2wt uibit_no_npc uibit_no_npc_p uibit_slider uibit_slider2 uibit_slider2_p uibit_slider_p uibit_stf_abi3 uibit_uparrowg uibit_uparrowo 23 - [ADDITIONAL] - Different Camera Modes & Dynamically Spawned Grid Of Placeables Spoiler Came across this recently, there is a Top Down Camera Mode. As defined in nwscript.nss int CAMERA_MODE_CHASE_CAMERA = 0; int CAMERA_MODE_TOP_DOWN = 1; int CAMERA_MODE_STIFF_CHASE_CAMERA = 2; Top Down Stiff Chase Camera Chase Camera A script to change this value, this script is meant to be used in a dialog. Spoiler void main() { int cValue = GetScriptParameter( 1 ); SetCameraMode(GetFirstPC(),cValue); } I was thinking about making a Chess mini-game. Having finished the script for generating the grid, I have made sure that the size can be altered with a single value, the value must be an even number otherwise the pattern doesn't work, I might look at fixing that later on for the fun of it. Below is the script I wrote to generate the grid, I have ensured to comment it fairly well to make it easier to understand. I am fairly certain it could be a lot more efficiently written, but this is what I ended up with when writing it from scratch. Spoiler void main() { float gridX = 0.0f;//Grid X co-ordinate float gridY = 0.0f;//Grid Y co-ordinate float gridS = 2.0f;//Grid Size ( Size or spacing of the object used as the tile is stored here) string gridO = "flpnl000";//Grid Object String = Template Res Ref location oLocation;//Object Location Variable int tCount=0;//tCount keeps track of the current tile being spawned int gridSize=8;//Length & Width have to be the same and multiples of 2 int tLength=gridSize;//Equal to gridSize ( this variable get's modified so that the while statement in the for loop repeats int i; for(i = 1; i <= gridSize; i++)//count from 1 to grid size { while(tCount != tLength) { oLocation = Location(Vector(gridX, gridY, -2.6f), 0.0f);//Set up the location co-ordinates. CreateObject(64,gridO,oLocation,FALSE);//Create the object at the specified co-ordinates gridX+=gridS;//adding the grid spacing to the X co-ordinate tCount++;//increase the tCount counter by 1 } tLength+=gridSize;//Adding gridSize to tLength each count so that the while statement repeats on the next count gridX=0.0f;//resetting the X co-ordinate to 0.0f gridY+=gridS;//adding the grid spacing to the Y co-ordinate } tLength=gridSize-1;//Reset tLength and remove one to account for it being used for the nTh value when setting the pattern and to match against tCount IE : 0-7 instead of 0-8 tCount=0;//Reset tCount int test=0;//Used to alternate the pattern each row of the grid for(i = 1; i <= gridSize; i++)//count from 1 to grid size { while(tCount <= tLength) { if(test==0) { test=1; } else { AssignCommand(GetObjectByTag("FloorPanel00", tCount), ActionPlayAnimation(201, 1.0, 0.0)); test=0; } tCount++; } tLength+=gridSize;//Adding tLength to gridSize each count so that the while statement repeats on the next count if(test==0) { test=1; } else { test=0; } } } Above is a 32x32 grid. In-case you are interested in checking out the level, I have included the .mod file here : 000top.mod ( Version 17 ) All source scripts are inside the archive, nothing really works yet but I have added a terminal and some test functions for using while I work out the specific interactions I want to use and the logic I need. 24 - [ADVANCED] - Hard Coded GUI Elements Spoiler For a while now it has bothered me that some of the GUI elements are hardcoded inside the executable and so I decided to take it upon myself to track them down and change them. Cursor Icons I used the application Resource Hacker, to replace the games cursor icons inside the executable for the game : https://github.com/qb40/resource-hacker Executable Addresses and Original Values As far as I can tell I have found all of the relevant values that effect the GUI colours in places that I am aware of. The only values I am uncertain of, is the Red & Green values for the text highlight on the GoG/Amazon/Aspyr versions of the game, it appears that they use the same value for both colours, but if anyone figures this out for certain, please let me know. The other value I haven't found for anything except the Steam version, is the Text Pulsing value, but the likelihood of finding this is pretty slim, it's also not really necessary to change. Initially I sourced values from the KotOR GUI Editor then entered them in HxD a hex editor to achieve the same colour as the rest of the GUI elements. But you can also preview colours here : https://rgbcolorpicker.com/0-1 KEY This is how I have formatted the information presented here, in some cases I have provided more information in brackets. VALUE @ ADDRESS = ORIGINAL BYTES ( EXTRA INFORMATION ) Reference Table I wrote up this table as reference while I was hex editing the executable, changing the values to 0.0 or 1.0 causes problems elsewhere in the game. It's likely that if the value was originally 0.0 or 1.0 for any of the RGB values used that that the values wouldn't have taken up four bytes and would have been compiled differently, though I am not certain. But I know that if I changed the red value for the text to 0.0, the game didn't load in and stayed stuck on a black screen and if I changed the blue value of the text to 1.0, models didn't load in properly starting with the main menu character. It's also possible that glColor3f or glColor4f just doesn't accept 0.0 or 1.0 but I am not certain. It will accept values such as 0.01 to 0.99 but I haven't included anything other than a simple set of references here. 0.1 = CD CC CC 3D 0.2 = CD CC 4C 3E 0.3 = 9A 99 99 3E 0.4 = CD CC CC 3E 0.5 = 00 00 00 3F 0.6 = 9A 99 19 3F 0.7 = 33 33 33 3F 0.8 = CD CC 4C 3F 0.9 = 66 66 66 3F It is now possible to fully re-colour the entire GUI of the game for the following systems. PC ( Amazon, GoG, Steam Aspyr & Disc ) Xbox The following systems cannot be re-coloured yet. PC ( Steam LegacyPC ) Android Mac OSX & iPhone iOS Health Colour Values Having said that, I have not yet tracked down the values for the colour of the health bar on the portraits, I thought it was contained in the .gui files but changing the progress colour value here makes no difference in-game, so it must also be stored in the .exe, changing the force colour in the .gui files does work however. Mac OSX & iPhone iOS I do not have access to a Mac or iPhone currently so I don't know when I will be able to look into finding the values for these systems. Android - Aspyr Patch Having extracted the android .apk file to try and track down these values for the mobile version of the game as well, I haven't actually tried editing any of them yet, but I have listed how many hits there are when searching for any of the values I am looking for. Determining which values to change is likely to take quite a while, unless they are all neatly stacked alongside one another which hasn't been the case for anything except the disc version of the game and the xbox executable. Even if I do successfully find the values that I need to alter, it might not be easy for the average user to install, so it's likely that I won't bother with altering the android .apk file, but it's something I am looking into for the sake of completing the search. Dialog Text ( RGB ) 0.10 @ = CD CC CC 3D ( 273 hits ) 0.69 @ = 33 33 33 3F ( 55 hits ) 0.55 @ = CD CC 0C 3F ( 8 hits ) ( Possibly @ 001CEEB44 ) Button Border ( RGB ) 0.05 @ = CD CC 4C 3D ( 90 hits ) ( effects use item text and item icon highlight as well ) 0.34 @ = 33 33 B3 3E ( 31 hits ) ( effects use item text and item icon highlight as well ) 0.27 @ = 71 3D 8A 3E ( 7 hits ) ( effects use item text, use item button border and item icon highlight as well ) Status Effects ( RGB ) 0.94 @ = 33 33 73 3F ( 20 hits ) 0.66 @ = C3 F5 28 3F ( 11 hits ) 0.30 @ = 9A 99 99 3E ( 122 hits ) ( effects use item button border in inventory and unused item button borders as well ) Text Highlight ( RGB ) Red & Green use the same address as the green value from the dialog text. ( I think but I am still searching ) 0.69 @ = 33 33 33 3F ( 55 hits ) 0.69 @ = 33 33 33 3F ( 55 hits ) 0.60 @ = 9A 99 19 3F ( 51 hits ) Text Highlight Pulsing ( BYTE ) A 3F somewhere amongst 164,432 3F's Amazon - Aspyr Patch The Amazon executable is practically identical to the GOG version. ( see below ) GOG - Aspyr Patch Dialog Text ( RGB ) 0.10 @ 00585084 = CD CC CC 3D 0.69 @ 00584B24 = 33 33 33 3F 0.55 @ 005850C8 = CD CC 0C 3F Button Border ( RGB ) 0.05 @ 005864AC = CD CC 4C 3D ( effects use item text and item icon highlight as well ) 0.34 @ 00589ED8 = 33 33 B3 3E ( effects use item text and item icon highlight as well ) 0.27 @ 00589F08 = 71 3D 8A 3E ( effects use item text, use item button border and item icon highlight as well ) Status Effects ( RGB ) 0.94 @ 00589F04 = 33 33 73 3F 0.66 @ 00589EE8 = C3 F5 28 3F 0.30 @ 00584B28 = 9A 99 99 3E ( effects use item button border in inventory and unused item button borders as well ) Text Highlight ( RGB ) Red & Green use the same address as the green value from the dialog text. ( I think but I am still searching ) 0.69 @ 00584B24 = 33 33 33 3F 0.69 @ 00584B24 = 33 33 33 3F 0.60 @ 00587BD0 = 9A 99 19 3F Text Highlight Pulsing ( BYTE ) A 3F somewhere amongst 7349 3F's Steam LegacyPC Though I have not yet checked for these values in the LegacyPC executable, replacing the cursors resulted in error code : 51 from Steam, which means that those bytes are checked when launching the game to verify the integrity of the executable. Unfortunately that means that it cannot be edited as of yet, I believe the following are the addresses for the dialog text, however this also results in error code : 51 from Steam. Dialog Text ( RGB ) 0.10 @ 00426E34 = CD CC CC 3D 0.69 @ 00426E38 = 33 33 33 3F 0.55 @ 00426E3C = CD CC 0C 3F Steam Aspyr Dialog Text ( RGB ) 0.10 @ 005862FC = CD CC CC 3D 0.69 @ 0058575C = 33 33 33 3F 0.55 @ 0059DBB0 = CD CC 0C 3F Button Border ( RGB ) 0.05 @ 0058C530 = CD CC 4C 3D ( effects use item text and item icon highlight as well ) 0.34 @ 0058AA98 = 33 33 B3 3E ( effects use item text and item icon highlight as well ) 0.27 @ 005A03AC = 71 3D 8A 3E ( effects use item text, use item button border and item icon highlight as well ) Status Effects ( R?B ) 0.94 @ 0059AF70 = 33 33 73 3F 0.66 @ 0059CE40 = C3 F5 28 3F 0.30 @ 00585760 = 9A 99 99 3E ( effects use item button border in inventory and unused item button borders as well ) Text Highlight ( RGB ) Red & Green use the same address as the green value from the dialog text. ( I think but I am still searching ) 0.69 @ 0058575C = 33 33 33 3F 0.69 @ 0058575C = 33 33 33 3F 0.60 @ 0058A978 = 9A 99 19 3F Text Highlight Pulsing ( BYTE ) Found this by accident. 63 @ 005861B7 = 3F The higher the value, the slower the pulsing. The lower the value, the faster the pulsing. Note : this byte is already at it's highest value. Disc Dialog Text ( RGB ) 0.10 @ 00425D34 = CD CC CC 3D 0.69 @ 00425D38 = 33 33 33 3F 0.55 @ 00425D3C = CD CC 0C 3F Button Border ( RGB ) 0.05 @ 00425D1C = CD CC 4C 3D ( effects use item text and item icon highlight as well ) 0.34 @ 00425D20 = 33 33 B3 3E ( effects use item text and item icon highlight as well ) 0.27 @ 00425D24 = 71 3D 8A 3E ( effects use item text, use item button border and item icon highlight as well ) Status Effects ( RGB ) 0.94 @ 00425D40 = 33 33 73 3F 0.66 @ 00425D44 = C3 F5 28 3F 0.30 @ 00425D48 = 9A 99 99 3E ( effects use item button border in inventory and unused item button borders as well ) Text Highlight ( RGB ) 0.69 @ 00425D28 = 33 33 33 3F 0.69 @ 00425D2C = 33 33 33 3F 0.60 @ 00425D30 = 9A 99 19 3F Text Highlight Pulsing ( BYTE ) A 3F somewhere amongst 5897 3F's Xbox Because I plan to get my project on the original Xbox one day, I also tracked down these values inside the .xbe and luckily they all sat neatly alongside each other. Light Green Text ( RGB ) 0.10 @ 003F5B50 = CD CC CC 3D 0.69 @ 003F5B54 = 33 33 33 3F 0.55 @ 003F5B58 = CD CC 0C 3F Dark Green Border ( RGB ) 0.05 @ 003F5B38 = CD CC 4C 3D 0.34 @ 003F5B3C = 33 33 B3 3E 0.27 @ 003F5B40 = 71 3D 8A 3E Status Effects ( RGB ) 0.94 @ 003F5B5C = 33 33 73 3F 0.66 @ 003F5B60 = C3 F5 28 3F 0.30 @ 003F5B64 = 9A 99 99 3E Text Highlight ( RGB ) 0.69 @ 003F5B44 = 33 33 33 3F 0.69 @ 003F5B48 = 33 33 33 3F 0.60 @ 003F5B4C = 9A 99 19 3F Text Highlight Pulsing ( BYTE ) A 3F somewhere amongst 9517 3F's The status effects colour effects items that you haven't viewed yet as well as the currently selected waypoint on the map. While searching for these values, I also found another value that seems to change the border of one of the inventory button icons, not entirely sure why. 0.05 @ 003F68D8 = CD CC 4C 3D How strange. 25 - One Line Dialogs Spoiler One line dialogs are a great way to give your background NPCs a bit of life. Starting Conditional Script Spoiler //Thor110 //TSL One Line Dialog Random Starting Conditional Script int StartingConditional() { int i = GetScriptParameter(1); return Random(i) == 0; } This script can be used to have as many one line dialogs as you want that make use of the Random function to determine which line is spoken. one_liner.dlg This dialog file showcases how to make use of it, ensure to compile it and pass it the correct line number. Like this. 26 - Writing a changes.ini for HoloPatcher Spoiler When writing a changes.ini for HoloPatcher or TSLPatcher, it is best to start with the documentation provided. However in some cases this isn't always as easy to navigate as one would hope. Generally I find it best to use a combination of techniques to generate a changes.ini If it's a small mod, use ChangeEdit to make your changes.ini, which will then be compatible with TSLPatcher and HoloPatcher. HoloPatcher has some unique features that TSLPatcher does not, so it's worth considering what your mod needs and weighing up the pros and cons of them both then deciding on which you want to use. For larger mods, you might need to generate the changes.ini file yourself, ChangeEdit locks up when adding too many files. One work around for this is to add the files in sections and have multiple install folders that point to the override. However I find it easier to simply generate a file list manually using batch scripting or any other programming language, just create a file list, then add "Replace#=" to the beginning of each line, increasing the number by 1 with each line, starting at 0. Feel free to learn from the changes.ini files contained within my project : https://github.com/Thor110/Expanded-Galaxy-Main/tree/main/Expanded Galaxy Main Installer/tslpatchdata As far as I am aware, my project makes use of a lot, perhaps even all of the new features that are made available by HoloPatcher. I also use a namespaces.ini to separate my changes.ini file into tailor made versions for each variation of the game. ( Amazon, GoG, Disc, LegacyPC, Steam & Xbox ) Though in most instances this isn't exactly necessary, in some it is as each version of the game has their own bugs. The two main versions are Aspyr and the 1.0b patch. Amazon, GoG and Steam use the Aspyr Patch. Disc & LegacyPC use the 1.0b Patch. It is possible to have the Disc version without the 1.0b patch, but it is not advisable. In the future I will try to add more detail and examples to this tutorial, but for now it just outlines suggestions for getting started. 27 - [MOBILE] - Android & iOS Modding Spoiler When making mods for the Android & iOS versions of the game, there are a few simple things to remember. Audio files must be properly converted using SithCodec in order for them to work, they cannot be .mp3 ( that I know of ) and Video files haven't been figured out by anyone yet and causes the game to crash. For the sake of testing I set up a room with a single character and dialog that could direct me to playing a movie that already exists in the base game files, or a custom movie that doesn't exist in the base game files. I even used a movie file that was extracted from the .obb file itself and simply renamed it, but it still caused the game to crash. Other than that, everything should work provided the level doesn't have too much in it. The following link contains the files from the override folder contained within the Android OBB files. https://deadlystream.com/files/file/2546-mobile-override-files/ 99 - [REQUESTS] - Submit a tutorial idea! Spoiler If you have ideas for a tutorial feel free to message me and let me know. For a while now I have been considering creating a playground of sorts across a few maps and filling it with a combination of all possible interactions in the game, from animations, to dialog and the various alien responses so that people could play through them, seeing everything in action and use it to better pick out the pieces of code, voiceover, items, placeables, doors or characters that they might need to use in their modification of the game. For now I have set up the Shuttle as an example Starship with access to the galaxy map, but there is a lot more work to be done before I release whatever this is. Very much like the testing rooms I have created that feature all the doors and characters in the game. I will continue to provide examples that I think might be useful to people, these are all for TSL so far. I hope these tutorials and any others I write will help people continue to make mods for KotOR 1 & 2. These tutorials are getting shorter and less detailed, I may or may not go back and re-write them at some point but if anyone struggles with anything feel free to message me and let me know what I haven't covered very well. Feel free to join the Discord for my project if you need help with anything related to KotOR modding and I will do my best to assist. Discord : https://discord.gg/S3YyfTjMV8 Base Game Scripts & How To Use Them Spoiler I am considering working on an index for the base game scripts and how they all function so that people can more easily use them in dialog files without having to constantly look up how they work, what parameters need to be passed along to the script and other such details. For now here is one such example that I discussed with another user recently. a_hitman.nss/.ncs - is used to turn an NPC hostile, if they are already hostile it will turn them insane. Spoiler //:: FileName a_hostile //:: Created By: Kevin Saunders //:: Created On: 07/20/04 //:: //:: Object with Tag = ScriptStringParameter becomes hostile. // Modified: Tony Evans 9/9/04 (Added nInst parameter) // Modified: Tony Evans 9/15/04 (Added OBJECT_SELF default and nSane param) void main() { string sCritter = GetScriptStringParameter(); int nInst = GetScriptParameter(1); int nSane = GetScriptParameter(2); object oTarg; if (sCritter == "") oTarg = OBJECT_SELF; else oTarg = GetObjectByTag(sCritter, nInst); if (!nSane) ChangeToStandardFaction(oTarg,STANDARD_FACTION_HOSTILE_1); else ChangeToStandardFaction(oTarg,STANDARD_FACTION_INSANE); } The above image shows how you would use this in a dialog file, example is from the Entertainment Promenade on Nar Shaddaa. KotOR Modding - Crash Course This 2 hour stream covers the basics of KotOR modding and some of the programs involved, I also regularly stream development of my mod project on Twitch/YouTube. Not all of this covers KotOR modding, there is about 10-20 minutes during the first hour where I get distracted and the second hour of it is mostly me playing games. Spoiler By the basics, I mean the very basics. An overview of the programs and filetypes associated with KotOR as well as the structure of level files. These are the testing rooms but for K1 the room is lacking a texture but I find this just makes it easier to look through the characters. Spoiler K1 Testing Rooms.7z If anything in any of my short tutorials isn't clear or you don't understand for some reason then let me know and I will do what I can to help. ADVANCED TUTORIALS Utilising the following batch scripts and suggestions might take a while to get to grips with for some users but I would always advise doing so, it's very handy to have the ability to quickly generate a file list or compare things in various ways utilising the power of batch scripting. Comparing Level Contents Let's say you have two levels and you need to compare the differences of the contents. Extract everything from the original level to a folder called "level-a" and the modified folder to "level-b" Run the following batch script inside the "level-a" folder. file-list.bat Then delete or move the .bat file and move "file-list.txt" that it just created outside of the folder. You can also use this script to check that all the files exist. check-if-file-exists-from-file-list.bat You will have to move the file-list.txt and this script inside the folder to run the script. Now run this script at the same location as "file-list.txt" to run a file check against the contents of both folders. compare-files-from-file-list.bat Hopefully this might help someone, where I recently had to transfer all of my changes from manual installs to a TSLPatcher changes.ini file, I found this process helped speed the process up a little bit. From here, you should know which files differ and you can then use ChangeEdit.exe that comes with TSLPatcher in order to generate the differences between GFF files. Compiling Scripts If you have made it this far into the tutorial, you should already be familiar with compiling scripts, however for large projects you might need to recompile a lot of scripts at once, so here is a batch script that I used to do it. compile.bat Simply edit the script so that it points to the location of nwnnsscomp.exe for you and then you will be able to put the script into any folder that you need to compile a lot of scripts in and use it to do it all at once. If the scripts don't work for you, you might need to edit them and read them a bit in order to understand them and then to make sure that you have all of the right files in the right places. Thor110 Edited October 20 by Thor110 Updated Merchant Script 8 1 Quote Share this post Link to post Share on other sites