-
Notifications
You must be signed in to change notification settings - Fork 11
Home
- You are strongly discouraged from using any modding tools in your actual online Steam installation as to prevent unlocking achievements, corrupting your savefile and cheating in the leaderboards. You should make a copy of your game somewhere else and install Mr. Goldbergs Steam Emulator in the game directory.
- That being said, you can probably use texture mods online in Steam just fine.
- Always create a backup of your local save file (i.e. savegame.sav) by copying it to a safe location.
- Backing up your Spel2.exe is not necessary when using Playlunky as it does not modify the executable.
- This tool is provided as is without any warranties. If do you break anything using it we can not take responsibility.
- Do not report modding related bugs to Blitworks.
Playlunky is integrated within Modlunky 2 as of version 0.11.0, which means you can download and use Playlunky from an actual user interface. So download Modlunky 2 rather than directly downloading Playlunky. To do so, just download Modlunky, start it up, navigate to the Playlunky tab, select the newest version of Playlunky on the top right, press download. The rest of the interface lets you disable mods, change load order of mods and set settings. See Additional Features for a description of those features.
- Download the latest release here after making sure that it is compatible with your installed version of Spelunky 2 (see the upper right corner in the main menu). Do not download the source code, you want
palylunky.zip
. - Extract the downloaded zip file to your Spelunky 2 installation folder, usually
C:\Program Files (x86)\Steam\SteamApps\common\Spelunky 2
. - Run
playlunky_launcher.exe
if you want to start the game with mods, runSpel2.exe
directly or through Steam to disable mods.
- Create an account on spelunky.fyi, navigate to
Settings
, pressClick to reveal
next toAPI Token
and copy the red text - Open Modlunky, go to the
Settings
tab, PressUpdate Token
, paste the previously copied text and pressOK
- Navigate to the mod you want to install while Modlunky is open
- Press
Install Latest
and wait just a few seconds.
- Download a mod from spelunky.fyi.
- Drag and drop the downloaded file (might be a
.png
or a.zip
, it doesn't matter) ontoplaylunky_installer.exe
(the one with the blueish icon) - Wait for it to say
Installation was successfull...
- Enjoy your mod every time you launch the game through
playlunky_launcher.exe
.
- Download a mod from spelunky.fyi.
- Place the contents of the mod into a subfolder in
Spelunky 2/Mods/Packs
(you might need to create these folders if you have no mods installed)
Alternatively you can just place the zipped mod directly into theSpelunky 2/Mods/Packs
folder. - Some mods may require you to rename the files that they ship, so always refer to the instructions that come with the mod.
- You should now have a folder or a zip inside the Packs folder, named after the mod you downloaded, for example
Spelunky 2/Mods/Packs/Cat Spelunker
orSpelunky 2/Mods/Packs/Cat Spelunker.zip
. Don't put loose files directly into thePacks
folder, if the mod you downloaded is just a single file just create your own folder with a random name. - Launch the game through
playlunky_launcher.exe
, this will automatically install your mod. For larger mods (such asfingerspit's Remix Mod
) the installation may take a while since Playlunky has to convert all files to a format usable by the base game. Give it a few minutes, if nothing seems to happen report a bug. - Enjoy your mod every time you launch the game through
playlunky_launcher.exe
.
To declare what order mods should be loaded in (e.g. when two mods replace the same file from the base game and you prefer one over the other) open the file Spelunky 2/Mods/Packs/load_order.txt
and just sort the mods in the order you want them to load in. Make sure every line contains exactly one mod name.
Also using load_order.txt
you can disable mods by prefixing their name with --
, aka two minus signs.
Next to playlunky_launcher.exe
you will find playlunky.ini
which has settings you can turn on and off simply by changing the word after the =
sign. Some of these settings can also be modified from Modlunky directly. The available categories and their settings are the following.
[general_settings]
-
enable_loose_file_warning
: Enables the warning you get when you have loose files in yourSpelunky 2/Packs
folder. This warning is intended for new users to reveal one potential mistake they are making, so it makes sense to disable this when you already know what you are doing. -
speedrun_mode
: Automatically blocks all mods other than what is legal by Mossranking rules. This means you can enable this if you want to do a speedrun without having to manually disable specific mods. -
disable_caching
: Disables caching of mod data, so every time Playlunky starts all conversions and merging of files will happen as if you just freshly installed your mods. -
enable_raw_string_loading
: Allows loading files such asstrings00.str
, disabled by default. This should incentivize everyone to use morestrings00_mod.str
files. -
block_save_game
: Avoids the game saving to yoursavegame.sav
file, use this if you want to avoid progress while playing with mods. -
use_playlunky_save
: Creates a separatesavegame.sav
and saves/loads to/from that while running Playlunky. -
allow_save_game_mods
: Allows loadingsavegame.sav
from installed mods. -
disable_steam_achievements
: Prevents getting Steam achievements while playing with mods.
[script_settings]
-
enable_developer_mode
: Allows reloading script mods by pressingCtrl
+F4
anywhere while the game is running and accepting input. -
enable_developer_console
: Enables the Lua Console -
enable_developer_console
: Defines how many items are saved in the console history
[audio_settings]
-
enable_loose_audio_files
: If enabled allows Playlunky to load loose audio files from mods rather than just loading full soundbank files. Some mods require this setting to be enabled in order to get the full experience. The only reason this is an option is because it will incur a few more seconds of startup time. -
cache_decoded_audio_files
: If enabled Playlunky will cache decoded loose audio files, which will speed up startup time after first load but requires more space on your hard drive. -
synchronous_update
: If enabled it tells FMOD to update its state synchronously which results in less potential threading errors. This does not mean mixing happens synchronously so performance and audio output should be largely unaffected.
[sprite_settings]
-
random_character_select
: If this setting is on, when loading a character file, e.g.char_black.png
, Playlunky will ignore load order and instead load char_black.png from a random mod, among all mods that ship with this file. Mods that ship char_black_full.png are only supported from v0.6.0 and later. -
generate_character_journal_stickers
: If enabled a sticker is generated for old style character mods. -
generate_character_journal_entries
: If enabled a journal sprite is generated for old style character mods. -
generate_sticker_pixel_art
: If enabled together withgenerate_character_journal_stickers
the generated sticker will have a crude pixel art in the style of vanilla stickers. -
enable_sprite_hot_loading
: Enables Playlunky to automatically reload sprite sheets when they are changed on disk. This is particularly useful when you work on a sprite mod.-
sprite_hot_load_delay
: How many milliseconds Playlunky waits before loading a changed sprite sheet.
-
-
enable_customizable_sheets
: Whether customizable sheets should be enabled or not, see See Customizable Sprite Mods-
enable_luminance_scaling
: Enables automatic scaling of luminance of customizable sprite mods based on the user-input colors luminance.
-
[bug_fixes]
-
missing_thorns
: Adds a texture for thorns with 0, 3 or 4 connections. -
missing_pipes
: Adds a texture for pipes with 0, 3 or 4 connections as well as logic for them based on user input. Warning: This breaks the game in multiplayer, both local and remote! -
out_of_bounds_liquids
: Removes liquid that is out of the bounds of the level, this would otherwise crash the game. Allows for e.g. liquid in ice caves.
[key_bindings]
-
console
: Button to open the console -
console_alt
: Alternative button to open the console -
console_close
: Alternative button to close the console
This tool is not sufficient for creating mods. You will instead need Modlunky 2, follow the instructions in their wiki.
When developing mods while using Playlunky however you do not need to repack the executable whenever you change your assets (i.e. skip the step "Repacking with Modlunky 2"). Also note that Playlunky will automatically organize files in your mod, meaning it might move files to different folders within your mods directory after you created them. This usually just means it will place textures into Data/Textures
, levels into Data/Levels
and audio into soundbank
.
Check out Malacath on spelunky.fyi for a bunch of sample mods for the features that are mentioned below. There are also a number of sample mods for specific scripting features and regularly new ones are uploaded.
You can ship your mod with a mod.json
file for any extended information about your mod. It is completely optional as some of the information in there is not used yet, but there are features that are only accessible through this file. A bare bones version of this file looks as follows:
{
"author": "Malacath",
"name": "Sample Mod",
"description": "This is a sample mod.",
"version": "1.0",
}
If you want to change a sprite for example on items.png
but you want your mod to be compatible with other mods that change a sprite on the same sheet then you can not just place items.png
into your mod folder, as that will result in only one mod loading said sprite sheet. For this purpose you will have to use custom sprite mapping, which is a set of instructions for Playlunky to copy regions from an image in your mod into a sprite sheet that the game reads. This is expressed in mod.json
through an object of the following structure (note that json does not support comments, they are here purely for illustrative purpose):
{
// author, name, description, version
"image_map": {
"path/to/source_image.png": {
"path/to/target_image.png": [ // Array of mappings
{
"from": [ 0, 0, 512, 128 ], // Take this region from source_image.png
"to": [ 384, 768, 896, 896 ] // Copy it into this region in target_image.png
},
{
"from": { // Can also be expressed as an object for clarity
"left": 0,
"right": 512,
"top": 128,
"bottom": 256
},
"to": {
"left": 896,
"right": 1048,
"top": 768,
"bottom": 896
}
}
]
}
}
}
In the example we mentioned above "path/to/source_image.png"
would be a path to a mod in your mod folder, e.g. resources/black_vlads_wings.png
, and "path/to/target_image.png"
would be "Data/Textures/items.png"
. The regions given should be understood such that they define a box with (top, left)
being the exact pixel position of the top-left corner of the region and (bottom, right)
being the exact pixel position of the bottom-right of the region. So selecting a region in your image editor should give you those coordinates directly, just try to stay grid-aligned in order to not overwrite other mods.
If multiple mods write to the same region in the same image then load order will determine which mod gets to final say.
As of version 0.8.0 Modlunky 2 extracts the games audio files into the soundbank
folder, where you will find two folders ogg
and wav
. Generally speaking the wav
folder contains the games SFX and the ogg
folder contains the games dynamic music snippets.
From version 0.5.6 of Playlunky it is not necessary anymore to repack these assets into a .bank
file when modding them, instead you can just place the audio files you changed into your mod folder and run directly with Playlunky. Note that the game still decides in most instances how long a clip is played, thus adding clips longer than the original may cut them off in game.
You can also ship your mod with different types of audio files than just .wav
and .ogg
, only the actual name of the file matters for resolving it correctly. Supported formats are all those that are supported by libnyquist (.wav
, .ogg
, .opus
, .wv
, .mp3
, .flac
, .mpc
and .mpp
) It is advisable not to ship your mods with music files in the .wav
format because they will be quite large.
Loading audio files requires Playlunky to do a specific preprocessing step that takes a bit more time than the usual startup (~1s), additionally each audio file has to be decoded into memory which requires additional time (10ms-200ms, depending on file type) and memory (50KB-16MB, depending on file type and length). If you do not want to incur this overhead, maybe because you are extra impatient or have only a tiny amount of memory, there is an option provided in playlunky.ini
that goes by the name of enable_loose_audio_files
. If you are only extra impatient you can enable the option cache_decoded_audio_files
which will save all decoded audio files in a raw format and thus speed up loading audio significantly.
If you place a sprite sheet called some_sheet.png
into your mod you can also place an additional some_sheet_col.png
into your mod to allow users of your mod to customize the sprite sheet by picking different colors. The rules for this _col
sheet are simple, it has to contain a small set of unique, solid colors, ideally without any feathered edges. Playlunky will use this sheet to figure out how many colors there are to customize and what the default settings are.
You can also place a _lumin
sheet that modifies the luminosity of the image, it makes sense when you want to have a default setup that requires modifying the luminosity of the image in addition to the colors.
Note for entity sheets, i.e. those extracted to Data/Textures/Entities
, you need to include the sheet itself in the mod. For vanilla sheets you do not have to do this. For custom sprite mapped sheets and custom in-engine textures you naturally include it in your mod anyways.
Modlunky2 has the option to generate entity sprite sheets during the extraction process, look for a checkbox labeled "Create Entity Sprites". These sprite sheets will be placed in Data/Textures/Entities
. Those sprite sheets contain all sprites used by one entity (i.e. stickers, journal entries, animations) and no other sprites. For example Mounts/turkey.png
contains the turkey animations, the turkey journal image, the cooked turkey in-game sprite and the cooked turkey journal image. Compare this to mounts.png
which contains all mounts and none of the extra sprites.
You can modify these entity sprite sheets like any regular sprite sheet and place them into your mod, Playlunky will then automatically generate the files the game requires (e.g. in the case of a modded turkey it will generate journal_entry_mons.png
, journal_entry_items.png
, items.png
and mounts.png
). This generation takes all enabled mods into account and respects specified load order.
The reason for those entity sprite sheets existence is simply to allow modding entities in a more fine grained way. A mod could previously not modify the turkey without also blocking other mods from modifying Qilin. At this point only very few monsters and NPCs are not available through these sheets.
The _grid.png
files that are generated next to the entity sheets can be used a guides to make sure sprites stay within their allotted space.
See Sprite Mods using Entity Sprite Sheets, with regular character sprite sheets users get a generated sticker and journal entry.
In addition to the sprite sheets characters have other properties such as their name, gender and color. Those have to be modded in a novel way which Playlunky introduced via a .json
file.
To do this for your sprite mod char_{color}.png
create a file char_{color}.json
and fill it with the following json data:
{
"full_name": "Extra Pink Pilot",
"short_name": "EP Pilot",
"color": "0xFF307B",
"gender": "female"
}
Now change the values to the right of the colon on each line to your desired values.
Full name, for example first name and last name. But it could just as well be the same as short name.
This is the name appearing in character select, for example just the first name.
This determines the color of the heart during gameplay as well as the color of constellations. It can be of several formats, either a hex-code as in the example or a json array of floats "color": [ 0.8, 0.3, 0.4 ]
or lastly a json object containing floats "color": { "red": 0.8, "green": 0.3, "blue": 0.4 }
. Pick whatever you prefer, none of the three options is superior.
This affects some dialogue in the game, for example being referred to as King or Queen. This is either "female"
or "male"
, anything that can not be recognized will fall back to "female"
. The game does not support any other genders but we support them in spirit 💓
To mod shaders place a shaders_mod.hlsl
file into your mod folder that contains only the functions that you want to modify. For now it is only supported to modify functions, not add them. Also make sure that you copy the exact same signature from the original shaders.hlsl
file, Playlunky does not properly parse the code but only matches strings. An example would be this shaders_mod.hsls
which inverts all colors in-game (thanks @Dregu):
float3 Grading_Helper(float3 color, Texture2D LUT) {
float slice;
float sliceLerp = modf(color.b * (LUT_SIZE - 1.f), slice);
float3 sliceColor1 = LUT.SampleLevel(smoothClampingSamplerState, LUT_Helper(color.r, color.g, slice + 0.f), 0).rgb;
float3 sliceColor2 = LUT.SampleLevel(smoothClampingSamplerState, LUT_Helper(color.r, color.g, slice + 1.f), 0).rgb;
// The next line was changed to return 1.f - color
return 1.f - lerp(sliceColor1, sliceColor2, sliceLerp);
}
An alternative to mod shaders is to just extend them. This would mean that you can write code that only conditionally changes the output of a shader. In the example above, if you wanted to modify the Grading_Helper
function only in same cases you would instead write:
#extends
bool Grading_Helper(float3 color, Texture2D LUT, out float3 out_value) {
// Only mod if colors are "very red"
if (color.r > 0.8f) {
float slice;
float sliceLerp = modf(cotlor.b * (LUT_SIZE - 1.f), slice);
float3 sliceColor1 = LUT.SampleLevel(smoothClampingSamplerState, LUT_Helper(color.r, color.g, slice + 0.f), 0).rgb;
float3 sliceColor2 = LUT.SampleLevel(smoothClampingSamplerState, LUT_Helper(color.r, color.g, slice + 1.f), 0).rgb;
// The next line was changed to return 1.f - color
out_value = 1.f - lerp(sliceColor1, sliceColor2, sliceLerp);
return true;
}
return false;
}
Here the function signature was changed as follows:
- Change return type to
bool
- Add an
out
parameter with the original return type, i.e. hereout float3
- Write
#extends
in front of the function
This now means if your function returns true
then the value in your last parameter will be used as the return value from the original function. The benefit of this approach is that multiple mods can change the same shader, e.g. useful for adding custom heart shaders.
To mod only select strings first extract your exe with Modlunky v0.6.4 or higher. Then find inside the Extracted folder a file named strings00_hashed.str
. Add a strings00_mod.str
file to your mod folder (or the equivalent for any of the other 7 valid string files) and copy for each string you want to change the corresponding line from strings00_hashed.str
into your file. Now change only the part after the :
for each line while leaving the hex code at the beginning of the line intact. Empty lines as well as lines starting with #
are ignored. An example would be the following strings00_mod.str
which modifies the strings in the main menu:
# Main Menu
0x49054a7e: Deth
0xa1023681: Deth Together
0xfe203cc2: For Dummies
0x34906f28: How Bad am I
0x8ca20866: Meself
0x9a19dfba: Real Deth
When translating a mod to another language you can just copy the whole strings00_mod.str
file, change the number on it to the corresponding language and change the strings. The hex code at the beginning of the line is the same for each language.
As of v0.7.0 Playlunky supports the same scripts that Overlunky supports. This functionality is still in development and subject to break. Playlunky will also not always be up to date with the latest and greatest Overlunky Whip builds, so it is recommended to develop scripts with Overlunky and only release them for Playlunky use when those features make it into Playlunky, or instruct your users to use Overlunky as well.
Currently only one script per mod pack is loaded, it has to be named main.lua
. Other than that the same restrictions and API apply as does for Overlunky. Only mods that are enabled will have their script loaded. A settings menu will be open while in the main menu, it can also be opened anywhere else by pressing Ctrl + F4. If you want to use Playlunky for developing scripts you can also enable developer mode in playlunky.ini
which enables reloading scripts by pressing Ctrl + F5. Errors will be displayed along other errors in the top left corner of the screen.
Check the Lua API Documentation for available functionality.
As of v0.9.0 Playlunky contains the same console as Overlunky. Inside the console you can write and execute any Lua code that you would be able to execute in a Script Mod and Script Mods can additionally export functionality to the console via register_console_command
. The following controls are available:
- Enable in
playlunky.ini
- Open with
~
or\
for US keyboards, if you don't have a US keyboard just try some buttons (configurable inplaylunky.ini
) - Close with those buttons or
ESC
(configurable inplaylunky.ini
) - Up & Down Arrow for history, max 20 items in history (configurable in
playlunky.ini
) - Tab for autocompletion and completion suggestions
- Ctrl + Enter for new-line
- Enter to execute code
If you find any bugs that appear related to your usage with Playlunky or it is missing some features that you absolutely need, head to the Issues page, look through the existing issues to see if it has already been reported and if not create an issue. When reporting bugs always attach your games log file, found in the Spelunky 2 installation directory and named spelunky.log
.