How To Write Your Own AI Scripts in 1.2

Just thought I'd run up a quick tutorial on how to mod the AI scripts.

 

First up, go download notepad++. Seriously, just make life easy on yourself. open it up, set the language to XML, and then in a new file copy and paste the following code:

 

 

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<AIStrategyList
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../Schema/AIStrategyDefs.xsd">

<AIStrategy>
<InternalName>Diplomatic_Strategy_General</InternalName>
<TurnStart>100</TurnStart>
<TurnLifetime>15</TurnLifetime>
<PlayerAtWar>NoWar</PlayerAtWar>
<PersonalityTraits>Diplomatic</PersonalityTraits>
<Spending>BreakEven</Spending>
<SpendUntilBrokeBuffer>1000</SpendUntilBrokeBuffer>
<WealthSlider>0.10</WealthSlider>
<ManufacturingSlider>0.30</ManufacturingSlider>
<ResearchSlider>0.60</ResearchSlider>
<MilitarySlider>0.70</MilitarySlider>
<StarbaseDefenderFillCap>0.4</StarbaseDefenderFillCap>
<ShipyardDefenderFillCap>0.4</ShipyardDefenderFillCap>
<PlanetDefenderFillCap>1</PlanetDefenderFillCap>
<PreferToRush>Manufacturing</PreferToRush>
<BuildShip>
<ShipClass>Colony</ShipClass>
<BuildFirst>2</BuildFirst>
<Weight>30</Weight>
</BuildShip>
<BuildShip>
<ShipClass>Constructor</ShipClass>
<Weight>15</Weight>
</BuildShip>
<BuildShip>
<ShipClass>Defender</ShipClass>
<MaintenanceCreditPerTurnMultipleBuffer>1</MaintenanceCreditPerTurnMultipleBuffer>
<Weight>8</Weight>
</BuildShip>
<BuildShip>
<ShipClass>Freighter</ShipClass>
<Weight>12</Weight>
</BuildShip>
<BuildShip>
<ShipClass>Escort</ShipClass>
<MaintenanceCreditPerTurnMultipleBuffer>1</MaintenanceCreditPerTurnMultipleBuffer>
<Weight>2</Weight>
</BuildShip>
<BuildShip>
<ShipClass>Assault</ShipClass>
<Weight>2</Weight>
</BuildShip>
<BuildShip>
<ShipClass>Sentinel</ShipClass>
<Weight>2</Weight>
</BuildShip>
<BuildShip>
<ShipClass>Transport</ShipClass>
<Weight>1</Weight>
</BuildShip>
<BuildShip>
<ShipClass>CapitalShip</ShipClass>
<MaintenanceCreditPerTurnMultipleBuffer>1</MaintenanceCreditPerTurnMultipleBuffer>
<Weight>1</Weight>
</BuildShip>
<TechWeightOffset>
<UseOffset>true</UseOffset>
<WeightOffset>
<Military>0</Military>
<Growth>4</Growth>
<Tech>4</Tech>
<Diplomacy>5</Diplomacy>
<Expansion>0</Expansion>
<Wealth>5</Wealth>
<Influence>5</Influence>
<Fortification>5</Fortification>
</WeightOffset>
</TechWeightOffset>
</AIStrategy>

 

 

</AIStrategyList>

End of quote

 

 

We're going to go through this a bit at a time, so don't panic. There's a couple of things to be aware of - first, XML is case-sensitive, so copy capital letters EXACTLY. GC3 uses standard coding conventions for the most part, AndSoWritesLikeThis, with no spaces and marking the start of every new word with a capital letter. Second, spaces are a character. IF you leave a space at the end of a tag, it is a different tag from one with no spaces. Third, everything is basically a mass of nested scopes. A scope is when you have matching sets of brackets around things that are aspects of the same thing, so to describe a dog we'd have:

 

<dog>

<tail>1</tail>

<nose>1</nose>

<stupid>1<stupid>

</dog>

 

Finally, all lines MUST be in the correct order. You can't, for example, stick the tech weighting at the top of a strategy - or shift the economy settings to the bottom. The order required is outlined in the Schema, but for general purposes as long as you copy from the other stuff in AIStrategyDefs.xml then you should be OK. The game will flid out and give you a debug log if these are incorrect.

