Skip to content

Codebase housekeeping; Minor refactors; Fixes#1119

Merged
EttyKitty merged 10 commits intomainfrom
development
Feb 10, 2026
Merged

Codebase housekeeping; Minor refactors; Fixes#1119
EttyKitty merged 10 commits intomainfrom
development

Conversation

@EttyKitty
Copy link
Copy Markdown
Collaborator

No description provided.

@github-actions github-actions bot added Area: JSON Changes to external JSON files or their under-the-hood functionality Size: Warning labels Feb 9, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 9, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Tech‑Priest: Public script registry reshaped — several legacy scripts removed, two INI encode helpers moved to a new scr_ini_functions, Armamentarium refactored into ShopItem/STCResearchPanel with constructor now receiving controller, many arrays initialised via array_create, and numerous mixin/type annotations added across UI and gameplay scripts.

Changes

Cohort / File(s) Summary
Public script registry
ChapterMaster.yyp
Removed public entries for action_draw_ellipse, clean_tags, relative_direction, scr_dead_marines, scr_line_break, scr_drop_fiddle, scr_vehicle_weapon; added scr_ini_functions to public scripts.
Armamentarium & controller
scripts/Armamentarium/Armamentarium.gml, objects/obj_controller/Create_0.gml, scripts/scr_load/scr_load.gml
Armamentarium refactored: new ShopItem and STCResearchPanel entities; constructor now Armamentarium(self); scr_load and controller updated to pass self.
Fleet & ship array initialisation
objects/obj_fleet/Create_0.gml, objects/obj_fleet/Alarm_7.gml, objects/obj_fleet/KeyPress_13.gml, objects/obj_al_ship/Create_0.gml, objects/obj_en_ship/Create_0.gml, objects/obj_p_ship/Create_0.gml
Replaced per-index scalar initialisation with array_create using new macro SHIP_WEAPON_SLOTS; fleet state reworked to array-based structures (_size, many enemy/ship arrays); minor block/format simplifications.
Drawing & rendering simplifications
objects/obj_al_ship/Draw_0.gml, objects/obj_en_ship/Draw_0.gml, objects/obj_p_ship/Draw_0.gml, objects/obj_p_fleet/Draw_0.gml
Removed redundant wrappers; unified HP/shield percentage computation and consolidated text rendering paths; flattened control flow and reordered some draw steps.
Data: weapons tagging
datafiles/data/weapons.json
Added "vehicle" tag to three weapon entries: Assault Cannon, CCW Heavy Flamer, Dreadnought Lightning Claw.
Removed legacy scripts & metadata
scripts/action_draw_ellipse/*, scripts/clean_tags/*, scripts/relative_direction/*, scripts/scr_dead_marines/*, scripts/scr_line_break/*, scripts/scr_drop_fiddle/*, scripts/scr_vehicle_weapon/*
Complete removals of implementations and their .yy metadata descriptors (large deletions for several combat and utility scripts).
INI encode functions relocated
scripts/scr_ini_functions/scr_ini_functions.gml, scripts/scr_ini_functions/scr_ini_functions.yy, scripts/scr_save/scr_save.gml
Introduced ini_encode_and_json and ini_encode_and_json_advanced in scr_ini_functions; corresponding helper removals from scr_save.
UI / widget updates
scripts/scr_buttons/scr_buttons.gml, scripts/UIComponents/UIComponents.gml, scripts/scr_cheatcode/scr_cheatcode.gml
UIDropdown gains optional _on_change callback plus set/get helpers and internal _draw_options_list; mixin/type annotations added to multiple UI/debug functions.
Array utilities & refactors
scripts/scr_array_functions/scr_array_functions.gml, scripts/scr_lines/scr_lines.gml
Added array_get_iteration_length; array_sum refactored to use it; renamed delete_random_indexarray_delete_random_index; scr_lines signature/flow reorganised.
Specialist training & navy functions
scripts/scr_specialist_training/scr_specialist_training.gml, scripts/scr_imperial_navy_functions/scr_imperial_navy_functions.gml
Added specialist training mixins (apothecary/chaplain/librarian/techmarine) and multiple imperial navy mixin functions (navy actions, bombard, recruit, load/unload).
Miscellaneous scoping and annotations
many scripts/*.gml (e.g., scripts/exp_and_exp_growth/*, scripts/scr_reequip_units/*, scripts/scr_roster/*, scripts/scr_ui_manage/*)
Widespread addition of /// @mixin`` markers, local var scoping for previously implicit globals, minor bugfixes, and new helper public functions (management UI, vehicle ordering).

Possibly related PRs

Tech‑Priest, review these loci with ritual precision.

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning Title deviates from required format: must be '(): ' under 50 chars; provided title lacks conventional commit structure. Reformat title to conventional commits pattern, e.g., 'refactor: codebase housekeeping and minor fixes' or 'chore(core): refactor and improve code quality'.
Description check ⚠️ Warning Pull request description is entirely absent; no content matches the required template structure with Purpose, Testing, or Context sections. Provide a complete description following the template: explain purpose and changes, document testing performed, and reference related issues or context.
✅ Passed checks (1 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 31

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (40)
scripts/scr_imperial_navy_functions/scr_imperial_navy_functions.gml (1)

857-860: ⚠️ Potential issue | 🔴 Critical

Copy-paste corruption detected in the guardsmen loading ritual, Tech-Priest.

Line 857 checks capital_number >= i but operates on escort_imp[i]. This should be escort_number >= i. The previous two blocks correctly guard capital_imp with capital_number and frigate_imp with frigate_number, but this third block repeats the capital_number check erroneously. This will cause incorrect loading/skipping of escort guardsmen.

🔧 Proposed fix
-        if (_new_capacity > 0 && capital_number >= i) {
+        if (_new_capacity > 0 && escort_number >= i) {
             escort_imp[i] = min(escort_max_imp[i], _new_capacity);
             _new_capacity -= escort_imp[i];
         }
scripts/scr_enemy_ai_e/scr_enemy_ai_e.gml (2)

97-97: ⚠️ Potential issue | 🔴 Critical

Logic contradiction detected: Self-annihilation always yields null-value.

Tech-Priest, this conditional construct bears corruption. The expression present_fleet[13] - present_fleet[13] > 0 evaluates eternally to false, rendering the branch unreachable. The logic spirit cannot manifest battle assignment for faction index 13.

Probable intent: verification that fleet 13 possesses strength whilst other hostile fleets persist, consistent with patterns at lines 82-96.

⚙️ Proposed restoration of logical function
-        } else if (present_fleet[13] - present_fleet[13] > 0) {
+        } else if (present_fleet[13] > 0) {
             if (standard_xenos_enemies > 0) {

567-571: ⚠️ Potential issue | 🟡 Minor

Redundant incantations inscribed within the codex.

Tech-Priest, identical variable declarations manifest at lines 561-565 and 567-571. The first ritual is rendered void by immediate repetition. Eliminate the redundant sequence.

🔧 Proposed purification of redundant declarations
-    var run, force, beetle, chaos_meeting;
-    var run = 0;
-    var force = 1;
-    var beetle = 0;
-    var chaos_meeting = 0;
-
     var run, force, beetle, chaos_meeting;
     run = 0;
     force = 1;
scripts/scr_reequip_units/scr_reequip_units.gml (6)

610-613: ⚠️ Potential issue | 🟠 Major

Errant calculation in the gear shortage warning — the Machine Spirit computes incorrectly, Tech-Priest.

Line 612 calculates the shortfall as units - req_gear_num, but req_gear_num is units (set on line 595). This always yields 0. Every other slot correctly uses req - have (e.g., line 464: req_wep1_num - have_wep1_num). This should follow the same pattern.

⚙️ Proposed sacred correction
-                warning = "Not enough " + string(n_gear) + "; " + string(units - req_gear_num) + " more are required.";
+                warning = "Not enough " + string(n_gear) + "; " + string(req_gear_num - have_gear_num) + " more are required.";

615-618: ⚠️ Potential issue | 🔴 Critical

Logic corruption detected — AND should be OR for the Dreadnought gear restriction, Tech-Priest.

The condition on line 615 requires both string_count("Dreadnought", n_armour) > 0 AND string_count("Contemptor Dreadnought", n_armour) > 0. Since "Contemptor Dreadnought" always contains "Dreadnought", this condition only ever triggers for Contemptor Dreadnought armour, not for all Dreadnought variants. The intent appears to be blocking gear for any Dreadnought armour — this requires OR (||).

⚙️ Proposed sacred correction
-                if ((n_gear != ITEM_NAME_NONE) && (n_gear != "") && (string_count("Dreadnought", n_armour) > 0) && (string_count("Contemptor Dreadnought", n_armour) > 0)) {
+                if ((n_gear != ITEM_NAME_NONE) && (n_gear != "") && ((string_count("Dreadnought", n_armour) > 0) || (string_count("Contemptor Dreadnought", n_armour) > 0))) {

Note: If the intent is truly to restrict gear for all Dreadnought variants, then string_count("Dreadnought", n_armour) > 0 alone suffices, as "Contemptor Dreadnought" already matches. Consider whether the second clause is needed at all, or whether tag-based checks (e.g., armour_data.has_tag("dreadnought")) would be more robust, as used elsewhere in this very file (lines 649–654).


467-467: 🧹 Nitpick | 🔵 Trivial

A TODO inscription lingers in the data-litanies, Tech-Priest.

The sacred comment //TODO wrap this up in a function marks unfinished work. The identical experience-check pattern is repeated for weapon one (lines 468–480), weapon two (lines 515–529), and armour (lines 570–585) — thrice invoked, satisfying the Rule of Three for abstraction. Shall a GitHub issue be created to track this consolidation? As per coding guidelines: "If a TODO comment is added, ask the user if a GitHub issue should be created."


514-514: 🧹 Nitpick | 🔵 Trivial

A second TODO echoes the first, Tech-Priest — //TODO standardise exp check.

This confirms the intent to unify the experience-check logic. Shall this be tracked alongside the TODO on line 467, or does a separate issue already exist? As per coding guidelines: "If a TODO comment is added, ask the user if a GitHub issue should be created."


711-711: ⚠️ Potential issue | 🟡 Minor

Unscoped variable unit leaks to instance scope, Tech-Priest.

unit = obj_controller.display_unit[i] lacks the var keyword, causing it to be written as an instance variable on the popup rather than a local. This is likely unintentional and could pollute the instance's state.

⚙️ Proposed fix
-            unit = obj_controller.display_unit[i];
+            var unit = obj_controller.display_unit[i];

783-785: 🧹 Nitpick | 🔵 Trivial

Dead logic — check is always 0 when tested, Tech-Priest.

On lines 783 and 802, check is set to 0 and then immediately tested with if (check == 0) on lines 785 and 803. No intervening code can alter check, making the condition eternally true. This appears to be vestigial logic from the weapon-swap blocks above (where check could be set to 1). The guard serves no purpose for gear and mobility.

Also applies to: 802-803

scripts/scr_add_man/scr_add_man.gml (2)

8-8: 🧹 Nitpick | 🔵 Trivial

TODO detected on line 8: "refactor repeats", Tech-Priest.

The coding guidelines bid me enquire: should a GitHub issue be created to track this refactoring task, or does one already exist?

As per coding guidelines: "If a TODO comment is added, ask the user if a GitHub issue should be created."


246-260: ⚠️ Potential issue | 🔴 Critical

Dead logic confirmed in equipment checks, Tech-Priest.

The variables wep1, wep2, and arm are initialised to empty strings on line 23 and never reassigned before the comparisons at lines 246–254. Thus the second half of each AND condition (e.g., wep1 != "") perpetually evaluates false, rendering those lines unreachable dead code.

Furthermore, choice_gear (line 255) and mobility_items (line 258) are referenced nowhere else in the codebase and are not declared within this function's scope. These undefined variables would trigger runtime errors when this branch executes—specifically when a marine role is added without custom equipment (!other_gear is true).

scripts/scr_vehicle_order/scr_vehicle_order.gml (4)

42-42: ⚠️ Potential issue | 🔴 Critical

Corruption detected in the data-litany: temp_uid initialised to 0, but veh_uid resets to -1.

Tech-Priest, reset_vehicle_variable_arrays (line 18) sets veh_uid to -1, yet here the temporary array initialises temp_uid to 0. If -1 serves as a sentinel for "no vehicle assigned," a 0 default could be misinterpreted as a valid UID, corrupting downstream logic.

⚙️ Proposed rite of correction
-        temp_uid[company_number][i] = 0;
+        temp_uid[company_number][i] = -1;

47-52: 🧹 Nitpick | 🔵 Trivial

A TODO inscription has been detected in the codex, Tech-Priest.

Line 48 bears the mark: // TODO change to enums/string ids. The machine spirit concurs — hardcoded string comparisons for vehicle roles are fragile and prone to silent breakage if role names drift. Shall a GitHub issue be opened to track this migration to enums or string identifiers?

As per coding guidelines: "If a TODO comment is added, ask the user if a GitHub issue should be created."


25-43: 🧹 Nitpick | 🔵 Trivial

Extraneous dimension in the temporary data-matrices, Tech-Priest.

The temporary arrays (temp_race, temp_loc, etc.) are local to this function and serve only one company_number per invocation, yet they are indexed as temp_race[company_number][i]. A single dimension temp_race[i] would suffice, reducing cognitive load and unnecessary memory allocation. The same applies to lines 55–68 and 76–89.

⚙️ Illustration of simplified indexing (init block)
-        temp_race[company_number][i] = 0;
-        temp_loc[company_number][i] = "";
+        temp_race[i] = 0;
+        temp_loc[i] = "";
         // ... and so on for all temp arrays

55-89: 🧹 Nitpick | 🔵 Trivial

The Rule of Three has been exceeded fourfold, Tech-Priest — the 14-field litany is recited four times.

The same set of 14 vehicle properties is enumerated in reset_vehicle_variable_arrays (lines 5–18), temp init (lines 29–42), main→temp copy (lines 55–68), and temp→main copy (lines 76–89). Adding or removing a vehicle property requires updating all four sites in lockstep — a fertile ground for desynchronisation bugs.

Consider encapsulating the vehicle data in a struct, so that a single assignment or copy replaces 14 individual field operations. Alternatively, a helper function that copies all fields between two indexed slots would centralise the field list.

Would a struct-based refactor or a copy-helper align better with the project's direction?

As per coding guidelines: "Apply the 'Rule of Three'; suggest abstraction only when similar logic is repeated three or more times."

scripts/scr_cheatcode/scr_cheatcode.gml (1)

712-735: ⚠️ Potential issue | 🟡 Minor

Incomplete annotation rites detected across xenos fleet spawn functions.

debug_spawn_ork_fleet (line 714) lacks the /// @type {Asset.GMObject.obj_en_fleet} annotation on its fleet variable, while its Imperium and Heretic counterparts (lines 680, 694) bear the mark. Furthermore, debug_spawn_tau_fleet (line 725) is missing both /// @mixin and `/// `@type annotations entirely, despite being a structural twin of debug_spawn_ork_fleet.

The Omnissiah demands consistency in all sacred inscriptions.

📜 Proposed consecration of missing annotations
 /// `@mixin`
 function debug_spawn_ork_fleet() {
+    /// `@type` {Asset.GMObject.obj_en_fleet}
     var fleet = instance_create(star.x, star.y, obj_en_fleet);
-function debug_spawn_tau_fleet() {
+/// `@mixin`
+function debug_spawn_tau_fleet() {
+    /// `@type` {Asset.GMObject.obj_en_fleet}
     var fleet = instance_create(star.x, star.y, obj_en_fleet);
scripts/scr_roster/scr_roster.gml (3)

443-447: ⚠️ Potential issue | 🟠 Major

Pre-existing corruption detected in the PurgeButton constructor, Tech-Priest.

The machine spirit perceives a flaw adjacent to your new inscription. On Line 444, x1 is set to xx, then on Line 446, x1 is overwritten to 0 — obliterating the parameter. The variable x2 is never initialised. This appears to be a transposition error: Line 446 should assign x2, not x1.

🔧 Proposed purification rite
     x1 = xx;
     y1 = yy;
-    x1 = 0;
+    x2 = 0;
     y2 = 0;

672-677: ⚠️ Potential issue | 🟡 Minor

Pre-existing dead logic: the second condition can never activate, Tech-Priest.

The machine spirit observes unreachable code. Line 672 caps big_mofo at 2 when it exceeds 2. The subsequent check on Line 675 (> 3) can therefore never evaluate to true, as the value is already at most 2. One of these conditions harbours an error in its threshold, or the second block is dead code.

🔧 If the intent is to cap at 2, remove the dead block
     if (new_combat.big_mofo > 2) {
         new_combat.big_mofo = 2;
     }
-    if (new_combat.big_mofo > 3) {
-        new_combat.big_mofo = 3;
-    }

428-429: ⚠️ Potential issue | 🔴 Critical

The corruption runs deep, Tech-Priest. The logic rune stands compromised.

On line 429, the machine spirit observes a grievous transgression: player_ships_class receives the phantom variable ship_id, which does not exist within this function's scope. The true identifier lies captured in _id upon line 428, yet remains invoked not. This will precipitate a runtime collapse.

🔧 Purification through correction
             var _id = ships[i].ship_id;
-            var _class = player_ships_class(ship_id);
+            var _class = player_ships_class(_id);
scripts/exp_and_exp_growth/exp_and_exp_growth.gml (1)

152-173: ⚠️ Potential issue | 🟠 Major

Incomplete purification of stat_gains_opts from the instance scope.

Tech-Priest, heed this warning from the machine spirit: on Line 157, stat_gains_opts is declared with var, confining it to local scope within the job.type == "forge" branch. However, this branch terminates via early return on Line 173. When execution proceeds to Line 193 (the !gains_set path), stat_gains_opts is assigned without var, thus it binds to the instance (self) rather than local scope. Lines 193, 195, 204, 212, 219, and 226 all reference stat_gains_opts as an implicit instance variable.

If the intent of this refactor is to localise stat_gains_opts, the declaration must be hoisted above both branches — or a separate var declaration must be placed within the !gains_set block. If stat_gains_opts is intentionally an instance variable on the non-forge path (e.g. read elsewhere), then the var on Line 157 is the anomaly and should be removed to maintain consistency.

🔧 Proposed fix: hoist declaration above both branches
  var gains_set = false;
+ var stat_gains_opts = [];

  if (job != "none") {
      if (job.type == "forge") {
-         var stat_gains_opts = ["technology"];
+         stat_gains_opts = ["technology"];
scripts/scr_fleet_functions/scr_fleet_functions.gml (1)

85-93: ⚠️ Potential issue | 🟡 Minor

Clarify the intent of intercept time calculation, Tech-Priest.

The scoping of targ_location with var is appropriate. However, the function computes the target's next location but uses it only as an existence guard—the distance calculation then employs action_x, action_y (this fleet's own action destination) rather than the target's predicted coordinates.

Either add a comment explaining why the intercept calculation ignores the target's location, or refactor the distance call to use targ_location.x, targ_location.y if the function should measure time to intercept the target itself.

scripts/scr_specialist_training/scr_specialist_training.gml (7)

191-191: ⚠️ Potential issue | 🟡 Minor

Lexographic corruption detected, Tech-Priest: "traning" → "training".

A minor glyph-error in the alert string shall sow confusion among the Adepts who read the logs.

🔧 Proposed correction
-                scr_alert("red", "recruitment", $"No marines available for {obj_ini.role[100][eROLE.APOTHECARY]} traning", 0, 0);
+                scr_alert("red", "recruitment", $"No marines available for {obj_ini.role[100][eROLE.APOTHECARY]} training", 0, 0);

283-294: ⚠️ Potential issue | 🔴 Critical

Inconsistent point deduction: threshold is 60, but only 48 is subtracted.

Tech-Priest, at line 283, the goal is set to 60, yet at line 294 the deduction reads psyker_points -= 48. In all sibling functions, the deduction matches the threshold (Apothecary: 48/48, Chaplain: 48/48). This discrepancy means 12 surplus points are silently retained each cycle, accelerating subsequent Librarian promotions beyond intended parameters.

Determine whether the threshold should be 48 (matching the deduction) or the deduction should be 60 (matching the goal).

🔧 If the deduction should match the goal
-                    psyker_points -= 48;
+                    psyker_points -= goal;

317-322: ⚠️ Potential issue | 🔴 Critical

Missing guard: open_slot not validated before use — risk of data corruption.

Tech-Priest, observe: in apothecary_training (line 177), chaplain_training (line 254), and techmarine_training (line 435), the code guards against open_slot == -1 before invoking scr_move_unit_info. Here in librarian_training, the call proceeds unchecked. Should find_company_open_slot(0) return -1, the subsequent operations will corrupt unit data by writing to an invalid slot.

🛡️ Proposed safeguard
             } else if (random_marine != "none") {
                 // This gets the last open slot for company 0
                 var marine_position = random_marine[1];
                 var marine_company = random_marine[0];
                 var open_slot = find_company_open_slot(0);
+                if (open_slot != -1) {
                 scr_move_unit_info(marine_company, 0, marine_position, open_slot);
                 unit = fetch_unit([0, open_slot]);
                 unit.update_role(novice_type);
                 unit.update_powers();
                 psyker_aspirant = 1;

                 unit.update_gear("");
                 unit.update_mobility_item("");
                 scr_alert("green", "recruitment", unit.name_role() + " begins training.", 0, 0);
                 with (obj_ini) {
                     scr_company_order(marine_company);
                     scr_company_order(0);
                 }
+                }
             }

358-369: ⚠️ Potential issue | 🔴 Critical

Point deduction ignores the variable threshold — always subtracts 360.

Tech-Priest, the threshold is conditionally set to 252 when at war with the Mechanicus (line 361), yet tech_points -= 360 on line 369 always deducts the full peacetime cost. When _threshold == 252, this over-deduction of 108 points penalises the chapter beyond the intended wartime benefit.

🔧 Proposed correction
-                    tech_points -= 360;
+                    tech_points -= _threshold;

115-195: 🧹 Nitpick | 🔵 Trivial

The four training rites share deeply duplicated logic — consider abstraction, Tech-Priest.

The machine spirit discerns a near-identical pattern across all four specialist training functions: point accumulation → threshold check → recruit promotion (with weapon/gear updates and alerts) or aspirant selection (with slot-finding and movement). The differences are confined to constants, role indices, and a few specialist-specific side effects.

This observation is recorded for future contemplation. Per the Rule of Three, with four repetitions the pattern is well-established and a unified training function parameterised by specialist type would reduce the maintenance burden and the risk of copy-paste divergences (as evidenced by the bugs already identified above). However, such a refactor may exceed the scope of this housekeeping PR.

Also applies to: 197-274, 276-338, 340-469


380-381: ⚠️ Potential issue | 🟠 Major

Expunge the orphaned variables t and r — they possess neither purpose nor declaration.

The machine spirit perceives no utility in these assignments. Lines 380–381 assign t and r to zero without var declaration, rendering them instance-scoped, yet they are referenced nowhere thereafter. Their singular-letter nomenclature violates the sacred principle of explicit intent. These are vestigial remnants that corrode the clarity of thy function.

Delete them entirely.


280-281: ⚠️ Potential issue | 🔴 Critical

Sanctity Breached: Librarian Training Denies Its Appointed Constant.

The librarian_training() function draws its point-values from CHAPLAIN_TRAINING_TIERS—a grave transgression. Observe: APOTHECARY_TRAINING_TIERS exists (line 120), CHAPLAIN_TRAINING_TIERS exists (line 202), yet no LIBRARIAN_TRAINING_TIERS constant dwells within this archive. The Librarian pursues a goal of 60 points (line 283), whilst Chaplain and Apothecary settle for 48, yet both wrongfully draw from identical Chaplain tier values. A LIBRARIAN_TRAINING_TIERS constant must be forged and interred within scr_recruit_data.gml to govern the Librarian's sacred progression.

scripts/scr_demand/scr_demand.gml (6)

18-28: ⚠️ Potential issue | 🟡 Minor

The machine spirit notes a temporal discrepancy, Tech-Priest.

inquis_use_inspection_pass() sets inspection leave to turn + 25 (line 22–23), whereas inquis_demand_inspection_pass() uses turn + 24 (line 39–40). The diplo_text in line 26 reads "24 months leave" despite the code granting 25. Verify whether this off-by-one is deliberate or an error — at minimum, the text and code should agree.

Also, commented-out code //obj_controller.liscensing=5; on line 24 (and again on line 41) constitutes dead logic. If this functionality is deprecated, purge it; if pending, mark it with a // TODO.


43-47: ⚠️ Potential issue | 🟡 Minor

Corrupted lexical data detected in diplomatic transmissions, Tech-Priest.

The user-facing strings on lines 43 and 47 contain multiple typographical errors:

  • Line 43: "reasoon" → "reason", "forgoe" → "forgo", "onece" → "once", "becomne" → "become"
  • Line 47: "i shal" → "I shall"

These are player-visible dialogue strings and should be corrected.


52-101: 🧹 Nitpick | 🔵 Trivial

Inconsistent use of faction identifiers weakens the rites of maintainability, Tech-Priest.

scr_demand uses the eFACTION enum in some places (e.g., eFACTION.IMPERIUM on line 78, eFACTION.TAU on line 287) but raw integers elsewhere — trading_demand == 2 (line 75), obj_controller.disposition[2] (lines 86, 89, 92), disposition[7] (line 275), disposition[8] / trading_demand == 8 (lines 391, 398, 405, etc.).

As this function is now being annotated as a public @mixin, consider a future pass to replace magic numbers with eFACTION enum references for consistency and readability.


102-122: 🧹 Nitpick | 🔵 Trivial

Redundant conditionals clutter the logic-engrams, Tech-Priest.

Throughout scr_demand, the pattern if (rull > resistance) { ... } if (rull <= resistance) { worked = false; } is repeated many times (lines 105–110, 119–121, 148–154, 164–170, 224–230, 260–267, 271–282, 309–316, 355–379, etc.). Since worked is initialised to false on line 59, the rull <= resistance branches are no-ops in most cases.

Line 108 uses else if while all other instances use a separate if — an inconsistency. Consider using else uniformly and removing the redundant worked = false assignments for clarity.


2-7: ⚠️ Potential issue | 🔴 Critical

Cogitator detects anomalous arithmetic upon a sacred object reference, Tech-Priest.

Line 5 performs integer division upon obj_controller—an object instance reference—not upon any numeric property. This yields a nonsensical value and betrays incomplete logic. A property access is almost certainly required; the operation should resemble floor(obj_controller.some_property / 20) or similar.

Additionally, this mixin declares four local variables (_threat, _good_imperium_position, _relative_strength, _nature) that are computed but never referenced. The function itself is never invoked anywhere within the codebase. This suggests incomplete implementation; the function should either populate these variables for use by a consuming context (if truly serving as a mixin), or the entire stub should be completed or removed.

The bare /// @mixin`` annotation—lacking a target object specification—is also anomalous; review whether a target context such as /// @mixin` obj_popup` should be specified.


190-218: ⚠️ Potential issue | 🟠 Major

Guard obj_temp5 property access against non-instantiation, Tech-Priest.

Lines 196–205 access obj_temp5.x and obj_temp5.y without ensuring an instance exists. The creation logic on lines 191–195 is conditional—obj_temp5 is created only if an Eldar craftworld is discovered. Should no craftworld with craftworld == 1 exist despite the faction being at War or Antagonism, lines 197 and 202 will attempt to dereference a non-existent instance, triggering a runtime error.

The codebase demonstrates the pattern: check with instance_exists(obj_temp5) before property access (as seen in scripts/scr_dialogue/scr_dialogue.gml).

scripts/scr_add_corruption/scr_add_corruption.gml (1)

25-29: ⚠️ Potential issue | 🔴 Critical

Corruption detected in the escort loop, Tech-Priest. Variable c is undefined; the loop index is i.

Line 27 references escort_num[c], but the loop iterator is i. This will either reference an unintended instance variable or cause a runtime error. The capital and frigate loops above correctly use i.

🔧 Proposed purification
         for (var i = 0; i < escort_number; i++) {
             if (obj_ini.ship_carrying[escort_num[i]] > 0) {
-                array_push(ships, escort_num[c]);
+                array_push(ships, escort_num[i]);
             }
         }
scripts/scr_draw_management_unit/scr_draw_management_unit.gml (1)

102-105: ⚠️ Potential issue | 🟡 Minor

Copy-paste corruption detected in weapon validation logic, Tech-Priest.

Line 104 checks is_string(ma_we1) when it should check is_string(ma_we2) — the validation guards weapon two, yet references weapon one. The same defect recurs at line 152 in the vehicle branch. This is a pre-existing fault, but given this PR's stated purpose includes fixes, the machine spirit urges remediation.

🔧 Proposed purification

Line 104:

-            ma_we2 = is_string(ma_we1) ? ma_we2 : "";
+            ma_we2 = is_string(ma_we2) ? ma_we2 : "";

Line 152:

-            ma_we2 = is_string(ma_we1) ? ma_we2 : "";
+            ma_we2 = is_string(ma_we2) ? ma_we2 : "";
scripts/scr_creation/scr_creation.gml (1)

106-114: ⚠️ Potential issue | 🟡 Minor

A typographical corruption has been detected in the sacred text, Tech-Priest.

Line 109: "The color of your Astartes' lenss." — the word lenss should read lenses. This string is presented to the user and must be corrected.

📝 Proposed correction
-            tooltip2: "The color of your Astartes' lenss.  Most of the time this will be the visor color.",
+            tooltip2: "The color of your Astartes' lenses.  Most of the time this will be the visor color.",
scripts/scr_creation_draw_slides/scr_creation_draw_slides.gml (1)

399-403: ⚠️ Potential issue | 🟡 Minor

Corrupted data-rune detected in tooltip string, Tech-Priest.

The "Fleet Based" tooltip on line 401 contains \R instead of \n. The Homeworld tooltip on the same line correctly uses \n for its newline. This will render the Fleet Based tooltip with a literal \R instead of a line break.

🔧 Proposed correction
-    chapter_type_radio = new RadioSet([{str1: "Homeworld", font: fnt_40k_14b, tooltip: "Homeworld\nYour chapter has a homeworld that they base on.  Contained upon it is a massive Fortress Monastery, which provides high levels of defense and automated weapons."}, {str1: "Fleet Based", font: fnt_40k_14b, tooltip: "Fleet Based\Rather than a homeworld your chapter begins near their recruiting world.  The fleet includes a Battle Barge, which serves as a mobile base, and powerful ship."}, {str1: "Penitent", font: fnt_40k_14b, tooltip: "Penitent\As with Fleet Based, but you must crusade and fight until your penitence meter runs out.  Note that recruiting is disabled until then."}], "Chapter Type", {x1: 445, y1: 211, max_width: 1125 - 445, center: true});
+    chapter_type_radio = new RadioSet([{str1: "Homeworld", font: fnt_40k_14b, tooltip: "Homeworld\nYour chapter has a homeworld that they base on.  Contained upon it is a massive Fortress Monastery, which provides high levels of defense and automated weapons."}, {str1: "Fleet Based", font: fnt_40k_14b, tooltip: "Fleet Based\nRather than a homeworld your chapter begins near their recruiting world.  The fleet includes a Battle Barge, which serves as a mobile base, and powerful ship."}, {str1: "Penitent", font: fnt_40k_14b, tooltip: "Penitent\nAs with Fleet Based, but you must crusade and fight until your penitence meter runs out.  Note that recruiting is disabled until then."}], "Chapter Type", {x1: 445, y1: 211, max_width: 1125 - 445, center: true});

Note: the "Penitent" tooltip suffers from the same affliction (\A instead of \n).

scripts/scr_ancient_ruins/scr_ancient_ruins.gml (2)

144-144: ⚠️ Potential issue | 🟠 Major

Errant data-glyph detected — stray quotation mark corrupts the sacred text, Tech-Priest.

Line 144 ends with forever."" — an extra " that will either cause a syntax error or inject a literal stray quote character into the player-facing string. The other narrative paths do not exhibit this corruption.

🔧 Proposed fix
-        pop.text = "Your strike team locates the site where the previous expedition made their last stand. They find nothing. Your equipment is gone and bodies nowhere to be found, the entire expedition appears to have vanished without a trace; they return empty handed. Something insidious happened. You must find whoever defiled your brothers, and eliminate them, forever."";
+        pop.text = "Your strike team locates the site where the previous expedition made their last stand. They find nothing. Your equipment is gone and bodies nowhere to be found, the entire expedition appears to have vanished without a trace; they return empty handed. Something insidious happened. You must find whoever defiled your brothers, and eliminate them, forever.";

128-141: ⚠️ Potential issue | 🟡 Minor

Multiple user-facing text impurities in the recovery litany, Tech-Priest.

Several narrative strings harbour defects:

  1. Line 128: "beyond saving;." — extraneous semicolon before the period.
  2. Line 130: "our strike team" — missing capital O at the start of the sentence.
  3. Line 138: "saved;{recoverable_gene_seed}" — missing space after the semicolon.
  4. Line 141: pop.text += $"The strike team returns" — no leading space, so this text runs directly into the previous sentence.
📝 Proposed text corrections
-            pop.text = $"Your strike team locates the site where the previous expedition made their last stand. They airlift whatever equipment and vehicles remain, disposing of anything beyond saving;. {_weapon_text} is repaired and restored to the armamentarium";
+            pop.text = $"Your strike team locates the site where the previous expedition made their last stand. They airlift whatever equipment and vehicles remain, disposing of anything beyond saving. {_weapon_text} is repaired and restored to the armamentarium";
-            pop.text = $"our strike team locates the site where the previous expedition made their last stand. They cannot find any intact equipment, and are forced to burn the derelicts to prevent capture; no equipment is added to the armamentarium";
+            pop.text = $"Our strike team locates the site where the previous expedition made their last stand. They cannot find any intact equipment, and are forced to burn the derelicts to prevent capture; no equipment is added to the armamentarium";
-            pop.text += $" The strike team returns with remains, apothecaries report the gene-seed was able to be saved;{recoverable_gene_seed} gene-seed is harvested from the chapter's fallen. At least their genetic legacy will continue, we will recover from this.";
+            pop.text += $" The strike team returns with remains, apothecaries report the gene-seed was able to be saved; {recoverable_gene_seed} gene-seed is harvested from the chapter's fallen. At least their genetic legacy will continue, we will recover from this.";
-            pop.text += $"The strike team returns with remains, but apothecaries report the gene-seed is too contaminated to use; no gene-seed is harvested from the chapter's fallen. Their legacy lives on through their armaments, we will hold onto their memory.";
+            pop.text += $" The strike team returns with remains, but apothecaries report the gene-seed is too contaminated to use; no gene-seed is harvested from the chapter's fallen. Their legacy lives on through their armaments, we will hold onto their memory.";
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0409518 and f3bd4a3.

📒 Files selected for processing (73)
  • ChapterMaster.yyp
  • datafiles/data/weapons.json
  • objects/obj_al_ship/Create_0.gml
  • objects/obj_al_ship/Draw_0.gml
  • objects/obj_controller/Create_0.gml
  • objects/obj_en_ship/Create_0.gml
  • objects/obj_en_ship/Draw_0.gml
  • objects/obj_fleet/Alarm_7.gml
  • objects/obj_fleet/Create_0.gml
  • objects/obj_fleet/KeyPress_13.gml
  • objects/obj_p_fleet/Draw_0.gml
  • objects/obj_p_ship/Draw_0.gml
  • objects/obj_star_select/Create_0.gml
  • scripts/Armamentarium/Armamentarium.gml
  • scripts/UIComponents/UIComponents.gml
  • scripts/__view_set_internal/__view_set_internal.gml
  • scripts/action_draw_ellipse/action_draw_ellipse.gml
  • scripts/action_draw_ellipse/action_draw_ellipse.yy
  • scripts/clean_tags/clean_tags.gml
  • scripts/clean_tags/clean_tags.yy
  • scripts/exp_and_exp_growth/exp_and_exp_growth.gml
  • scripts/explode_script/explode_script.gml
  • scripts/is_specialist/is_specialist.gml
  • scripts/relative_direction/relative_direction.gml
  • scripts/relative_direction/relative_direction.yy
  • scripts/scr_add_artifact/scr_add_artifact.gml
  • scripts/scr_add_corruption/scr_add_corruption.gml
  • scripts/scr_add_man/scr_add_man.gml
  • scripts/scr_ancient_ruins/scr_ancient_ruins.gml
  • scripts/scr_animated_scanline/scr_animated_scanline.gml
  • scripts/scr_apothecarium/scr_apothecarium.gml
  • scripts/scr_array_functions/scr_array_functions.gml
  • scripts/scr_buttons/scr_buttons.gml
  • scripts/scr_cheatcode/scr_cheatcode.gml
  • scripts/scr_civil_roster/scr_civil_roster.gml
  • scripts/scr_creation/scr_creation.gml
  • scripts/scr_creation_draw_slides/scr_creation_draw_slides.gml
  • scripts/scr_dead_marines/scr_dead_marines.gml
  • scripts/scr_dead_marines/scr_dead_marines.yy
  • scripts/scr_demand/scr_demand.gml
  • scripts/scr_dialogue/scr_dialogue.gml
  • scripts/scr_diplomacy_helpers/scr_diplomacy_helpers.gml
  • scripts/scr_draw_management_unit/scr_draw_management_unit.gml
  • scripts/scr_drop_fiddle/scr_drop_fiddle.gml
  • scripts/scr_drop_fiddle/scr_drop_fiddle.yy
  • scripts/scr_drop_select_function/scr_drop_select_function.gml
  • scripts/scr_enemy_ai_a/scr_enemy_ai_a.gml
  • scripts/scr_enemy_ai_b/scr_enemy_ai_b.gml
  • scripts/scr_enemy_ai_c/scr_enemy_ai_c.gml
  • scripts/scr_enemy_ai_d/scr_enemy_ai_d.gml
  • scripts/scr_enemy_ai_e/scr_enemy_ai_e.gml
  • scripts/scr_fleet_functions/scr_fleet_functions.gml
  • scripts/scr_imperial_navy_functions/scr_imperial_navy_functions.gml
  • scripts/scr_ini_functions/scr_ini_functions.gml
  • scripts/scr_ini_functions/scr_ini_functions.yy
  • scripts/scr_inquisition_mission/scr_inquisition_mission.gml
  • scripts/scr_line_break/scr_line_break.gml
  • scripts/scr_line_break/scr_line_break.yy
  • scripts/scr_lines/scr_lines.gml
  • scripts/scr_load/scr_load.gml
  • scripts/scr_marine_struct/scr_marine_struct.gml
  • scripts/scr_player_fleet_combat_functions/scr_player_fleet_combat_functions.gml
  • scripts/scr_powers/scr_powers.gml
  • scripts/scr_reequip_units/scr_reequip_units.gml
  • scripts/scr_role_setup/scr_role_setup.gml
  • scripts/scr_roster/scr_roster.gml
  • scripts/scr_save/scr_save.gml
  • scripts/scr_specialist_training/scr_specialist_training.gml
  • scripts/scr_struct_functions/scr_struct_functions.gml
  • scripts/scr_ui_manage/scr_ui_manage.gml
  • scripts/scr_vehicle_order/scr_vehicle_order.gml
  • scripts/scr_vehicle_weapon/scr_vehicle_weapon.gml
  • scripts/scr_vehicle_weapon/scr_vehicle_weapon.yy
💤 Files with no reviewable changes (18)
  • scripts/scr_dead_marines/scr_dead_marines.gml
  • scripts/scr_dialogue/scr_dialogue.gml
  • scripts/action_draw_ellipse/action_draw_ellipse.gml
  • scripts/scr_drop_fiddle/scr_drop_fiddle.gml
  • scripts/relative_direction/relative_direction.gml
  • scripts/scr_save/scr_save.gml
  • scripts/scr_animated_scanline/scr_animated_scanline.gml
  • scripts/scr_vehicle_weapon/scr_vehicle_weapon.yy
  • scripts/scr_struct_functions/scr_struct_functions.gml
  • scripts/action_draw_ellipse/action_draw_ellipse.yy
  • scripts/scr_vehicle_weapon/scr_vehicle_weapon.gml
  • scripts/scr_line_break/scr_line_break.yy
  • scripts/scr_drop_fiddle/scr_drop_fiddle.yy
  • scripts/scr_dead_marines/scr_dead_marines.yy
  • scripts/scr_line_break/scr_line_break.gml
  • scripts/relative_direction/relative_direction.yy
  • scripts/clean_tags/clean_tags.yy
  • scripts/clean_tags/clean_tags.gml
🧰 Additional context used
📓 Path-based instructions (4)
**/*.gml

