r/StarfieldCreationKit

Starfield Creation Kit Tutorial - Quick edit Layered Material Swaps by scrolling
▲ 21 r/StarfieldCreationKit+1 crossposts

Starfield Creation Kit Tutorial - Quick edit Layered Material Swaps by scrolling

Hey all! Trying my hand at video tutorials. This is my first one, just got setup with my tooling so I'll have to refine as I go along.

This tutorial shows you how to quickly edit layered material swaps on statics and packins when editing in the render window, using some handy hotkeys!

Basically, change the color and texture of objects quickly when they have prebuilt options to do so.

Most of my tutorials will be on CK basics, and then some specifics around POIs and dungeon setup.

youtube.com
u/cyberpsyche_mods — 9 hours ago
▲ 110 r/StarfieldCreationKit+2 crossposts

Free Lanes update brought randomized loot placement to many locations

Good news! Hadn't seen anyone mentioned this yet, and I'm not sure it was mentioned in any of the official change logs.

It looks like how it works is the loot on a map (or any item really) is assigned into three groups. One of which will be randomly enabled when the map loads, and the rest will be disabled (not visible for players)

So if you noticed the placement and variety of loot differing on many of the new POIs you were not crazy!

Observations:

  • I didn't see this added to any old locations, so it only appears to be the new POIs.
  • Some key loot like boss chests are not included in the random placement, which makes sense to me. If you wanted to do something like that and make it make sense you would need to design locations around that which adds more complexity. That is because you want the boss near the boss chest and levels often are designed to flow a particular way around a boss location/boss fight if they are combat focused.
  • In some maps it seems like the three groups of loot are sort of a low, med, high value loot type arrangement. I haven't looked at a ton of the maps though so could just be the way I'm interpreting the loot selection.
  • The three groups of items to enable/disable include lootable things such as credsticks, containers and displays of all kinds, corpses, and some associated things such as blood decals associated with the corpses/scenery and stuff.

Technical, for mod authors, if you want to inspect:

  • Look for the SFBGS00D_RandomizeDummy activator in a cell on a map, this has a script which performs the random roll OnCellLoad, and chooses a set (number is set by property) number of enable markers to enable. The markers are in a linkref chain. I recommend looking at the script, although I don't think it de-compiles fully via Champollion.
  • Right click SFBGS00D_RandomizeDummy in the object window and look at Use Info to see every location using it currently.
  • To see all the loot in a given group, right click an enable marker, and choose Select Enable State Children. Set your cell view to Selected, (keep in mind cell view only shows you whats in the current cell, not the whole map in an exterior worldspace)

If you want to add it or use it to your POI:

  • There is a packin that has the "kit" of the activator and enable markers, already linked up. "SFBGS00D_RandomizerPackin" to make it easier to place.
  • Looks like you would drop this in, then select groups of loot and items, use batch reference actions to set enable parents on those items to one of the three enable markers, rinse and repeat. At a glance I think that is it?
  • I haven't tested any of this out on a custom POI yet, but I will soon!
u/cyberpsyche_mods — 4 days ago
▲ 65 r/StarfieldCreationKit+1 crossposts

Nothing crazy, just went into the cell editor, deleted everything with the word light on it and loaded the game.

It feels way more atmospheric, tense and like a real abandoned place, although a proper "moody" relighting should be done because some areas are pitch black.

u/AleGR_93 — 10 days ago
▲ 103 r/StarfieldCreationKit+1 crossposts

Hey all! I was poking through Free Lanes additions in the CK and found SFBGS00DWorldArtAssets under Interior cells. Check it out! It has a ton of art assets placed for reference. VERY useful. It isn't everything, but it is a ton.

If you aren't already aware of the pre-existing "warehouse" and "test" cells. Search Interior cells by those terms and go through some of those. WarehouseTraps is pretty interesting and useful!

u/cyberpsyche_mods — 12 days ago

Hey all!

I was making a fix for the ship builder crashes from the Terran Armada couch and I learned a bit. Uploaded a fix as well!

After lots of testing to verify, it looks like having more than one OutpostGroupPackinDummy REFRs in the Instanced Packin for your constructible object results in a ship builder crash after trying to edit a ship with one of those packins in it.

Multiple other authors acknowledged this is a known source of crashes, and since I also confirmed it with testing I wanted to share. I try to never spread misinformation so if I get any details wrong here, please chime in.

Below is an xedit script written by twenty rounds with ChatGPT Codex and myself that will scan through packin cells in an ESM and look for any with more than one dummy. It provides a bit of other additional information as well.

Log output looks like in the screenshot, which is the run on SFBGSS050.esm. You'll notice it found multiple dummies in a couple of unused packins, as well as another buildable, but that other buildable is Instanced Static and in my testing doesn't cause a crash there.

