I had a conversation with @darklinkpower about how to use `IItemCollection`/reference objects in Playnite. I thought I'd share my notes for everyone else here. The below text talks about `Feature` objects, but all of this should apply to `Categories`, `Tags`, `Series` or anything else that works like this.
This is actually covered in the Playnite docs, but I thought some example code might help everyone here. https://playnite.link/docs/tutorials/scr...nce-fields
* * *
A Game object has a `Features` field with all the features it currently has. This list is read only, you must instead make changes to `FeatureIds`.
Listing a game's feature names
Query for all games with a feature name
Both of the above examples convert the Features list to a list of strings for easier querying in PowerShell. If you'd like to actually work with the `Feature` object you can do something like this:
Add a new Feature to a List of Games
ItemCollection.Add(String) is documented to return the existing item from the database if it already exists, so you can safely just always try to create the `Feature` in the DB, even if it's already there. (Assuming that's the behavior you want.) This function also takes a string, so can pass it a string and it returns the existing `Feature` or it creates it for you and returns it. Please note that the comparison is case insensitive when checking the DB, whatever you use the first time becomes the capitalization stored in the DB. https://playnite.link/docs/api/Playnite....em_String_
Here's some half tested code to demonstrate adding a Feature:
This is actually covered in the Playnite docs, but I thought some example code might help everyone here. https://playnite.link/docs/tutorials/scr...nce-fields
* * *
A Game object has a `Features` field with all the features it currently has. This list is read only, you must instead make changes to `FeatureIds`.
Listing a game's feature names
$game = $playniteApi.MainView.SelectedGames[0]
$game.Features.Name # Returns a list of strings for all the feature names
Query for all games with a feature name
$playniteApi.Database.Games | Where-Object {$_.Features.Name -Contains "Achievements"}
$feature = $PlayniteApi.Database.Features | Where-Object {$_.Name -Eq "Achievements"}
# $feature is $null if it did not exist in the DB
$playniteApi.Database.Games | Where-Object {$_.Features -Contains $feature}
Add a new Feature to a List of Games
ItemCollection.Add(String) is documented to return the existing item from the database if it already exists, so you can safely just always try to create the `Feature` in the DB, even if it's already there. (Assuming that's the behavior you want.) This function also takes a string, so can pass it a string and it returns the existing `Feature` or it creates it for you and returns it. Please note that the comparison is case insensitive when checking the DB, whatever you use the first time becomes the capitalization stored in the DB. https://playnite.link/docs/api/Playnite....em_String_
Here's some half tested code to demonstrate adding a Feature:
$featureName = "Test"
$feature = $PlayniteApi.Database.Features.Add($featureName)
# "Test" is guaranteed to be an existing Feature in the DB now
foreach ($game in $PlayniteApi.MainView.SelectedGames) {
# Neither of these work, you can't add to Features directly:
# $game.Features.Add($feature)
# $game.Features.Add("Test")
# Instead add the GUID of the $feature to the FeatureIds list
# Also, += is a nice shortcut for .Add()
# Make sure you test for the case where a game has no features yet ($game.FeatureIds can be null)
[guid[]]$featureIds = $feature.Id
if ($game.FeatureIds) {
$game.FeatureIds += $featureIds
} else {
$game.FeatureIds = $featureIds
}
# Remember to always update the game
$PlayniteApi.Database.Games.Update($game)
}