Playnite Forums
7-Zip Game Compression Script - Printable Version

+- Playnite Forums (https://playnite.link/forum)
+-- Forum: Extension Database (https://playnite.link/forum/forum-3.html)
+--- Forum: Generic Extensions (https://playnite.link/forum/forum-6.html)
+--- Thread: 7-Zip Game Compression Script (/thread-71.html)



7-Zip Game Compression Script - Morgan - 12-18-2019

It decompresses any game from a 7zip file and recompresses it afterwards.

This should work very well for ROMs too, even if they're a bunch of BIN and CUE files.

Just add these to the Scripts tab of your game and make sure PowerShell is selected



Limitations
  • Every ROM file or game entry must be in its own directory. This is because the script is too simple to recognize the Playnite entry and files themselves. Keep every ROM or game in its own directory and everything is good.
  • It assumes you compressed the files\folders in the first place.
  • It takes a long time to for Playnite to launch it or for Playnite to recognize the game as ready to launch again. Compression\Decompression takes a good long while depending on the core\thread count of your CPU and the size of the game.  So expect a bit of a wait if you decide to use this.

INSTALLATION

Add this to the top panel in the Scripts Tab:
<# 7-zip archive script by Morgan#7301 - Requires PowerShell 3 or up.
Looks inside the folder as defined by the INSTALLATION tab,
extracts the 7z archive of the game,
and deletes the 7z archive afterwards.
WARNING!  Archive\Installation MUST be of its own directory.
Putting multiple ROMS or games in same directory will cause issues.
WARNING!  Must also make sure the location of your stand-alone (7za.exe) or installed (7z.exe) is defined below.#>

#Execute before starting game

$quotemark = ('"')
$getdirectoryname = resolve-path . | split-path -leaf
$dirname = $quotemark + $getdirectoryname + $quotemark

Start-Process -Wait -WindowStyle Minimized "C:\Program Files\7-Zip\7z.exe" "x -y $dirname.7z"

Remove-Item -Path ('.\' + $getdirectoryname + '.7z')

Add this to the bottom panel:
<# 7-zip archive script by Morgan#7301 - Requires PowerShell 3 or up.
Looks inside the folder as defined by the INSTALLATION tab,
packs the game into a 7z archive,
and deletes game files\ROM afterwards.
WARNING!  Archive\Installation MUST be of its own directory.
Putting multiple ROMS or games in same directory will cause issues.
WARNING!  Must also make sure the location of your stand-alone (7za.exe) or installed (7z.exe) is defined below.#>

#Execute after exiting game

$quotemark = ('"')
$getdirectoryname = resolve-path . | split-path -leaf
$dirname = $quotemark + $getdirectoryname + $quotemark

Start-Process -WindowStyle Minimized "C:\Program Files\7-Zip\7z.exe" "a -t7z $dirname.7z -y -mx=9 -sdel"

WANT BETTER SPEED\COMPRESSION?

You can get better compression that crunches everything even further.. at the cost of speed and RAM.

7-Zip has extra options that aren't normally used, but you will need to do a little digging to find out if it's right for you.  There is problems such as some games don't compress as well as others and there's a law of diminishing returns where you can get a 1-10% better compression depending on the files.  If you have the CPU performance, RAM, and patience, it may not be so bad.

To show what I'm talking about, I have the Steam version of The Darkness 2, a relatively modern 3D game.  Here's some general stats:
  • Uncompressed raw folder size:  6.80 GB
  • NTFS Compression:  6.71 GB
  • 7-ZIP - Ultra w\Default:  5.83 GB
  • 7-ZIP - W\Extra compression:  5.79 GB

And this is some added switches\arguments.  Like I said, there's a law of diminishing returns and not every game can be compressed well.  This works best on older titles like PS1 games where compressed ISO\Bin+CUE files are usually crunched 50-75% smaller than its uncompressed size.  If you absolutely MUST have the most compression possible for every game on your hard drive, you'll possibly be saving 10's of gigabytes depending on how big your downloaded library is.

NOTE:  NTFS Compression is a type of dynamic file compression built into modern Windows machines.  It's the equivalent of having your files in ZIP containers that the OS dynamically reads without an external program or user input.  You can tell it's activated when you open up File Explorer and see the names of your files\folders are colored Blue.  If file\folder names are still black, right click it, go to Properties at the bottom of the list, click Advanced on the bottom right of the General tab, and checkmark "Compress contents to save disk space", click OK, and click OK.  The file\folders must not be in use by another program and don't do this to the "C:\Windows" folder or your PC won't boot.



HOW DO I GET IT MORE COMPRESSION?

Highly recommend reading this and the rest of the documentation.  It's confusing at first, but I'll highlight the most important parts.

To add these switches, just go into the script and put them at the end of -sdel and before the parenthesis.
Start-Process -WindowStyle Minimized "C:\Program Files\7-Zip\7z.exe" "a -t7z $dirname.7z -y -mx=9 -sdel"

File Analysis Level Wrote:-yx=[0 | 1 | 3 | 5 | 7 | 9 ]

This switch has levels of file analysis that can help compressing files in certain situations.  WAV files and EXE files can gain better compression depending on this switch.  It might only be useful as a way to compress old games that still use uncompressed WAV files instead of something semi-modern like MP3, FLAC, AAC, or OGG.

The default if you never touch it is "yx=5", but putting in "-yx" will set it to level 9 and will take its time going through the files to analyze them for better compression.

Type in -yx= and then the number representing the level of file analysis.

Solid Mode Wrote:s=[off | on | [e] [{N}f] [{N}b | {N}k | {N}m | {N}g | {N}t)]

A blessing and a curse.  It improves compression by grouping files and packing them tighter together like Tetris pieces, than if they were non-solid\loose files.  There's several problems with this method though: You cannot update the archive without having to recompress the entire archive again.  Extracting files is slower.  If one part of the file is corrupted, the entire archive is corrupted.

Corruption isn't an issue in Non-Solid archives that either doesn't pack the files together or only packs certain sizes of the archive.  For example, if you have a 50 gigabyte archive, but one part of it got corrupted, you can still recover the rest of the archive.  In a Solid archive or only that section of solid blocks, you can't recover.

s=off and s=on is self explanetory.

``e``
Use a separate solid block for each new file extension. You need to use qs option also.

{N}f
{N} equals the set limit for number of files in one solid block.

{N}b | {N}k | {N}m | {N}g | {N}t
{N} equals the set limit for the total size of a solid block in <b>ytes / <K>iB / <M>iB / <G>iB / <T>iB.

This is important if you want to have the upside of better compression, being able to update chunks of the archive without recompressing the whole archive, and still not lose all the files in case of corruption.

Example:  s=100f10m    Sets solid mode with 100 files & 10 MB limits per one solid block.

These are the default limits for the solid block size
  • Compression Level: Solid block size
  • Store:  0 B
  • Fastest:  16 MB
  • Fast:  128 MB
  • Normal:  2 GB
  • Maximum:  4 GB
  • Ultra:  4 GB

Sorting Method Wrote:qs=[off | on]

Enables or disables sorting files by type in solid archives. The default mode is qs=off.

New versions of 7-Zip (starting from version 15.06) support two sorting orders:

qs-
Sorting by name : it's default order.

qs
Sorting by type (by file extension).

You can get big difference in compression ratio for different sorting methods, if dictionary size is smaller than total size of files. If there are similar files in different folders, the sorting "by type" can provide better compression ratio in some cases.

Note that sorting "by type" has some drawbacks. For example, NTFS volumes use sorting order "by name", so if an archive uses another sorting, then the speed of some operations for files with unusual order can fall on HDD devices (HDDs have low speed for "seek" operations).

If "qs" mode provides much better compression ratio than default "qs-" mode, you still can increase compression ratio for "qs-" mode by increasing of dictionary size.

If you think that unusual file order is not problem for you, and if better compression ratio with small dictionary is more important for you, use "qs" mode.

Note: There are some files (for example, executable files), that are compressed with additional filter. 7-Zip can't use different compression methods in one solid block, so 7-zip can create several groups of files that don't follow "by name" order in "qs-" mode, but files inside each group are still sorted by name in "qs-" mode.


Header Compression Wrote:hc=[off | on]

Enables or disables archive header compressing. The default mode is hc=on. If archive header compressing is enabled, the archive header will be compressed with LZMA method.

Multi-Threading Wrote:mt=[off | on | {N}]

Sets multithread mode. If you specify {N}, for example mt=4, 7-Zip tries to use 4 threads. LZMA compression uses only 2 threads. Your PC should at least be a quad-core with hyper-threading enabled. So either mt=4 or mt=8 would be sufficient.



RE: 7-Zip Game Compression Script - Morgana - 08-19-2020

((Apparently, the admin or a bot didn't like the original email service I had, so I had to make a new account.))

VERSION 2.0!


This one includes a conditional statement that checks to see if the game's 7z file already exists.  If the compressed file doesn't exist (as in the game already being extracted), it doesn't try throwing an error for extracting a non-existent file.

The code was also tidied up with more variables so the execution code is clearer.

Remember to set Script Runtime to PowerShell.

#Execute before starting game

$quotemark = ('"')
$getdirectoryname = resolve-path . | split-path -leaf
$dirname = $quotemark + $getdirectoryname + $quotemark
$filename = ('.\' + $getdirectoryname + '.7z')
$7zip = "C:\Program Files\7-Zip\7z.exe"


If (Test-Path $filename) {

     Start-Process -Wait -WindowStyle Minimized $7zip "x -y $dirname.7z"

     Remove-Item -Path $filename

     }

#Execute after exiting game

$quotemark = ('"')
$getdirectoryname = resolve-path . | split-path -leaf
$dirname = $quotemark + $getdirectoryname + $quotemark
$7zip = "C:\Program Files\7-Zip\7z.exe"

Start-Process -WindowStyle Minimized $7zip "a -t7z $dirname.7z -y -mx=9 -sdel"

EDIT

If anyone asks "just use a RAM Disk instead of your HDD\SDD. This script can't be good for it." Or "Oh there are better ways to do this".

Yes, I know. And there's several reasons why you're asking me to take on a major job.

1. To do this from absolute scratch, I'd need to make a device driver. That's way beyond my current capabilities.
2. Open-source and closed-source software are sketchy when it comes to scripting\automation AT BEST. Dynamic RAM Disk generation is out.
3. There's plenty of proprietary software that does a better job than I could, but many of them cost plenty of money. We're talking at least $10-40 USD at least.
4. This script would become so complicated, it'd probably be easier to make a separate program doing this.

Better solutions would be:

1. Get a USB stick if space is so precious.
2. Make a permanent RAM Disk using one of the many free proprietary software packages out there
3. Just leave the most played\recently played games on your system uncompressed.

This script is basically meant for PS1 games where no emulator of its kind can read compressed archives and some rarely played store games. PS2, GameCube\Wii, Atari 2600, Super Nintendo, etc, etc. The vast majority of them all support 7z\zip\gz archives to various degrees.

Even this Compactor program that uses Windows own internal dynamic compression system is decent. https://github.com/Freaky/Compactor

If you're not interested in this script or think you can do better, move along.