⚙️ CodeRabbit configuration file

  • All code should comply with the 2026 GML documentation.

Files:

  • scripts/scr_enemy_ai_a/scr_enemy_ai_a.gml
  • objects/obj_en_ship/Draw_0.gml
  • scripts/scr_role_setup/scr_role_setup.gml
  • scripts/explode_script/explode_script.gml
  • scripts/scr_add_corruption/scr_add_corruption.gml
  • scripts/scr_enemy_ai_e/scr_enemy_ai_e.gml
  • objects/obj_fleet/Alarm_7.gml
  • objects/obj_star_select/Create_0.gml
  • scripts/scr_draw_management_unit/scr_draw_management_unit.gml
  • objects/obj_fleet/KeyPress_13.gml
  • scripts/scr_ini_functions/scr_ini_functions.gml
  • scripts/scr_creation/scr_creation.gml
  • scripts/UIComponents/UIComponents.gml
  • scripts/scr_enemy_ai_d/scr_enemy_ai_d.gml
  • scripts/scr_reequip_units/scr_reequip_units.gml
  • scripts/scr_player_fleet_combat_functions/scr_player_fleet_combat_functions.gml
  • scripts/scr_enemy_ai_b/scr_enemy_ai_b.gml
  • scripts/exp_and_exp_growth/exp_and_exp_growth.gml
  • scripts/scr_vehicle_order/scr_vehicle_order.gml
  • scripts/scr_ui_manage/scr_ui_manage.gml
  • scripts/scr_enemy_ai_c/scr_enemy_ai_c.gml
  • scripts/scr_creation_draw_slides/scr_creation_draw_slides.gml
  • objects/obj_controller/Create_0.gml
  • scripts/scr_add_man/scr_add_man.gml
  • scripts/scr_powers/scr_powers.gml
  • scripts/scr_specialist_training/scr_specialist_training.gml
  • scripts/scr_demand/scr_demand.gml
  • scripts/scr_civil_roster/scr_civil_roster.gml
  • scripts/scr_array_functions/scr_array_functions.gml
  • objects/obj_en_ship/Create_0.gml
  • scripts/scr_lines/scr_lines.gml
  • scripts/is_specialist/is_specialist.gml
  • scripts/scr_drop_select_function/scr_drop_select_function.gml
  • scripts/scr_apothecarium/scr_apothecarium.gml
  • scripts/scr_roster/scr_roster.gml
  • scripts/scr_load/scr_load.gml
  • scripts/__view_set_internal/__view_set_internal.gml
  • scripts/scr_diplomacy_helpers/scr_diplomacy_helpers.gml
  • scripts/scr_ancient_ruins/scr_ancient_ruins.gml
  • objects/obj_al_ship/Create_0.gml
  • scripts/scr_add_artifact/scr_add_artifact.gml
  • objects/obj_p_fleet/Draw_0.gml
  • scripts/scr_marine_struct/scr_marine_struct.gml
  • scripts/scr_cheatcode/scr_cheatcode.gml
  • objects/obj_p_ship/Draw_0.gml
  • scripts/scr_fleet_functions/scr_fleet_functions.gml
  • scripts/scr_imperial_navy_functions/scr_imperial_navy_functions.gml
  • scripts/scr_inquisition_mission/scr_inquisition_mission.gml
  • scripts/scr_buttons/scr_buttons.gml
  • objects/obj_al_ship/Draw_0.gml
  • scripts/Armamentarium/Armamentarium.gml
  • objects/obj_fleet/Create_0.gml
