Starcraft 2 Data Manager
This application allows you to make macros or "Templates" for Starcraft 2 XML data, and then use these macros to create new XML data really quickly. Each Template contains a bunch of variables, or placeholders. When new XML data is created from a Template, the user specifies values for each of the variables located within that Template.
- Template: a macro or group of XML data, with some attributes containing variables and formulas.
- Custom Item: an instantiation of a Template, with required variables' values filled in, and all formulas computed.
- Data Object: any XML node that is a child of a "Catalog" node. I.e. CUnit, CEffect, CActor, etc.
This tool was built upon two main ideas:
- The same piece of XML code should never be written twice (by a human). Tasks like tediously copying data should be left to computers: not humans. They are much more consistent about it.
- Greater control doesn't have to be gained at the expense of ease-of-use. There is no doubt that the SC2 Map Editor is powerful, but it is also much less user friendly than it needs to be. This tool attempts to bridge the gap by allowing the user to make Templates that can be used by other modders, who just see the Templates as magical black boxes that do what they want.
For example, once someone has figured out the perfect way to add knockback to abilities, that person should be able to make a knockback Template. Then he should be able to share his Template online such that fellow modders can add knockback to all the abilities in their maps, without knowing how knockback actually works. Thanks to the Starcraft 2 Data Manager, this is no longer just an idea; it is a reality. Now it's just up to you to create Templates and share them with the community.
Stuff you could create using Templates:
- Abilites with levels
- ...and pretty much any XML data that you would write more than once.
Demo Video: Creating two heroes using a "Warcraft 3-style" Hero Template.
The SC2DM has a number of features which you can use in your Templates. Most of these features involve filling in XML data automatically, once the user gives values to the variables that the Template needs. The most basic features just involve inserting placeholder variables into your XML data.
These are the most commonly used form of variables in Templates. When the user creates a Custom Item, he must specify the value to use for all required variables: otherwise, the tool will complain.
- #[variable name]#
- Insert the value of the variable called 'unitId'. This variable must be given a value.
In a custom item, if we give unitId the value "HungryBaneling", this becomes:
If the user does not specify the value of an optional variable, it will use a default value instead of complaining. The default value is specified in the variable declaration.
- #[variable name]=[default value]#
- Take the value of the variable called 'damage'. If it has no value, use "10".
<Damage value="#damage=10#"/>Alternatively, if we don't give 'damage' a value, we get:
Demo Video: Simple "Tome of Experience" Template creation:
Look for required variables in action in this video, which walks through the creation of a simple "Tome of Experience" Template.
Users can embed mathematical expressions in their Templates. Formulas are automatically evaluated after variable values have been filled in. Formulas can contain many standard mathematical operations and functions, and can contain any number of other variables. Since variables have string values, an error occurs when a variable used in a formula is given a non-numerical value.
- =[math expression]=
- A simple expression that means "2 times the value of the variable called 'level'":
- An expression that means "Take the value of the 'level' variable, subtract one from it, then multiply it by 10":
- LocalOffset normally takes rectangular (X/Y) coordinates. We use two formulas in one attribute to convert polar (radius/theta) coordinates to rectangular coordinates:
When we set radius="10" and theta="-.785" (-PI/4), this becomes:
<LocalOffset value="=#radius#*cos(#theta#)=, =#radius#*sin(#theta#)="/>Of if we set radius="10" and theta="1.05" (PI/3), this becomes:
<LocalOffset value="7.07, -7.07"/>
<LocalOffset value="5, 8.66"/>
Together with formulas, this feature will save you guys arbitrarily large amounts of time. Inside your Template's XML files, you can place SC2DM_foreach nodes. These are similar in concept to foreach loops seen in modern programming languages. When a foreach loop is seen, a local variable is initialized. This variable is incremented on each run of the loop. The contents of the loop are repeated until the variable becomes greater than its terminal value.
<SC2DM_foreach varName="[varName]" from="[integer start value]" to="[integer end value]"> ... </SC2DM_foreach>
The value of this attribute is the name of a new variable, which only exists within the foreach loop. This variable's value is initialized to the value of the 'from' attribute. On each run of the loop, this variable's value is incremented (increased by one).
The initial value of the variable. Must be an integer. Can contain variables and/or formulas as long as those result in an integral value.
The last value of the variable. Must be an integer. Can contain variables and/or formulas as long as those result in an integral value. If this value is less than the value of "from", the child nodes of "SC2DM_foreach" will not be output.
- A simple foreach loop that adds #numTurrets# turret weapons to a unit (unit not shown):
If we set numTurrets=4, the contents of the foreach get duplicated 4 times, using values 0,1,2, and 3 for turretIndex:
<SC2DM_foreach varName="turretIndex" from="0" to="=#numTurrets#-1="> <WeaponArray Link="BigGun#turretIndex#" Turret="BigGun#turretIndex#"/> </SC2DM_foreach>
<WeaponArray Link="BigGun0" Turret="BigGun0"/> <WeaponArray Link="BigGun1" Turret="BigGun1"/> <WeaponArray Link="BigGun2" Turret="BigGun2"/> <WeaponArray Link="BigGun3" Turret="BigGun3"/>
- This foreach loop duplicates the VeterancyLevelArray for all the values of level between 2 and #maxLevel# (inclusive). It also uses a formula to calculate the required XP for each level:
If we set maxLevel=8, this becomes:
<SC2DM_foreach varName="level" from="2" to="#maxLevel#"> <VeterancyLevelArray MinVeterancyXP="=10*(#level#-1)="> ... </VeterancyLevelArray> </SC2DM_foreach>Foreach loops can also be nested, though each foreach should be careful to use a unique variable name.
<VeterancyLevelArray MinVeterancyXP="10"> ... </VeterancyLevelArray> <VeterancyLevelArray MinVeterancyXP="20"> ... </VeterancyLevelArray> <VeterancyLevelArray MinVeterancyXP="30"> ... </VeterancyLevelArray> <VeterancyLevelArray MinVeterancyXP="40"> ... </VeterancyLevelArray> <VeterancyLevelArray MinVeterancyXP="50"> ... </VeterancyLevelArray> <VeterancyLevelArray MinVeterancyXP="60"> ... </VeterancyLevelArray> <VeterancyLevelArray MinVeterancyXP="70"> ... </VeterancyLevelArray>
Allowing Templates to modify existing objects:
When a Template writes to a map, it normally creates completely new data objects. It cannot modify the maps' existing objects without appending special attributes to the objects it wants to change. In this section I'll talk about these special attributes.
First, let's look at an example. I want to make a Template which allows you to create a Turret, and attach it to any unit. In order to make this, I need the Attachment template to modify an existing unit. The first thing I need to do is create the Template as if it's adding the attachment to a new, blank unit. Here's the code from the UnitData.xml file of my Template, for this step of the process:
<CUnit id="#hostUnitId#"> <AbilArray Link="attack"/> <AbilArray Link="stop"/> <WeaponArray Link="#id#" Turret="#id#"/> <CardLayouts> <LayoutButtons Face="AttackRedirect" Type="AbilCmd" AbilCmd="attack,Execute" Row="0" Column="0"/> <LayoutButtons Face="Stop" Type="AbilCmd" AbilCmd="stop,Stop" Row="0" Column="1"/> </CardLayouts> </CUnit>
As is, this code would create a new unit called #hostUnitId#, and would give it a turret attachment (created in the other .xml files) called #id#. By giving the CUnit node some special attributes, we can make this code look for an existing unit called #hostUnitId# and modify it:
<CUnit id="#hostUnitId#" SC2DM_shouldAlreadyExist="yes" SC2DM_whatToDoIfExists="modify">
These attributes will be read by SC2DataManager, then immediately deleted. In this case, they tell the program that the object <CUnit id="#hostUnitId#"> must exist in the map and that the existing object should be merged with the object created by the Template.
This attribute determines whether a copy of an object is expected to exist in the map or not. The program gives you an error if this expectation is not met. This attribute has three possible values:
- yes: this object must exist in the map.
- no: this object must not exist in the map.
- idc: AKA "I don't care": this object can either exist or not exist in the map.
This attribute tells the program what to do in the event that the object exists in the map. This attribute is not used if SC2DM_shouldAlreadyExist=no. This attribute has three possible values:
- modify: the existing object is merged with the new object.
- overwrite: the existing object is replaced by the new object.
- doNothing: the existing object remains unchanged.
TODO: explain what it means to "merge" two data objects.
At the moment, this application does not have a GUI. It runs based on parameters located in files in the program folder. The user has to manually change these parameters before each run. Of course, this is not user friendly, so I'm planning to make a GUI version. This GUI will be compatible with all major operating systems, thanks to the magic of the QT framework.
Templates with Localized Data, Terrain Data, etc:
In order to make Templates more general and more useful, I will probably structure Template directories exactly like SC2Map directories. This would allow Templates to not only be able to copy stuff like hotkeys and object tooltips, but would also allow Templates to be used to i.e. generate complex terrain based on user parameters. Since most terrain effects cannot be created through triggers or scripts, Terrain Templates would open many artistic doors.
Managing Data created from Custom Items:
Suppose a user creates a Hero from a template, then two days later realizes that he gave the hero the wrong max level. Suppose also that he does not know how to make a hero from scratch. What can he do? Well, right now, there is no way for him to tell SC2DM to remake that hero, using the correct max level. In fact, after running, SC2DM has no idea whether or not XML data was created by it or not. I would like to change this. In the Custom Items excel files, I would like to allow users to keep track of custom items created on previous runs of the program, instead of having to start fresh with each run. This would be extremely useful for balancing, since custom items based on the same template could be easily compared, and the parameters of old items could be changed.
This tool is now in the beta stage. While all the above features (besides future features) are fully implemented, the program may contain some bugs. If this software sounds like something you'd like to use, please download it and give me as much feedback as you are willing to. I am eager to hear how I can improve it. You can email me any time at firstname.lastname@example.org.
Currently, only the Windows version is available (in the ZIP archive in the "Download" link). The Mac version will be available soon (and I don't mean "soon" by Blizzard standards). For legal purposes, I must say the following: This software comes with no guarantees, implied or otherwise, of fitness to any degree. Said software could cause damage to the user's computer. The software developer (me) cannot be held accountable for any damages caused by said software.
If you have comments not directly related to reviewing this tool, please put them here in this discussion thread. I love getting criticism of any form whatsoever. Also, if you give me a good idea, I will definitely give you credit for it.