Skip to content

Sides, lifeforms & faces

Narrative missions need factions to fight (sides), characters to talk to (lifeforms), and faces for comms.

Sides

Create sides with prefab_side_generic, then set how they feel about each other. await captures the side id the prefab yields:

tsn      = await prefab_spawn(prefab_side_generic, data={"key":"tsn"})
side_set_display_name(tsn, "TSN")
side_set_description(tsn, "The Terran Stellar Navy")
side_set_icon_color(tsn, "#07F")

# or set it all in the prefab data:
raider   = await prefab_spawn(prefab_side_generic, data={"key":"raider", "name":"Raider", "color":"#F00", "desc":"Hostile Aliens"})
amb_side = await prefab_spawn(prefab_side_generic, data={"key":"ambassador", "name":"Ambassador", "color":"#FFF"})

side_set_relations(tsn, raider, sbs.DIPLOMACY.HOSTILE)
side_set_relations(tsn, amb_side, sbs.DIPLOMACY.NEUTRAL)

sim.set_diplomacy_color(sbs.DIPLOMACY.HOSTILE, "#F00")
sim.set_diplomacy_color(sbs.DIPLOMACY.NEUTRAL, "#077")

An object's side is the first role in its npc_spawn roles string ("tsn, station" → side tsn).

Declaring sides as data

A whole faction set can be authored in an AMD document and declared with sides_load_amd("maps/sides.amd") — one heading per side, the fence carrying its identity and diplomacy:

# [Raider](raider)
---
Color: #F00
Enemies: players, civilians
---
Hostile Aliens.

# [Civ](civ)
---
Color: white
Civilian: true
Neutral: players
---
Civilians. Protect them from attack.

Relations exist only where you declare them. Nothing defaults an unnamed pair, so a set of factions that each name one enemy produces a star — one side hostile to everyone, and every other pair silently neutral. That failure is invisible in testing, because what breaks is the shooting rather than the script: ships spawn on the right sides, correctly armed, and simply never fire.

Three reserved words save you from naming every pair. Explicit names always win over a token.

Token Means
* every other side in this document
players every side in PLAYER_LIST, plus any side a player ship is actually on
civilians every side declaring Civilian: true, in any document

players and civilians deliberately reach across documents, which is what lets an addon and a total conversion coexist: neither can name the other's sides, so Enemies: tsn is inert beside a mod whose crews fly federation. Written as Enemies: players, raiders prey on whoever turns up. * stays inside its own document, so an addon cannot silently redefine a relation with a side it has never heard of.

Sides are declared before any ship exists, so players resolves from the roster at that point. Call sides_apply_audiences() after the crew is real — or after a mission moves a crew to another side — and the same rules re-resolve against the live ships.

Lifeforms (NPCs)

A lifeform is an NPC used for comms, names, and faces. Create them at the top level (shared) so every task can reach them:

shared admiral = lifeform_spawn("Admiral Harkin", "ter #964b00 8 1;ter #fff 3 5;", "admiral")

Arguments: display name, a face string, and a role. Read its face and name later with get_face(admiral.id) and admiral.name.

Attach a lifeform to a player ship as crew (shown in interior views):

ensign_rachel.host = artemis_id

Faces

Faces are strings. Build random ones, or set an object's face directly:

set_face(station_id, random_terran(civilian=True))
set_face(amb_id, random_terran(civilian=False))
set_face(raider_id, random_kralien())
face = get_face(admiral.id)      # e.g. to pass to a comms message

Use the face when sending a message (see Story & NPC messages) or in comms dialogue. See the faces API and the lifeform API.