**/*.*

⚙️ CodeRabbit configuration file

**/*.*: - Code Philosophy: Prioritize explicit intent and maintainability over brevity. If a
solution is "clever" but mentally taxing, request a refactor to a clearer approach.

  • Variable Naming: Use clear, descriptive names; avoid over-abbreviation.

  • Abstraction: Apply the "Rule of Three"; suggest abstraction only when similar logic is
    repeated three or more times to avoid premature complexity.

  • Subjective Choices: For naming or architecture, ask guiding questions to prompt developer
    reflection and provide at least two alternative perspectives.

  • TODOs: If a TODO comment is added, ask the user if a GitHub issue should be created. If a
    TODO comment is deleted, remind the user to check the status of that specific issue.

Files:

  • scripts/scr_enemy_ai_a/scr_enemy_ai_a.gml
  • objects/obj_en_ship/Draw_0.gml
  • scripts/scr_role_setup/scr_role_setup.gml
  • scripts/explode_script/explode_script.gml
  • scripts/scr_add_corruption/scr_add_corruption.gml
  • scripts/scr_enemy_ai_e/scr_enemy_ai_e.gml
  • objects/obj_fleet/Alarm_7.gml
  • objects/obj_star_select/Create_0.gml
  • scripts/scr_draw_management_unit/scr_draw_management_unit.gml
  • scripts/scr_ini_functions/scr_ini_functions.yy
  • objects/obj_fleet/KeyPress_13.gml
  • scripts/scr_ini_functions/scr_ini_functions.gml
  • scripts/scr_creation/scr_creation.gml
  • scripts/UIComponents/UIComponents.gml
  • scripts/scr_enemy_ai_d/scr_enemy_ai_d.gml
  • scripts/scr_reequip_units/scr_reequip_units.gml
  • scripts/scr_player_fleet_combat_functions/scr_player_fleet_combat_functions.gml
  • scripts/scr_enemy_ai_b/scr_enemy_ai_b.gml
  • scripts/exp_and_exp_growth/exp_and_exp_growth.gml
  • scripts/scr_vehicle_order/scr_vehicle_order.gml
  • scripts/scr_ui_manage/scr_ui_manage.gml
  • scripts/scr_enemy_ai_c/scr_enemy_ai_c.gml
  • scripts/scr_creation_draw_slides/scr_creation_draw_slides.gml
  • objects/obj_controller/Create_0.gml
  • scripts/scr_add_man/scr_add_man.gml
  • scripts/scr_powers/scr_powers.gml
  • scripts/scr_specialist_training/scr_specialist_training.gml
  • scripts/scr_demand/scr_demand.gml
  • scripts/scr_civil_roster/scr_civil_roster.gml
  • scripts/scr_array_functions/scr_array_functions.gml
  • objects/obj_en_ship/Create_0.gml
  • scripts/scr_lines/scr_lines.gml
  • scripts/is_specialist/is_specialist.gml
  • scripts/scr_drop_select_function/scr_drop_select_function.gml
  • scripts/scr_apothecarium/scr_apothecarium.gml
  • scripts/scr_roster/scr_roster.gml
  • scripts/scr_load/scr_load.gml
  • scripts/__view_set_internal/__view_set_internal.gml
  • scripts/scr_diplomacy_helpers/scr_diplomacy_helpers.gml
  • scripts/scr_ancient_ruins/scr_ancient_ruins.gml
  • objects/obj_al_ship/Create_0.gml
  • scripts/scr_add_artifact/scr_add_artifact.gml
  • objects/obj_p_fleet/Draw_0.gml
  • scripts/scr_marine_struct/scr_marine_struct.gml
  • datafiles/data/weapons.json
  • scripts/scr_cheatcode/scr_cheatcode.gml
  • objects/obj_p_ship/Draw_0.gml
  • scripts/scr_fleet_functions/scr_fleet_functions.gml
  • ChapterMaster.yyp
  • scripts/scr_imperial_navy_functions/scr_imperial_navy_functions.gml
  • scripts/scr_inquisition_mission/scr_inquisition_mission.gml
  • scripts/scr_buttons/scr_buttons.gml
  • objects/obj_al_ship/Draw_0.gml
  • scripts/Armamentarium/Armamentarium.gml
  • objects/obj_fleet/Create_0.gml
