Dev notes: Best Practices - openly-retro/stellaris-machine-robot-expansion GitHub Wiki

Code formatting

  • Indent by 4 spaces. Do not mix tabs and spaces.
  • Prefer expanding blocks over one-liners, unless there are a lot of the same kind of effect / invocation, in which it's fine to use one-liners
  • First line inside any effect or trigger should explain what it does

Effect / script naming convention

<author_tag>_mdlc_<scope>_<description>

including the scope is extremely important. It will say in which scope is the effect expected to be run

Example:

oxr_mdlc_planet_check_district_armies_full

You know by looking at this that it should be run in the planet scope, and who to poke if it's not working.

All effects & triggers must be explicitly scoped where possible

Standard way:

country_event = {
	...

	trigger = {
		has_ascension_perk = ap_mechromancy
	}

Better:

country_event = {
	...

	trigger = {
		owner = { has_ascension_perk = ap_mechromancy }
	}

You might say this is more code, more typing, but it is worth it especially in large effects. So.. I am asking you to do this.

A few notes: planet is a valid scope in planet and owner is a valid scope in country, they refer to themselves, so it's a clean way to be explicit about scope.

Optimization

Use counters over iterators

Avoid triggers or effects that count things. Instead, set up a system of effects to increment a variable in the scope (planet, country) and then refer to that variable for a counter.

Example: How many districts are there on the planet?

Standard solution: Use a built-in script value to count districts on the planet

Better solution: on district built and destroyed, fire a custom on_action that increments or decrements a "num_districts" variable on the planet. Then, any time you need to know how many districts are on the planet, you refer to the value of num_districts and do not use the script value. This is O(1) versus O(n)

Make use of custom on_actions

Example: If the last district destroyed on a planet was one in a list, then run an event

Standard solution: Switch on last district destroyed, or an OR block checking last district destroyed with entries for all districts that the event should be fired for

Performant solution: on district destroyed, fire a custom on_action that links to the desired event

Reasoning: While iterating over a list is fine, it is still O(n) time complexity. Arguably, a very small list of 10 items is not worth refactoring. However, firing an event directly from district on_destroyed block is O(1)

Image export

  • Decisions: RGBA8 uncompressed, otherwise, border pixel glitches occur
⚠️ **GitHub.com Fallback** ⚠️