That's more or less it in terms of rules for XML. Everything else is just learning the vocab.

 

On to the files.

 

The blurb at the top tells the game that this should be appended to the AI strategy list:

 

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<AIStrategyList
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../Schema/AIStrategyDefs.xsd">

 

End of quote

 

We don't want to touch that. Next up is the beginning of the individual strategy class:

 

<AIStrategy>

End of quote

 

Every new strategy you create MUST start with this, and end with </AIStrategy>. This tells the game that everything between this pair is a single strategy.

 

Below this, we have the internal name - every strategy must have a unique one. The strategy above is called Diplomatic_Strategy_General. Since it already exists, change it to 'Xenophobic_strategy_General':

 

    <InternalName>Xenophobic_Strategy_General</InternalName>

End of quote

 

Under that, we have the triggers:

 

<TurnStart>100</TurnStart>
<TurnLifetime>15</TurnLifetime>
<PlayerAtWar>NoWar</PlayerAtWar>
<PersonalityTraits>Diplomatic</PersonalityTraits>

End of quote

 

This tells the AI that it can start using this strategy after turn 100, that it uses the strategy for 15 turns before checking for another, that it can only pick it if it's not at war, and that it's only valid for AIs that have the 'diplomatic' personality traits. Since we're coding for the Xenophobic AI, change the <PersonalityTraits> value to 'Xenophobic'. Everything else can be left as it is, though you might want to bring the turn lifetime down to 5 so the AI can change direction quicker:

 

<TurnStart>100</TurnStart>
<TurnLifetime>5</TurnLifetime>
<PlayerAtWar>NoWar</PlayerAtWar>
<PersonalityTraits>Xenophobic</PersonalityTraits>

End of quote

 

You can also use <TurnEnd></TurnEnd> to tell the AI to stop using a strategy at a certain point. This MUST come after the TurnStart, but before the TurnLifetime.

 

After that comes the AI's economy settings:

 

<Spending>BreakEven</Spending>
<SpendUntilBrokeBuffer>1000</SpendUntilBrokeBuffer>
<WealthSlider>0.10</WealthSlider>
<ManufacturingSlider>0.30</ManufacturingSlider>
<ResearchSlider>0.60</ResearchSlider>
<MilitarySlider>0.70</MilitarySlider>

End of quote

 

<Spending> tells the AI whether to spend all it's money, break even, or try to save up. It is generally better to put this on SpendUntilBroke.

<SpendUntilBrokeBuffer> is the point where the AI will switch to breaking even, in this case at 1000 credits. 

Below that are the slider settings. Wealth, manufacturing and research should total at 1. So you might have 0.2 wealth, 0.5 manufacturing and 0.3 research. The AI will usually adjust the wheel toward wealth the moment it hits breakeven anyway, so wealth can pretty much be left at 0.

The military slider can be set to anything between 0 and 1. At 0, it spends 100% social manufacturing. At 1, it spends 100% military manufacturing. 

So, baring the above in mind, a more reasonable set of economy settings might be:

 

<Spending>SpendUntilBroke</Spending>
<SpendUntilBrokeBuffer>200</SpendUntilBrokeBuffer>
<WealthSlider>0.0</WealthSlider>
<ManufacturingSlider>0.6</ManufacturingSlider>
<ResearchSlider>0.4</ResearchSlider>
<MilitarySlider>0.9</MilitarySlider>

End of quote

 

This tells the AI to spend aggressively until it only has 200 cash left. Once it has 200 cash, it will raise only as much money as it needs to pay its maintenance costs, and splits the rest 60-40 between manufacturing and research. It spends 90% of it's manufacturing clout on units, and saves 10% for social production.

 

After that comes 

<StarbaseDefenderFillCap>0.4</StarbaseDefenderFillCap>
<ShipyardDefenderFillCap>0.4</ShipyardDefenderFillCap>
<PlanetDefenderFillCap>1</PlanetDefenderFillCap>

End of quote

 

This determines how many defenders the AI will station around starbases, shipyards and planets. It can more or less be left alone. After that, we have <PreferToRush>, which tells the AI what kind of improvements to rush-buy. Either Manufacturing or Research are the best settings here.

 

