Jump to content
Age of History 3
11:59 Development Team

ANALYTICALENGINE | Custom UIs, Mapmodes, Event Scripting, Modded Multiplayer, and Tooltips

Recommended Posts

AnalyticalEngine - Icon

AOC3, Open Sourced.

Take a sledgehammer to those modding restrictions.

---

Join our community! 68747470733a2f2f696d672e736869656c64732e

AnalyticalEngine (Project Orion) is a game engine that opens up the core binary code of AOC3 and removes hardcoded features and mechanics by allowing for full NashornJS scripting in mods, as well as providing an API for Event Conditions, Effects, Game Scopes, modded Multiplayer (MP) support, and custom mapmodes and UIs. This allows for full hybrid Java and JavaScript modding support.

To get started with modding in AnalyticalEngine, simply add .ds/.js files in your mod folder. These will be automatically detected by the game engine and executed in-game. Consider also reading the attached Documentation or asking for support from our Discord server.

Installation: GitHub | Steam

Latest Release: 0.6b - Centurion. (Make sure to check GitHub installation instructions before downloading).

  1. Install Java SDK 23.
  2. Download the current src/AOC3-Source.jar, and drop it into any basegame AOC3 directory.
  3. You may now either run it normally as a Java binary or via the command line in the extracted folder if you wish to access AnalyticalEngine's console: java -jar src/AOC3-Source.jar

-

image.thumb.png.2dc0a90ae42b6511db3d57f9c88b02b0.png

Documentation:

Note: Documentation is currently a work-in-progress and may not necessarily be complete.

Features:

image.thumb.png.64ad4b0f03eff7f44db0d3d9c4db0be5.png

Current Feature List.

  • Added Singleplayer support for the Multiplayer build of the game.
  • Custom Event support.
  • Custom Mapmode support.
  • Custom UI support.
  • Fixed various localisation glitches.
  • Fixed various map glitches.
  • Full NashornJS compatibility and scripting.
  • Modded Multiplayer support.
  • Overhauled Editor UIs:
    • Civilisations can now be directly edited by right clicking on a Civilisation in the Scenario Editor.
    • Province Names can be edited directly from in-game editors.
    • Resource Editor overhaul.
    • Scenario Editor overhaul.
    • Terrain Editor overhaul.
  • Overhauled tooltips now allow for inline coloured text changes and images in Events.
  • Reworked Conditions (Triggers) and Scopes.

-

image.thumb.png.4e3362206d843fec30972ad385199e65.pngimage.thumb.png.b23e876e376c4fffcde7c4d01e8e8e75.png

image.thumb.png.011741256590e6844d9cda105bddad7f.pngimage.thumb.png.a3a2367d9f15b7a1a738d140ba42b255.png

image.png

Edited by 11:59 Development Team
Added latest release.

Share this post


Link to post
Share on other sites

 

DEV UPDATE #1 - Regions And Hours.

Since the last update, AnalyticalEngine has added in several new changes, including a revamped in-game Regions Editor, better Event limit optimisation, as well as adding back hours to the MP version of the game. Alongside other Map editors, the Regions Editor allows you to edit Regions from the game without messing with .json files, and allows for adding new regions more easily. It can be seen below:

image.thumb.png.7d087005da5730a2c32bd0ba77b779ca.png

The new Regions Editor in action.

There are several missing features between the Singleplayer (SP) and Multiplayer (MP) versions of the game, and we're working currently to bridge the gap. We still haven't really been able to properly confirm MP compatibility with these new changes, so they may be breaking in that regard. Additionally, we plan to wait until Lukasz settles down and much of the MP/SP gap is addressed before updating to newer versions.

In this regard, we have also readded vanilla event parsing to Multiplayer games. Normally, MP Events are completely disabled - we have re-enabled them.