**/*.yy

⚙️ CodeRabbit configuration file

**/*.yy: - When any script or sprite .yy files are deleted, their paths should also be deleted from the project .yyp file, otherwise the game will crash.

  • When any script or sprite .yy files are created, their paths should be added to the project .yyp file, otherwise they'll fail.

Files:

  • scripts/scr_ini_functions/scr_ini_functions.yy
**/*.json

⚙️ CodeRabbit configuration file

  • In this project, JSON files with comments are supported by the parser. It's allowed to use comments in JSON.

Files:

  • datafiles/data/weapons.json
🧠 Learnings (21)
📓 Common learnings
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 0
File: :0-0
Timestamp: 2025-04-05T20:58:21.881Z
Learning: In the ChapterMaster game, there's a need to refactor hardcoded item effects and move them to a "specials" property of items, following the pattern established with the `combi_tool` special. This improves code maintainability and makes effects more explicit in item definitions.
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 0
File: :0-0
Timestamp: 2025-04-05T20:58:21.881Z
Learning: In the ChapterMaster game, there's a need to refactor hardcoded item effects and move them to a "specials" property of items, following the pattern established with the `combi_tool` special. This improves code maintainability and makes effects more explicit in item definitions.
Learnt from: MCPO-Spartan-117
Repo: Adeptus-Dominus/ChapterMaster PR: 526
File: objects/obj_popup/Draw_0.gml:234-239
Timestamp: 2025-03-01T11:06:25.427Z
Learning: The comment "Need to modify ^^^^ based on if it is chaos or daemonic" in the artifact gifting code is intentionally kept as a reminder that this implementation is not yet finished, despite the significant refactoring already done.
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 647
File: scripts/scr_en_weapon/scr_en_weapon.gml:24-928
Timestamp: 2025-03-29T10:30:25.598Z
Learning: A data-driven approach for weapon management in `scripts/scr_en_weapon/scr_en_weapon.gml` is planned for a future PR, not within the scope of PR `#647`.
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 0
File: :0-0
Timestamp: 2025-04-05T20:54:45.813Z
Learning: EttyKitty requested a rework of the vehicle and marine recovery system in ChapterMaster. The current system allows guaranteed recovery with enough recovery points, while the proposed system would use random chance modified by techmarine skill and item bonuses.
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 424
File: scripts/scr_flavor/scr_flavor.gml:34-36
Timestamp: 2025-03-09T02:33:43.867Z
Learning: EttyKitty prefers to keep PRs focused on their stated goals and scope, and may decline to implement otherwise valid suggestions if they're not directly related to the PR's primary objective.
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 579
File: objects/obj_enunit/Alarm_0.gml:200-202
Timestamp: 2025-03-11T01:38:19.874Z
Learning: EttyKitty welcomes easy, committable suggestions that improve documentation of code chunks, variables with strange names, and functions. Their codebase is generally lacking documentation, but they prioritize human-readable code above documentation.
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 878
File: sprites/spr_weapon_phobos_bolt_pistol/spr_weapon_phobos_bolt_pistol.yy:26-44
Timestamp: 2025-06-16T17:08:08.239Z
Learning: EttyKitty prefers automated solutions over manual cleanup for .yy file formatting and is open to automated tools for GameMaker Studio .yy file cleanup.
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 938
File: scripts/scr_complex_colour_kit/scr_complex_colour_kit.gml:478-478
Timestamp: 2025-07-21T17:03:28.251Z
Learning: EttyKitty acknowledges when PRs contain scope creep and agrees that changes should be focused on the stated PR objectives, reinforcing their preference for keeping PRs narrowly scoped to their primary purpose.
📚 Learning: 2025-06-16T17:12:13.045Z
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 878
File: scripts/scr_culture_visuals/scr_culture_visuals.gml:1256-1352
Timestamp: 2025-06-16T17:12:13.045Z
Learning: In scripts/scr_culture_visuals/scr_culture_visuals.gml, the weapon visual data declarations contain known DRY violations that are acknowledged by the development team but deferred to future refactoring efforts rather than addressed in individual feature PRs.

Applied to files:

  • objects/obj_en_ship/Draw_0.gml
  • objects/obj_en_ship/Create_0.gml
  • scripts/scr_add_artifact/scr_add_artifact.gml
  • scripts/scr_cheatcode/scr_cheatcode.gml
📚 Learning: 2026-01-28T13:37:09.640Z
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 649
File: objects/obj_enunit/Alarm_0.gml:289-291
Timestamp: 2026-01-28T13:37:09.640Z
Learning: GameMaker Studio's function `action_if_variable(image_index, -500, 0)` is auto-generated code from GameMaker's visual Drag and Drop system. It checks if image_index equals -500. In ChapterMaster, this was being used as a special flag for enemy unit movement, but wasn't triggering consistently, causing enemies to move only every other turn. The refactored code replaced this with direct function calls at specific combat stages.

Applied to files:

  • objects/obj_en_ship/Draw_0.gml
  • objects/obj_fleet/KeyPress_13.gml
  • objects/obj_p_ship/Draw_0.gml
  • objects/obj_al_ship/Draw_0.gml
📚 Learning: 2026-02-07T01:59:24.810Z
Learnt from: CR
Repo: Adeptus-Dominus/ChapterMaster PR: 0
File: docs/CODE_STYLE.md:0-0
Timestamp: 2026-02-07T01:59:24.810Z
Learning: Applies to docs/**/*.gml : Don't create a separate file for every single small script; instead store scripts in library-like files (`scr_string_functions.gml`, `scr_array_functions.gml`, etc.)

Applied to files:

  • scripts/scr_role_setup/scr_role_setup.gml
  • scripts/scr_draw_management_unit/scr_draw_management_unit.gml
  • scripts/scr_add_man/scr_add_man.gml
  • scripts/scr_civil_roster/scr_civil_roster.gml
  • scripts/scr_array_functions/scr_array_functions.gml
  • scripts/scr_lines/scr_lines.gml
  • scripts/scr_apothecarium/scr_apothecarium.gml
  • ChapterMaster.yyp
📚 Learning: 2026-02-07T01:59:24.810Z
Learnt from: CR
Repo: Adeptus-Dominus/ChapterMaster PR: 0
File: docs/CODE_STYLE.md:0-0
Timestamp: 2026-02-07T01:59:24.810Z
Learning: Applies to docs/**/*.gml : Don't add `scr_` prefix for constructor files; instead name such files as the main class inside (e.g., `CoolConstructor.gml`)

Applied to files:

  • scripts/scr_role_setup/scr_role_setup.gml
  • scripts/scr_add_corruption/scr_add_corruption.gml
  • scripts/scr_add_man/scr_add_man.gml
  • scripts/scr_civil_roster/scr_civil_roster.gml
  • scripts/scr_apothecarium/scr_apothecarium.gml
📚 Learning: 2025-03-31T14:44:02.699Z
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 649
File: scripts/scr_punit_combat_heplers/scr_punit_combat_heplers.gml:204-212
Timestamp: 2025-03-31T14:44:02.699Z
Learning: In GML files, JSDoc comments should be placed above the function declaration, not inside the function body. The correct order is: function description JSDoc comments first, then any annotations like `mixin`, then the function declaration.

Applied to files:

  • scripts/explode_script/explode_script.gml
  • scripts/scr_add_corruption/scr_add_corruption.gml
  • scripts/scr_enemy_ai_e/scr_enemy_ai_e.gml
  • scripts/scr_draw_management_unit/scr_draw_management_unit.gml
  • scripts/UIComponents/UIComponents.gml
  • scripts/scr_enemy_ai_d/scr_enemy_ai_d.gml
  • scripts/scr_player_fleet_combat_functions/scr_player_fleet_combat_functions.gml
  • scripts/scr_civil_roster/scr_civil_roster.gml
  • scripts/scr_drop_select_function/scr_drop_select_function.gml
  • scripts/scr_apothecarium/scr_apothecarium.gml
📚 Learning: 2026-01-28T13:37:09.640Z
Learnt from: OH296
Repo: Adeptus-Dominus/ChapterMaster PR: 646
File: objects/obj_pnunit/Alarm_5.gml:84-91
Timestamp: 2026-01-28T13:37:09.640Z
Learning: In obj_pnunit/Alarm_5.gml, the function get_armour_data("maintenance") will always return a numeric value (at minimum 0), making null/undefined checks unnecessary.

Applied to files:

  • objects/obj_fleet/Alarm_7.gml
  • objects/obj_en_ship/Create_0.gml
  • scripts/scr_roster/scr_roster.gml
  • scripts/scr_marine_struct/scr_marine_struct.gml
📚 Learning: 2025-03-07T01:56:40.971Z
Learnt from: MCPO-Spartan-117
Repo: Adeptus-Dominus/ChapterMaster PR: 562
File: scripts/scr_marine_struct/scr_marine_struct.gml:0-0
Timestamp: 2025-03-07T01:56:40.971Z
Learning: Marines' ages should be incremented at the year transition in obj_turn_end/Alarm_1.gml rather than calculated dynamically based on the current year and recruitment date. This ensures proper aging without retroactive application.

Applied to files:

  • objects/obj_fleet/Alarm_7.gml
  • scripts/scr_marine_struct/scr_marine_struct.gml
📚 Learning: 2025-03-06T16:02:06.286Z
Learnt from: MCPO-Spartan-117
Repo: Adeptus-Dominus/ChapterMaster PR: 554
File: objects/obj_popup/Step_0.gml:756-767
Timestamp: 2025-03-06T16:02:06.286Z
Learning: The variable 'woopwoopwoop' in ancient ruins exploration code is a poorly named boolean flag that controls the flow between detecting a battle in ruins and initiating the combat sequence.

Applied to files:

  • objects/obj_fleet/KeyPress_13.gml
