DDS Script Extensions

v1.1.0·Updated 2026-09-12

Lua driven script extensions for the DDS system to enable dynamic scripted text

About this mod Author’s original text

Piepieonline's DDSScriptExtensions

Lua driven script extensions for the DDS system to enable dynamic scripted text. Looks for JSON files named ddsscripts.sod.json in the Bepinex mods directory and subdirectories.

ddsscripts.sod.json Format

This is a subset taken from the default ddsscripts.sod.json file (/DDSContent/ddsscripts.sod.json) that comes with this mod:

{

"values": {

"citizen": {

"selected_random": {

"seed": "tonumber(inputObject.seed)",

"script": "return 'Random number is: '.. math.random(0, 10)"

},

"owner": {

"script": "return 'Current location owner is: '.. inputObject.currentGameLocation.thisAsAddress.owners[0].citizenName"

}

},

"random": {

"alpha6": {

"script": "return string.format('#%06X', math.random(0, 0xFFFFFF))"

}

},

"city": {

"player_name": {

"script": "return Player.citizenName"

}

},

"time": {

"twohourslater": {

"script": "return SessionData.TimeString(tonumber(CSToString(inputObject)) + 2, true)"

}

}

},

"scopes": {

"citizen": {

"vmail_participant_a": {

"scope": "citizen",

"script": "return inputObject.thread.participantA > -1 and CityData.citizenDictionary[inputObject.thread.participantA] or nil"

}

}

}

}

  • At the top level, scripts are split into scopes (contain other scopes and values) and values
  • Each script is placed into an existing scope, which means that the relevent scope object will be passed in as inputObject (So for a letter, it'll have the evidence scope).
  • The next level are keys that will be called from the DDS system, for example:
  • values
  • |writer.custom_selected_random| - Will generate a random number for each civilian, the same each time it is called
  • |writer.custom_selected_random_1| - Will call the above function, but generate a different number with an adjusted seed
  • |writer.custom_owner| - Will show the name of the owner of the current location of the writer
  • |random.custom_alpha6| - Will generate a random 6 digit hex code each time the text is shown
  • |city.custom_player_name| - Will show the player's citizen name
  • |killer.lastmurder.time.custom_twohourslater| - Will show the time (in 24 hour time) 2 hours after the previous murder was committed. Time is represented as a float where the integer component is hours since world start.
  • scopes
  • |customscope_vmail_participant_a.fullname| - Will set the scope to the first participant in the vmail chain, and then get the fullname value (Only valid in a vmail scope, which is based on the citizen scope)

When referencing scope scripts from the DDS system, each needs to be prefixed with 'customscope_'.

When referencing value scripts from the DDS system, each needs to be prefixed with 'custom_'. If a numeric postfix is attached, the generated seed will be offset by this number.

  • Instead of an inline script, a value or scope can specify "file": "path/to/script.lua", relative to the directory containing ddsscripts.sod.json
  • _caller is available in every script, and contains the name of the script being run without the custom_/customscope_ prefix
  • _cache is a Lua table available in every script for storing state between calls. It is cleared each time a city is loaded

Debugging

There is a debugging configuration flag to log a lot of information from each script execution.

Scripts can also be reloaded at runtime by running DDSScriptExtensions.DDSScriptExtensionsPlugin.ReloadScriptList() in UnityExplorer

Manual Installation

  • Ensure you have BepInEx BE installed
  • Extract the mod to ".\BepInEx\plugins\", so you should have ".\BepInEx\plugins\DDSScriptExtensions\DDSScriptExtensions.dll"

Source:

Install & use Install: follow the bundled instructions

  1. Unzip the archive from playbuff and read the bundled readme / instructions first.
  2. Most mods rely on the game's mod loader — the usual route is a community mod manager (such as r2modman): pick this game, install, and it handles the loader and dependencies.
  3. For a manual install, put the mod files into the matching Mod / plugins folder inside the game directory.
  4. Launch the game to confirm it loaded; mods with listed dependencies need those installed as well.

Install locations vary a lot between mods — the bundled readme is the most reliable guide.

Dependencies

Install these first, or the mod will not work:

BepInEx-BepInExPack_IL2CPPPiepieonline-Asset_Bundle_Loader

File & checksum

Filename
DDS_Script_Extensions-1.1.0.zip
File size
181.5 KiB