World & props
Sky hologram advertisements
Create and preload custom sky hologram advertisements.
On this page5 sections
Replace supported sky-advertising textures with a custom resource pack. The following sections describe the asset layout, build process and deployment requirements.
This is a pre-boot asset pipeline. Lua declares the resulting package, but it cannot swap these textures while the game is running: the particle material resolves its XBM through REDengine's resource depot when the game boots.
Build the Open77 example
Requirements:
- Cyberpunk 2077 2.31 available at the game directory;
- PowerShell 7;
- WolvenKit CLI 8.19 or a compatible release.
From the repository root:
pwsh scripts/new-open77-sky-ad-texture.ps1
pwsh scripts/build-sky-advertising.ps1 `
-InputPath assets/sky-ads/open77-towers-of-light.png `
-ArchiveName Open77SkyAds `
-OutputDirectory resources/open77_sky_ads/dist `
-WolvenKitCli E:/Apps/WolvenKit.Console/WolvenKit.CLI.exe
The first command deterministically composites the tracked assets/open77.png logo into a
128Γ2048 strip. The second command:
- extracts the four matching vanilla XBM headers from the local game installation;
- imports the PNG into each header while preserving the measured texture contract;
- validates dimensions, compression, group, gamma, streaming, downgrade and 12 mips;
- packs
Open77SkyAds.archive; - wraps it as
Open77SkyAds.zipunderarchive/pc/mod/; - writes a manifest with hashes and sizes.
The archive index timestamp and its CRC64 are normalized, so rebuilding unchanged input produces the same archive and package hash instead of forcing every player to download identical art again.
The scripts never install the archive and never start or stop the game. Extracted CDPR resources
stay under ignored build/ paths and are not committed.
Put it in a resource
Use this layout:
resources/open77_sky_ads/
open77.lua
server/main.lua
source/custom-strip.png
dist/Open77SkyAds.zip
open77.lua:
resource "open77_sky_ads"
version "1.0.0"
auto_start true
server_script "server/main.lua"
preload_mod "dist/Open77SkyAds.zip"
server/main.lua can be minimal; the declaration does the boot work:
AddEventHandler("onResourceStart", function(name)
if name == GetCurrentResourceName() then
print("Open77 sky-ad theme declared for the next launcher boot")
end
end)
Select open77_sky_ads in resources.load and leave requiredMods.enabled set to true. Restart
the dedicated server. Its effective required-mod digest now includes the resource package; players
receive it through the normal launcher Connect flow before Cyberpunk starts.
Do not also add the ZIP to files. Open77 excludes it if a broad glob happens to match, but the
source PNG does not need client delivery either. It is build input, not a WebUI texture.
Custom PNG or DDS
The input must be exactly 128Γ2048. PNG is the simplest authoring format. DDS is accepted for artists who already control its export, but the rebuilt XBM is still validated against the vanilla contract.
All four bands are replaced by default:
pwsh scripts/build-sky-advertising.ps1 `
-InputPath resources/open77_sky_ads/source/custom-strip.dds `
-OutputDirectory resources/open77_sky_ads/dist `
-ArchiveName MyWorldSkyAds
For a diagnostic partial replacer, pass -Targets a,b (valid values are a, b, b_censored,
and c). A public world should normally replace all four so quest/censorship variants do not fall
back to unrelated vanilla art.
What is replaced
The archive overrides four vanilla depot paths below:
base/environment/decoration/advertising/holograms/giant_commercial_stripe/
They are giant_commercial_stripe_a.xbm, _b.xbm, _b_censored.xbm, and _c.xbm.
Ten cityscape/quest particle resources consume these textures. The particles keep their own
vertical scroll, glow, alpha mask and fade, so source art remains static.
Ordinary billboards are a different Ink/TweakDB worldAdvertisementNode system. Tools such as
World Advert Configurator apply to those panels, not to the four sky stripes.
Update and removal
After changing the source image:
- rebuild the ZIP into the resource;
- restart the dedicated server so it computes and publishes the new hash;
- leave the current game session;
- reconnect through the launcher so the new world profile is projected before boot.
A resource restart is insufficient. Removing the resource from resources.load, restarting the
server and launching that world again removes its package from the profile and restores vanilla,
unless another installed replacer targets the same paths.
// For agents & LLMsthis page as Markdownllms.txtllms-full.txt
