Jump to content
Sign in to follow this  
deanolium

Mod Script Findings

Recommended Posts

Since Thygrrr released his cc unpacker tool and thus exposed the moddable scripts, the next step for the community is probably to put down our findings of playing with the code.

Here's my current findings - feel free to add your own to this list. Also please note that there may (and probably will be) errors in this list as it's just based on reading the code and some observations. If you find any mistakes, list them below and we can try and keep this updated:

1 - TimeWarp. This is controlled by g_Game.TimeWarp - a function which takes 'true' to turn it on, and 'false' to turn it off. However, there is a few problems with this. At the start of the game, this function can be freely turned on and off (for a 12x acceleration). But once you do something which normally turns timewarp off (either hitting 'v' to stop the carrier; setting sail to an island and it arrives; or hit cancel on TimeWarp) then whenever you call the TimeWarp function to turn it on it just goes directly to "Leaving TimeWarp 3....2....1....". There's no apparent function to control this behaviour - so manual timewarp will be difficult to set up. A possible work around is to have a variable holding whether manual timewarp is on or not; and if it is then every cycle it calls g_Game.TimeWarp(true), which should either keep Leaving TimeWarp set on '3', or will make it do the countdown again and again. Pretty kludgy though.

I've played around with TimeWarp more, and making it call the TimeWarp function each cycle when you press a button works. However, timewarp has some strange effects. Vehicle speed (except for Carrier and Barque) isn't increased during TimeWarp. So it won't speed up Mantas or Walruses. Also it turns off the PathFinding AI, so any vehicle moving will just go in a straight line regardless of anything. I'm not sure if it speeds up command center building (need to time it manually with and without I guess), but resource gain and production are increased.

2 - AI Pathfinding. This doesn't appear to be exposed. The functions which seem to handle this are: CreateMovementAction, CreateRouteFollowAction, FindClosestWaypoint, FindClosestReachable - all of these appear to be in the executable itself.

3 - AI Tactics. This looks like it is exposed to us, though the AI itself is pretty basic - especially for carrier attack/defense AI. For the carrier this appears totally unfinished, which explains the easy time people have been having against the enemy carrier. It simply sends out it's vehicles to attack the first enemy it finds in it's list. Also, it appears that it might only send out as many vehicles as there are attackers. All of which will just attack that first enemy. From it's EstimateUnitNeed function (which is meant to take in a type of vehicle, and it then says how many of which it needs), it doesn't care about what type of vehicle is needed. However, it does look like it will spit out Mantas before spitting out Walrus's. This is really sorely lacking and could easily be fixed up to make the carrier AI more formidable.

4 - Unit Control Behaviour - By this I mean how the game decides which units should be selected to assist the current unit; and when to suspend/enable plotted routes. This is all controlled by telecontrol.h. The DetermineX set of functions appear to be called in a big loop (which goes through each vehicle you have) for each vehicle, and return 0 if that vehicle shouldn't be selected for that command, and 1 if it should. That is, when you put, say, the reticle on an enemy then use the radial menu to select attack, which units are then eligable.

There's also a set of OnX functions which are called when certain events happen. For instance, OnMap appears to be called when the player moves onto or out of the map. For people who have an issue with the AI resuming plans when you leave a unit, this is the place to go.

That's the first set of findings. I hope it helps other modders, and it'll be interesting to see what things we can actually do with this!

---------- Post added at 11:49 ---------- Previous post was at 11:45 ----------

5 - Messages. To add a message on screen, use g_Game.AddMessage(message, color, type). I've not explored this too much, but am using it like g_Game.AddMessage("Test Message", COLOR_GREEN, LMF_EMPIRE) for testing.

Edited by deanolium

Share this post


Link to post
Share on other sites

nice work indeed !!

3 - AI Tactics. This looks like it is exposed to us, though the AI itself is pretty basic - especially for carrier attack/defense AI. For the carrier this appears totally unfinished, which explains the easy time people have been having against the enemy carrier. It simply sends out it's vehicles to attack the first enemy it finds in it's list. Also, it appears that it might only send out as many vehicles as there are attackers. All of which will just attack that first enemy. From it's EstimateUnitNeed function (which is meant to take in a type of vehicle, and it then says how many of which it needs), it doesn't care about what type of vehicle is needed. However, it does look like it will spit out Mantas before spitting out Walrus's. This is really sorely lacking and could easily be fixed up to make the carrier AI more formidable.

This needs to be adressed as soon as possible imho

Share this post


Link to post
Share on other sites