Then we come to the ship building list. The AI determines what to build by rolling a dice on a weighted table. So it may have 10 weight for a constructor, 10 weight for a frigate and 20 weight for a colony ship; it rolls a 40-sided dice, and on 1-10 builds a constructor, on 11-20 it builds a frigate and on 21-40 it builds a colony ship.

 

<BuildShip>
<ShipClass>Colony</ShipClass>
<BuildFirst>2</BuildFirst>
<Weight>30</Weight>
</BuildShip>

End of quote

 

<Shipclass> is the AI ship class listed for a ship in ShipClassDefs.xml. <BuildFirst> is optional, and tells the AI to build x number of this before rolling on the table. <Weight> determines it's weight on the table. You can add or remove as many different classes to the table as you like; the AI will only build things available to it on this list for as long as the script is active. There's a good mixed bag there, but since this is a turn 100+ strategy, maybe we should dump the <BuildFirst> from the colony ship. It's up to you.

 

Finally, we have the Tech Weights:

 

<TechWeightOffset>
<UseOffset>true</UseOffset>
<WeightOffset>
<Military>0</Military>
<Growth>4</Growth>
<Tech>4</Tech>
<Diplomacy>5</Diplomacy>
<Expansion>0</Expansion>
<Wealth>5</Wealth>
<Influence>5</Influence>
<Fortification>5</Fortification>
</WeightOffset>
</TechWeightOffset>

End of quote

 

<WeightOffset> and <TechWeightOffset> are class definitions - so everything in between them is part of the same thing, in this case the offset values for technology. <UseOffset> just tells the AI to apply the settings listed. Military, Growth, Tech, Diplomacy, Expansion, Wealth, Influence and Fortification are all characteristics of techs. Every faction has it's own set of preferred ones, and this applies an offset - it increases or decreases the number. The number is then compared to the values listed on the technologies, and the closer it is to a match, the higher the chance the AI will research that tech.

 

Then we just close   </AIStrategy>, save the file as xenophobicstrat.xml, and make it into a mod. Go to the My Documents/My Games/GalCiv3/mods folder, and create a new folder called 'AImods'. Put the xenophobicstrat.xml file into this folder. Launch the game, activate mods, and then restart the game. Viola, your first added AI is now working.

24,153 views 22 replies +2 Loading…
Reply #1 Top

Also, feel free to ask for clarifications, advice, troubleshooting and even to post whole scripts here for others to try.

+1 Loading…
Reply #2 Top

Great post :)

 

Reply #3 Top

Thanks, is there a specific language you are supposed to use in XML? Is there a way to add more 'hooks' that the ai checks?

Reply #4 Top

Quoting Larsenex, reply 3

Thanks, is there a specific language you are supposed to use in XML? Is there a way to add more 'hooks' that the ai checks?
End of Larsenex's quote

it;s basically english.  technically xml can be any language (or some crazy confusing meaningless gibberish), but it's usually something like english/spanish/german/etc depending on where the particular thing it's for was developed.  regarding "more hooks".  depending on what you call a "hook" no or kinda sorta I guess

Reply #5 Top

So awesome!

Reply #6 Top

Quoting Larsenex, reply 3

Thanks, is there a specific language you are supposed to use in XML? Is there a way to add more 'hooks' that the ai checks?
End of Larsenex's quote

As a hint, look in the xsd File referred at the top of the xml: Schema/AIStrategyDefs.xsd

There is defined what is allowed in the xml and what structure it must have. There are some includes at the top which contain definitions that are also used elsewhere, for a complete reference they must be taken into account also.

Reply #7 Top
<StarbaseDefenderFillCap>0.4</StarbaseDefenderFillCap>
<ShipyardDefenderFillCap>0.4</ShipyardDefenderFillCap>
<PlanetDefenderFillCap>1</PlanetDefenderFillCap>

This determines how many defenders the AI will station around starbases, shipyards and planets. It can more or less be left alone.

End of quote

Can you elaborate on that? Is that also some kind of weight specification, meaning something like "from every defender built send 0.4 / 1.8 = 22% to a (randomly selected) starbase, send 0.4 / 1.8 = 22% to a randomly selected shipyard and send 1 / 1.8 = 56% to a randomly selected planet (of those sponsoring the defender producing shipyard)"?

 

Reply #8 Top

Quoting lyssailcor, reply 7


Quoting ,


