PlanetsLib
Code, graphics and conventions to help modders creating planets, moons and other systems. This library is a community project and will grow over time. Anyone is welcome to open a pull request on Github. For feature requests, please open an issue. For general discussion, use Discord.
Contributors
Notes for contributors
- In your pull requests, please list your changes in changelog.txt to be included in the next release. Please also update
README.md
to add sections for your new functionality (even with only 'Documentation pending') and add yourself to the contributors list. - Contributions MUST be tested before a PR is made, ideally with multiple planets installed.
- We aim to never make any breaking changes. Sometimes APIs are removed from the documentation, that does not mean they are no longer supported.
- Feel free to use the file
todo.md
.
Documentation
Defining planets
PlanetsLib provides an API to define planets and space locations. It is a simple wrapper for data:extend.
The reasons one may choose to use it over a plain data:extend
are some additional features: you can specify positions with respect to a parent body; if the parent body is moved by another mod your planet will move with it; a sprite depicting the orbit can be supplied; and various other mods are sensitive to the orbit tree.
PlanetsLib:extend(configs)
— A wrapper/replacement fordata:extend
. Should not be called indata-final-fixes
. Throws an error if passeddistance
ororientation
. Each config instead takes the fields listed below.type
—"planet"
or"space-location"
orbit
— Object containing orbital parameters:parent
— Object containingname
andtype
fields, corresponding to a parent atdata.raw[type][name]
. Planets in the original solar system should have an orbit withtype = "space-location"
andname = "star"
.distance
— Number — orbital distance from parentorientation
— Number — orbital angle from parent (0-1). Note that orientation is absolute, not relative to the parent's orientation.sprite
— Object (optional) — Sprite for the planet’s orbit. This will be centered on the parent's location.
sprite_only
— Boolean (optional) — If true, this prototype will be removed indata-final-fixes
and replaced by its sprites on the starmap (unless it has no sprites, in which case nothing will show).- This is useful for constructing stars and other locations that should not have a space platform 'docking ring'.
- Any other valid
planet
orspace-location
prototype fields. - See here or here for usage examples.
PlanetsLib:update(configs)
— A simple helper that can be used to update the positions of pre-existing space locations, as identified by the passedtype
andname
fields. Any other fields passed will be updated on the prototype, and if theorbit
field is passed thedistance
andorientation
fields on the prototype will also be updated. Any fields not passed will be left unchanged. Should not be called indata-final-fixes
.
The distance
and orientation
fields on the prototype will be generated automatically. These are actually still treated as authoritative by PlanetsLib, and will determine its final location. The exception is if PlanetsLib sees the distance
/orientation
of one of your planet's parents has been moved relative to its orbit
specification. In that case it will treat whatever mod intercepted the positions as intending to move all of that planet's children too, so PlanetsLib will update their locations appropriately.
Any space locations defined without PlanetsLib:extend are assigned the sun as their orbital parent. All the space locations thus form a ‘family tree’ structure.
Planet tiers
The companion mod PlanetsLib: Tiers defines 'tier values' for planets and space locations. Tiers have no functionality by themselves, but are a rough indicator where the planet fits in a vanilla-style game of Space Age for the purposes of other mods that wish to use this information. With this mod installed, tiers can be accessed with local tier = data.raw["mod-data"]["PlanetsLib-tierlist"].data[type][name] or data.raw["mod-data"]["PlanetsLib-tierlist"].data.default
The tier listing is here on GitHub.. Players are encouraged to submit edits to keep it up-to-date.
Planet Cargo Drops technology
You can use the library to restrict cargo drops on your planet until a certain technology is researched. To implement:
- Use the helper function
PlanetsLib.cargo_drops_technology_base(planet, planet_technology_icon, planet_technology_icon_size)
to create a base technology prototype.- This will create a technology with name pattern:
planetslib-[planet-name]-cargo-drops
- PlanetsLib detects this technology by name. Players will be unable to drop cargo (excluding players and construction robots) to planets with that name before researching the technology.
- Only the fields
type
,name
,localised_name
,localised_description
,effects
,icons
will be defined, so you will need to addunit
(orresearch_trigger
) and prerequisites. - A locale entry for this technology is automatically generated, but you are free to override it.
- This will create a technology with name pattern:
- Note that players can use this mod to disable the effect of this restriction.
Rocket part recipes
You can use the library to assign unique rocket part recipes to rocket silos placed on a specified planet to increase or decrease the difficulty of launching rockets on the planet. Rocket silos with their recipe fixed to the vanilla rocket-part
recipe are targeted by PlanetsLib. To implement:
- Use the helper function
PlanetsLib.assign_rocket_part_recipe(planet,recipe)
to assign a recipe to a planet.- PlanetsLib stores rocket part recipe assignments in a mod-data prototype named
Planetslib-planet-rocket-part-recipe
. Planets with their own system for assigning rocket part recipes are exempted with the assigned recipe name_other
. Muluna and Maraxsis are currently exempted in this manner to maintain backwards compatibility with those mods. - Planets without an assigned recipe default to the vanilla
rocket-part
recipe.
- PlanetsLib stores rocket part recipe assignments in a mod-data prototype named
Surface conditions
New surface conditions
PlanetsLib includes new surface conditions disabled by default and can be enabled via this line in settings-updates.lua (using 'oxygen' as an example):
data.raw["bool-setting"]["PlanetsLib-enable-oxygen"].forced_value = true
Restricting and relaxing conditions
Typically, when planet mods want to modify a surface condition, what they are trying to do is restrict or relax the range of values for which that recipe or entity is allowed.
For example, Space Age recyclers have a maximum magnetic field of 99. If mod A wants to allow recyclers to be built up to 120, whilst mod B wants to allow them up to 150, compatibility issues can arise if mod A acts last and overrides mod B's change (which it ought to have been perfectly happy with). Instead mod A should modify existing surface conditions only if necessary.
Hence relax_surface_conditions
and restrict_surface_conditions
are provided, used like so:
PlanetsLib.relax_surface_conditions(data.raw.recipe["recycler"], {property = "magnetic-field", max = 120})
PlanetsLib.restrict_surface_conditions(data.raw.recipe["boiler"], {property = "pressure", min = 10})
NOTE: Calling relax_surface_conditions
without a min
field will not remove any existing min
conditions for that property (and similarly for max
).
Removing surface conditions
PlanetsLib.remove_surface_condition(recipe_or_entity, "magnetic-field")
— Removes allmagnetic-field
surface conditions.PlanetsLib.remove_surface_condition(recipe_or_entity, {property = "magnetic-field", max = 120})
— Removes all surface conditions that exactly match the provided condition.
Science & Technologies
PlanetsLib.get_child_technologies(tech_name)
— Returns a list of the names of all technologies that havetech_name
as a prerequisite.PlanetsLib.sort_science_pack_names(science_pack_names_table)
— Sorts the given list of science pack names (strings expected) by theorder
fields of the corresponding prototypes, or by their names if anorder
field does not exist.- This is useful for defining the inputs of labs because (unlike in Factoriopedia) science packs displayed in labs aren't ordered by the
order
field.
- This is useful for defining the inputs of labs because (unlike in Factoriopedia) science packs displayed in labs aren't ordered by the
Recipe productivity technology helper field
PlanetsLib adds a new field named PlanetsLib_recipe_productivity_effects
to technologies, used by recipe productivity technologies. During data-final-fixes,
technologies with this field will have their effects list appended or replaced with recipes matching either an output name or recipe category.
TechnologyPrototype
field: PlanetsLib_recipe_productivity_effects
Properties:
effects
:array[ChangeResultProductivityModifier]
category_blacklist
-array[
RecipeCategoryID
]
purge_other_effects
- boolean. Default: false. Before adding effects added byPlanetsLib_recipe_productivity_effects
, remove all effects not flagged withPlanetsLib_force_include
.
ChangeResultProductivityModifier
Properties:
allow_multiple_results
: boolean. Default: false. When false, only recipes with one result are added to the technology's effect list.category
(optional) -RecipeCategoryID
Either(name and type) or category
required. Forbidden whencategory_blacklist ~= nil
.type
(optional) -ProductPrototype
name
(optional) -ItemID
Inherited from ChangeRecipeProductivityModifier
change
icons
(optional)icon
(optional)icon_size
(optional)hidden
(optional)use_icon_overlay_constant
(optional)
New BaseModifier
field: PlanetsLib_force_include
- Makes this modifier immune to
purge_other_effects
.
New 'RecipePrototype' field: PlanetsLib_blacklist_technology_updates
- Stops PlanetsLib from targeting this recipe in technology updates.
Tech tree adjustments
PlanetsLib.excise_tech_from_tech_tree(tech_name)
— Seamlessly removes a technology from the tech tree by making all its dependencies depend instead on the technology's prerequisites. In addition,hidden = true
is set on the technology.PlanetsLib.excise_recipe_from_tech_tree(recipe_name)
— Removes this recipe from all technologies, and if this would cause any technology to have zero effects, the technology is excised usingPlanetsLib.excise_tech_from_tech_tree
.PlanetsLib.excise_effect_from_tech_tree(effect)
— Similar toexcise_recipe_from_tech_tree
, but any effect can be passed.- Example:
PlanetsLib.excise_effect_from_tech_tree({ type = "unlock-quality", quality = "uncommon" })
- Example:
PlanetsLib.add_science_packs_from_vanilla_lab_to_technology(technology)
— Adds all science packs that the vanilla lab have slots for to the unit of the given technology. Can be useful when defining endgame technologies.
Biolab
Because modders often forget about the Biolab, PlanetsLib mirrors all science packs from the vanilla lab to the Biolab in data-final-fixes
.
Subgroups
Subgroups are rows in Factoriopedia.
satellites
— A new Factoriopedia row for satellites (below the planets row).- Note that being in this subgroup affects Redrawn Space Connections and Cosmic Social Distancing.
Assorted helpers
PlanetsLib.technology_icon_moon(tech_icon: string, icon_size: integer)
— Creates a moon discovery technology icon by adding a little moon icon on your technology icon, like in vanilla, but for moon type planets.PlanetsLib.technology_icon_planet(tech_icon: string, icon_size: integer)
— Creates a planet discovery technology icon by adding a little planet icon on your technology icon, like in vanilla.PlanetsLib.set_default_import_location(item_name, planet_name)
— Sets the default import location for an item on a planet.PlanetsLib.borrow_music(source_planet, target_planet)
— Clones music tracks fromsource_planet
prototype totarget_planet
prototype. Does not overwrite existing music fortarget_planet
. To clone music from or to space platforms, set the respective parameter to "space-platform." Otherwise, use the relevant planet object.
Assorted graphics
__PlanetsLib__/graphics/icons/research-progress-product.png
— an iconographic science pack icon intended for items used exclusively as ResearchProgressProducts, since mods using a common icon might help players understand the mechanic.
Python helper scripts
lib/orbit_graphic_generator.py
— contains a Python script that generates orbit sprites.generate_orbit(distance, output_file, mod_name)
,distance
being the same as your orbital distance. After generating your sprite, the script will print a block of lua code that imports your sprite with proper scaling. Orbit sprites should be scaled at 0.25 to ensure that no pixels are visible on 4K monitors.