One thing is that for the Carrier Tactics, that's just based on a look through the files and I may well be missing something (that's almost guaranteed) as I haven't actually tested my findings yet. But if it is what it looks like, then it means that simply making it's carrier AI evaluation functions a bit more complex could create a more interesting challenge.

Share this post


Link to post
Share on other sites

//! send unit at 'to'

proto native Action CreateMovementAction( vector to );

//! send unit at 'to' by direct steering

proto native Action CreateIMovementAction( vector to );

These in cc.h, CreateIMovementAction is not in any other file, yet CreateMovementAction is used 30 times in 7 files, I tried changing all the CreateMovementAction to CreateIMovementAction in those 7 files, the walrus seemed to have more positive steering and climb better but that could be just wishfull thinking.

Share this post


Link to post
Share on other sites

Interesting -- definitely something to play with. I just wish that the code for these functions were exposed. Or at least what interactions it has so we could make our own versions. I really do think that there's pretty interesting path finding code in there, it just has a couple of flaws which cause the whole system to break down.

Share this post


Link to post
Share on other sites

Something interesting I've just found. The AI takes literally no time (well one cycle) to take over a neutral island. This means it can rapidly take them over far faster than the player. This is controlled in scripts/advisors/assault.h and I'm not sure whether it's a bug or not. It does make it unfair and probably should be tweaked to take some time for the AI to do so.

Share this post


Link to post
Share on other sites

Anyone figue out how to add GUI stuff yet? Like slider bars for the game setup?

Share this post


Link to post
Share on other sites

My cliffnotes / rants / silver linings on the horizon:

  • The scripting language has polymorphy and is object oriented. Native functions are explicitly marked as such, making it easy to stop searching.
  • It will be possible to make pretty awesome mods with this. Having discected Arma2 and DayZ, I have to say this game is the most elegantly moddable game of the three. The Carrier Command engine is considerably superior in this regard.
  • Some code is commented in czech. Google translate has problems with it, but usually you can guess what they meant.
  • My favorite string literal in the game is "muj walrus". So cute! :o
  • There are multiple remnants of old strategy campaigns, meaning it's nice to see how to build a small campaign with fewer islands for testing
  • UI is not (really) possible because there doesn't seem to be a way to add an event handler for new buttons, etc. However, you could possibly abuse new values. You can easily change the ui by editing the layouts in the layouts folder. Dram mentioned they will expose more UI functionality to scripts
  • Like many game code bases, the whole code is full of todos and hacks (sometimes documented as such, sometimes just left as stubs / obvious hardcoded things)
  • Rewriting/Improving/Modding the AI state machines isn't too much work, but understanding the way the assemblies on the game side work is going to be harrrrrd
  • Not exactly sure how do add new scripts to the game. Are they automagically compiled?
  • Scripts totally abuse headers (.h) files, no idea why this is the case (probably just bad coding style)
  • Lots of redundant code everywhere. I hope this gets cleaned up / refactored
  • Tremendous amounts of semi-hardcoded campaign events (that are the obvious source of the campaign bugs). I wonder why this wasn't at the very least encapsulated in a behavior class to unclutter the core game classes.
  • The AI system is, at best, half-done; on the plus side, it's very possible to fill in the blanks. Problematic will be strategic functions like getIslandImportance() or the whole pathfinding stuff, which, sometimes mysteriously, are in native code.
  • The hardest part will be to clean up the carrier class so both carriers are treated the same in code. This would make it feasible to have (gasp!) more than two factions duking it out.
  • However, there are some parts where a big warning says to not even change the order of function calls or "everything will be screwed up".

Edited by Thygrrr

Share this post


Link to post
Share on other sites

More Findings:

  • the bad island avoidance code appears to be overly convoluted. I'm also pretty sure that once the maximum of avoided islands comes up, it will repeatedly overwrite the first island in the list (index 0), which could induce the "Ping pong" behavior we witnessed, where the carrier bounces between two islands it keeps failing to conquer
  • I haven't checked all the places, but array index overruns are probably quite likely to happen in that code if enough islands are being avoided, too

Actually, I'm pretty sure that once the 9th island is being marked for avoidance, the whole system breaks badly (the carrier is probably no longer able to make any decision on attacking an island, or the game even crashes).

That is presuming the military advisor / APA_MilitaryAdvisor is even used. I can't really find evidence of it, but it may be some native magic.

Edited by Thygrrr

Share this post


Link to post
Share on other sites

More findings

  • even as little as 10% damage to the engines makes the enemy carrier avoid your carrier

The carrier could be totally trashed otherwise (down to 60% or 40% depending on player.getskill() [whatever that is, exactly]), but if its engines need as much as a gentle wipe with a soft damp cloth, the enemy carrier becomes the world's largest chicken coop.

---------- Post added at 12:19 ---------- Previous post was at 11:56 ----------

Question

Has anyone found out where the concrete ______Advisors, like, APA_MilitaryAdvisor and UEC_ProductionAdvisor are actually instantiated?

I suspect it's in native code, but I'm not sure. Not even their names are mentioned as strings anywhere, yet they contain sumbstantial code.

---------- Post added at 12:45 ---------- Previous post was at 12:19 ----------

Eeep! Patch Files

c:\Program Files (x86)\Bohemia Interactive\Carrier Command Gaea Mission\patch00.pak <--- uh oh.

I'd really like to take a look at that file, please.

On the plus side, we probably found a way to deploy mods in packages (still poor mod interoperability, of course).

---------- Post added at 13:50 ---------- Previous post was at 12:45 ----------

Patch Files

The 1.02 patch is almost identical in script code (it only has a demo campaign added).

However, the databases are different. I'll try the new DB and tell you if that improves Steam pathfinding.

Retail data02.cc is identical to Steam data02.cc

---------- Post added at 13:57 ---------- Previous post was at 13:50 ----------

Self Patching

Game doesn't run after fiddling with the database. I suppose they are incompatible. Putting the whole .pak in doesn't work (no visible changes); and putting the unpacked .pak in breaks it as well.

On to a binary comparison of the two databases...

---------- Post added at 14:01 ---------- Previous post was at 13:57 ----------

DB Differences 1.01 Steam to 1.02 Retail

Version info at the start, and a dataset containing the string "Gravon", near some Walrus data. Several bytes were changed there.

---------- Post added at 14:09 ---------- Previous post was at 14:01 ----------

DB Manual Patch

Well... smack my head and call me Sandy. I think I now have the smartest Walruses on Steam.

Actually, they fail depending on island. They are pretty good on Fornax (and I think they are worse with the old db), but they completely fail trying to move across Deadlock, for example.

They seem to have problems on the roads leading down to the bridge at the center. And at the beach. And slopes in general, because they slide a bit or move faster than they expect, and then they skid when they come to a screeching halt, totally disoriented.

Hmm. Actually I think Deadlock has a totally broken navigation map. The walruses don't even understand how to go to certain locations, even though there's clearly roads leading there.

Edited by Thygrrr

Share this post


Link to post
Share on other sites

Native Functions

Binding to a native function that doesn't exist causes a read at address 0, I guess their linker simply creates the function pointers and if their loader returns a null, it uses that as the pointer. You then get a very nice crash message with an actual call stack / line number in the script.

Script Compiling

If you try to call a function in a script that doesn't exist (i.e. "doesntexist()"), the game won't launch.

Share this post


Link to post
Share on other sites

UI Modding

UI Scripting is actually *quite* possible already, including proper Observer Pattern / Event Handling and loading custom UI from UI files.

I'll post a short example in a little bit.

---------- Post added at 11:16 ---------- Previous post was at 11:08 ----------

Addendum: We could actually create a UI registry that would allow mod plugins that are cross compatible (as long as they focus on UI elements or adhere to a standard). The actual use of this might be limited, but it'd potentially alleviate the problem that all mods are mutually exclusive at the time.

Edited by Thygrrr

Share this post


Link to post
Share on other sites

Thygrrr, AFAIK any function needs to be specified to be scriptable before you can hope to call it.

I've successfully done some UI scripting already, that part of the game is pretty well scriptable. What I'd loooove to find out is where the animated crewmate stuff is defined (you know, the two guys sitting at consoles pushing buttons). I'd love to remove them from the background of the map because they make the game unplayable on my laptop (they use up a ton of polys and add little to the game) - Any ideas?

---------- Post added at 13:44 ---------- Previous post was at 12:58 ----------

Answer to my own question: The map background is defined in worlds/carriercontrolroom.ent and I've succeeded in completely removing all the background of the map. This makes the game completely playable on a Lenovo x121e with intel HD 3000 integrated graphics! Can I post the modified file here or is that a problem?

Edited by Toumal

Share this post


Link to post
Share on other sites
What I'd loooove to find out is where the animated crewmate stuff is defined (you know, the two guys sitting at consoles pushing buttons). I'd love to remove them from the background of the map because they make the game unplayable on my laptop (they use up a ton of polys and add little to the game)

Too bad to hear they are a resource hog, I think it looks fantastic with them there in the background! :)

Ps. Seen that wide curved monitor the guy to the left have in front of him? Mmmm... :)

Edited by Scepticer

Share this post