<StarbaseDefenderFillCap>0.4</StarbaseDefenderFillCap>
<ShipyardDefenderFillCap>0.4</ShipyardDefenderFillCap>
<PlanetDefenderFillCap>1</PlanetDefenderFillCap>


This determines how many defenders the AI will station around starbases, shipyards and planets. It can more or less be left alone.


Can you elaborate on that? Is that also some kind of weight specification, meaning something like "from every defender built send 0.4 / 1.8 = 22% to a (randomly selected) starbase, send 0.4 / 1.8 = 22% to a randomly selected shipyard and send 1 / 1.8 = 56% to a randomly selected planet (of those sponsoring the defender producing shipyard)"?

 

End of lyssailcor's quote

 

I'm not sure. I suspect it may be a hard cap of 'never fill with more than x% of logistics cap' hard barrier; the actual AI generally deals with specific placement.

Reply #9 Top

Quoting naselus, reply 8


Quoting lyssailcor,






Quoting ,





<StarbaseDefenderFillCap>0.4</StarbaseDefenderFillCap>
<ShipyardDefenderFillCap>0.4</ShipyardDefenderFillCap>
<PlanetDefenderFillCap>1</PlanetDefenderFillCap>



This determines how many defenders the AI will station around starbases, shipyards and planets. It can more or less be left alone.



Can you elaborate on that? Is that also some kind of weight specification, meaning something like "from every defender built send 0.4 / 1.8 = 22% to a (randomly selected) starbase, send 0.4 / 1.8 = 22% to a randomly selected shipyard and send 1 / 1.8 = 56% to a randomly selected planet (of those sponsoring the defender producing shipyard)"?

 



 

I'm not sure. I suspect it may be a hard cap of 'never fill with more than x% of logistics cap' hard barrier; the actual AI generally deals with specific placement.

End of naselus's quote

Anyone else? Frogboy?

Reply #10 Top

Quoting Larsenex, reply 3

 Is there a way to add more 'hooks' that the ai checks?
End of Larsenex's quote

 

Not within the xml. You can implemented calls in the C to look for certain things in the XML, but if you're doing that then you've reverse-engineered the .exe file. Releasing a doctored .exe as part of a mod will probably result in swift legal action from Stardock, since you're basically giving away their IP if you do that.

 

The Schema outlines what's acceptable within a class, in the xsd files listed in the blurb at the top of the scripts - DO NOT ATTEMPT TO CHANGE THE XSD FILES. It won't work, but it will break your game and force you to validate and re-download half a dozen files. I do hope that this will be changed, but it's unlikely to happen any time soon.

 

In the case of triggers for the strat scripts, the valid triggers are:

 

<TurnStart>  - checks which turn this strategy is valid from; this is very useful for fine granular control at points when we KNOW what the AI ought to be doing, like say the early game.

<RequiredObjective> - checks the victory conditions. This is helpful for the end-game, when on a tech victory the AI ought to be rushing tech from about turn 200 or so.

<TechAge> - checks whether a tech age has been reached; this is of somewhat limited use imo, given how broad the tech ages are, but can help specify beyond just the turn check. Every tech age listed in the strategy needs to have been reached for the strategy to be available. 

and

<PersonalityTraits> - checks the personality traits of the AI. AI players have one or more personality traits listed in their faction file. This locks the strategy to only work for AIs which have the traits listed.

 

<PlayerAtWar> also counts as a trigger, since it can be set to AtWar, Any or NoWar to check war status. 

 

When two strategies are available, the AI will pick the most restricted one it has access to - so it one has a turn limit restriction, and the other has a turn limit restriction AND a personality restriction, it will pick the latter. In cases where the restrictions are equal, it picks the most recent loaded one.

Reply #11 Top

Quoting naselus, reply 10