We have also been working on further Deepscript Effects and laying the groundwork for Deepscript Variables. Once done, Variables will allow you to bind JS variables to specific scopes (i.e. Provinces/Civilisations), where they can be kept track of and displayed in-game. To this end, current Scope OnActions allow you to track players' in-game interactions and hook them to an Event, Custom UI, or even Mapmode. Various event handlers are also available to detect in-game page changes, for instance. Full Deepscript compatibility as outlinedd in documentation should be complete by March.

Steam Installation.

There has also been some confusion as to how you can download this from Steam. Simply put, you open your game's file folder, go to mods/AnalyticalEngine/, and drag out AOC3-Source.jar into your game folder before running it. Make sure JDK 23 is installed before you do. This is similar to how the Map Editor is installed.

 

Anyway, that'll be it. Hopefully these changes are of use. We do not plan to immediately revamp the Continents editor in the same way since there are less Continents fpr this system to be useful, but we will also be considering it at a later date.

Share this post


Link to post
Share on other sites

10 hours ago, 11:59 Development Team said:

 

DEV UPDATE #1 - Regions And Hours.

Since the last update, AnalyticalEngine has added in several new changes, including a revamped in-game Regions Editor, better Event limit optimisation, as well as adding back hours to the MP version of the game. Alongside other Map editors, the Regions Editor allows you to edit Regions from the game without messing with .json files, and allows for adding new regions more easily. It can be seen below:

image.thumb.png.7d087005da5730a2c32bd0ba77b779ca.png

The new Regions Editor in action.

There are several missing features between the Singleplayer (SP) and Multiplayer (MP) versions of the game, and we're working currently to bridge the gap. We still haven't really been able to properly confirm MP compatibility with these new changes, so they may be breaking in that regard. Additionally, we plan to wait until Lukasz settles down and much of the MP/SP gap is addressed before updating to newer versions.

In this regard, we have also readded vanilla event parsing to Multiplayer games. Normally, MP Events are completely disabled - we have re-enabled them.

We have also been working on further Deepscript Effects and laying the groundwork for Deepscript Variables. Once done, Variables will allow you to bind JS variables to specific scopes (i.e. Provinces/Civilisations), where they can be kept track of and displayed in-game. To this end, current Scope OnActions allow you to track players' in-game interactions and hook them to an Event, Custom UI, or even Mapmode. Various event handlers are also available to detect in-game page changes, for instance. Full Deepscript compatibility as outlinedd in documentation should be complete by March.

Steam Installation.

There has also been some confusion as to how you can download this from Steam. Simply put, you open your game's file folder, go to mods/AnalyticalEngine/, and drag out AOC3-Source.jar into your game folder before running it. Make sure JDK 23 is installed before you do. This is similar to how the Map Editor is installed.

 

Anyway, that'll be it. Hopefully these changes are of use. We do not plan to immediately revamp the Continents editor in the same way since there are less Continents fpr this system to be useful, but we will also be considering it at a later date.

Yes 

Share this post


Link to post
Share on other sites

I'll try to close out the Effects and related Documentation by the tail end of March, after which I'll be working on refactoring the game to be more mod-compatible, expanding some basegame mechanics, and making those modular (i.e. Pops, Production Chains, Buildings).

Share this post


Link to post
Share on other sites

On 2/23/2025 at 1:36 PM, PeteFromPat said:

Hey can we use this for our mod?

AnalyticalEngine can be used for any mod. You can also fork, redistribute, repackage, or modify the engine however you wish to.