Link to post
Share on other sites
A wiki would be nice, otherwise well done!

That's not a bad idea; I'm going to be pretty busy over the next couple of weeks, but if someone wants to set one up, that could be a good way to organise this information.

---------- Post added at 23:50 ---------- Previous post was at 23:46 ----------

That is presuming the military advisor / APA_MilitaryAdvisor is even used. I can't really find evidence of it, but it may be some native magic.

Military Advisor is definitely being run. I used a function to display text on the screen whenever parts of Military Advisor was run; along with some data values (which is how I figured out what's going on with island invasions/assaults) and it's showing that the functions are called.

I haven't done more than a very quick glance at the bad island code, but it's interesting that it looks bugged. Definitely be a good thing to fix.

Share this post


Link to post
Share on other sites

Yes I'm starting to figure most of it out now.

About fixing the code - the more I look at it, I think I'll make a cleaned up version of the game's script code that only shadows "script.c". That would make for a much cleaner code base. The current script code is a complete dependency hell, and has so many unrelated things bunched into the same files. The problem is, it requirea touching / refactoring almost every file in the scripts folder.

Another issue is (of course) the code base being improved / fixed by Bohemia Interactive guys themselves over the next months. I'll create a private repo somewhere so I can track their script changes.

That said, there are silver linings, such as the strategy pattern being used extensively for unit actions (like the Manta Dogfight Motions). That'll be easy to extend and improve. Also, some sections have good comments and a fairly clean code style. Others - not so much...

I can imagine an intermediate step (so one can release early, release often), but in the long run, I want to use this cool engine to make a really cool mod unencumbered by chaotic code that's partially documented in Czech. :cool:

I'm not entirely sure how much is really scripted in /scripts. So my idea might get shot down by reality even before it can fail to fly.

Edited by Thygrrr

Share this post


Link to post
Share on other sites

Sadly much of the internal stuff just seems to not be exposed to scripting at all. I don't know if they'll change that anytime soon because it would mean converting the stuff currently in C/C++ into script code...

Also Thygrrr, nice to see someone else who's read the GOF book on patterns ;)

Share this post


Link to post
Share on other sites

carrier.exe

The executable file supports the following command line switches (there may be more, especially implicit arguments without switches):

  • -nosplash
  • -load
  • -client
  • -server

I have no clue about the syntax. The game doesn't properly launch as -client or as -server; -nosplash works as expected.

---------- Post added at 09:01 ---------- Previous post was at 08:58 ----------

Shadowing content with PAK files

On steam, the following techniques do NOT result in successfully modifying the game.

  • adding a patch00.pak with custom content, with or without mentioning it first in settings.xml (first or last)
  • adding a mymod.pak with custom content, with or without mentioning it first in settings.xml (first or last)
  • adding a data03.cc, with or without mentioning it first in settings.xml (first or last)
  • creating a new data02.cc with changed files from data00.cc and data01.cc

There may be some command line option necessary to get it to work. Kudos to whoever finds the solution first.

Edited by Thygrrr

Share this post


Link to post
Share on other sites
carrier.exe

The executable file supports the following command line switches (there may be more, especially implicit arguments without switches):

  • -nosplash
  • -load
  • -client
  • -server

I have no clue about the syntax. The game doesn't properly launch as -client or as -server; -nosplash works as expected.

---------- Post added at 09:01 ---------- Previous post was at 08:58 ----------

Shadowing content with PAK files

On steam, the following techniques do NOT result in successfully modifying the game.

  • adding a patch00.pak with custom content, with or without mentioning it first in settings.xml (first or last)
  • adding a mymod.pak with custom content, with or without mentioning it first in settings.xml (first or last)
  • adding a data03.cc, with or without mentioning it first in settings.xml (first or last)
  • creating a new data02.cc with changed files from data00.cc and data01.cc

There may be some command line option necessary to get it to work. Kudos to whoever finds the solution first.

Did you try to use the -load switch with a packed mod file?

Share this post


Link to post
Share on other sites

Not yet.

---------- Post added at 10:10 ---------- Previous post was at 09:31 ----------

-load takes a savegame as argument.

Share this post


Link to post
Share on other sites

The -client and -server commands are taunting me. I wanna have multiplayer :/

Share this post


Link to post
Share on other sites

More Command Line Params

  • -player me|neutral|enemy (yes, you can play as green or red! but it doesn't *really* work, lol)
  • -nowaitres 1
  • -campaign

---------- Post added at 17:02 ---------- Previous post was at 16:28 ----------

Main Entry Point

The main entry point is in script.c (I wasn't exactly sure, but it's there). That means to write a total conversion, you only need to exchange that file and you can rewrite almost your entire game logic from there (I might be talking out of my ass but it seems to be this way). EDIT: Maybe not. I'm trying to build a "minimal mod", basically a hello world. It dies when it tries to set up some part of the physics system.

Other required files to run the game barebones are:

anm/animsetdef.xml

anm/pivots.xml

anm/skeletons.xml

anm/bonegroups.xml

sounds/soundsetdef.xml

materials/materials.h

sounds/shaders2.h

sounds/shaders2.h

sounds/xaudio2env.h

physics/materials.xml

physics/ragdolls.h

scripts/templates.ent

scripts/entities.xml

---------- Post added at 17:09 ---------- Previous post was at 17:02 ----------

Command Line Parameters in scripts

The int main(string cliparams) function in script.c seems to get the carrier.exe's command line parameters.

---------- Post added at 17:17 ---------- Previous post was at 17:09 ----------

File Access API

There's a complete file access API in proto.h, meaning you can parse stuff like your own custom island layouts and missions. This is very powerful. One could make a mod launcher with this.

Console Logging

proto void Print(void var); as specified in proto.h, no fricken clue where this is logging to, though. Netstat doesn't show any open ports so it's not logging to a debug monitor port or something.

---------- Post added at 19:06 ---------- Previous post was at 17:17 ----------

Dynamic Binding / Function Calls

Call(this, funcName, param);

---------- Post added at 19:07 ---------- Previous post was at 19:06 ----------

I am starting to wonder why they had to put so much into the native code. This engine can do pretty much anything script side!

---------- Post added at 19:12 ---------- Previous post was at 19:07 ----------

Goofed Up Polymorphism

	//! Determine if unit is manta
proto native bool IsManta();
//! Determine if unit is walrus
proto native bool IsWalrus();
//! Determine if unit is turret
proto native bool IsTurret();

Too bad the scripters for some reason couldn't use the engine's powerful OO capabilities to prevent such bollocks.

---------- Post added at 19:40 ---------- Previous post was at 19:12 ----------

Preprocessor

The scripting language has a macro preprocessor. Not sure how powerful it is.

However, one can define symbols like this (for example at the start of script.c)

#define DEVELOPER 1 (this actually enables a shitload of developer options. still trying to figure out where all the logging happens.)

However, it does seem like DEVELOPER has to be defined in every file you want it defined (I guess it's related to the interactive designer outlined below)

---------- Post added at 19:49 ---------- Previous post was at 19:40 ----------

Interactive Designer Tool

The Enforce engine SDK probably ships with an interactive editor, for which all the AddDesignerCheat(...) functions are. I'd love to get my hands on an Enforce SDK. Probably no good without the native codebase of Carrier Command, though.

---------- Post added at 20:04 ---------- Previous post was at 19:49 ----------

Log Files

Log Files are written into your steam profile.

<Steam Installation Path>\Steam\userdata\<your user id number>\65740\local

This is also where your savegames end up I guess. The (borked) video encoder in the game puts its video files there, as well.

---------- Post added at 20:29 ---------- Previous post was at 20:04 ----------

Profile-Based ccsettings.xml

Important tidbit: The ccsettings.xml in the Steam Carrier Command directory is merely a template. The actual used one is in your profile directory!

I can now mount arbitrary .pak files at load time. However, it doesn't shadow any existing files, no matter which way around I do it. (strange!). So maybe there is still an issue with the file. Maybe (!) chunk alignment, I'll try that.

---------- Post added at 21:03 ---------- Previous post was at 20:29 ----------

Shadowing content with PAK files

Okay, I figured it out. I skipped a byte in my pac1.py tool and the Enforce engine couldn't handle the smaller chunk (even though it wasn't malformed). Additionally, I was using the wrong settings file.

STEAM ONLY: Steps to shadow content with a PAC1 file (use the latest version of CarrierTools!!!)

  • Put all your mod components into a directory named like you want your mod to be named, and then pack that directory using pac1.py or by dragging that directory onto the package.bat that I conveniently include with the CarrierTools.
  • Put the resulting .pak into your Carrier Command directory
  • Open the ccsettings.xml that belongs to your player's profile - this is NOT the one in the Carrier Command directory, it's the one where your save games are.
  • Add the line <path directory="mymodname.pak" /> to the top of the filesystems list, replacing mymodname with the name of your mod, obviously.
  • Launch and enjoy.

This might still fail with patchXX.pak files around, though. Maybe one of you retail/sprocket (non-steam) users can send me your ccsettings.xml and tell me where it was saved so we can complete the documentation on this.

Edited by Thygrrr

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×