All location identifiers are compared against S3maphore's normalized lowercase values. Define lookup tables once, outside isValidCallback, so S3maphore can reuse cached results.
cellNameExact
Playback.rules.cellNameExact(cellNames) -> booleanReturns true when the current PlaylistState.cellName is a key with value true in cellNames. This is exact matching, not substring matching.
local Cells = {
['balmora'] = true,
['balmora, caius cosades\'s house'] = true,
}
isValidCallback = function()
return Playback.rules.cellNameExact(Cells)
end
Keys must be lowercase. A missing key or a key with a false value does not match.
cellNameMatch
Playback.rules.cellNameMatch(patterns) -> booleanPerforms case-sensitive plain substring matching against the already-lowercased cell name. disallowed patterns are checked first; if any matches, the rule returns false. Otherwise, any allowed match returns true.
local AshlandsCells = {
allowed = { 'ashlands', 'red mountain' },
disallowed = { 'telvanni tower' },
}
isValidCallback = function()
return Playback.rules.cellNameMatch(AshlandsCells)
end
Both arrays are optional. An empty or non-matching allowed list returns false.
region
Playback.rules.region(regionNames) -> booleanMatches PlaylistState.nearestRegion against an IDPresenceMap. An interior may get its nearest region from a teleport door when the cell itself has no region.
local CoastalRegions = {
['azura\'s coast region'] = true,
['bitter coast region'] = true,
}
isValidCallback = function()
return Playback.rules.region(CoastalRegions)
end
The rule returns false when no region is known.
weatherType
Playback.rules.weatherType(weatherNames) -> booleanMatches the current weather record ID against an IDPresenceMap.
local StormWeather = {
rain = true,
thunder = true,
}
isValidCallback = function()
return Playback.rules.weatherType(StormWeather)
end
Use the weather record IDs supplied by the active game content. The rule returns false when no current weather matches.
timeOfDay
Playback.rules.timeOfDay(minHour, maxHour) -> booleanMatches the current game hour in the half-open interval [minHour, maxHour): the lower bound is included and the upper bound is excluded.
isValidCallback = function()
return Playback.rules.timeOfDay(8, 18)
end
This example matches 08:00 through 17:59. For a range that crosses midnight, split it into two rules in the callback.
exteriorGrid
Playback.rules.exteriorGrid(gridRules) -> booleanMatches the current actual exterior grid coordinate against an array of { x, y } tables. It returns false indoors and in quasi-exterior cells because PlaylistState.currentGrid is nil there.
local SacredGridCells = {
{ x = -2, y = -3 },
{ x = -1, y = -3 },
}
isValidCallback = function()
return Playback.rules.exteriorGrid(SacredGridCells)
end
The coordinates are world exterior grid coordinates, not local coordinates relative to the player.