Patch Notes (25 February 2025) - Beta 0.2.

  • Regions Editor fixed.
  • Steam Workshop page fixed (English/French/German).
  • Main Menu overhauled so that the Multiplayer build can now load games properly.
  • Added the following functions to Deepscript:
    • getCivilisationFlag(arg0_civ_tag, arg1_flag_key)
      getGlobalFlag(arg0_flag_key)
      getProvinceFlag(arg0_province, arg1_flag_key)
      setCivilisationFlag(arg0_civ_tag, arg1_flag_key)
      setGlobalFlag(arg0_flag_key)
      setProvinceFlag(arg0_province, arg1_flag_key)
      removeCivilisationFlag(arg0_civ_tag, arg1_flag_key)
      removeGlobalFlag(arg0_flag_key)
      removeProvinceFlag(arg0_province, arg1_flag_key)

      getCivilisationVariable(arg0_civ_tag, arg1_variable_key)
      getGlobalVariable(arg0_variable_key)
      getProvinceVariable(arg0_province, arg1_variable_key)
      setCivilisationVariable(arg0_civ_tag, arg1_variable_key, arg2_value)
      setGlobalVariable(arg0_variable_key, arg1_value)
      setProvinceVariable(arg0_province, arg1_variable_key, arg2_value)
      removeCivilisationVariable(arg0_civ_tag, arg1_variable_key)
      removeGlobalVariable(arg0_variable_key)
      removeProvinceVariable(arg0_province, arg1_variable_key)

  • Note. Variables do not currently carry between sessions. This can be manually implemented, but we are currently working on implementing that feature.

We'll try to implement remaining Effects by the end of the week and move onto proper full-domain feature support and better cross-platform compatibility.

Share this post


Link to post
Share on other sites

On 2/26/2025 at 1:39 PM, Wayne23lololh said:

And what about the war system, would it be possible to reduce troops movements in enemy territory ? Or something like that

Create a new file in your mods/<mod_name>. It must have a .js extension.

You can then reduce troop movements in enemy territory as follows:

//mods/<mod_name>/occupied_territory_reduce_movement_speed.js
//Example Code: Reduce troop movement in all occupied territory
onGameMonthlyInterval(function(){
  var all_provinces = getAllProvinces();
  
  for (var i = 0; i < all_provinces.length; i++)
    if (isOccupied(all_provinces[i])) {
      //Set terrain to be hostile if occupied
      setProvinceVariable(all_provinces[i], "cached_terrain", all_provinces[i].getTerrainID()); //Cache previous terrain
      all_provinces[i].setTerrainID(getTerrainID("Hostile Terrain"));
    } else {
      //Rollback terrain if no longer occupied
      var cached_terrain = getProvinceVariable(all_provinces[i], "cached_terrain");
      if (cached_terrain) all_provinces[i].setTerrainID(cached_terrain);
    }
});

//mods/<mod_name>/game/terrain/TerrainTypes.json
{
	Name: "Hostile Terrain",
	ImageFile: ["no_terrain.png"],
	Color: [0, 0, 0],
	BaseEconomy: 0,
	BasePopulation: 0,
	BattleOver: 1,
	BuildCost: 1,
	Defense: 0,
	IncreaseGrowthRateCost: 0,
	MovementSpeed: 0.1, //-90% Movement Speed
	PopulationGrowth: 0
},

And that will basically set a -90% movement speed penalty on occupied terrain. Keep in mind you can do far more things with AnalyticalEngine. For example:

onWar(arg0_function)
- (arg0_options)
- civ_obj: (Object)
- civ_tag: (String)
- ot_civ_obj: (Object)
- ot_civ_tag: (String)
- war_obj: (Object)

onWarEnd(arg0_function)
(arg0_options)
- attackers: (Array<String, CivTag>)
- defenders: (Array<String, CivTag>)
- war_obj: (Object)

Can also be used as scopes similar to what is seen above with onGameMonthlyInterval(). That would allow you to microtarget specific armies and reduce their speed in certain provinces, but this is a pretty easy example of a similar mechanism.

Edited by 11:59 Development Team

Share this post


Link to post
Share on other sites

19 hours ago, 11:59 Development Team said:

Create a new file in your mods/<mod_name>. It must have a .js extension.

You can then reduce troop movements in enemy territory as follows:

//mods/<mod_name>/occupied_territory_reduce_movement_speed.js
//Example Code: Reduce troop movement in all occupied territory
onGameMonthlyInterval(function(){
  var all_provinces = getAllProvinces();
  
  for (var i = 0; i < all_provinces.length; i++)
    if (isOccupied(all_provinces[i])) {
      //Set terrain to be hostile if occupied
      setProvinceVariable(all_provinces[i], "cached_terrain", all_provinces[i].getTerrainID()); //Cache previous terrain
      all_provinces[i].setTerrainID(getTerrainID("Hostile Terrain"));
    } else {
      //Rollback terrain if no longer occupied
      var cached_terrain = getProvinceVariable(all_provinces[i], "cached_terrain");
      if (cached_terrain) all_provinces[i].setTerrainID(cached_terrain);
    }
});

//mods/<mod_name>/game/terrain/TerrainTypes.json
{
	Name: "Hostile Terrain",
	ImageFile: ["no_terrain.png"],
	Color: [0, 0, 0],
	BaseEconomy: 0,
	BasePopulation: 0,
	BattleOver: 1,
	BuildCost: 1,
	Defense: 0,
	IncreaseGrowthRateCost: 0,
	MovementSpeed: 0.1, //-90% Movement Speed
	PopulationGrowth: 0
},

And that will basically set a -90% movement speed penalty on occupied terrain. Keep in mind you can do far more things with AnalyticalEngine. For example:

onWar(arg0_function)
- (arg0_options)
- civ_obj: (Object)
- civ_tag: (String)
- ot_civ_obj: (Object)
- ot_civ_tag: (String)
- war_obj: (Object)

onWarEnd(arg0_function)
(arg0_options)
- attackers: (Array<String, CivTag>)
- defenders: (Array<String, CivTag>)
- war_obj: (Object)

Can also be used as scopes similar to what is seen above with onGameMonthlyInterval(). That would allow you to microtarget specific armies and reduce their speed in certain provinces, but this is a pretty easy example of a similar mechanism.

Bro I don't know where you came from but you're already one of the best modder here !

Share this post


Link to post
Share on other sites

On 2/28/2025 at 1:56 AM, YouravaragebrazilianAoCfan said:

Question here:

If I made mods for AoH3 using this mod would it have a compatibility issue with vanilla? (Example: Scenarios not working properly)

AnalyticalEngine is a superset of AOC3. So what this means is that if your mod is compatible with vanilla, it is compatible with AnalyticalEngine. But if your mod is compatible with AnalyticalEngine, it might not be vanilla compatible without the end player having AnalyticalEngine also installed.

Share this post


Link to post
Share on other sites

Posted (edited)

Patch Notes (1 March 2025) - Beta 0.4.

These patch notes cover everything from the release of 0.2b Cogwheel to 0.4b Perimeter. The current release can be found at https://github.com/Australis-0/AnalyticalEngine/releases/tag/beta-0.4.0-perimeter.

0.4b - Perimeter

(1 March 2025). 03:19GMT. Stable Release.

  • Core Deepscript Functions are complete.
  • Finished adding Civilisation effects.
  • Added Province effects.
  • Fixed bugs related to the base 11:59 scenario not loading.
  • Further integrated Steam into AnalyticalEngine
  • Steam should now automatically start up on Windows/MacOS/Linux if not already started
  • This should fix both Steam and out-of-directory startup issues

0.3.2b - Chrome Dome

(28 February 2025). 17:22GMT. Stable Release.

  • CRITICAL BUGFIX: Fixed issues with setGlobalVariable() having duplicate namespaces, causing in-game editors not to work
  • Fixed some event handlers
  • Fixed in-game Custom UIs
  • Added better .json parsing for mods with multiline descriptions

0.3.1b - Broken Arrow

(27 February 2025). 23:32GMT. Stable Release.

  • Fixed working directory compatibility issues (Windows). This is a PRIMFIX and is not guaranteed
  • If you continue to run into issues with this in the meantime, make sure you run java -jar AOC3-Source.jar from the folder in which it is located.
  • Fixed repo Deepscript Variable issues with merging
  • Added Civilisation effects up to 'Politics (Internal)'
  • Added additional military_framework functions, unit_framework, as well as fixed helper functions for dealing with Generals and Advisors
  • Fixed loadGenerals()

0.3b - Empty Quiver

(25 February 2025). 20:43GMT. Stable Release.

  • Removed AOC3-Source.jar from LFS tracking. This is now moved to manual binaries.
  • Fixed repo conditions.
  • Added main.gamestate saving/loading, meaning that Deepscript Variables now properly function.
Edited by 11:59 Development Team

Share this post


Link to post
Share on other sites

1 hour ago, 11:59 Development Team said:

AnalyticalEngine is a superset of AOC3. So what this means is that if your mod is compatible with vanilla, it is compatible with AnalyticalEngine. But if your mod is compatible with AnalyticalEngine, it might not be vanilla compatible without the end player having AnalyticalEngine also installed.

So I may not be able to play this great mod as I mostly play AoH3 to make mods for others so this would make many scenarios of mine not vanilla compatible

Share this post


Link to post
Share on other sites

Posted (edited)
11 hours ago, YouravaragebrazilianAoCfan said:

So I may not be able to play this great mod as I mostly play AoH3 to make mods for others so this would make many scenarios of mine not vanilla compatible

Your scenarios would be vanilla compatible, but higher-level elements (Custom UIs, Scripted Events with Custom Tooltips) obviously wouldn't be. AnalyticalEngine is basically similar to Uwut Engine (for AOC2), but much broader in scope and supports heavy-duty scripting.

We plan to release with full installer support but that will take some time.

Edited by 11:59 Development Team

Share this post


Link to post
Share on other sites

Posted (edited)

Patch Notes. 0.5 Beta (Rhine).
(15 March 2025). 18:44GMT. Stable Release.
- Added support for custom mapmodes (in-game, as well as editor mapmodes) for modding. This should now appear in-game next to the minimap.
- Loading tips have been overhauled.
  - Custom loading tips are now possible by overwriting the relevant Bundle with locale support.
  - Ellipses at the end of loading tips have been removed.
- Map scripting now supports loading both Population and Economy/BaseDevelopment data from Velkscala/Eoscala.
  - Eoscala 1.0 - Gridded economic raster data from 10000BC-2022AD (GDP PPP), separate project: https://github.com/Confoederatio/Eoscala-Velkscala/tree/main/eoscala_1.0
  - Velkscala 0.5 - Gridded population raster data from 10000BC-2023AD, separate project: https://github.com/Confoederatio/Eoscala-Velkscala/tree/main/velkscala_0.5
  - Both Eoscala/Velkscala may be loaded in-game through the use of console loadPopulationNumberData(arg0_provinces_file_path, arg1_numbers_file_path) and console loadEconomyNumberData(arg0_provinces_file_path, arg1_numbers_file_path) respectively. You need to generate a provinces file from the loaded gamestate first and align it with those rasters. You can do so by using console saveProvinceMap(arg0_file_path).

NOTE: Eoscala/Velkscala are used for Map Editor > Map > Base Development Level (Economy) and Map Editor > Map > Growth Rate Editor (Population) respectively. 
- Music framework allows for mods to use the playMainTheme() function upon game load. This function is semi-stable, and rarely results in Vorbis crashes, but it can happen.

Edited by 11:59 Development Team

Share this post


Link to post
Share on other sites

DEV UPDATE #2 - Custom Mapmodes and Map Scripting.

It has been some time since the previous update since we were primarily busy with university. That is now through. To celebrate this, we've added In-Game Custom Mapmode support, Map Scripting support, a new music framework, and databases to go along with it. We have also moved our GitHub account's URL from one of our personal contributors' accounts fully over to Confoederatio. That's right - repossessed. In addition, both the nascent 11:59 mod as well as AnalyticalEngine have been placed under CTD, or Confoederatio, Technical Division (in contrast with CRD, the research division that does actual research). The full fixes and patch notes for it are seen above.

image.png.9c0f0e5a9d84da0ba522517f7c1cde24.png

Mapmodes now fold outwards from the Minimap. You can click the chevron at left to expand custom modded mapmodes.

The way custom mapmodes work are by specifying a .js file in your mod folder and utilising the addMapmode() scope with the following options:

/**
 * addMapmode() - Adds a modded in-game mapmode to config.mapmodes.
 * @param {Object} [arg0_options]
 *  @param {String} [arg0_options.id] - The ID of the mapmode to declare in config.mapmodes. Best practices indicate you should have a dedicated mod ID.
 *  @param {String} [arg0_options.name] - The in-game display name for your mapmode.
 *
 *  @param {boolean} [arg0_options.is_editor_mapmode=false] - Whether this is an editor mapmode.
 *  @param {boolean} [arg0_options.is_game_mapmode=false] - Whether this is an in-game mapmode.
 *  @param {boolean} [arg0_options.live_update=false] - Whether this is mapmode should update live. Decreases performance at the cost of a live update loop.
 *  @param {boolean} [arg0_options.separate_mapmode=false] - Whether this is a fully-fledged mapmode, or a sub-mapmode of the pre-existing applied mapmode.
 *
 *  @param {Function} [arg0_options.special_function] - Must return an RGBA value for all provinces in array format, [0-255, 0-255, 0-255, 0-1]. Passes (province_obj). Undefined assumes a fully transparent province.
 */

We provide the example of a religion mapmode in the Devlog, but this is fully customisable so long as you make sure that it returns an RGBA value that you wish from various conditions (see Documentation). There is still some level of jank with in-game mapmodes, but this can always be fixed by the end user, though we are working on it. You can see exactly how you would go about coding such a custom mapmode below:

addMapmode({
    id: "11.59_religion",
    name: "Religion",

    is_editor_mapmode: true,
    is_game_mapmode: true,
    live_update: true,
    separate_mapmode: true,

    special_function: function (arg0_province_obj) {
       //Convert from parameters
       var province_obj = getProvince(arg0_province_obj);

       //Initialise main
       if (!main.all_religions) main.all_religions = getAllReligions();

       //Declare local instance variables
       var religion_obj = main.all_religions[province_obj.getReligion()];
       var province_colour = undefined;
       var province_religion_colour = religion_obj.Color;

       //Return statement
       return [province_religion_colour[0]*255, province_religion_colour[1]*255, province_religion_colour[2]*255, 0.85];
    }
});

We have also added better Windows-side support. AnalyticalEngine will no longer malfunction if you do not have Steam open, and it will also work if you start AnalyticalEngine from outside the given src file. You may still have to start it twice to get it working each time your computer boots up - we are unsure why this is. There are now also options for playing custom music: playMusic() works like the Event Outcome provided by the basegame, whilst adding playMainTheme(arg0_file_path) plays a song as the main theme upon startup. It must, of course, be in a .js file within the mods/<mod_name> folder.

gdp_ppp_1100.thumb.png.a7e95a861860281024b875ce49d6506f.png

GDP (PPP) in 1100AD. You can now use data like this for automatically populating base province map data, assuming your projection is equirectangular.

Finally, there is economic and population scripting. Most of these instructions have been published above alongside corresponding datasets (for Base Development/Economy and Population/Province Growth Rate) for use, and you can view the full methodology for constructing these datasets here: https://github.com/Confoederatio/Eoscala-Velkscala/blob/main/Eoscala 1.0-Velkscala 0.5 - A Gridded Reconstruction of Global GDP and Population from 10000BC to the Present.pdf.

With that, 0.5b - Rhine is released. The only main missing feature left are Custom UIs, which are technically supported, but for which good tooling does not currently exist.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Age of History Games