Once you identify the packin cells you need to go find the associated packins, edit them and remove the dummies. How to do all that is far outside the scope of this post.

tl;dr don't leave multiple dummies in instanced packins that will be used as buildables in ships. (probably don't want them in hab packins there but I couldn't reproduce a crash with it in the hab packins themselves)

unit userscript;

{
  Starfield xEdit scanner.

  Run:
    Right-click an ESM/ESP in the left pane
    Apply Script
    Select this script

  Purpose:
    Find PackIn* CELLs in the selected plugin that contain more than one
    placed REFR whose base object is OutpostGroupPackinDummy.

  This version processes REFR records directly.
}

const
  TargetCellPrefixLower = 'packin';
  TargetBaseEditorID = 'OutpostGroupPackinDummy';
  TargetBaseFixedFormID = $00015804;

  // Set False if you only want active/non-deleted refs.
  CountDeletedRefs = True;

  // Debug limits.
  MaxTargetRefDebugLogs = 100;

var
  TotalRecordsProcessed: Integer;
  TotalRefsProcessed: Integer;
  TotalTargetRefsFound: Integer;
  TotalPackinTargetRefsFound: Integer;
  TotalDeletedTargetRefsFound: Integer;
  DebugTargetRefLogs: Integer;

  CellKeys: TStringList;
  CellCounts: TStringList;
  CellFirstRef: TStringList;

function BoolString(b: Boolean): string;
begin
  if b then
    Result := 'True'
  else
    Result := 'False';
end;

function ContainsInsensitive(s, part: string): Boolean;
begin
  Result := Pos(LowerCase(part), LowerCase(s)) > 0;
end;

function StartsWithInsensitive(s, prefixLower: string): Boolean;
var
  sLower: string;
begin
  Result := False;

  if Length(s) < Length(prefixLower) then
    Exit;

  sLower := LowerCase(Copy(s, 1, Length(prefixLower)));

  if sLower = prefixLower then
    Result := True;
end;

function BaseMatchesTarget(baseObj: IInterface): Boolean;
var
  baseEdid: string;
  baseName: string;
  baseFixedID: Cardinal;
begin
  Result := False;

  if not Assigned(baseObj) then
    Exit;

  baseEdid := EditorID(baseObj);
  baseName := Name(baseObj);
  baseFixedID := FixedFormID(baseObj);

  if baseEdid = TargetBaseEditorID then begin
    Result := True;
    Exit;
  end;

  if baseFixedID = TargetBaseFixedFormID then begin
    Result := True;
    Exit;
  end;

  if ContainsInsensitive(baseName, TargetBaseEditorID) then begin
    Result := True;
    Exit;
  end;
end;

function IsTargetDummyRef(refRec: IInterface): Boolean;
var
  baseObj: IInterface;
begin
  Result := False;

  if Signature(refRec) <> 'REFR' then
    Exit;

  if GetIsDeleted(refRec) and not CountDeletedRefs then
    Exit;

  baseObj := LinksTo(ElementByPath(refRec, 'NAME'));
  if not Assigned(baseObj) then
    Exit;

  if BaseMatchesTarget(baseObj) then
    Result := True;
end;

function ExtractCellFromRefName(refRec: IInterface): string;
var
  s: string;
  pCell: Integer;
  pStart: Integer;
begin
  Result := '';

  {
    Known Starfield xEdit format from your test:

      [REFR:020838B9] (in PackInSFBGS037ElevatedCabinDesignerCouchStorageCell [CELL:02083804])

    We want:

      PackInSFBGS037ElevatedCabinDesignerCouchStorageCell
  }

  s := Name(refRec);

  pCell := Pos(' [CELL:', s);
  if pCell = 0 then
    Exit;

  // Most common observed format: "(in CellName [CELL:...])"
  pStart := Pos('(in ', s);
  if pStart > 0 then begin
    Result := Copy(s, pStart + 4, pCell - (pStart + 4));
    Exit;
  end;

  // Fallback for alternate format: " in CellName [CELL:...]"
  pStart := Pos(' in ', s);
  if pStart > 0 then begin
    Result := Copy(s, pStart + 4, pCell - (pStart + 4));
    Exit;
  end;
end;

procedure AddCellHit(cellKey: string; refName: string);
var
  idx: Integer;
  count: Integer;
begin
  idx := CellKeys.IndexOf(cellKey);

  if idx = -1 then begin
    CellKeys.Add(cellKey);
    CellCounts.Add('1');
    CellFirstRef.Add(refName);
  end
  else begin
    count := StrToInt(CellCounts[idx]);
    Inc(count);
    CellCounts[idx] := IntToStr(count);
  end;
end;

function Initialize: Integer;
begin
  TotalRecordsProcessed := 0;
  TotalRefsProcessed := 0;
  TotalTargetRefsFound := 0;
  TotalPackinTargetRefsFound := 0;
  TotalDeletedTargetRefsFound := 0;
  DebugTargetRefLogs := 0;

  CellKeys := TStringList.Create;
  CellCounts := TStringList.Create;
  CellFirstRef := TStringList.Create;

  AddMessage('Starting REFR-based scan...');
  AddMessage('Looking for REFRs with base object: ' + TargetBaseEditorID);
  AddMessage('Target fixed FormID fallback: ' + IntToHex(TargetBaseFixedFormID, 8));
  AddMessage('Only counting refs whose parent cell name starts with PackIn / Packin / packin.');
  AddMessage('Count deleted refs: ' + BoolString(CountDeletedRefs));
  AddMessage('This version processes REFR records directly.');

  Result := 0;
end;

function Process(e: IInterface): Integer;
var
  cellName: string;
begin
  Result := 0;

  Inc(TotalRecordsProcessed);

  if Signature(e) <> 'REFR' then
    Exit;

  Inc(TotalRefsProcessed);

  if not IsTargetDummyRef(e) then
    Exit;

  Inc(TotalTargetRefsFound);

  if GetIsDeleted(e) then
    Inc(TotalDeletedTargetRefsFound);

  cellName := ExtractCellFromRefName(e);

  if DebugTargetRefLogs < MaxTargetRefDebugLogs then begin
    Inc(DebugTargetRefLogs);
    AddMessage(
      'Target dummy REFR found #' + IntToStr(DebugTargetRefLogs) +
      ' | Deleted: ' + BoolString(GetIsDeleted(e)) +
      ' | Cell: "' + cellName + '"' +
      ' | Ref: ' + Name(e)
    );
  end;

  if cellName = '' then
    Exit;

  if not StartsWithInsensitive(cellName, TargetCellPrefixLower) then
    Exit;

  Inc(TotalPackinTargetRefsFound);

  AddCellHit(cellName, Name(e));
end;

function Finalize: Integer;
var
  i: Integer;
  count: Integer;
  matchedCells: Integer;
begin
  matchedCells := 0;

  AddMessage('Scan complete.');
  AddMessage('Total records processed by script: ' + IntToStr(TotalRecordsProcessed));
  AddMessage('Total REFR records processed: ' + IntToStr(TotalRefsProcessed));
  AddMessage('Total OutpostGroupPackinDummy REFRs found anywhere: ' + IntToStr(TotalTargetRefsFound));
  AddMessage('Total deleted OutpostGroupPackinDummy REFRs found anywhere: ' + IntToStr(TotalDeletedTargetRefsFound));
  AddMessage('Total OutpostGroupPackinDummy REFRs found in PackIn* cells: ' + IntToStr(TotalPackinTargetRefsFound));
  AddMessage('Unique PackIn* cells with at least one dummy: ' + IntToStr(CellKeys.Count));

  AddMessage('--- PackIn* cells with more than one OutpostGroupPackinDummy ---');

  for i := 0 to CellKeys.Count - 1 do begin
    count := StrToInt(CellCounts[i]);

    if count > 1 then begin
      Inc(matchedCells);
      AddMessage(
        'MATCH: ' + CellKeys[i] +
        ' | OutpostGroupPackinDummy refs: ' + IntToStr(count)
      );
      AddMessage('  First matching ref seen: ' + CellFirstRef[i]);
    end;
  end;

  AddMessage('Matching PackIn* cells with more than one dummy: ' + IntToStr(matchedCells));

  CellKeys.Free;
  CellCounts.Free;
  CellFirstRef.Free;

  Result := 0;
end;

end.
u/cyberpsyche_mods — 7 days ago
▲ 6 r/StarfieldCreationKit+1 crossposts

Is it possible to increase the activation range of the Social Skills? (Intimidation, Instigation, etc etc)

Hello, I've been toying around with the Creation Kit as of late. So far I've just been making my own changes to perks, but one thing I haven't been able to figure out so far is how to increase the range in which you can use one of the Social Skills on people.

I know the scanner can have its range increased via a playerskill quest stage, but simply adding that quest from Surveying into the entry table for one of the social skills perks doesn't do anything.

So, I'm pretty much at a dead end for figuring out how to get the Social Skills range to increase. Searching around for any tutorial usually just results in how to import weapons or make quests and such - nothing related to what I'm trying to do.

Ideally, I want the activation range for the skills to go up as the Surveying skill goes up.

(also, so as to not need to make another post, what does the priority in a perk's entry table mean and how does it work? I haven't been able to figure this out.)

reddit.com
u/cinnaminiii — 2 days ago

Like the title says. Every time I try to create a new location on a planet CK crashes. Been following Jramos video step by step and still getting crashes. Any ideas?

So just to update it was using underscores in the title of the esp file. Thanks for all the help y’all

reddit.com
u/Feeling_Mushroom6633 — 9 days ago