- checks whether a tech age has been reached; this is of somewhat limited use imo, given how broad the tech ages are, but can help specify beyond just the turn check. Every tech age listed in the strategy needs to have been reached for the strategy to be available. 
End of naselus's quote
It looks like you also need to include a victory type like <RequiredObjective>AscensionVictory</RequiredObjective>or somethingm, disappointingly enough, just plonking in <techage>AgeOfBlah</techage> bombs out cryptically :(

Reply #12 Top

You don't. More likely, you've put the triggers in in the wrong order or something. Post the script and I'll take a look

Reply #13 Top

Quoting naselus, reply 12

You don't. More likely, you've put the triggers in in the wrong order or something. Post the script and I'll take a look
End of naselus's quote

nifty, I didn't try too hard, I think it was just this

<AIStrategy>
<InternalName>StartStrat_Default_Colonization</InternalName>
<TurnStart>0</TurnStart>
    <TechAge>AgeOfColonization</TechAge>

<TurnEnd>75</TurnEnd>
<TurnLifetime>10</TurnLifetime>
<PlayerAtWar>Any</PlayerAtWar>
<Spending>SpendUntilBroke</Spending>
<SpendUntilBrokeBuffer>2500</SpendUntilBrokeBuffer>
<WealthSlider>0</WealthSlider>
<ManufacturingSlider>0.50</ManufacturingSlider>
<ResearchSlider>0.50</ResearchSlider>
<MilitarySlider>0.50</MilitarySlider>
<StarbaseDefenderFillCap>0.4</StarbaseDefenderFillCap>
<ShipyardDefenderFillCap>0.4</ShipyardDefenderFillCap>
<PlanetDefenderFillCap>1</PlanetDefenderFillCap>
<PreferToRush>Manufacturing</PreferToRush>
<BuildShip>
<ShipClass>Colony</ShipClass>
<PreferToRush>false</PreferToRush>
<Weight>50</Weight>
</BuildShip>
<BuildShip>
<ShipClass>Scout</ShipClass>
<PreferToRush>false</PreferToRush>
<Weight>5</Weight>
</BuildShip>
<BuildShip>
<ShipClass>Colony</ShipClass>
<Weight>2</Weight>
</BuildShip>
<BuildShip>
<ShipClass>Colony</ShipClass>
<Weight>4</Weight>
</BuildShip>
<TechWeightOffset>
<UseOffset>true</UseOffset>
<WeightOffset>
<Military>-100</Military>
<Growth>6</Growth>
<Tech>6</Tech>
<Diplomacy>-10</Diplomacy>
<Expansion>10</Expansion>
<Wealth>5</Wealth>
<Influence>-10</Influence>
<Fortification>-10</Fortification>
</WeightOffset>
</TechWeightOffset>
</AIStrategy>

<AIStrategy>
<InternalName>StartStrat_Aggressive</InternalName>
<TurnStart>0</TurnStart>
<TurnEnd>100</TurnEnd>
<TurnLifetime>10</TurnLifetime>
<PlayerAtWar>Any</PlayerAtWar>
<PersonalityTraits>Aggressive</PersonalityTraits>
<Spending>BreakEven</Spending>
<SpendUntilBrokeBuffer>2500</SpendUntilBrokeBuffer>
<WealthSlider>0</WealthSlider>
<ManufacturingSlider>0.50</ManufacturingSlider>
<ResearchSlider>0.50</ResearchSlider>
<MilitarySlider>0.50</MilitarySlider>
<StarbaseDefenderFillCap>0.4</StarbaseDefenderFillCap>
<ShipyardDefenderFillCap>0.4</ShipyardDefenderFillCap>
<PlanetDefenderFillCap>1</PlanetDefenderFillCap>
<PreferToRush>Manufacturing</PreferToRush>
<BuildShip>
<ShipClass>Colony</ShipClass>
<PreferToRush>true</PreferToRush>
<Weight>50</Weight>
</BuildShip>
<BuildShip>
<ShipClass>Scout</ShipClass>
<PreferToRush>false</PreferToRush>
<Weight>1</Weight>
</BuildShip>
<BuildShip>
<ShipClass>Colony</ShipClass>
<Weight>1</Weight>
</BuildShip>
<BuildShip>
<ShipClass>Colony</ShipClass>
<Weight>12</Weight>
</BuildShip>

<TechWeightOffset>
<UseOffset>true</UseOffset>
<WeightOffset>
<Military>-100</Military>
<Growth>6</Growth>
<Tech>6</Tech>
<Diplomacy>-100</Diplomacy>
<Expansion>10</Expansion>
<Wealth>-100</Wealth>
<Influence>-100</Influence>
<Fortification>-100</Fortification>
</WeightOffset>
</TechWeightOffset>
</AIStrategy>

End of quote

 

Yes I know, aoc isn't a default techage, I tried a default one & some other stuff too before shrugging & going on to test the rest of the changes in an overnight soak with a shrug

Reply #14 Top

Hmmm. Might be throwing a shoe because of the space in the text. Will need to check when I get home from work in a few hours. I've not bothered using the tech ages myself - I find them thoroughly unhelpful - but I'm fairly sure there's examples of them being used without the victory condition listed.

Reply #15 Top

yea the default tech ages are too big. I was going to add some with the intention of letting me account for things like how lucky they are at using explore (god we need a scout starts) to find habitable planets. A race that lucks out & finds a some quickly (say under 20 turns) is going to be in a different position than one with a single class 5 & 8 because they were scouting empty space most of that.

 

Reply #16 Top

It's REALLY pernickity about the order that things are laid out within a class - which is a royal pain if you're used to other scripting languages or high-level programming in C-derivatives, and are used to just chucking stuff in as needed. About 99% of my debugging comes down to having something 1 line above or below where it's meant to be. Of course, it may well just need the condition in there, though I'm not sure why it would.

Reply #17 Top

Quoting naselus, reply 16

It's REALLY pernickity about the order that things are laid out within a class - which is a royal pain if you're used to other scripting languages or high-level programming in C-derivatives, and are used to just chucking stuff in as needed. About 99% of my debugging comes down to having something 1 line above or below where it's meant to be. Of course, it may well just need the condition in there, though I'm not sure why it would.
End of naselus's quote

ick, the techdefs files are extremely easy going as long as all the required bits are there, I was hoping the aiscripts would be similar.  Looking back with that said though, the error might have been more of the "this is the proper order stupid human" than "cryptic".  I'm pretty jazzed about getting to play and see how my of my combined tweaks all over run against a stupid human instead of the ai's amongst themselves in a soak :)

Reply #18 Top

Quoting Tetrasodium, reply 17

ick, the techdefs files are extremely easy going as long as all the required bits are there, I was hoping the aiscripts would be similar.  Looking back with that said though, the error might have been more of the "this is the proper order stupid human" than "cryptic".  I'm pretty jazzed about getting to play and see how my of my combined tweaks all over run against a stupid human instead of the ai's amongst themselves in a soak :)

End of Tetrasodium's quote

 

Yeah, I'm thinking of doing an AAR using my mod at some point (probably once the AI's current pacifism is sorted). If anything, just to actually sit down and play the game myself for a bit :P I'v eplayed only a few hours myself in the past couple of weeks.

Reply #19 Top

Quoting naselus, reply 18


Quoting Tetrasodium,

ick, the techdefs files are extremely easy going as long as all the required bits are there, I was hoping the aiscripts would be similar.  Looking back with that said though, the error might have been more of the "this is the proper order stupid human" than "cryptic".  I'm pretty jazzed about getting to play and see how my of my combined tweaks all over run against a stupid human instead of the ai's amongst themselves in a soak :)




 

Yeah, I'm thinking of doing an AAR using my mod at some point (probably once the AI's current pacifism is sorted). If anything, just to actually sit down and play the game myself for a bit :P I'v eplayed only a few hours myself in the past couple of weeks.

End of naselus's quote
AAR?

Reply #20 Top

Quoting Tetrasodium, reply 19

AAR?

End of Tetrasodium's quote

 

After action report. Basically, do a write-up of the game. It's usually great advertizing for mods.

 

Oh, and to fix your script, you just need to move 'techage' to after the TurnEnd setting.

Reply #21 Top

While notepad++ is good for text editing, there are much better xml editor. In particular you can find schema aware editor. For example, intelij idea community edition ( https://www.jetbrains.com/idea/ ) is free and work very well on GC3 xml files, no configuration required. It will tell you in real time if you make any mistake in your file (tag name, order or even content) and it has very useful auto completion (ctrl+space). There are other too. It will make you win a lot of time I think :) Having schema and schema aware tooling is one of the main reason to use xml instead of less verbose, easier to read/write configuration files.

Reply #22 Top

I recommend notepad++ mostly because it's very lightweight and straightforward; for most people, that's more useful than using a full-on IDE. Also, Schema awareness doesn't work automatically unless you're modding directly in the game folder (which strongly recommend against), as the location is defined using relative pathing. You can change that, if you know what you're doing - but I'd rather not assume people do.