Posted May 17, 2010
This mod makes you a billionaire, upgrades your afterburners, shields and firepower. You’re DarkStar One on steroids. You don’t have to start all over, instructions are on the web. Also a mod maker was released, letting you make your own mods. Stay away from all those trainers, they want more money than the game cost and this Mod will still let you enjoy exploring without you getting killed at every jump gate, you can start kicking ass. This is the real way Dad built DarkStar One for his son, I think Robert did some sabotage before handing it over. Below is the modding guide this is just taste to get you hungury for more
ModdingGuide
Content
Requirements for Darkstar One Modding
Darkstar One Modding Options
Preparations and Sample Mod
Tutorial Mod
"darkstarmod.ini"
Mod Directory
Ini Files
Solar Systems
Planets
Cluster and Solar Systems
Cargo Vessels and Cargo Vessel Definitions
All Other Data
Creating Your Own Texts
Self-made Sounds
Playing of Sound Effects
Creating a Database File
Script System
General Information about Script Functions
Script Structure
The Transition Table
Function Parameters V and Data
Sequence of a Script
Script Events
Script Types
Sample Script
Further Samples
Script Tools
The Script Debugger
Breakpoints
Variables, Stack et al
Script Compiler
Modifying 3D Objects
File Structures
General Procedure
Structure of XML Scene Files
Types of Objects
AVCMesh
Level of Detail and AVCLODSelector
The X File Converter
Blender Compiler
Sample Blender (simple_blender)
Additional Tools
How to Replace the Container Model (Sample)
Circulating Mods
--------------------------------------------------------------------------------
Requirements for Darkstar One Modding
Modding will be supported beginning with Darkstar One Version 1.2. The required update is readily available in the internet at http://www.ascaron.com. The version number is displayed at the bottom of the main menu.
--------------------------------------------------------------------------------
Darkstar One Modding Options
Here they are - the modding tools for your favorite game. Before you start, there are a few things to be considered. Modding is not easy and you will have to be knowledgeable in programming as well as having artistic abilities.
Unfortunately, Darkstar One was not made to support external changes. All modding opportunities were supplementary implementations. Therefore, it may not necessarily be easy to use them.
That said, with the tools and short guides that are being introduced here it will be possible to amend Darkstar One according to your preferences. Create your own missions, add more solar systems or even create your own ship models. It can be done with some effort and enthusiasm.
These are the modding opportunities for DSO:
Missions
You can write missions, which will be either offered at the terminal or triggered in space under certain conditions as soon as you enter a solar system. Created missions may contain new texts, new voice-over files or new sounds.
Ini-files
All available configuration files (*.ini) can be modified. This will have an impact on the
structure of solar systems
trade system
parameters for shields, weapons etc.
Graphics
Available 3D models (objects) and textures may be exchanged or amended. Note: You will not be able to add new objects. Currently, the object formats are only supported in the X-format. A converter for the format used with Darkstar will be available. Read more in the chapter "Amending 3D Objects".
--------------------------------------------------------------------------------
Preparations and Sample Mod
All modifications must observe a certain directory structure, which will be explained here. Version 1.2 of Darkstar One will create a "Customization" subfolder in the "My Documents\Ascaron Entertainment\Darkstar One\" folder. Every mod must be stored in separate folders within this folder. You can freely choose the name for these subfolders. Once the mod has been correctly installed, you will be able to select it from the main menu of Darkstar One from the "Mods" menu. The name of the mod will be determined in the file "darkstarmod.ini" which must exist for each mod (see below).
--------------------------------------------------------------------------------
Tutorial Mod
The mod tools will install a sample modification in the folder "Tutorial" in "My Documents\Ascaron Entertainment\Darkstar One\Customization".
"Tutorial" contains a full modification including all files (source codes, string tables) that were used to create it. All samples and explanations in this modding guide are referring to contents of the modding tutorial. Therefore, the mod "Tutorial" will be a good reference for your own mods.
--------------------------------------------------------------------------------
"darkstarmod.ini"
Each mod contains a "darkstarmod.ini" which is structured like this:
[darkstarmod]
mod_name = (name of the mod)
mod_desc = (short, one-line description)
The name and the description will be displayed in the selection menu for modifications.
--------------------------------------------------------------------------------
Mod Directory
This is the structure of a mod directory:
/inifiles
All .ini files should be available in this folder (simply extract from "ds_3dadd.cpr" if you want to make any changes).
/scripts
All .lua files, which you created or compiled will be found in here
/sound
All sound files (preferably mp3) belong in here.
/strings
The resource file "user_strings.res" for new texts is found in this directory. Furthermore, a zip file with the name "user_data.zip" is available for 3D data. The structure of this file is explained in the chapter "3D". Missing directories or files will prompt the game to use the default data. The prime example are the *.ini files. If they are missing in the mod, the original Darkstar One files will be loaded. The sample modification will explain all opportunities for changing the game.
In order to guarantee the compatibility of the save games, each modification will save its own save games. If you save a game while mod "A" is active, this save game will only be available for modification "A". Only compatible save games will be displayed for each mod.
--------------------------------------------------------------------------------
".Ini" Files
The entire game logic (solar systems, trade logic) receives its initial data from text files. Upon starting the program, these files are read and a new binary file will be created if necessary. Many files are dependant on each other (amount of solar systems in clusters etc.). These dependencies will be mentioned if and when they exist.
In order to adapt a modification to the logic, all required files have to be copied into the "inifiles" directory of the resprective mod. The sources are available in the archive "ds_3dadd.cpr". Rename to "ds_3dadd.zip", unpack and copy the files.
A short description of the files and the part of the logic they contain will follow.
Creating a ".Bin" file
All ".ini" files are loaded during the start-up process and stored in a binary file ("ini_file.bin"). If you change the configuration files, the binary file must be deleted in order to be recreated during the next start of the program. When you restart the program again, only this binary file will be loaded in order to optimize speed.
Note
Please be sure to copy all files. One or more missing files will result in a corrupted ".Bin" file.
--------------------------------------------------------------------------------
Solar Systems
Darkstar One may contain a maximum number of 403 solar systems. They are defined in the file "StarSystem.ini" and they are numbered from 0 to 402. Each system consists of these attributes:
Artefakt: Does an artifact exist in this system?
Bedroht: Is this system occupied by pirates yes / no
B�rger: Number of inhabitants in Billion
Cluster: Number of the cluster where the system is situated
Energylevel: The higher the level, the more particles drift in space
Faction: Which faction does this system belong to (0=Galactic Union, 1=Pirate system, 2=neutral)?
FunctionX1/2/3 and Function_Y: Define parameters for trading simulation
Nachbarregel: Defines the systems that have to be entered in order to make this system available
Piratengang: Index of pirate gang (65535 if no pirate gang is present)
Planeten: Number of planets in the system (? "Planets.ini")
PosX, PosY: Position on the navigation map
Prodution1-5: Which goods are produced in this system
Produktionsfaktor: Amount of produced goods. Factor 0 to 1
Regierung: Form of government (0=Democracy, 1=Dictatorship, 2=Federation, 3=Anarchy, 4=Empire, 5=Monarchy)
Sichtbarkeitstyp: Under which conditions does this system become available (0=starting the game, 2=enter neighboring system, 4=story related, 6=never, 7=hidden system) ?
StarLightID: The system lighting defines the security of the system that results from the form of government (anarchies are unsafe and therefore, they have a reddish light setting. Democracies are safe and have a more friendly and lighter setting) and refers to the "StarLight.ini" (where the light settings for the systems are defined)
UniqueItem: >0, if a unique item is hidden within the system
--------------------------------------------------------------------------------
Planets
Each system consists of a fixed number of objects such as a sun, one or more planets, meteorite fields, stations and one jump gate. The parameters in the "Planets.ini" are self-explanatory.
--------------------------------------------------------------------------------
Cluster and Solar Systems
Each clusters features a configuration file (cluster.ini) and consists of three definitions:
amount of cargo vessels
definition of the cargo vessels
production values of the goods "contained" within the cluster
--------------------------------------------------------------------------------
Cargo Vessels and Cargo Vessel Definitions
Structure of a cargo vessel definition:
starting system
target system
type of cargo vessel
amount of goods carried
types of goods and their respective quantities
This data defines all cargo vessels within a cluster. We recommend not changing this data manually. The initial distribution is handled automatically by Darkstar One when the game is started.
The amount of goods available in each system within the cluster is defined separately from the cargo vessel definitions. The quantity is defined for each of the 24 available types of goods within the game.
--------------------------------------------------------------------------------
All Other Data
The files all contain commentary and they are divided into these areas:•Spielerschiff: Afterburners.ini, Engines.ini, Equipment.ini, Thrusters.ini, Upgrades.ini, StarFlight.ini
Spielerschiff (everything relating to the player’s ship): Engines.ini, Equipment.ini, Thrusters.ini, Upgrades.ini, StarFlight.ini
Handel (trading): Goods.ini, Prices.ini
Objekte (objects): Meteorids.ini, TradeStation.ini, StarShip.ini
Bewegung general movement): StarFlight.ini
Simulation: Time.ini, HitPoint.ini
Effekte (effects): Projectiles.ini, Explosion.ini, ExplosionDef.ini
--------------------------------------------------------------------------------
Creating Your Own Texts
In order to create your own scripts and missions you will have to create new texts. Darkstar One is using a special resource format in order to simplify the work on localizations. Internally, Darkstar uses so-called StringIDs; therefore, you will have to create your own IDs. Ideally, you should use Microsoft Excel in order to create them. The StringID is entered into the first column, the actual text in the next column. The StringID will identify the text in the game.
The Excel file must be saved as an XML sheet. The file below is also available as a sample file in the tutorial mod.
In order to use the texts in the game, the Excel file must be converted. A program called "Xml2ResConverter.exe" is available in the "Tools" folder. You will have to specify three files: the original global.res file of Darkstar One (in order to avoid conflicts with existing StringIDs), the XML file and the target file. The target file ("user_strings.res") must be copied into the mod’s directory. The Excel file must be closed during the conversion.
That is all you have to do. The texts will now be available for all missions via their StringIDs. In order to have a text appear in a certain place of the script, you will have to specify the StringID, i.e. NGUI.ShowSubtitle ("ID_MY_FIRST_STRING_ID").
Image: The list of strings in Excel. Left is the StringID, right is the corresponding text.
--------------------------------------------------------------------------------
Self-made Sounds
You will be able to embed your own sound files for mission scripts into your modification. Similar to the texts, these files are not addressed by their file names but rather by an ID. However, these IDs are not manually assigned; instead, they are created from the structure of the directories and the file names. Initially, three subfolders for the main groups ("(stream)", "(sfx2d)" and "(sfx3d)") should be created in the modification’s "Sound" folder. The names of the subfolders must be in brackets.
Stream
Files in this main group are played as a stream. Music files should be saved here.
2d
Simple stereo effects belong into this folder
3d
Folder for three-dimensional effects
New subgroups may be created for every main group by creating new directories called 'grp_groupname'.
--------------------------------------------------------------------------------
Playing of Sound Effects
Once a sound database has been created with the "KlangKollektor" (german for "sound collector") tool, all effects and music are ready to be used in scripts. The script programmer can access the IDs of the effects by using the created groups. You can play them by using "NSound.PlayUserSound". The parameters are the groups (not the main groups) without the prefix "grp_". If the sound effect is stored in "(sfx2d)/grp_maingroup/grp_subgroup/sound.mp3" you can address a specific sound:
NSound.PlayUserSound( "maingroup.subgroup.sound" )
Or you can address a random sound from a group:
NSound.PlayUserSound( "maingroup.subgroup" )
If you do not specify a sound, a random sound from that group will be played.
--------------------------------------------------------------------------------
Creating a Database File
With the "KlangKollektor" Tool, you will be able to create a user_sounds.xml file from the directory structure and the .asset files. This file will be loaded when the game is started; it will register all files with their specific names and make them available for the script programmer.
Create file:
KlangKollektor.exe -o user_sounds.xml sound
--------------------------------------------------------------------------------
Script System
Darkstar One uses a lua-based script system (http://www.lua.org) with slight modifications for missions.
All scripts (missions as well as story missions) use a condition-based system. Instead of implementing separate functions for each event, so-called transitions are defined which become active according to the current step of the mission. Thus, scripts for the missions can be written in chronological order, which makes understanding a script much easier.
Essential for writing scripts is a sound knowledge of lua, especially the tables. General programming knowledge will also be useful.
We will only address the basics of the system here; an extensive documentation of the script commands can be found in the "html" folder of the documentation.
--------------------------------------------------------------------------------
General Information about Script Functions
All functions of the script system are divided into logical subgroups, each with their own name spaces. These are the groups: NScript General script functions
NMission Missions specific functions
NComm Dialogue system, radio messages etc.
NGUI Graphical interface (show textes etc. )
NPlayer Everything concerning the player and his ship
NCamera Cameras for ingame cutscenes
NStarSystem Functions concerning wingmen (space ship groups)
NWing Space ships in general
NShip Raumschiffe allgemein
NObject Objects in general
NWaypoint Waypoint system
All groups contain creational functions for the respective groups and a variety of additional functions.
Each namespace that is used within a script must be imported beforehand (see sample script). All functions follow a consistent scheme: Each function is assigned to exactly one parameter, the parameter table. The return value is also defined in one table, the return value table.
Both tables contain named fields, which have to be filled and submitted. Functions that do not have any parameters will be assigned with an empty table. There are no functions without argument.
In order to analyze the return value table you must also look at the named fields, otherwise you will not be able to retrieve the data.
V.Container = NContainer.Create( { Type=CONTAINER_SHIP, Ship=V.Ship} ).Container
Now would be a good time to familiarize yourself with the commands of the respective groups :-)
--------------------------------------------------------------------------------
Script Structure
Basically, a script consists of the command "NScript.Register". The rest of the script is contained as parameter(s).
NScript.Register( {
Name = < Missionname >,
Group = < GroupId >,
Type = < Missiontyp >,
Transistions = < Transitiontable > } )
--------------------------------------------------------------------------------
The Transition Table
The transition table is a lua table with an arbitrary number of transitions. Each transition is a table with four elements.
{ < MinStep >, < MaxStep >, < Event >, < Function > }
MinStep and MaxStep are float values and the condition of the mission has to be between (including) these values in order for the function to run properly. Event is a string with the name of the event. If a faulty event name is used, an evaluation will be triggered. If all three conditions are true, the code will be activated in function using parameter V and Data. A complete transition would look like this:
{ nil, nil, "MissionStart", function( V, Data )
NGUI.ShowInfoText( Text="IDM_NEW_LOGENTRY" )
NStarSystem.SetAsMissionTarget( {System=2,Set=1 })
V.Step=1
end },
Here, the float values for MinStep and MaxStep are defined as "nil". Nil stands for an undefined value and it will result in always executing this transition when the event MissionStart is triggered. Also, V.Step is set to 1 at the end in order to define the condition of the mission. When a transition is supposed to change the following status, V.Step must be assigned. V.Step should be started with a float value >0, as C++ does not differentiate between nil and 0. In order to stick with the concept, you should start with V.Step = 1. As and may differ, transitions, which can be applied to a number of conditions, can be written. This is especially interesting for shortcuts within the mission. If 3 to 14 events can happen in the conditions but can be avoided by leaving the solar system, you should use this transition:
{ 3.0, 14.0, "LeaveSystem", function( V, Data )
V.Step = 15
end },
Each event will evaluate all possible defined transitions. The sequence is not defined. You should bear that in mind.
--------------------------------------------------------------------------------
Function Parameters V and Data
Each script, or rather each mission contains a "script global" table V, which will be submitted to each function as a parameter. This parameter enables the forwarding of conditions, variables etc between transitions.
The variable "V.Step" is very important here, as it contains the current progress of the mission (which will activate the relevant transitions). This table contains an arbitrary number of variables, depending on how the author of the scripts intends to use them.
The "Date" table, however, depends on the respective events, which are triggered. It contains every variable that is connected to the event. The parameters are available in the documentation of the events.
--------------------------------------------------------------------------------
Sequence of a Script
All scripts follow a consistent scheme:
Load
Before starting a script, it will be run completely once, i.e. the "NScript.Register" command will be executed; however, the functions within the defined transitions will not be executed.
Initialize
In order to determine, whether a script should be executed, an "Init" event is triggered, which requires an answer of either 0 or 1, where 1 = "yes, start the script".
Start
When the script is started, the "init" will be executed again. If the return value is not 1, an error will occur. Afterwards, the event "create" will be triggered. The condition is undefined at this time. Therefore, "create" has to be a (nil,nil) transition. At this stage, the V table can be written for the first time and the step can be set (it is important to do this ? V.Step = 1). The next event will be "MissionStart", which will be executed straight after "Create". Afterwards, random events may be assigned by the program.
End
The script will end as soon as the condition of the mission is set to MSTATE_ACHIEVED or MSTATE_FAILED. This condition is separate from the entry in V.Step and is set by the function "Event.SetState()". Once these conditions have been set, the appropriate event "Achieved" or "Failed" will be triggered.
--------------------------------------------------------------------------------
Skript Events
An extensive list of all used events is available in the html documentation. So go, take a look :)
--------------------------------------------------------------------------------
Script Types
There are different types of missions. Two special mission types are available for self-made scripts, which the game will give preference to: MTYPE_USER_TERMINAL and MTYPE_USER_SPACE. Terminal missions are offered on terminals within the stations. When such a mission can be created (i.e. "init" returns a 1) it will take precedence and be displayed. The same applies to space missions, which are triggered by entering a new system via the hyper jump gate. When several, equal missions are available, the "MTYPE_USER" missions will be preferred.
--------------------------------------------------------------------------------
Sample Script
We would like to demonstrate how to create a mission with a sample script (terminal mission). Before programming a script, you should know exactly what you want your mission to do/be. Once you have determined this concept, you can work the script step by step and change it into lua code.
The Idea
For our first script, we will create a simple rescue mission, where a container must be collected and returned to the station.
Note
The described script can be found in the tutorial under /scripts/skript_tut001.lua
The sequence of the script should be:
The missions should only be offered in the start system
When the mission has been accepted at the terminal, the container should be created near the station when the station is left. One string should cover the content ("Darkstar One Dokumentation")
When the container has been collected, the task should be adapted. The player will receive a message to return to the station.
If the player returns the container, the mission will be accomplished
If the player lands on the station without the container, nothing happens
If the player leaves the system, the mission will fail
If the player destroys the container, the mission will fail
As you can see, it is important to cover all possible actions of the player in order to create a consistent, believable mission. Especially those actions leading to the failure of a mission must be carefully considered.
The Script
The lua template from the TutorialMod "template.luatemplate") is the basis for our sample. Copy it and rename to .lua. Everything marked with <$...$> must be filled in by the script author.
The "Import" part of the template imports all important namespaces and additional functions. Always keep this line just to be on the safe side.
Here is the actual mission header, the "NScript.Register" command:
NScript.Register( {
--name
Name = <$ INSERT SCRIPT NAME HERE $>,
--group
Group = 0,
--type
Type = <$ INSERT SCRIPT TYPE HERE $>,
--transition table
Transitions = {
All you have to do here is to insert the name of the script (a string) as well as the type of script. A list of all possible script types is available in the html documentation.
Name = "SKRIPT_TUT_001",
--group
Group = 0,
--type
Type = MTYPE_USER_TERMINAL,
The transitions follow immediately after. Essential transitions are already implemented in the template and all you have to do is fill them with mission specific details. Each mission should yield a reward for the player. Therefore, we enter a transition variable in the "V" table of "MissionStart".
{ --Mission starts
nil, nil, "MissionStart", function( V, Data )
--the necessary initializations should happen here
V.Reward = 9876; -- credits for the player
--the actual mission starts here
V.Step = 1
end },
The step of the mission is set to 1 here, which means that the mission will start now. You should use "V.Reward" for rewards since this variable is already used in the template.
The preliminaries are done - you can now implement the actual mission steps. We will take you through our basic concept step by step.
The first step ("The mission may only be offered in the start system") must be entered into the "Init" transition. This function will be queried every time a mission is offered or created. "Init" must return true or false depending on whether the mission may be started or not.
local start_system = MissionLib.GetStarSystemId()
if start_system == 8 then
return{ Ready = true }
end
return{ Ready = false }
The "MissionLib" function "GetStarSystemID()" supplies the ID of the solar system where the player is currently located. If he is in system eight (the start system of the game), the mission may start. Otherwise, it will not start. If true is returned, the "Create" transition will be initiated. Depending on the mission type, "MissionStart" will be initiated; in this case, it will be initiated when the player accepts the mission at the terminal.
We will also adjust the necessary steps in this "MissionStart" transition.
NStarSystem.SetAsMissionTarget( { System = MissionLib.GetStarSystemId(), Set = true } )
MissionLib.LogUpdateStory()
V.Step = 1
The current solar system will be marked as the active mission system on the navigation map. We will also let the player know that his logbook has changed (this "MissionLib" is readily available during installation and contains a variety of helpful additional functions.) Additionally, Step will be set to 1. This will start the actual mission. Now, it will be useful to have the source code for the tutorial mission handy.
The first event that we want to look at is "Station". If someone enters or leaves a station, this event will be triggered. When this happens, we will create a container via NContainer.Create, that will be filled with mission specific goods. In the end, we will save the handle of the container in the mission global table V and will advance the step of the mission further (V.Step=2).
This will activate additional transitions, which will "watch" over the player’s activities. Three of these events will be observed: "System" in case the player leaves the system, "Container" in case the container is destroyed and "Grab" for collecting the container. If the container is destroyed or if the player leaves the system too early, the state of the mission will be set to MSTATE_FAILED. The mission will be finished (and it will trigger the appropriate "Failed" event).
If the player collects the container (transition "Grab"), the mission will be set to step 3 and another transition will become active ("Station"). This new transition is the reaction to entering the station. If the player carries the container, it will set the state to MSTATE_ACHIEVED.
--------------------------------------------------------------------------------
Further Samples
There are another two mission scripts in the sample mod, which explain the creation of opponents as well as the dialogue system.
skript_tut002.lua
skript_tut003.lua
skript_tut004.lua
--------------------------------------------------------------------------------
Skript Tools
Writing scripts is great, but sooner or later you will have to debug them. A very efficient LUA-Debugger is available via HTML. As long as the game is running, the frontend is available at "localhost:54321" via a webbrowser.
--------------------------------------------------------------------------------
The Script Debugger
Once you have loaded the page, follow the "Missions" link. You will find a table listing all currently active missions. Further down is a list of all other missions that have been loaded.
Image: Table of the currently active missions. The name of the script, its current status and a link to the source of the script are displayed.
--------------------------------------------------------------------------------
Breakpoints
In order to set breakpoints you will have to display the source code. Click on the link "View script source" or go to the page "localhost:54321/Framework/ViewScript".
Image: Script Code in the LUA Debugger. Clicking on line number will set (or remove) a breakpoint at the next executable line. Breakpoints are marked by the prefix '@'.
--------------------------------------------------------------------------------
Variables, Stack et al
When a breakpoint is reached and the game stops, the display will change. At the top, debug data will appear, at the bottom left the source is displayed and on the right the current variables (local, global, stack etc.) will appear. It might be necessary to reload the site in order to refresh it.
If you have worked with a debugger before, it should not take long to familiarize yourself with this one. Commands and input that will be executed via the "Eval" button must be entered in the window at the top left. "Step" will jump into the currently displayed function (do not forget "next" to switch to source if possible).
Image: Script display when a breakpoint has been reached
--------------------------------------------------------------------------------
Script Compiler
When all scripts are finished and tested, a file that will contain all scripts in byte code can be created with the script compiler ("Tools" directory).
scriptcompiler.exe -o user_scripts.bin *.lua
In order to be able to compile the LUA files it is essential that these files from the Darkstar directory are available:
BattleLib.Lua
BattleLibEx.lua
CameraLib.lua
MissionLib.lua
Afterwards, they can be deleted from the mod directory. If you do not want to compile your LUA files, this step is not necessary. The created "user_scripts.bin" file must be located in the "scripts" folder; otherwise, Darkstar One will be unable to access it.
Note
Once the scripts have been compiled, they will be inaccessible. Therefore, it will not be possible to add more breakpoints.
--------------------------------------------------------------------------------
Modifying 3D Objects
Once writing scripts for new missions and changing the galaxy has become boring, you will be able to exchange 3D objects or implement new textures. Unfortunately, we are not able to release the entire tool chain due to legal restrictions; therefore, creating and implementing modified objects is slightly more complex, but not impossible to do ;).
--------------------------------------------------------------------------------
File Structures
All files necessary for three-dimensional visuals are stored in these three archives:
ds_3dgen.cpr
ds_3dobj.cpr
ds_3dtex.cpr If you want to change 3D files, you should unpack these archives first.
Note
Cpr archives can be packed or unpacked with any "zip" decompression program if you replace the suffix ".cpr" with ".zip".
Do NOT unpack the archives into the Darkstar One folder!
Once you have unpacked the archives you will see a "3DView" folder, which contains most of the important data.
--------------------------------------------------------------------------------
General Procedure
In order to change a model or a texture, you should isolate the original data and copy it into the directory of the future mod. However, make sure that you observe the directory structure (originating from "3DView"). As some of the models have fixed objects that the program will need to address, we recommend changing the "3do" references and possibly the shader within the XML files only. Completely replacing an XML file is extremely complex and time-consuming.
The next step is creating a "3do" file with the converter and writing appropriate blenders.
--------------------------------------------------------------------------------
Structure of XML Scene Files
A game model consists of an XML scene that refers to all applied resources. These resources are the actual model (in "3do" format), the used shaders (blender) as well as the applied textures. Originating from the root node, all objects are structured hierarchically (scene graph). Generally, an object is compiled of several separate objects, which are assigned to certain "tasks". The best thing to do is to load an object (i.e. "Freighter_A_0.xml") in the "TakeALookXP" tool (see paragraph 7.7). You will be able to go through the hierarchy of a scene and view the respective ‘sub’objects. That should make matters easier to understand.
--------------------------------------------------------------------------------
Types of Objects
AVCWorldRoot: base node
AVCTransformationNode: basic transformation node
AVCMesh: basic mesh in ".3do" format
AVCShieldMesh: mesh for an object’s shield
AVCGlowObject: mesh for the "glowing" areas of an object
AVCDistortionObject: mesh for the distortion effect (i.e. heat haze) of an object
AVCLODSelector: level-of-detail step definition
--------------------------------------------------------------------------------
AVCMesh
This is the most important type of object: it defines the object that will be displayed. It contains „EffectContainer". The number of these containers corresponds with the number of materials in the „3do" object that is being used. This is important when entering a new object. A blender (shader) is assigned to each effect container (Path="..."). Material attributes as well as further parameters for the blender are entered as child nodes of the respective containers.
An „EffectContainer" looks as follows:
<EffectContainer path="test/test.bsd9">
<Material>
+0.000000 +0.261784 +0.344000 +0.000000
+0.471080 +0.471080 +0.471080 +0.000000
+0.000000 +0.761000 +1.000000 +0.000000
+0.025000 +0.050000 +0.100000 +0.000000
+100.000000
</Material>
<Parameters>
<Float semantic="..." value="+1.00000" />
...
</Parameters>
</EffectContainer>
The material consists of diffuse, ambient, specular and emissive color as well as shininess. All colors are specified in RGBA. The material attributes as well as the parameters will be available for the specified blender by semantics. Further details are available under "Blender Compiler".
Important: If several LOD levels exist in "3do" object, the number of effect containers is equal to the sum of all materials in the LOD levels.
--------------------------------------------------------------------------------
Level of Detail and AVCLODSelector
Darkstar One supports several LOD levels per object with the "3do" format. Separate from the number of LOD levels in the object file, an object of the type "AVCLODSelector" is required in the XML scene. This object will define the distance when the levels are switched and which parts of the objects may be switched off during the scene.
<Object Type=".?AVCLODSelector@@" ... LODNumber="2">
LODNumber does not define the number of levels within the mesh; instead, it defines the number of "LODDesc" (LOD Descriptions), which are following. This description will define which parts of the objects are changing in comparison to the previous scene. The partial objects are addressed by their names, according to the hierarchy of the scene.
<LODDesc Clients="2">
lod_0|object_a 1 +0.00000
lod_0|object_b 1 +0.00000
</LODDesc>
<LODDesc Distance="+25.000000" Clients="2">
lod_0|object_a 0 +0.000000
lod_0|object_b 1 +0.750000
</LODDesc>
"Clients" defines the number of objects that will be changed. "Distance" defines the distance to the viewer that has to be reached in order to activate the LOD level. The path in the scene to the affected object defines a client. 0=switch object off, 1=switch object on. The latter value is set to a value between zero and one. It will select the LOD level within the "3do" file. Zero is the first level, one the last. A value greater than ‘one’ may be entered, but only if the object is switched off.
--------------------------------------------------------------------------------
The X File Converter
A rudimentary tool is available to convert models from the "x" format to .3do. Starting the tool is easy:
3do_convert <lod1.x> <lod2.x> ... <output.3do>
Simply enter the source files. The last parameter defines the return file. That is all. Please note that the entered "x" files should correspond with the various level-of-detail meshes (unless you want to convert a spaceship into a container when the object reaches a certain distance in game). One level will be sufficient for an initial test.
3do_convert <input.x> <output.3do>
The converter creates a simple preview ("output.xml") which can be seen with the "TakeALookXP"-Tool. All LODs are included in the object.
--------------------------------------------------------------------------------
Blender Compiler
You will be able to create your own shaders for self-made models with the help of the blender compiler. Sound knowledge of programming shaders is essential; otherwise, this will not be fun at all. As a simple example, we will use a blender that will only transform the vertices and will assign a color. (This color may be defined in the XML scene file.)
--------------------------------------------------------------------------------
Sample Blender (simple_blender)
In order to create a blender you will need two files: the shader ("fx" format) and a corresponding XML file. Initially, it is important to define the used Techniques in the XML file. You may enter several of these techniques; the first functional one will be used (from left to right).
<?xml version="1.0" encoding="utf-8" ?>
<Blender>
<Effect include="simple_blender.fx">
</Effect>
<Variables/>
<EffectAnimators totaltime="2.0">
<EffectAnimator name="DOIT" duration="2.0" techniques="simple">
<Trigger animator="DOIT" time="2.0" />
<Init />
<Main />
</EffectAnimator>
</EffectAnimators>
</Blender>
This template can be applied; however, you should amend the "fx" file ;)
There is a multitude of values in an effect that the engine will initialize. Among those are certain matrixes. The tutorialmod contains an example in "3DView/my_objects/simple_blender.fx" as well as "3DView/my_objects/simple_blender.xml".
Initialized Values
The values initialized by the engine are listed with their semantics:
World: Worldmatrix
WorldView: Worldmatrix*Viewmatrix
WorldViewProjection: World*View*Projection
WorldInverseTransposed: Wordmatrix invertiert und transponiert
View: ViewMatrix
ViewInverse: Inverses der Viewmatrix
ViewProjection: View*Projection
Projection: Projectionmatrix The above named matrixes can be used in the shader Further values can be entered into the shader from the scene description using "<Material>" or "<Parameters>".
Material
A material description consists of ambient, diffuse, specular and emissive color. These values are to be used in the shader with these semantics:
Ambient
Diffuse
Specular
Emission
Parameters
Semantics are assigned to all parameters in order to enable the shader to address them. There are several types of semantics for parameters:
Float: simple float-Value
Vector: float4
Lighting
Objects in Darkstar One can be illuminated by a maximum of four light sources. Shader that want to use lighting will receive the number of light sources from the engine and will relate them to the shader via the "uniform" parameter. You should view the blender sample that is supplied by the "Blendercompiler". In there, an array of shaders is created with the appropriate parameters for the number of active light sources.
--------------------------------------------------------------------------------
Additional Tools
Once you have created a new object, you can look at it by using "TakeALookXP". In order to familiarize yourself with the tool, you might want to look at some objects from the unzipped archives.
Left: hierarchic structure of the XML scene file, below the camera settings. Right the 3D view as well as the returned debug data.
The converter tool will also create an "output.xml" file, where you will be able to view your converted objects.
--------------------------------------------------------------------------------
How to Replace the Container Model (Sample)
As a simple example, we will use a cargo container and replace it with another simple model.
First, we will create the required folder structure in the mod directory. We create a "3DView" directory and copy the "Container.xml" as well as the "Contain_low.xml" from the archive "ds_3dgen.cpr". In this folder we create a subfolder "my_objects" for our own data. Next, we will have to convert our object and create an appropriate blender. We will copy these files into the "my_objects" folder. Once that is done, we will search the files "Container.xml" and "Container_low.mal" for the node that we need to change. Typically, this node is a "?AVCMESH@@" type. Be careful to replace the effect containers appropriately for your own blender and mesh. The paths also have to be correct (here: "my_objects/.3do" etc.). That is all. The "3DView" folder that we created must now be packed into a zipfile called "user_data.zip" and it must be located in the root of the mod directory.
Files with the suffix *_low.xml
All 3d objects exist as XML file as well as "*_low.xml" file. The files with the suffix "_low" are required for shader 1.1 graphics cards and they use adapted blenders. Further adjustments will be needed for older graphics cards.
--------------------------------------------------------------------------------
Circulating Mods
Once a mod is finished and tested, you may distribute it freely. However, you do not need to submit all files (unless other users should further advance them). These files may be omitted when distributing a mod:
".lua"-files, once a .bin file has been compiled from them (and they have thereby been error-checked)
All graphics files, once a user_data.zip has been created
All ".ini" files, once the ini_files.bin has been created
ModdingGuide
Content
Requirements for Darkstar One Modding
Darkstar One Modding Options
Preparations and Sample Mod
Tutorial Mod
"darkstarmod.ini"
Mod Directory
Ini Files
Solar Systems
Planets
Cluster and Solar Systems
Cargo Vessels and Cargo Vessel Definitions
All Other Data
Creating Your Own Texts
Self-made Sounds
Playing of Sound Effects
Creating a Database File
Script System
General Information about Script Functions
Script Structure
The Transition Table
Function Parameters V and Data
Sequence of a Script
Script Events
Script Types
Sample Script
Further Samples
Script Tools
The Script Debugger
Breakpoints
Variables, Stack et al
Script Compiler
Modifying 3D Objects
File Structures
General Procedure
Structure of XML Scene Files
Types of Objects
AVCMesh
Level of Detail and AVCLODSelector
The X File Converter
Blender Compiler
Sample Blender (simple_blender)
Additional Tools
How to Replace the Container Model (Sample)
Circulating Mods
--------------------------------------------------------------------------------
Requirements for Darkstar One Modding
Modding will be supported beginning with Darkstar One Version 1.2. The required update is readily available in the internet at http://www.ascaron.com. The version number is displayed at the bottom of the main menu.
--------------------------------------------------------------------------------
Darkstar One Modding Options
Here they are - the modding tools for your favorite game. Before you start, there are a few things to be considered. Modding is not easy and you will have to be knowledgeable in programming as well as having artistic abilities.
Unfortunately, Darkstar One was not made to support external changes. All modding opportunities were supplementary implementations. Therefore, it may not necessarily be easy to use them.
That said, with the tools and short guides that are being introduced here it will be possible to amend Darkstar One according to your preferences. Create your own missions, add more solar systems or even create your own ship models. It can be done with some effort and enthusiasm.
These are the modding opportunities for DSO:
Missions
You can write missions, which will be either offered at the terminal or triggered in space under certain conditions as soon as you enter a solar system. Created missions may contain new texts, new voice-over files or new sounds.
Ini-files
All available configuration files (*.ini) can be modified. This will have an impact on the
structure of solar systems
trade system
parameters for shields, weapons etc.
Graphics
Available 3D models (objects) and textures may be exchanged or amended. Note: You will not be able to add new objects. Currently, the object formats are only supported in the X-format. A converter for the format used with Darkstar will be available. Read more in the chapter "Amending 3D Objects".
--------------------------------------------------------------------------------
Preparations and Sample Mod
All modifications must observe a certain directory structure, which will be explained here. Version 1.2 of Darkstar One will create a "Customization" subfolder in the "My Documents\Ascaron Entertainment\Darkstar One\" folder. Every mod must be stored in separate folders within this folder. You can freely choose the name for these subfolders. Once the mod has been correctly installed, you will be able to select it from the main menu of Darkstar One from the "Mods" menu. The name of the mod will be determined in the file "darkstarmod.ini" which must exist for each mod (see below).
--------------------------------------------------------------------------------
Tutorial Mod
The mod tools will install a sample modification in the folder "Tutorial" in "My Documents\Ascaron Entertainment\Darkstar One\Customization".
"Tutorial" contains a full modification including all files (source codes, string tables) that were used to create it. All samples and explanations in this modding guide are referring to contents of the modding tutorial. Therefore, the mod "Tutorial" will be a good reference for your own mods.
--------------------------------------------------------------------------------
"darkstarmod.ini"
Each mod contains a "darkstarmod.ini" which is structured like this:
[darkstarmod]
mod_name = (name of the mod)
mod_desc = (short, one-line description)
The name and the description will be displayed in the selection menu for modifications.
--------------------------------------------------------------------------------
Mod Directory
This is the structure of a mod directory:
/inifiles
All .ini files should be available in this folder (simply extract from "ds_3dadd.cpr" if you want to make any changes).
/scripts
All .lua files, which you created or compiled will be found in here
/sound
All sound files (preferably mp3) belong in here.
/strings
The resource file "user_strings.res" for new texts is found in this directory. Furthermore, a zip file with the name "user_data.zip" is available for 3D data. The structure of this file is explained in the chapter "3D". Missing directories or files will prompt the game to use the default data. The prime example are the *.ini files. If they are missing in the mod, the original Darkstar One files will be loaded. The sample modification will explain all opportunities for changing the game.
In order to guarantee the compatibility of the save games, each modification will save its own save games. If you save a game while mod "A" is active, this save game will only be available for modification "A". Only compatible save games will be displayed for each mod.
--------------------------------------------------------------------------------
".Ini" Files
The entire game logic (solar systems, trade logic) receives its initial data from text files. Upon starting the program, these files are read and a new binary file will be created if necessary. Many files are dependant on each other (amount of solar systems in clusters etc.). These dependencies will be mentioned if and when they exist.
In order to adapt a modification to the logic, all required files have to be copied into the "inifiles" directory of the resprective mod. The sources are available in the archive "ds_3dadd.cpr". Rename to "ds_3dadd.zip", unpack and copy the files.
A short description of the files and the part of the logic they contain will follow.
Creating a ".Bin" file
All ".ini" files are loaded during the start-up process and stored in a binary file ("ini_file.bin"). If you change the configuration files, the binary file must be deleted in order to be recreated during the next start of the program. When you restart the program again, only this binary file will be loaded in order to optimize speed.
Note
Please be sure to copy all files. One or more missing files will result in a corrupted ".Bin" file.
--------------------------------------------------------------------------------
Solar Systems
Darkstar One may contain a maximum number of 403 solar systems. They are defined in the file "StarSystem.ini" and they are numbered from 0 to 402. Each system consists of these attributes:
Artefakt: Does an artifact exist in this system?
Bedroht: Is this system occupied by pirates yes / no
B�rger: Number of inhabitants in Billion
Cluster: Number of the cluster where the system is situated
Energylevel: The higher the level, the more particles drift in space
Faction: Which faction does this system belong to (0=Galactic Union, 1=Pirate system, 2=neutral)?
FunctionX1/2/3 and Function_Y: Define parameters for trading simulation
Nachbarregel: Defines the systems that have to be entered in order to make this system available
Piratengang: Index of pirate gang (65535 if no pirate gang is present)
Planeten: Number of planets in the system (? "Planets.ini")
PosX, PosY: Position on the navigation map
Prodution1-5: Which goods are produced in this system
Produktionsfaktor: Amount of produced goods. Factor 0 to 1
Regierung: Form of government (0=Democracy, 1=Dictatorship, 2=Federation, 3=Anarchy, 4=Empire, 5=Monarchy)
Sichtbarkeitstyp: Under which conditions does this system become available (0=starting the game, 2=enter neighboring system, 4=story related, 6=never, 7=hidden system) ?
StarLightID: The system lighting defines the security of the system that results from the form of government (anarchies are unsafe and therefore, they have a reddish light setting. Democracies are safe and have a more friendly and lighter setting) and refers to the "StarLight.ini" (where the light settings for the systems are defined)
UniqueItem: >0, if a unique item is hidden within the system
--------------------------------------------------------------------------------
Planets
Each system consists of a fixed number of objects such as a sun, one or more planets, meteorite fields, stations and one jump gate. The parameters in the "Planets.ini" are self-explanatory.
--------------------------------------------------------------------------------
Cluster and Solar Systems
Each clusters features a configuration file (cluster.ini) and consists of three definitions:
amount of cargo vessels
definition of the cargo vessels
production values of the goods "contained" within the cluster
--------------------------------------------------------------------------------
Cargo Vessels and Cargo Vessel Definitions
Structure of a cargo vessel definition:
starting system
target system
type of cargo vessel
amount of goods carried
types of goods and their respective quantities
This data defines all cargo vessels within a cluster. We recommend not changing this data manually. The initial distribution is handled automatically by Darkstar One when the game is started.
The amount of goods available in each system within the cluster is defined separately from the cargo vessel definitions. The quantity is defined for each of the 24 available types of goods within the game.
--------------------------------------------------------------------------------
All Other Data
The files all contain commentary and they are divided into these areas:•Spielerschiff: Afterburners.ini, Engines.ini, Equipment.ini, Thrusters.ini, Upgrades.ini, StarFlight.ini
Spielerschiff (everything relating to the player’s ship): Engines.ini, Equipment.ini, Thrusters.ini, Upgrades.ini, StarFlight.ini
Handel (trading): Goods.ini, Prices.ini
Objekte (objects): Meteorids.ini, TradeStation.ini, StarShip.ini
Bewegung general movement): StarFlight.ini
Simulation: Time.ini, HitPoint.ini
Effekte (effects): Projectiles.ini, Explosion.ini, ExplosionDef.ini
--------------------------------------------------------------------------------
Creating Your Own Texts
In order to create your own scripts and missions you will have to create new texts. Darkstar One is using a special resource format in order to simplify the work on localizations. Internally, Darkstar uses so-called StringIDs; therefore, you will have to create your own IDs. Ideally, you should use Microsoft Excel in order to create them. The StringID is entered into the first column, the actual text in the next column. The StringID will identify the text in the game.
The Excel file must be saved as an XML sheet. The file below is also available as a sample file in the tutorial mod.
In order to use the texts in the game, the Excel file must be converted. A program called "Xml2ResConverter.exe" is available in the "Tools" folder. You will have to specify three files: the original global.res file of Darkstar One (in order to avoid conflicts with existing StringIDs), the XML file and the target file. The target file ("user_strings.res") must be copied into the mod’s directory. The Excel file must be closed during the conversion.
That is all you have to do. The texts will now be available for all missions via their StringIDs. In order to have a text appear in a certain place of the script, you will have to specify the StringID, i.e. NGUI.ShowSubtitle ("ID_MY_FIRST_STRING_ID").
Image: The list of strings in Excel. Left is the StringID, right is the corresponding text.
--------------------------------------------------------------------------------
Self-made Sounds
You will be able to embed your own sound files for mission scripts into your modification. Similar to the texts, these files are not addressed by their file names but rather by an ID. However, these IDs are not manually assigned; instead, they are created from the structure of the directories and the file names. Initially, three subfolders for the main groups ("(stream)", "(sfx2d)" and "(sfx3d)") should be created in the modification’s "Sound" folder. The names of the subfolders must be in brackets.
Stream
Files in this main group are played as a stream. Music files should be saved here.
2d
Simple stereo effects belong into this folder
3d
Folder for three-dimensional effects
New subgroups may be created for every main group by creating new directories called 'grp_groupname'.
--------------------------------------------------------------------------------
Playing of Sound Effects
Once a sound database has been created with the "KlangKollektor" (german for "sound collector") tool, all effects and music are ready to be used in scripts. The script programmer can access the IDs of the effects by using the created groups. You can play them by using "NSound.PlayUserSound". The parameters are the groups (not the main groups) without the prefix "grp_". If the sound effect is stored in "(sfx2d)/grp_maingroup/grp_subgroup/sound.mp3" you can address a specific sound:
NSound.PlayUserSound( "maingroup.subgroup.sound" )
Or you can address a random sound from a group:
NSound.PlayUserSound( "maingroup.subgroup" )
If you do not specify a sound, a random sound from that group will be played.
--------------------------------------------------------------------------------
Creating a Database File
With the "KlangKollektor" Tool, you will be able to create a user_sounds.xml file from the directory structure and the .asset files. This file will be loaded when the game is started; it will register all files with their specific names and make them available for the script programmer.
Create file:
KlangKollektor.exe -o user_sounds.xml sound
--------------------------------------------------------------------------------
Script System
Darkstar One uses a lua-based script system (http://www.lua.org) with slight modifications for missions.
All scripts (missions as well as story missions) use a condition-based system. Instead of implementing separate functions for each event, so-called transitions are defined which become active according to the current step of the mission. Thus, scripts for the missions can be written in chronological order, which makes understanding a script much easier.
Essential for writing scripts is a sound knowledge of lua, especially the tables. General programming knowledge will also be useful.
We will only address the basics of the system here; an extensive documentation of the script commands can be found in the "html" folder of the documentation.
--------------------------------------------------------------------------------
General Information about Script Functions
All functions of the script system are divided into logical subgroups, each with their own name spaces. These are the groups: NScript General script functions
NMission Missions specific functions
NComm Dialogue system, radio messages etc.
NGUI Graphical interface (show textes etc. )
NPlayer Everything concerning the player and his ship
NCamera Cameras for ingame cutscenes
NStarSystem Functions concerning wingmen (space ship groups)
NWing Space ships in general
NShip Raumschiffe allgemein
NObject Objects in general
NWaypoint Waypoint system
All groups contain creational functions for the respective groups and a variety of additional functions.
Each namespace that is used within a script must be imported beforehand (see sample script). All functions follow a consistent scheme: Each function is assigned to exactly one parameter, the parameter table. The return value is also defined in one table, the return value table.
Both tables contain named fields, which have to be filled and submitted. Functions that do not have any parameters will be assigned with an empty table. There are no functions without argument.
In order to analyze the return value table you must also look at the named fields, otherwise you will not be able to retrieve the data.
V.Container = NContainer.Create( { Type=CONTAINER_SHIP, Ship=V.Ship} ).Container
Now would be a good time to familiarize yourself with the commands of the respective groups :-)
--------------------------------------------------------------------------------
Script Structure
Basically, a script consists of the command "NScript.Register". The rest of the script is contained as parameter(s).
NScript.Register( {
Name = < Missionname >,
Group = < GroupId >,
Type = < Missiontyp >,
Transistions = < Transitiontable > } )
--------------------------------------------------------------------------------
The Transition Table
The transition table is a lua table with an arbitrary number of transitions. Each transition is a table with four elements.
{ < MinStep >, < MaxStep >, < Event >, < Function > }
MinStep and MaxStep are float values and the condition of the mission has to be between (including) these values in order for the function to run properly. Event is a string with the name of the event. If a faulty event name is used, an evaluation will be triggered. If all three conditions are true, the code will be activated in function using parameter V and Data. A complete transition would look like this:
{ nil, nil, "MissionStart", function( V, Data )
NGUI.ShowInfoText( Text="IDM_NEW_LOGENTRY" )
NStarSystem.SetAsMissionTarget( {System=2,Set=1 })
V.Step=1
end },
Here, the float values for MinStep and MaxStep are defined as "nil". Nil stands for an undefined value and it will result in always executing this transition when the event MissionStart is triggered. Also, V.Step is set to 1 at the end in order to define the condition of the mission. When a transition is supposed to change the following status, V.Step must be assigned. V.Step should be started with a float value >0, as C++ does not differentiate between nil and 0. In order to stick with the concept, you should start with V.Step = 1. As and may differ, transitions, which can be applied to a number of conditions, can be written. This is especially interesting for shortcuts within the mission. If 3 to 14 events can happen in the conditions but can be avoided by leaving the solar system, you should use this transition:
{ 3.0, 14.0, "LeaveSystem", function( V, Data )
V.Step = 15
end },
Each event will evaluate all possible defined transitions. The sequence is not defined. You should bear that in mind.
--------------------------------------------------------------------------------
Function Parameters V and Data
Each script, or rather each mission contains a "script global" table V, which will be submitted to each function as a parameter. This parameter enables the forwarding of conditions, variables etc between transitions.
The variable "V.Step" is very important here, as it contains the current progress of the mission (which will activate the relevant transitions). This table contains an arbitrary number of variables, depending on how the author of the scripts intends to use them.
The "Date" table, however, depends on the respective events, which are triggered. It contains every variable that is connected to the event. The parameters are available in the documentation of the events.
--------------------------------------------------------------------------------
Sequence of a Script
All scripts follow a consistent scheme:
Load
Before starting a script, it will be run completely once, i.e. the "NScript.Register" command will be executed; however, the functions within the defined transitions will not be executed.
Initialize
In order to determine, whether a script should be executed, an "Init" event is triggered, which requires an answer of either 0 or 1, where 1 = "yes, start the script".
Start
When the script is started, the "init" will be executed again. If the return value is not 1, an error will occur. Afterwards, the event "create" will be triggered. The condition is undefined at this time. Therefore, "create" has to be a (nil,nil) transition. At this stage, the V table can be written for the first time and the step can be set (it is important to do this ? V.Step = 1). The next event will be "MissionStart", which will be executed straight after "Create". Afterwards, random events may be assigned by the program.
End
The script will end as soon as the condition of the mission is set to MSTATE_ACHIEVED or MSTATE_FAILED. This condition is separate from the entry in V.Step and is set by the function "Event.SetState()". Once these conditions have been set, the appropriate event "Achieved" or "Failed" will be triggered.
--------------------------------------------------------------------------------
Skript Events
An extensive list of all used events is available in the html documentation. So go, take a look :)
--------------------------------------------------------------------------------
Script Types
There are different types of missions. Two special mission types are available for self-made scripts, which the game will give preference to: MTYPE_USER_TERMINAL and MTYPE_USER_SPACE. Terminal missions are offered on terminals within the stations. When such a mission can be created (i.e. "init" returns a 1) it will take precedence and be displayed. The same applies to space missions, which are triggered by entering a new system via the hyper jump gate. When several, equal missions are available, the "MTYPE_USER" missions will be preferred.
--------------------------------------------------------------------------------
Sample Script
We would like to demonstrate how to create a mission with a sample script (terminal mission). Before programming a script, you should know exactly what you want your mission to do/be. Once you have determined this concept, you can work the script step by step and change it into lua code.
The Idea
For our first script, we will create a simple rescue mission, where a container must be collected and returned to the station.
Note
The described script can be found in the tutorial under /scripts/skript_tut001.lua
The sequence of the script should be:
The missions should only be offered in the start system
When the mission has been accepted at the terminal, the container should be created near the station when the station is left. One string should cover the content ("Darkstar One Dokumentation")
When the container has been collected, the task should be adapted. The player will receive a message to return to the station.
If the player returns the container, the mission will be accomplished
If the player lands on the station without the container, nothing happens
If the player leaves the system, the mission will fail
If the player destroys the container, the mission will fail
As you can see, it is important to cover all possible actions of the player in order to create a consistent, believable mission. Especially those actions leading to the failure of a mission must be carefully considered.
The Script
The lua template from the TutorialMod "template.luatemplate") is the basis for our sample. Copy it and rename to .lua. Everything marked with <$...$> must be filled in by the script author.
The "Import" part of the template imports all important namespaces and additional functions. Always keep this line just to be on the safe side.
Here is the actual mission header, the "NScript.Register" command:
NScript.Register( {
--name
Name = <$ INSERT SCRIPT NAME HERE $>,
--group
Group = 0,
--type
Type = <$ INSERT SCRIPT TYPE HERE $>,
--transition table
Transitions = {
All you have to do here is to insert the name of the script (a string) as well as the type of script. A list of all possible script types is available in the html documentation.
Name = "SKRIPT_TUT_001",
--group
Group = 0,
--type
Type = MTYPE_USER_TERMINAL,
The transitions follow immediately after. Essential transitions are already implemented in the template and all you have to do is fill them with mission specific details. Each mission should yield a reward for the player. Therefore, we enter a transition variable in the "V" table of "MissionStart".
{ --Mission starts
nil, nil, "MissionStart", function( V, Data )
--the necessary initializations should happen here
V.Reward = 9876; -- credits for the player
--the actual mission starts here
V.Step = 1
end },
The step of the mission is set to 1 here, which means that the mission will start now. You should use "V.Reward" for rewards since this variable is already used in the template.
The preliminaries are done - you can now implement the actual mission steps. We will take you through our basic concept step by step.
The first step ("The mission may only be offered in the start system") must be entered into the "Init" transition. This function will be queried every time a mission is offered or created. "Init" must return true or false depending on whether the mission may be started or not.
local start_system = MissionLib.GetStarSystemId()
if start_system == 8 then
return{ Ready = true }
end
return{ Ready = false }
The "MissionLib" function "GetStarSystemID()" supplies the ID of the solar system where the player is currently located. If he is in system eight (the start system of the game), the mission may start. Otherwise, it will not start. If true is returned, the "Create" transition will be initiated. Depending on the mission type, "MissionStart" will be initiated; in this case, it will be initiated when the player accepts the mission at the terminal.
We will also adjust the necessary steps in this "MissionStart" transition.
NStarSystem.SetAsMissionTarget( { System = MissionLib.GetStarSystemId(), Set = true } )
MissionLib.LogUpdateStory()
V.Step = 1
The current solar system will be marked as the active mission system on the navigation map. We will also let the player know that his logbook has changed (this "MissionLib" is readily available during installation and contains a variety of helpful additional functions.) Additionally, Step will be set to 1. This will start the actual mission. Now, it will be useful to have the source code for the tutorial mission handy.
The first event that we want to look at is "Station". If someone enters or leaves a station, this event will be triggered. When this happens, we will create a container via NContainer.Create, that will be filled with mission specific goods. In the end, we will save the handle of the container in the mission global table V and will advance the step of the mission further (V.Step=2).
This will activate additional transitions, which will "watch" over the player’s activities. Three of these events will be observed: "System" in case the player leaves the system, "Container" in case the container is destroyed and "Grab" for collecting the container. If the container is destroyed or if the player leaves the system too early, the state of the mission will be set to MSTATE_FAILED. The mission will be finished (and it will trigger the appropriate "Failed" event).
If the player collects the container (transition "Grab"), the mission will be set to step 3 and another transition will become active ("Station"). This new transition is the reaction to entering the station. If the player carries the container, it will set the state to MSTATE_ACHIEVED.
--------------------------------------------------------------------------------
Further Samples
There are another two mission scripts in the sample mod, which explain the creation of opponents as well as the dialogue system.
skript_tut002.lua
skript_tut003.lua
skript_tut004.lua
--------------------------------------------------------------------------------
Skript Tools
Writing scripts is great, but sooner or later you will have to debug them. A very efficient LUA-Debugger is available via HTML. As long as the game is running, the frontend is available at "localhost:54321" via a webbrowser.
--------------------------------------------------------------------------------
The Script Debugger
Once you have loaded the page, follow the "Missions" link. You will find a table listing all currently active missions. Further down is a list of all other missions that have been loaded.
Image: Table of the currently active missions. The name of the script, its current status and a link to the source of the script are displayed.
--------------------------------------------------------------------------------
Breakpoints
In order to set breakpoints you will have to display the source code. Click on the link "View script source" or go to the page "localhost:54321/Framework/ViewScript".
Image: Script Code in the LUA Debugger. Clicking on line number will set (or remove) a breakpoint at the next executable line. Breakpoints are marked by the prefix '@'.
--------------------------------------------------------------------------------
Variables, Stack et al
When a breakpoint is reached and the game stops, the display will change. At the top, debug data will appear, at the bottom left the source is displayed and on the right the current variables (local, global, stack etc.) will appear. It might be necessary to reload the site in order to refresh it.
If you have worked with a debugger before, it should not take long to familiarize yourself with this one. Commands and input that will be executed via the "Eval" button must be entered in the window at the top left. "Step" will jump into the currently displayed function (do not forget "next" to switch to source if possible).
Image: Script display when a breakpoint has been reached
--------------------------------------------------------------------------------
Script Compiler
When all scripts are finished and tested, a file that will contain all scripts in byte code can be created with the script compiler ("Tools" directory).
scriptcompiler.exe -o user_scripts.bin *.lua
In order to be able to compile the LUA files it is essential that these files from the Darkstar directory are available:
BattleLib.Lua
BattleLibEx.lua
CameraLib.lua
MissionLib.lua
Afterwards, they can be deleted from the mod directory. If you do not want to compile your LUA files, this step is not necessary. The created "user_scripts.bin" file must be located in the "scripts" folder; otherwise, Darkstar One will be unable to access it.
Note
Once the scripts have been compiled, they will be inaccessible. Therefore, it will not be possible to add more breakpoints.
--------------------------------------------------------------------------------
Modifying 3D Objects
Once writing scripts for new missions and changing the galaxy has become boring, you will be able to exchange 3D objects or implement new textures. Unfortunately, we are not able to release the entire tool chain due to legal restrictions; therefore, creating and implementing modified objects is slightly more complex, but not impossible to do ;).
--------------------------------------------------------------------------------
File Structures
All files necessary for three-dimensional visuals are stored in these three archives:
ds_3dgen.cpr
ds_3dobj.cpr
ds_3dtex.cpr If you want to change 3D files, you should unpack these archives first.
Note
Cpr archives can be packed or unpacked with any "zip" decompression program if you replace the suffix ".cpr" with ".zip".
Do NOT unpack the archives into the Darkstar One folder!
Once you have unpacked the archives you will see a "3DView" folder, which contains most of the important data.
--------------------------------------------------------------------------------
General Procedure
In order to change a model or a texture, you should isolate the original data and copy it into the directory of the future mod. However, make sure that you observe the directory structure (originating from "3DView"). As some of the models have fixed objects that the program will need to address, we recommend changing the "3do" references and possibly the shader within the XML files only. Completely replacing an XML file is extremely complex and time-consuming.
The next step is creating a "3do" file with the converter and writing appropriate blenders.
--------------------------------------------------------------------------------
Structure of XML Scene Files
A game model consists of an XML scene that refers to all applied resources. These resources are the actual model (in "3do" format), the used shaders (blender) as well as the applied textures. Originating from the root node, all objects are structured hierarchically (scene graph). Generally, an object is compiled of several separate objects, which are assigned to certain "tasks". The best thing to do is to load an object (i.e. "Freighter_A_0.xml") in the "TakeALookXP" tool (see paragraph 7.7). You will be able to go through the hierarchy of a scene and view the respective ‘sub’objects. That should make matters easier to understand.
--------------------------------------------------------------------------------
Types of Objects
AVCWorldRoot: base node
AVCTransformationNode: basic transformation node
AVCMesh: basic mesh in ".3do" format
AVCShieldMesh: mesh for an object’s shield
AVCGlowObject: mesh for the "glowing" areas of an object
AVCDistortionObject: mesh for the distortion effect (i.e. heat haze) of an object
AVCLODSelector: level-of-detail step definition
--------------------------------------------------------------------------------
AVCMesh
This is the most important type of object: it defines the object that will be displayed. It contains „EffectContainer". The number of these containers corresponds with the number of materials in the „3do" object that is being used. This is important when entering a new object. A blender (shader) is assigned to each effect container (Path="..."). Material attributes as well as further parameters for the blender are entered as child nodes of the respective containers.
An „EffectContainer" looks as follows:
<EffectContainer path="test/test.bsd9">
<Material>
+0.000000 +0.261784 +0.344000 +0.000000
+0.471080 +0.471080 +0.471080 +0.000000
+0.000000 +0.761000 +1.000000 +0.000000
+0.025000 +0.050000 +0.100000 +0.000000
+100.000000
</Material>
<Parameters>
<Float semantic="..." value="+1.00000" />
...
</Parameters>
</EffectContainer>
The material consists of diffuse, ambient, specular and emissive color as well as shininess. All colors are specified in RGBA. The material attributes as well as the parameters will be available for the specified blender by semantics. Further details are available under "Blender Compiler".
Important: If several LOD levels exist in "3do" object, the number of effect containers is equal to the sum of all materials in the LOD levels.
--------------------------------------------------------------------------------
Level of Detail and AVCLODSelector
Darkstar One supports several LOD levels per object with the "3do" format. Separate from the number of LOD levels in the object file, an object of the type "AVCLODSelector" is required in the XML scene. This object will define the distance when the levels are switched and which parts of the objects may be switched off during the scene.
<Object Type=".?AVCLODSelector@@" ... LODNumber="2">
LODNumber does not define the number of levels within the mesh; instead, it defines the number of "LODDesc" (LOD Descriptions), which are following. This description will define which parts of the objects are changing in comparison to the previous scene. The partial objects are addressed by their names, according to the hierarchy of the scene.
<LODDesc Clients="2">
lod_0|object_a 1 +0.00000
lod_0|object_b 1 +0.00000
</LODDesc>
<LODDesc Distance="+25.000000" Clients="2">
lod_0|object_a 0 +0.000000
lod_0|object_b 1 +0.750000
</LODDesc>
"Clients" defines the number of objects that will be changed. "Distance" defines the distance to the viewer that has to be reached in order to activate the LOD level. The path in the scene to the affected object defines a client. 0=switch object off, 1=switch object on. The latter value is set to a value between zero and one. It will select the LOD level within the "3do" file. Zero is the first level, one the last. A value greater than ‘one’ may be entered, but only if the object is switched off.
--------------------------------------------------------------------------------
The X File Converter
A rudimentary tool is available to convert models from the "x" format to .3do. Starting the tool is easy:
3do_convert <lod1.x> <lod2.x> ... <output.3do>
Simply enter the source files. The last parameter defines the return file. That is all. Please note that the entered "x" files should correspond with the various level-of-detail meshes (unless you want to convert a spaceship into a container when the object reaches a certain distance in game). One level will be sufficient for an initial test.
3do_convert <input.x> <output.3do>
The converter creates a simple preview ("output.xml") which can be seen with the "TakeALookXP"-Tool. All LODs are included in the object.
--------------------------------------------------------------------------------
Blender Compiler
You will be able to create your own shaders for self-made models with the help of the blender compiler. Sound knowledge of programming shaders is essential; otherwise, this will not be fun at all. As a simple example, we will use a blender that will only transform the vertices and will assign a color. (This color may be defined in the XML scene file.)
--------------------------------------------------------------------------------
Sample Blender (simple_blender)
In order to create a blender you will need two files: the shader ("fx" format) and a corresponding XML file. Initially, it is important to define the used Techniques in the XML file. You may enter several of these techniques; the first functional one will be used (from left to right).
<?xml version="1.0" encoding="utf-8" ?>
<Blender>
<Effect include="simple_blender.fx">
</Effect>
<Variables/>
<EffectAnimators totaltime="2.0">
<EffectAnimator name="DOIT" duration="2.0" techniques="simple">
<Trigger animator="DOIT" time="2.0" />
<Init />
<Main />
</EffectAnimator>
</EffectAnimators>
</Blender>
This template can be applied; however, you should amend the "fx" file ;)
There is a multitude of values in an effect that the engine will initialize. Among those are certain matrixes. The tutorialmod contains an example in "3DView/my_objects/simple_blender.fx" as well as "3DView/my_objects/simple_blender.xml".
Initialized Values
The values initialized by the engine are listed with their semantics:
World: Worldmatrix
WorldView: Worldmatrix*Viewmatrix
WorldViewProjection: World*View*Projection
WorldInverseTransposed: Wordmatrix invertiert und transponiert
View: ViewMatrix
ViewInverse: Inverses der Viewmatrix
ViewProjection: View*Projection
Projection: Projectionmatrix The above named matrixes can be used in the shader Further values can be entered into the shader from the scene description using "<Material>" or "<Parameters>".
Material
A material description consists of ambient, diffuse, specular and emissive color. These values are to be used in the shader with these semantics:
Ambient
Diffuse
Specular
Emission
Parameters
Semantics are assigned to all parameters in order to enable the shader to address them. There are several types of semantics for parameters:
Float: simple float-Value
Vector: float4
Lighting
Objects in Darkstar One can be illuminated by a maximum of four light sources. Shader that want to use lighting will receive the number of light sources from the engine and will relate them to the shader via the "uniform" parameter. You should view the blender sample that is supplied by the "Blendercompiler". In there, an array of shaders is created with the appropriate parameters for the number of active light sources.
--------------------------------------------------------------------------------
Additional Tools
Once you have created a new object, you can look at it by using "TakeALookXP". In order to familiarize yourself with the tool, you might want to look at some objects from the unzipped archives.
Left: hierarchic structure of the XML scene file, below the camera settings. Right the 3D view as well as the returned debug data.
The converter tool will also create an "output.xml" file, where you will be able to view your converted objects.
--------------------------------------------------------------------------------
How to Replace the Container Model (Sample)
As a simple example, we will use a cargo container and replace it with another simple model.
First, we will create the required folder structure in the mod directory. We create a "3DView" directory and copy the "Container.xml" as well as the "Contain_low.xml" from the archive "ds_3dgen.cpr". In this folder we create a subfolder "my_objects" for our own data. Next, we will have to convert our object and create an appropriate blender. We will copy these files into the "my_objects" folder. Once that is done, we will search the files "Container.xml" and "Container_low.mal" for the node that we need to change. Typically, this node is a "?AVCMESH@@" type. Be careful to replace the effect containers appropriately for your own blender and mesh. The paths also have to be correct (here: "my_objects/.3do" etc.). That is all. The "3DView" folder that we created must now be packed into a zipfile called "user_data.zip" and it must be located in the root of the mod directory.
Files with the suffix *_low.xml
All 3d objects exist as XML file as well as "*_low.xml" file. The files with the suffix "_low" are required for shader 1.1 graphics cards and they use adapted blenders. Further adjustments will be needed for older graphics cards.
--------------------------------------------------------------------------------
Circulating Mods
Once a mod is finished and tested, you may distribute it freely. However, you do not need to submit all files (unless other users should further advance them). These files may be omitted when distributing a mod:
".lua"-files, once a .bin file has been compiled from them (and they have thereby been error-checked)
All graphics files, once a user_data.zip has been created
All ".ini" files, once the ini_files.bin has been created
Attachments:
Post edited May 19, 2010 by stevenhwood