📚 Learning: 2025-03-31T15:41:45.611Z
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 649
File: objects/obj_enunit/Alarm_0.gml:289-291
Timestamp: 2025-03-31T15:41:45.611Z
Learning: GameMaker Studio's function `action_if_variable(image_index, -500, 0)` was part of an old enemy movement system in ChapterMaster. This syntax is auto-generated from GameMaker's Drag-and-Drop interface and checks if image_index is greater than or equal to -500. In the refactored code, enemy movement is triggered directly through function calls rather than relying on this conditional check.

Applied to files:

  • scripts/scr_enemy_ai_d/scr_enemy_ai_d.gml
  • objects/obj_p_ship/Draw_0.gml
📚 Learning: 2025-03-29T10:30:25.598Z
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 647
File: scripts/scr_en_weapon/scr_en_weapon.gml:24-928
Timestamp: 2025-03-29T10:30:25.598Z
Learning: A data-driven approach for weapon management in `scripts/scr_en_weapon/scr_en_weapon.gml` is planned for a future PR, not within the scope of PR `#647`.

Applied to files:

  • scripts/scr_reequip_units/scr_reequip_units.gml
  • objects/obj_en_ship/Create_0.gml
  • objects/obj_al_ship/Create_0.gml
  • datafiles/data/weapons.json
📚 Learning: 2026-02-07T01:59:24.810Z
Learnt from: CR
Repo: Adeptus-Dominus/ChapterMaster PR: 0
File: docs/CODE_STYLE.md:0-0
Timestamp: 2026-02-07T01:59:24.810Z
Learning: Applies to docs/**/*.gml : Follow the general GameMaker convention of using type prefixes in file names (`scr_`, `spr_`, etc.)

Applied to files:

  • scripts/scr_enemy_ai_c/scr_enemy_ai_c.gml
  • scripts/scr_civil_roster/scr_civil_roster.gml
📚 Learning: 2026-02-07T01:59:24.810Z
Learnt from: CR
Repo: Adeptus-Dominus/ChapterMaster PR: 0
File: docs/CODE_STYLE.md:0-0
Timestamp: 2026-02-07T01:59:24.810Z
Learning: Applies to docs/**/*.gml : Complex variable types should use `type` during declaration (e.g., `type {Array<Array<Struct.TTRPG_stats>>}`) for type hinting

Applied to files:

  • scripts/scr_powers/scr_powers.gml
  • scripts/scr_civil_roster/scr_civil_roster.gml
📚 Learning: 2025-02-24T07:38:42.267Z
Learnt from: MCPO-Spartan-117
Repo: Adeptus-Dominus/ChapterMaster PR: 508
File: scripts/scr_specialist_training/scr_specialist_training.gml:371-371
Timestamp: 2025-02-24T07:38:42.267Z
Learning: The spec_train_data array index for Techmarine training data is 0, as confirmed by the maintainer.

Applied to files:

  • scripts/scr_specialist_training/scr_specialist_training.gml
📚 Learning: 2026-02-07T01:59:24.810Z
Learnt from: CR
Repo: Adeptus-Dominus/ChapterMaster PR: 0
File: docs/CODE_STYLE.md:0-0
Timestamp: 2026-02-07T01:59:24.810Z
Learning: Applies to docs/**/*.gml : Precalculate array length for loops (e.g., `for (var i = 0, l = array_length(array); i < l; i++)`)

Applied to files:

  • scripts/scr_array_functions/scr_array_functions.gml
📚 Learning: 2025-09-04T14:52:45.005Z
Learnt from: OH296
Repo: Adeptus-Dominus/ChapterMaster PR: 0
File: :0-0
Timestamp: 2025-09-04T14:52:45.005Z
Learning: Project coding style summary:
- Constructors PascalCase; functions/variables snake_case with group prefixes (scr_*).
- Enums: enum name eNAME in SNAKE_CASE; entries PascalCase.
- Macros: ALL_CAPS SNAKE_CASE.
- Indentation 4 spaces; semicolons; use &&/||; parentheses for mixed ops; prefer ++/--.
- Prefer template strings $"..."; use “///” doc comments.
- Locals recommended with leading underscore.
- Organize scripts into library-like files; use early returns and init vars at declaration.

Applied to files:

  • scripts/scr_lines/scr_lines.gml
📚 Learning: 2026-02-07T01:59:24.810Z
Learnt from: CR
Repo: Adeptus-Dominus/ChapterMaster PR: 0
File: docs/CODE_STYLE.md:0-0
Timestamp: 2026-02-07T01:59:24.810Z
Learning: Applies to docs/**/*.gml : Local variables should have a `_` prefix (e.g., `var _player_health`) to ease readability and prevent namespace clashes with instance variables and scripts. Not required for loop indices.

Applied to files:

  • scripts/is_specialist/is_specialist.gml
📚 Learning: 2025-03-01T11:06:25.427Z
Learnt from: MCPO-Spartan-117
Repo: Adeptus-Dominus/ChapterMaster PR: 526
File: objects/obj_popup/Draw_0.gml:234-239
Timestamp: 2025-03-01T11:06:25.427Z
Learning: The comment "Need to modify ^^^^ based on if it is chaos or daemonic" in the artifact gifting code is intentionally kept as a reminder that this implementation is not yet finished, despite the significant refactoring already done.

Applied to files:

  • scripts/scr_add_artifact/scr_add_artifact.gml
📚 Learning: 2025-07-23T19:23:39.543Z
Learnt from: OH296
Repo: Adeptus-Dominus/ChapterMaster PR: 943
File: scripts/scr_librarium/scr_librarium.gml:79-79
Timestamp: 2025-07-23T19:23:39.543Z
Learning: In the ChapterMaster codebase, the correct function to set up gift popups for artifacts is `setup_gift_artifact_popup()`, not `setup_gift_items_popup()` which does not exist. The available gift setup functions are `setup_gift_popup()`, `setup_gift_artifact_popup()`, and `setup_gift_stc_popup()`.

Applied to files:

  • scripts/scr_add_artifact/scr_add_artifact.gml
📚 Learning: 2025-04-05T20:58:21.881Z
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 0
File: :0-0
Timestamp: 2025-04-05T20:58:21.881Z
Learning: In the ChapterMaster game, there's a need to refactor hardcoded item effects and move them to a "specials" property of items, following the pattern established with the `combi_tool` special. This improves code maintainability and makes effects more explicit in item definitions.

Applied to files:

  • scripts/Armamentarium/Armamentarium.gml
📚 Learning: 2025-03-11T01:34:29.268Z
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 579
File: objects/obj_enunit/Alarm_0.gml:186-187
Timestamp: 2025-03-11T01:34:29.268Z
Learning: In the ChapterMaster game, the variable `_column_size_value` represents the physical size/mass of a column of units, calculated as (vehicles * 2.5) + (dreadnoughts * 2) + (men * 0.5), and is used for determining back row protection rules.

Applied to files:

  • objects/obj_fleet/Create_0.gml

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@EttyKitty
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 10, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 23

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (16)
scripts/scr_ancient_ruins/scr_ancient_ruins.gml (1)

128-131: ⚠️ Potential issue | 🟡 Minor

The litany at Line 130 begins without proper capitalisation — a corruption in the sacred text.

Tech-Priest, though this defect predates your current rites, it dwells adjacent to the changes you have wrought. Line 130 reads "our strike team locates..." — the sentence lacks the capital "Y" to read "Your strike team...", unlike its counterpart at Line 128 which correctly begins "Your strike team...".

Additionally, Line 128 contains a stray semicolon before the period in "beyond saving;." — a minor blemish in the prose.

📜 Proposed corrections to the sacred texts
-        pop.text = $"Your strike team locates the site where the previous expedition made their last stand. They airlift whatever equipment and vehicles remain, disposing of anything beyond saving;. {_weapon_text} is repaired and restored to the armamentarium";
+        pop.text = $"Your strike team locates the site where the previous expedition made their last stand. They airlift whatever equipment and vehicles remain, disposing of anything beyond saving. {_weapon_text} is repaired and restored to the armamentarium.";
-            pop.text = $"our strike team locates the site where the previous expedition made their last stand. They cannot find any intact equipment, and are forced to burn the derelicts to prevent capture; no equipment is added to the armamentarium";
+            pop.text = $"Your strike team locates the site where the previous expedition made their last stand. They cannot find any intact equipment, and are forced to burn the derelicts to prevent capture; no equipment is added to the armamentarium.";
scripts/scr_roster/scr_roster.gml (1)

672-677: ⚠️ Potential issue | 🟡 Minor

A logic anomaly festers in these ancient circuits, Tech-Priest.

The second conditional on line 675 (if (new_combat.big_mofo > 3)) is unreachable. The preceding block on line 672 already clamps big_mofo to 2 when it exceeds 2, making the > 3 check a dead rune. While this is pre-existing code untouched by your hand, it warrants attention — perhaps > 1 was the intended threshold for the first check?

scripts/exp_and_exp_growth/exp_and_exp_growth.gml (1)

249-273: ⚠️ Potential issue | 🟠 Major

stat_gains is not reset within the level-up loop — stale value may cause phantom stat increments.

Tech-Priest, attend this peril: stat_gains is initialised to undefined on Line 249 but is never reset at the start of each iteration of the _lvl loop (Line 252). Should random(100) yield a value that falls outside the covered probability ranges (e.g. due to floating-point gaps between running_total and 100), stat_gains retains its value from a prior iteration. The conditional on Line 260 then fires again, awarding a duplicate stat point to whatever stat was last chosen.

While this may be pre-existing logic, the refactoring to local scope is the ideal moment to seal this flaw.

🔧 Proposed correction — reset stat_gains each iteration
         for (var _lvl = 0; _lvl < _levels; _lvl++) {
+            stat_gains = undefined;
             //var extra_stats_earned = d100_roll(false);
             var stat_gain_choice = random(100);
scripts/scr_creation/scr_creation.gml (1)

42-42: 🛠️ Refactor suggestion | 🟠 Major

The machine spirit discerns the true nature of the runes, Tech-Priest.

Thine loop bound of 19 aligns with eROLE.VETERANSERGEANT within the enumeration already scribed in the codebase. Though the number shall not be replaced with mere reference, its manifold invocation across eight or more locations doth warrant the employment of this named constant to ward against future corruption. The single-invocation exemption doth not shield this pattern.

The index 100 remaineth shrouded in mystery—no obvious constant claims it. Verify whether this designates a race count or some other immutable boundary.

Consider elevating i <= eROLE.VETERANSERGEANT to render thy intent manifest to those who read thine code in the aeons to come.

scripts/scr_specialist_training/scr_specialist_training.gml (3)

360-364: 🧹 Nitpick | 🔵 Trivial

The threshold sigil is declared within divergent branches, Tech-Priest.

While GML's var is function-scoped and this functions correctly, declaring _threshold before the conditional would improve clarity and make the intent unambiguous.

♻️ Proposed clarification
-        if (obj_controller.faction_status[eFACTION.MECHANICUS] != "War") {
-            var _threshold = 360;
-        } else {
-            var _threshold = 252;
-        }
+        var _threshold = (obj_controller.faction_status[eFACTION.MECHANICUS] != "War") ? 360 : 252;

420-420: ⚠️ Potential issue | 🟡 Minor

A cryptic rune persists in the code-scriptures, Tech-Priest.

The comment // 135 ; probably also want to increase the p_player by 1 just because reads as a stale note or unresolved intent. If this is an actionable directive, it should be formalised as a TODO. If it is no longer relevant, the machine spirit recommends its excision to avoid confusion.


148-161: 🛠️ Refactor suggestion | 🟠 Major

The Rule of Three is invoked, Tech-Priest — the equipment-warning litany is thrice repeated.

The pattern of calling update_weapon_one, update_weapon_two, and update_gear, accumulating warnings, and issuing an alert appears in apothecary_training, chaplain_training, and techmarine_training. This incantation is ripe for extraction into a shared helper, such as:

function equip_and_warn(unit, role_index) {
    var warn = "";
    if (unit.update_weapon_one(obj_ini.wep1[100][role_index]) == "no_items")
        warn += $", {obj_ini.wep1[100][role_index]}";
    if (unit.update_weapon_two(obj_ini.wep2[100][role_index]) == "no_items")
        warn += $", {obj_ini.wep2[100][role_index]}";
    if (unit.update_gear(obj_ini.gear[100][role_index]) == "no_items")
        warn += $", {obj_ini.gear[100][role_index]}";
    if (warn != "") {
        warn += ".";
        scr_alert("red", "recruitment", "Not enough equipment: " + string(warn), 0, 0);
    }
}

This would reduce duplication and centralise maintenance of the equipment-assignment rite.

As per coding guidelines: "Abstraction: Apply the 'Rule of Three'; suggest abstraction only when similar logic is repeated three or more times."

Also applies to: 227-240, 392-405

scripts/scr_imperial_navy_functions/scr_imperial_navy_functions.gml (7)

847-860: ⚠️ Potential issue | 🔴 Critical

CRITICAL: The Machine Spirit detects a corruption in the logic-engrams, Tech-Priest.

Line 857: escort_imp >= i compares an array to an integer index. The sacred pattern established on Lines 848 and 852 dictates this should be escort_number >= i. This corruption will prevent Imperial Guard from being loaded into escort vessels, weakening the fleet's ground-assault capacity.

⚙️ Rite of Correction
-        if (_new_capacity > 0 && escort_imp >= i) {
+        if (_new_capacity > 0 && escort_number >= i) {

390-390: ⚠️ Potential issue | 🔴 Critical

CRITICAL: Navigational cogitator malfunction detected, Tech-Priest.

The y-component of the coordinate calculation invokes lengthdir_x where the rites demand lengthdir_y. The fleet's intercept course will be erroneously computed, sending it astray in the void.

⚙️ Rite of Correction
-                        goto = instance_nearest(x + lengthdir_x(diss, dirr), y + lengthdir_x(diss, dirr), obj_star);
+                        goto = instance_nearest(x + lengthdir_x(diss, dirr), y + lengthdir_y(diss, dirr), obj_star);

509-537: 🧹 Nitpick | 🔵 Trivial

Variable bombard is declared twice with divergent purpose, Tech-Priest.

Line 509 declares bombard as a boolean gate, and Line 526 re-declares it as a planet index. In GML, var is function-scoped, so the second declaration overwrites the first. While currently functional, this dual nature obscures intent and invites future corruption. Consider renaming the inner variable to bombard_planet or similar.


419-433: 🧹 Nitpick | 🔵 Trivial

Purge this dead code from the sacred texts, Tech-Priest.

This large commented-out block serves no function and clutters the logic-engrams. If it holds historical value, commit it to the annals of version control and remove it from the active codex.


161-161: 🧹 Nitpick | 🔵 Trivial

TODO detected in the machine-liturgy, Tech-Priest.

//TODO here we can make fleet be restored more quickly by better forge worlds — shall a GitHub issue be consecrated to track this enhancement?

As per coding guidelines: "If a TODO comment is added, ask the user if a GitHub issue should be created."


204-204: ⚠️ Potential issue | 🟡 Minor

TODO detected, and a scribal error mars it further, Tech-Priest.

//TODO further breakup into a nvay fleet functions script — "nvay" should read "navy". Shall a GitHub issue be created to track this planned refactor?

As per coding guidelines: "If a TODO comment is added, ask the user if a GitHub issue should be created."

⚙️ Minor correction
-//TODO further breakup into a nvay fleet functions script
+//TODO further breakup into a navy fleet functions script

36-41: ⚠️ Potential issue | 🟠 Major

Undefined reference corrupts the logic matrix, Tech-Priest.

Line 37 invokes the unbound variable i within orbiting.p_owner[i], yet i exists not within the local scope of navy_orbiting_planet_end_turn_action(). The variable _forge—obtained from scr_get_planet_with_type() on line 36—holds the requisite planet index. Replace i with _forge to restore coherence.

⚙️ Rite of Correction
-            if (_forge == -1 || orbiting.p_owner[i] != eFACTION.MECHANICUS) {
+            if (_forge == -1 || orbiting.p_owner[_forge] != eFACTION.MECHANICUS) {
scripts/scr_vehicle_order/scr_vehicle_order.gml (2)

48-48: 🧹 Nitpick | 🔵 Trivial

The TODO litany has been inscribed, Tech-Priest. Shall a formal edict be raised?

A TODO marks the intent to migrate these raw strings to enums or string identifiers. As per coding guidelines, would you wish a GitHub issue to be created to track this transmutation?


28-43: 🧹 Nitpick | 🔵 Trivial

The sacred fourteen properties are transcribed four times, Tech-Priest — a rite ripe for unification.

The same 14 vehicle fields are enumerated in the temp-init loop (lines 28–43), the copy-to-temp block (lines 54–69), the write-back block (lines 75–90), and reset_vehicle_variable_arrays (lines 4–19). Should a future modification add or remove a vehicle property, all four sites must be amended in lockstep — a breeding ground for divergence.

Consider encapsulating the vehicle property set into a struct or a pair of helper functions (e.g., copy_vehicle_data(src, dst, src_idx, dst_idx) and init_vehicle_defaults(target, idx)). This would reduce the 14-field repetition to a single definition.

That said, given the known deferral of DRY consolidation in this codebase, this may be addressed in a future undertaking.

Also applies to: 54-69, 75-90

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f3bd4a3 and 983ac74.

📒 Files selected for processing (29)
  • objects/obj_al_ship/Create_0.gml
  • objects/obj_al_ship/Draw_0.gml
  • objects/obj_en_ship/Create_0.gml
  • objects/obj_en_ship/Draw_0.gml
  • objects/obj_fleet/KeyPress_13.gml
  • objects/obj_p_fleet/Draw_0.gml
  • objects/obj_p_ship/Create_0.gml
  • objects/obj_p_ship/Draw_0.gml
  • objects/obj_star_select/Create_0.gml
  • scripts/Armamentarium/Armamentarium.gml
  • scripts/exp_and_exp_growth/exp_and_exp_growth.gml
  • scripts/macros/macros.gml
  • scripts/scr_add_corruption/scr_add_corruption.gml
  • scripts/scr_add_man/scr_add_man.gml
  • scripts/scr_ancient_ruins/scr_ancient_ruins.gml
  • scripts/scr_buttons/scr_buttons.gml
  • scripts/scr_creation/scr_creation.gml
  • scripts/scr_creation_draw_slides/scr_creation_draw_slides.gml
  • scripts/scr_diplomacy_helpers/scr_diplomacy_helpers.gml
  • scripts/scr_draw_management_unit/scr_draw_management_unit.gml
  • scripts/scr_enemy_ai_e/scr_enemy_ai_e.gml
  • scripts/scr_fleet_functions/scr_fleet_functions.gml
  • scripts/scr_imperial_navy_functions/scr_imperial_navy_functions.gml
  • scripts/scr_lines/scr_lines.gml
  • scripts/scr_marine_struct/scr_marine_struct.gml
  • scripts/scr_reequip_units/scr_reequip_units.gml
  • scripts/scr_roster/scr_roster.gml
  • scripts/scr_specialist_training/scr_specialist_training.gml
  • scripts/scr_vehicle_order/scr_vehicle_order.gml
🧰 Additional context used
📓 Path-based instructions (2)
**/*.gml

⚙️ CodeRabbit configuration file

  • All code should comply with the 2026 GML documentation.

Files:

  • scripts/macros/macros.gml
  • scripts/scr_creation/scr_creation.gml
  • scripts/scr_add_corruption/scr_add_corruption.gml
  • objects/obj_fleet/KeyPress_13.gml
  • scripts/scr_diplomacy_helpers/scr_diplomacy_helpers.gml
  • objects/obj_en_ship/Create_0.gml
  • scripts/scr_ancient_ruins/scr_ancient_ruins.gml
  • objects/obj_p_ship/Draw_0.gml
  • scripts/scr_add_man/scr_add_man.gml
  • scripts/scr_lines/scr_lines.gml
  • scripts/exp_and_exp_growth/exp_and_exp_growth.gml
  • scripts/scr_specialist_training/scr_specialist_training.gml
  • objects/obj_en_ship/Draw_0.gml
  • objects/obj_al_ship/Draw_0.gml
  • scripts/scr_draw_management_unit/scr_draw_management_unit.gml
  • scripts/scr_vehicle_order/scr_vehicle_order.gml
  • scripts/scr_imperial_navy_functions/scr_imperial_navy_functions.gml
  • objects/obj_star_select/Create_0.gml
  • objects/obj_p_ship/Create_0.gml
  • objects/obj_p_fleet/Draw_0.gml
  • objects/obj_al_ship/Create_0.gml
  • scripts/scr_fleet_functions/scr_fleet_functions.gml
  • scripts/scr_marine_struct/scr_marine_struct.gml
  • scripts/scr_reequip_units/scr_reequip_units.gml
  • scripts/scr_buttons/scr_buttons.gml
  • scripts/scr_enemy_ai_e/scr_enemy_ai_e.gml
  • scripts/Armamentarium/Armamentarium.gml
  • scripts/scr_roster/scr_roster.gml
  • scripts/scr_creation_draw_slides/scr_creation_draw_slides.gml
**/*.*

⚙️ CodeRabbit configuration file

**/*.*: - Code Philosophy: Prioritize explicit intent and maintainability over brevity. If a
solution is "clever" but mentally taxing, request a refactor to a clearer approach.

  • Variable Naming: Use clear, descriptive names; avoid over-abbreviation.

  • Abstraction: Apply the "Rule of Three"; suggest abstraction only when similar logic is
    repeated three or more times to avoid premature complexity.

  • Subjective Choices: For naming or architecture, ask guiding questions to prompt developer
    reflection and provide at least two alternative perspectives.

  • TODOs: If a TODO comment is added, ask the user if a GitHub issue should be created. If a
    TODO comment is deleted, remind the user to check the status of that specific issue.

Files:

  • scripts/macros/macros.gml
  • scripts/scr_creation/scr_creation.gml
  • scripts/scr_add_corruption/scr_add_corruption.gml
  • objects/obj_fleet/KeyPress_13.gml
  • scripts/scr_diplomacy_helpers/scr_diplomacy_helpers.gml
  • objects/obj_en_ship/Create_0.gml
  • scripts/scr_ancient_ruins/scr_ancient_ruins.gml
  • objects/obj_p_ship/Draw_0.gml
  • scripts/scr_add_man/scr_add_man.gml
  • scripts/scr_lines/scr_lines.gml
  • scripts/exp_and_exp_growth/exp_and_exp_growth.gml
  • scripts/scr_specialist_training/scr_specialist_training.gml
  • objects/obj_en_ship/Draw_0.gml
  • objects/obj_al_ship/Draw_0.gml
  • scripts/scr_draw_management_unit/scr_draw_management_unit.gml
  • scripts/scr_vehicle_order/scr_vehicle_order.gml
  • scripts/scr_imperial_navy_functions/scr_imperial_navy_functions.gml
  • objects/obj_star_select/Create_0.gml
  • objects/obj_p_ship/Create_0.gml
  • objects/obj_p_fleet/Draw_0.gml
  • objects/obj_al_ship/Create_0.gml
  • scripts/scr_fleet_functions/scr_fleet_functions.gml
  • scripts/scr_marine_struct/scr_marine_struct.gml
  • scripts/scr_reequip_units/scr_reequip_units.gml
  • scripts/scr_buttons/scr_buttons.gml
  • scripts/scr_enemy_ai_e/scr_enemy_ai_e.gml
  • scripts/Armamentarium/Armamentarium.gml
  • scripts/scr_roster/scr_roster.gml
  • scripts/scr_creation_draw_slides/scr_creation_draw_slides.gml
🧠 Learnings (24)
📓 Common learnings
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 938
File: scripts/scr_complex_colour_kit/scr_complex_colour_kit.gml:478-478
Timestamp: 2025-07-21T17:03:28.251Z
Learning: EttyKitty acknowledges when PRs contain scope creep and agrees that changes should be focused on the stated PR objectives, reinforcing their preference for keeping PRs narrowly scoped to their primary purpose.
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 424
File: scripts/scr_flavor/scr_flavor.gml:34-36
Timestamp: 2025-03-09T02:33:43.867Z
Learning: EttyKitty prefers to keep PRs focused on their stated goals and scope, and may decline to implement otherwise valid suggestions if they're not directly related to the PR's primary objective.
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 579
File: objects/obj_enunit/Alarm_0.gml:200-202
Timestamp: 2025-03-11T01:38:19.874Z
Learning: EttyKitty welcomes easy, committable suggestions that improve documentation of code chunks, variables with strange names, and functions. Their codebase is generally lacking documentation, but they prioritize human-readable code above documentation.
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 878
File: sprites/spr_weapon_phobos_bolt_pistol/spr_weapon_phobos_bolt_pistol.yy:26-44
Timestamp: 2025-06-16T17:08:08.239Z
Learning: EttyKitty prefers automated solutions over manual cleanup for .yy file formatting and is open to automated tools for GameMaker Studio .yy file cleanup.
📚 Learning: 2025-03-29T10:30:25.598Z
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 647
File: scripts/scr_en_weapon/scr_en_weapon.gml:24-928
Timestamp: 2025-03-29T10:30:25.598Z
Learning: A data-driven approach for weapon management in `scripts/scr_en_weapon/scr_en_weapon.gml` is planned for a future PR, not within the scope of PR `#647`.

Applied to files:

  • scripts/macros/macros.gml
  • objects/obj_fleet/KeyPress_13.gml
  • objects/obj_en_ship/Create_0.gml
  • scripts/scr_add_man/scr_add_man.gml
  • scripts/scr_draw_management_unit/scr_draw_management_unit.gml
  • objects/obj_p_ship/Create_0.gml
  • objects/obj_al_ship/Create_0.gml
  • scripts/scr_reequip_units/scr_reequip_units.gml
  • scripts/Armamentarium/Armamentarium.gml
📚 Learning: 2025-03-01T11:06:25.427Z
Learnt from: MCPO-Spartan-117
Repo: Adeptus-Dominus/ChapterMaster PR: 526
File: objects/obj_popup/Draw_0.gml:234-239
Timestamp: 2025-03-01T11:06:25.427Z
Learning: The comment "Need to modify ^^^^ based on if it is chaos or daemonic" in the artifact gifting code is intentionally kept as a reminder that this implementation is not yet finished, despite the significant refactoring already done.

Applied to files:

  • objects/obj_fleet/KeyPress_13.gml
  • scripts/scr_lines/scr_lines.gml
  • scripts/scr_specialist_training/scr_specialist_training.gml
  • scripts/scr_fleet_functions/scr_fleet_functions.gml
  • scripts/scr_marine_struct/scr_marine_struct.gml
  • scripts/Armamentarium/Armamentarium.gml
📚 Learning: 2025-03-06T16:02:06.286Z
Learnt from: MCPO-Spartan-117
Repo: Adeptus-Dominus/ChapterMaster PR: 554
File: objects/obj_popup/Step_0.gml:756-767
Timestamp: 2025-03-06T16:02:06.286Z
Learning: The variable 'woopwoopwoop' in the ChapterMaster codebase is a poorly named multi-purpose variable used both for controlling ancient ruins combat flow and for passing menu state in the save/load system. This type of naming makes code maintenance difficult.

Applied to files:

  • objects/obj_fleet/KeyPress_13.gml
  • scripts/scr_marine_struct/scr_marine_struct.gml
📚 Learning: 2025-03-06T16:02:06.286Z
Learnt from: MCPO-Spartan-117
Repo: Adeptus-Dominus/ChapterMaster PR: 554
File: objects/obj_popup/Step_0.gml:756-767
Timestamp: 2025-03-06T16:02:06.286Z
Learning: The variable 'woopwoopwoop' in ancient ruins exploration code is a poorly named boolean flag that controls the flow between detecting a battle in ruins and initiating the combat sequence.

Applied to files:

  • objects/obj_fleet/KeyPress_13.gml
📚 Learning: 2026-01-28T13:37:09.640Z
Learnt from: OH296
Repo: Adeptus-Dominus/ChapterMaster PR: 646
File: objects/obj_pnunit/Alarm_5.gml:84-91
Timestamp: 2026-01-28T13:37:09.640Z
Learning: In obj_pnunit/Alarm_5.gml, the function get_armour_data("maintenance") will always return a numeric value (at minimum 0), making null/undefined checks unnecessary.

Applied to files:

  • objects/obj_fleet/KeyPress_13.gml
  • objects/obj_en_ship/Draw_0.gml
  • objects/obj_al_ship/Draw_0.gml
  • objects/obj_star_select/Create_0.gml
  • scripts/scr_marine_struct/scr_marine_struct.gml
  • scripts/scr_reequip_units/scr_reequip_units.gml
  • scripts/scr_buttons/scr_buttons.gml
  • scripts/scr_roster/scr_roster.gml
📚 Learning: 2025-03-07T01:56:40.971Z
Learnt from: MCPO-Spartan-117
Repo: Adeptus-Dominus/ChapterMaster PR: 562
File: scripts/scr_marine_struct/scr_marine_struct.gml:0-0
Timestamp: 2025-03-07T01:56:40.971Z
Learning: Marines' ages should be incremented at the year transition in obj_turn_end/Alarm_1.gml rather than calculated dynamically based on the current year and recruitment date. This ensures proper aging without retroactive application.

Applied to files:

  • objects/obj_fleet/KeyPress_13.gml
  • scripts/scr_add_man/scr_add_man.gml
  • scripts/scr_specialist_training/scr_specialist_training.gml
  • scripts/scr_marine_struct/scr_marine_struct.gml
📚 Learning: 2026-01-28T13:37:09.640Z
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 649
File: objects/obj_enunit/Alarm_0.gml:289-291
Timestamp: 2026-01-28T13:37:09.640Z
Learning: GameMaker Studio's function `action_if_variable(image_index, -500, 0)` is auto-generated code from GameMaker's visual Drag and Drop system. It checks if image_index equals -500. In ChapterMaster, this was being used as a special flag for enemy unit movement, but wasn't triggering consistently, causing enemies to move only every other turn. The refactored code replaced this with direct function calls at specific combat stages.

Applied to files:

  • objects/obj_fleet/KeyPress_13.gml
  • objects/obj_p_ship/Draw_0.gml
  • objects/obj_en_ship/Draw_0.gml
  • objects/obj_star_select/Create_0.gml
  • scripts/scr_enemy_ai_e/scr_enemy_ai_e.gml
📚 Learning: 2025-06-16T17:12:13.045Z
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 878
File: scripts/scr_culture_visuals/scr_culture_visuals.gml:1256-1352
Timestamp: 2025-06-16T17:12:13.045Z
Learning: In scripts/scr_culture_visuals/scr_culture_visuals.gml, the weapon visual data declarations contain known DRY violations that are acknowledged by the development team but deferred to future refactoring efforts rather than addressed in individual feature PRs.

Applied to files:

  • objects/obj_fleet/KeyPress_13.gml
  • objects/obj_en_ship/Create_0.gml
  • scripts/scr_add_man/scr_add_man.gml
  • objects/obj_en_ship/Draw_0.gml
  • scripts/scr_draw_management_unit/scr_draw_management_unit.gml
  • objects/obj_p_ship/Create_0.gml
  • objects/obj_al_ship/Create_0.gml
  • scripts/scr_marine_struct/scr_marine_struct.gml
  • scripts/scr_reequip_units/scr_reequip_units.gml
  • scripts/Armamentarium/Armamentarium.gml
  • scripts/scr_roster/scr_roster.gml
  • scripts/scr_creation_draw_slides/scr_creation_draw_slides.gml
📚 Learning: 2025-03-31T15:41:45.611Z
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 649
File: objects/obj_enunit/Alarm_0.gml:289-291
Timestamp: 2025-03-31T15:41:45.611Z
Learning: GameMaker Studio's function `action_if_variable(image_index, -500, 0)` was part of an old enemy movement system in ChapterMaster. This syntax is auto-generated from GameMaker's Drag-and-Drop interface and checks if image_index is greater than or equal to -500. In the refactored code, enemy movement is triggered directly through function calls rather than relying on this conditional check.

Applied to files:

  • objects/obj_fleet/KeyPress_13.gml
  • objects/obj_p_ship/Draw_0.gml
  • objects/obj_en_ship/Draw_0.gml
📚 Learning: 2025-04-05T20:58:21.881Z
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 0
File: :0-0
Timestamp: 2025-04-05T20:58:21.881Z
Learning: In the ChapterMaster game, there's a need to refactor hardcoded item effects and move them to a "specials" property of items, following the pattern established with the `combi_tool` special. This improves code maintainability and makes effects more explicit in item definitions.

Applied to files:

  • objects/obj_fleet/KeyPress_13.gml
  • scripts/Armamentarium/Armamentarium.gml
  • scripts/scr_creation_draw_slides/scr_creation_draw_slides.gml
📚 Learning: 2025-03-03T00:16:52.440Z
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 424
File: objects/obj_pnunit/Alarm_0.gml:18-19
Timestamp: 2025-03-03T00:16:52.440Z
Learning: Style improvements, such as replacing assignment operators (=) with comparison operators (==) in conditionals, should be suggested but not insisted upon when they're outside the scope of the current PR. These changes are better handled in dedicated style-focused PRs.

Applied to files:

  • objects/obj_fleet/KeyPress_13.gml
📚 Learning: 2026-02-07T01:59:24.823Z
Learnt from: CR
Repo: Adeptus-Dominus/ChapterMaster PR: 0
File: docs/CODE_STYLE.md:0-0
Timestamp: 2026-02-07T01:59:24.823Z
Learning: Applies to docs/**/*.gml : Don't create a separate file for every single small script; instead store scripts in library-like files (`scr_string_functions.gml`, `scr_array_functions.gml`, etc.)

Applied to files:

  • scripts/scr_add_man/scr_add_man.gml
  • scripts/scr_lines/scr_lines.gml
  • scripts/scr_creation_draw_slides/scr_creation_draw_slides.gml
📚 Learning: 2026-02-07T01:59:24.823Z
Learnt from: CR
Repo: Adeptus-Dominus/ChapterMaster PR: 0
File: docs/CODE_STYLE.md:0-0
Timestamp: 2026-02-07T01:59:24.823Z
Learning: Applies to docs/**/*.gml : Don't add `scr_` prefix for constructor files; instead name such files as the main class inside (e.g., `CoolConstructor.gml`)

Applied to files:

  • scripts/scr_add_man/scr_add_man.gml
📚 Learning: 2026-02-07T01:59:24.823Z
Learnt from: CR
Repo: Adeptus-Dominus/ChapterMaster PR: 0
File: docs/CODE_STYLE.md:0-0
Timestamp: 2026-02-07T01:59:24.823Z
Learning: Applies to docs/**/*.gml : Local variables should have a `_` prefix (e.g., `var _player_health`) to ease readability and prevent namespace clashes with instance variables and scripts. Not required for loop indices.

Applied to files:

  • scripts/scr_add_man/scr_add_man.gml
  • scripts/exp_and_exp_growth/exp_and_exp_growth.gml
  • scripts/scr_marine_struct/scr_marine_struct.gml
  • scripts/scr_roster/scr_roster.gml
📚 Learning: 2025-09-04T14:52:45.005Z
Learnt from: OH296
Repo: Adeptus-Dominus/ChapterMaster PR: 0
File: :0-0
Timestamp: 2025-09-04T14:52:45.005Z
Learning: Project coding style summary:
- Constructors PascalCase; functions/variables snake_case with group prefixes (scr_*).
- Enums: enum name eNAME in SNAKE_CASE; entries PascalCase.
- Macros: ALL_CAPS SNAKE_CASE.
- Indentation 4 spaces; semicolons; use &&/||; parentheses for mixed ops; prefer ++/--.
- Prefer template strings $"..."; use “///” doc comments.
- Locals recommended with leading underscore.
- Organize scripts into library-like files; use early returns and init vars at declaration.

Applied to files:

  • scripts/scr_lines/scr_lines.gml
📚 Learning: 2026-02-09T23:42:26.326Z
Learnt from: MCPO-Spartan-117
Repo: Adeptus-Dominus/ChapterMaster PR: 508
File: scripts/scr_specialist_training/scr_specialist_training.gml:371-371
Timestamp: 2026-02-09T23:42:26.326Z
Learning: The spec_train_data array index for Techmarine training data is 0, as confirmed by the maintainer.

Applied to files:

  • scripts/scr_specialist_training/scr_specialist_training.gml
📚 Learning: 2025-02-24T17:50:27.583Z
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 474
File: scripts/scr_buttons/scr_buttons.gml:153-201
Timestamp: 2025-02-24T17:50:27.583Z
Learning: For consistency in GML code, prefer multi-line conditions with brackets over single-line conditions.

Applied to files:

  • objects/obj_en_ship/Draw_0.gml
📚 Learning: 2025-04-15T11:03:37.154Z
Learnt from: VanWeapon
Repo: Adeptus-Dominus/ChapterMaster PR: 725
File: scripts/scr_initialize_custom/scr_initialize_custom.gml:2474-2572
Timestamp: 2025-04-15T11:03:37.154Z
Learning: In the ChapterMaster initialization code, negative values in the company structure (e.g., for vehicles like rhinos, landspeeders) are acceptable as only positive values will result in units being created.

Applied to files:

  • scripts/scr_vehicle_order/scr_vehicle_order.gml
📚 Learning: 2025-04-15T11:07:33.927Z
Learnt from: VanWeapon
Repo: Adeptus-Dominus/ChapterMaster PR: 725
File: scripts/scr_initialize_custom/scr_initialize_custom.gml:956-959
Timestamp: 2025-04-15T11:07:33.927Z
Learning: Negative vehicle counts (like `rhino -= 2` potentially resulting in negative values) are acceptable in the `scr_initialize_custom` function, particularly when handling chapter advantages like "Lightning Warriors". This is intentional behavior in the game's design.

Applied to files:

  • objects/obj_star_select/Create_0.gml
📚 Learning: 2025-03-11T01:34:29.268Z
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 579
File: objects/obj_enunit/Alarm_0.gml:186-187
Timestamp: 2025-03-11T01:34:29.268Z
Learning: In the ChapterMaster game, the variable `_column_size_value` represents the physical size/mass of a column of units, calculated as (vehicles * 2.5) + (dreadnoughts * 2) + (men * 0.5), and is used for determining back row protection rules.

Applied to files:

  • objects/obj_al_ship/Create_0.gml
📚 Learning: 2025-02-25T13:20:39.523Z
Learnt from: MCPO-Spartan-117
Repo: Adeptus-Dominus/ChapterMaster PR: 514
File: scripts/scr_specialist_training/scr_specialist_training.gml:321-327
Timestamp: 2025-02-25T13:20:39.523Z
Learning: For the ChapterMaster project, the developer prefers to keep magic numbers directly in the code without extracting them to named variables when they're only used once.

Applied to files:

  • objects/obj_al_ship/Create_0.gml
  • scripts/Armamentarium/Armamentarium.gml
📚 Learning: 2025-04-19T23:59:08.325Z
Learnt from: VanWeapon
Repo: Adeptus-Dominus/ChapterMaster PR: 737
File: scripts/scr_save/scr_save.gml:203-205
Timestamp: 2025-04-19T23:59:08.325Z
Learning: In the ChapterMaster codebase, empty values are expected when retrieving units with fetch_unit(), and checking for empty strings with `if(unit == "")` is sufficient error handling. Additional struct validation is not required.

Applied to files:

  • scripts/scr_buttons/scr_buttons.gml
📚 Learning: 2025-07-01T20:29:44.075Z
Learnt from: OH296
Repo: Adeptus-Dominus/ChapterMaster PR: 902
File: objects/obj_shop/Create_0.gml:550-655
Timestamp: 2025-07-01T20:29:44.075Z
Learning: In GML shop item initialization code, when setting nobuy flags for shop items, the nobuy[i] = 1 assignment must occur before incrementing the index (i += 1). Setting nobuy after incrementing i will apply the flag to the wrong item, potentially making restricted items purchasable or blocking intended purchasable items.

Applied to files:

  • scripts/Armamentarium/Armamentarium.gml
🔇 Additional comments (62)
scripts/scr_creation_draw_slides/scr_creation_draw_slides.gml (2)

399-403: The machine spirit acknowledges these corrections, Tech-Priest.

The errant escape runes \R and \A have been purified to \n, restoring the sacred newline invocations within the "Fleet Based" and "Penitent" tooltips. This aligns them with the already-correct "Homeworld" tooltip. The /// @mixin`` consecration is consistent with the rites observed at lines 14 and 405.


928-929: Mixin rite properly inscribed, Tech-Priest.

The /// @mixin`` annotation upon draw_chapter_homeworld_select() is consistent with the sacred pattern applied to its sibling functions. No anomalies detected in the augury.

scripts/scr_draw_management_unit/scr_draw_management_unit.gml (1)

1-1: The machine spirit acknowledges this rite of annotation.

The /// @mixin`` tag is properly applied, Tech-Priest. The Omnissiah's records are duly updated.

scripts/scr_ancient_ruins/scr_ancient_ruins.gml (1)

144-144: The textual amendment is acknowledged.

Tech-Priest, the machine spirit finds this revision to the recovery failure narrative acceptable. The prose flows without logical defect.

scripts/scr_diplomacy_helpers/scr_diplomacy_helpers.gml (2)

72-91: The Machine Spirit approves this logic, Tech-Priest.

Reverse iteration for in-place array_delete is the correct rite — index integrity is preserved as elements are excised from the array's terminus inward. The early return on empty arrays is a worthy optimisation. The filtering logic is sound.

One minor observation: global.logger.debug(_opt) will serialise the entire option struct to the log. Ensure this does not produce excessive log noise in production builds.


250-250: The parameter's rite of binding is now made explicit, Tech-Priest.

Defaulting new_path to undefined correctly documents the existing invocation pattern — callers at lines 281, 305, and 330 already omit this argument when supplying a complex_path function. The logic at line 253 (!is_method(complex_path)) ensures new_path is only consumed when complex_path is not callable, so the undefined default introduces no new risk.

A worthy formalisation of what was previously implicit.

scripts/scr_roster/scr_roster.gml (5)

428-429: The machine spirit approves this rectification, Tech-Priest.

The corrupt data-link referencing ship_id has been purged and replaced with the sanctified local variable _id, as declared on the preceding line. The logic flows true once more.


446-446: A crucial misalignment in the cogitator's geometry has been corrected.

Previously, x1 was being overwritten to 0 a second time instead of initialising x2. The coordinate matrix is now properly formed.


454-454: New data-field description inscribed into the PurgeButton construct. Acknowledged.


506-506: Mixin annotation and local scoping — the rites of proper declaration are observed.

The /// @mixin`` marker and var _unit_role declaration conform to the sacred code conventions. The variable bears the `_` prefix as ordained.

Also applies to: 531-531


761-761: Type annotation for targ acknowledged. The machine spirit's omniscience over this object is strengthened.

scripts/exp_and_exp_growth/exp_and_exp_growth.gml (4)

62-62: Proper local scoping — the Omnissiah approves.

The declaration of trait_stat_value as a local variable is a righteous correction, Tech-Priest.


80-80: @mixin annotation duly noted.

The machine spirit acknowledges this doctrinal marker, Tech-Priest.


182-182: Local scoping of cur_trait and growth_share — sanctioned.

These declarations properly confine the variables to their ritual scope. The logic is sound.

Also applies to: 202-202


276-289: Post-loop error handling and return paths are coherent.

The corrected instance_stat_point_gains is returned on Line 278 upon successful growth, while the error branch (Lines 280–284) logs diagnostics via multiple channels. The dual path is consistent with the refactored local scoping.

One observation: stat_gains on Line 276 only reflects the last iteration's outcome. If only the final iteration fails to match but earlier ones succeeded, the function logs a spurious "No stat gains!" error despite having already incremented stats and populated instance_stat_point_gains. This is a downstream consequence of the stale-value issue flagged above — resolving that will also correct this branch's behaviour.

scripts/scr_buttons/scr_buttons.gml (4)

720-731: The logic circuits of set_value are sanctified and sound.

The iteration pattern is clear, the early continue reduces nesting, and the boolean return communicates success to the caller. The machine spirit approves.


780-789: The restructured draw rite is well-formed.

Tech-Priest, the extraction of _draw_options_list and the close-on-outside-click logic are sound. Both pop_draw_return_values() exit paths (Lines 776 and 787) are properly consecrated, ensuring no draw-state corruption. The machine spirit approves this refactor.


822-831: The is_callable ward is properly inscribed.

Tech-Priest, the invocation guard at Line 828 correctly employs is_callable(on_change), shielding against non-callable corruption. The prior augury concerning this defence is resolved.


795-840: The _draw_options_list subroutine is well-machined.

Tech-Priest, this extraction consolidates the options-list rendering and interaction logic into a single, focused method — improving readability and reducing cognitive load within draw. The machine spirit finds no defects in these circuits.

scripts/scr_creation/scr_creation.gml (1)

11-11: The @mixin consecrations are duly noted, Tech-Priest.

The machine spirit acknowledges the addition of /// @mixin`` annotations to set_complex_livery_buttons, `update_creation_roles_radio`, and `bulk_selection_buttons_setup`. These liturgical markings are consistent and properly placed. The code's purpose is made more explicit to future Tech-Priests who tend to its maintenance.

Also applies to: 38-38, 58-58

scripts/scr_lines/scr_lines.gml (2)

1-8: The sacred rites of modernisation have been observed, Tech-Priest.

Named parameters, underscore-prefixed locals, and /// doc-comments align with the project's coding canons and the 2026 GML codex. The machine spirit approves this sanctification.


36-38: The final seal is applied without flaw.

The trailing "@" marker and return are consistent with the function's documented purpose. No anomalies detected.

scripts/scr_specialist_training/scr_specialist_training.gml (6)

1-1: The mixin sigil is inscribed. The machine spirit acknowledges this rite of annotation, Tech-Priest.


115-195: The Apothecary training rites have been sanctified, Tech-Priest.

The machine spirit notes the corrected inscription on line 191 — the corruption in the alert litany has been purged. The open_slot ward at line 177 ensures no marine is dispatched into the void. All proceeds in accordance with the Omnissiah's will.


197-274: The Chaplain training codex is properly warded, Tech-Priest.

The open_slot sentinel at line 254 prevents void-displacement of marines. The mixin sigil is correctly applied.


322-336: The open-slot ward is properly inscribed, Tech-Priest.

The machine spirit approves the safe-handling of open_slot != -1 before committing marine relocation. This prevents void-displacement errors in the Librarium training flow.


371-371: The parameterised deduction pleases the machine spirit, Tech-Priest.

Using _threshold rather than a hardcoded value ensures the Mechanicus war-state is properly honoured in the points calculus.


346-354: Reference the TECHMARINE_TRAINING_TIERS constant instead of this inline array.

The TECHMARINE_TRAINING_TIERS macro is already defined in scr_recruit_data.gml. Thy apothecary and chaplain training functions employ their respective named constants—the Techmarine rites must align with this prescribed pattern. Replace the inline array with the constant reference.

scripts/scr_imperial_navy_functions/scr_imperial_navy_functions.gml (2)

1-1: The @mixin annotations are duly consecrated. The Machine Spirit approves.

The systematic application of /// @mixin`` annotations across these fleet-command functions is orderly and consistent.

Also applies to: 139-139, 247-247, 294-294, 463-463, 507-507, 659-659, 673-673, 816-816, 841-841, 883-883


657-658: 🧹 Nitpick | 🔵 Trivial

Blank lines added adjacent to the TODO — acknowledged, Tech-Priest.

Line 657 contains an existing TODO (//TODO allow for splitting forces). As this region was touched, shall a GitHub issue be forged to track this aspiration?

As per coding guidelines: "If a TODO comment is added, ask the user if a GitHub issue should be created."

⛔ Skipped due to learnings
Learnt from: EttyKitty
Repo: Adeptus-Dominus/ChapterMaster PR: 0
File: :0-0
Timestamp: 2025-02-18T17:36:23.214Z
Learning: When commenting out code, add TODO comments explaining why the code is commented out.
Learnt from: MCPO-Spartan-117
Repo: Adeptus-Dominus/ChapterMaster PR: 526
File: objects/obj_popup/Draw_0.gml:234-239
Timestamp: 2025-03-01T11:06:25.427Z
Learning: The comment "Need to modify ^^^^ based on if it is chaos or daemonic" in the artifact gifting code is intentionally kept as a reminder that this implementation is not yet finished, despite the significant refactoring already done.
scripts/scr_reequip_units/scr_reequip_units.gml (4)

1-1: The sacred rite of annotation is duly observed.

The /// @mixin`` designation upon set_up_equip_popup aligns with the broader mixin-annotation campaign across this PR. The machine spirit finds no fault.


198-198: Mixin inscription acknowledged.

The anointing of reload_items with /// @mixin`` is consistent and correct. The Omnissiah approves.


213-213: Mixin sigil inscribed upon draw_popup_equip.

Acknowledged. The rite is consistent with the other functions in this file.


699-699: Local scoping of unit and mixin consecration — the machine spirit is appeased.

The introduction of var unit at line 722 properly confines the variable to its rightful scope within the loop, preventing unintended persistence at instance level. The /// @mixin`` annotation is duly noted.

Also applies to: 722-722

scripts/scr_add_man/scr_add_man.gml (3)

1-1: The machine spirit acknowledges this rite of annotation.

The /// @mixin`` directive is a sound addition, Tech-Priest. It properly marks this script for the compiler's blessing.


29-29: Proper consecration of the local variable unit — the machine spirit approves.

Tech-Priest, the addition of var ensures unit is correctly scoped as a local rather than leaking into the instance namespace unbidden. A necessary correction — unscoped variables are a vector for data-corruption heresies.


2-6: The machine spirit perceives a grave discrepancy in the verification-augurs' initial assessment.

The scrutiny reveals no prior validation block exists in the current iteration of scr_add_man.gml. The codebase exhibits no if (!other_gear) guarding validation logic — only the current if (other_gear == true) conditional remains (line 30). Furthermore, alter_unit_equipment itself contains no equipment-consistency checks or missing-gear alerts; it merely delegates equipment assignment to subordinate functions without sentinel verification.

The code stands as intentionally transitional: comments at lines 3–4 explicitly acknowledge this implementation shall be supplanted by TTRPG_stats methods once construction completes. The TODO markers scattered throughout the function reinforce this is unfinished labour, not corrupted logic.

No validation was excised. The machine-spirit registers no cause for alarm.

Likely an incorrect or invalid review comment.

objects/obj_star_select/Create_0.gml (1)

15-15: The redundant ternary has been excised. The machine spirit approves.

The expression now correctly yields a boolean directly from the comparison operator, as befits logical clarity.

scripts/macros/macros.gml (1)

31-34: The Omnissiah's constant is properly sanctified, Tech-Priest.

Centralising the weapon slot count into a single macro is a worthy act of standardisation. All ship-type creation scripts may now draw from this singular source of truth.

scripts/scr_add_corruption/scr_add_corruption.gml (2)

25-28: Critical index corruption purged, Tech-Priest. The machine spirit commends this repair.

The escort loop iterates with i, yet the prior code referenced escort_num[c] — a variable absent from this scope. This corrects a genuine defect that would have caused incorrect ship identification during corruption propagation.


1-1: Mixin annotation acknowledged.

Consistent with the PR-wide pattern of annotating reusable functions.

scripts/scr_enemy_ai_e/scr_enemy_ai_e.gml (3)

97-101: A corruption of logic most grievous has been purified, Tech-Priest.

The prior incantation present_fleet[13] - present_fleet[13] > 0 perpetually evaluates to 0 > 0 — always false. The Necron dynasty's fleets were thereby rendered invisible to the AI battle resolution. This correction restores their rightful place in the calculus of war.


561-564: Inline variable declarations are properly consolidated.

Declaring and initialising in a single statement improves readability without altering behaviour.


1-1: Mixin annotation acknowledged.

objects/obj_fleet/KeyPress_13.gml (1)

1-12: The rite of battle initiation has been purified, Tech-Priest. The logic flows with newfound clarity.

The prior labyrinthine conditional structure has been distilled to its essential components: cooldown gating, battle start, and battle end. The two branches are mutually exclusive by the start variable, ensuring correct sequencing.

objects/obj_al_ship/Draw_0.gml (1)

3-16: The consolidation of the rendering path is a worthy simplification, Tech-Priest.

The prior multi-branch structure with separate colour, font, and alignment settings per condition has been unified into a single, coherent rendering flow. The zoom-based branching is now cleanly expressed as a simple if/else.

scripts/scr_fleet_functions/scr_fleet_functions.gml (3)

85-93: Proper local scoping of targ_location strengthens the intercept calculation, Tech-Priest.

The variable is now declared within the function's scope and used consistently for coordinate access. This eliminates reliance on implicit state and clarifies the data flow.


223-225: Local scoping of eta is a sound improvement.

Ensuring eta is declared with var prevents accidental leakage into the instance scope, guarding against subtle state corruption in fleet ETA calculations.


146-146: Mixin annotations acknowledged across fleet functions.

The /// @mixin`` markers are consistently applied to set_fleet_movement, `calculate_action_speed`, `scr_efleet_arrive_at_trade_loc`, and `fleet_arrival_logic`.

Also applies to: 260-260, 305-305, 647-647

objects/obj_p_ship/Draw_0.gml (2)

21-24: The stale boarding cursor anomaly has been exorcised. Approved, Tech-Priest.

The else branch now correctly resets obj_cursor.board and image_alpha when no obj_en_ship instances exist, preventing phantom boarding prompts.


1-5: Rendering flow flattened — a worthy simplification, Tech-Priest.

The direct if (selected == 1) gating and the linear circle-drawing sequence are clearer than the prior nested structure. The triple-circle technique for a thicker selection indicator is a pragmatic approach.

objects/obj_en_ship/Draw_0.gml (1)

26-30: The Battlekroozer conditional has been unified into proper if/else form. Approved, Tech-Priest.

The mutually exclusive rendering paths are now explicit, as previously counselled.

objects/obj_en_ship/Create_0.gml (2)

34-41: The sacred constant SHIP_WEAPON_SLOTS now binds all weapon arrays. Approved, Tech-Priest.

The migration from per-element initialisation to array_create(SHIP_WEAPON_SLOTS, ...) is consistent and well-aligned with the parallel changes in obj_al_ship and obj_p_ship.


39-39: Divergent weapon_ammo initialisation is intentional: player ships use safe sentinel.

The divergence between obj_p_ship (0) and enemy/ally ships (999) is by design. Player ships initialise to 0 as a sentinel to prevent weapon discharge before Alarm_0 populates ammo to 999. The firing logic guards with weapon_ammo[gg] > 0, rendering the sentinel safe. Enemy and ally ships bypass this sentinel path, initialising directly to 999. Both approaches converge to full ammunition in Alarm_0.gml.

objects/obj_p_ship/Create_0.gml (1)

53-60: Weapon arrays unified under SHIP_WEAPON_SLOTS. Approved, Tech-Priest.

Clean and consistent migration. The weapon_ammo default of 0 (vs 999 in enemy/allied ships) has been flagged in the obj_en_ship/Create_0.gml review for verification.

objects/obj_al_ship/Create_0.gml (1)

36-43: The profane repetition of 8 has been sanctified into SHIP_WEAPON_SLOTS, as previously ordained. Approved, Tech-Priest.

All weapon arrays now draw their size from the unified constant, fulfilling the edict from the prior review cycle.

scripts/scr_vehicle_order/scr_vehicle_order.gml (1)

32-33: The divergent sentinel values are intentional and pose no corruption risk, Tech-Priest.

veh_wid uses 0 as sentinel (denoting "not on a world") whilst veh_lid uses -1 (denoting "not in a ship"). The codebase correctly observes these semantics: veh_wid is checked with > 0 to verify planetary placement, and veh_lid with > -1 to confirm ship assignment. The differing values reflect their distinct domains—one is a world identifier (positive or zero), the other a ship array index (zero or positive). No silent corruption shall occur from this divergence.

scripts/Armamentarium/Armamentarium.gml (5)

5-7: Sacred constants consecrated — the Omnissiah approves, Tech-Priest.

The extraction of STC_MAX_LEVEL, STC_POINTS_PER_LEVEL, and FORGE_QUEUE_MAX into named macros satisfies prior counsel. The machine spirit finds these declarations sound.


12-154: The ShopItem data-construct is well-formed, Tech-Priest.

The decoupling of calculate_costs from obj_controller by accepting _known_techs as a parameter is a worthy improvement. The static cache within _get_tech_display_name is an efficient pattern. This construct reads cleanly and serves its purpose.


411-444: The refactoring into ShopItem, STCResearchPanel, and Armamentarium is commendable, Tech-Priest.

The monolithic construct has been decomposed into coherent, single-responsibility components. The controller reference is now injected rather than assumed, and the STCResearchPanel receives a callback for change propagation. The machine spirit finds the architecture sound.


574-578: The Machine Spirits decree: concern dispelled, code sanctified.

array_contains_ext with default parameters (matchAll=false) returns true if any element from the values array exists in the target array. Line 574 correctly classifies items bearing "sponson", "turret", or "vehicle" tags to vehicle_gear. The reclassification logic functions as intended. No further intervention required.


399-399: The Omnissiah's records confirm: this custom utility operates as intended.

array_random_element is not a standard GML function; it is a bespoke utility defined within thy scriptorium at scripts/scr_array_functions/scr_array_functions.gml. The function is properly wrought and invoked throughout the codebase in manifold places. Thy implementation at line 399 is correct. The machine spirit finds no fault herein.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@EttyKitty EttyKitty merged commit a778ee6 into main Feb 10, 2026
2 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: JSON Changes to external JSON files or their under-the-hood functionality Size: Warning

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant