Skip to content

Instantly share code, notes, and snippets.

@PrzemekWolw
Last active February 14, 2025 18:46
Show Gist options
  • Save PrzemekWolw/d1c79bc9822b30c12a1bf03d1f568f9e to your computer and use it in GitHub Desktop.
Save PrzemekWolw/d1c79bc9822b30c12a1bf03d1f568f9e to your computer and use it in GitHub Desktop.

Additional settings for Tokyo Xtreme Racer, HDR, VSM, Streaming, Weather, Time of Day and more

This UE4SS script will allow you to adjust render settings in Tokyo Xtreme Racer.

This allows you to:

  • Enable 10 bit HDR Display Output, requires HDR enabled in Windows settings
  • Enable Virtual Shadow Maps, more crisp and accurate shadows
  • Disable textures streaming. Game will load all texture assets on level load to reduce CPU overhead at a cost of memory usage. Requires 8GB GPU or better.
  • Enable lowest possible settings for a low end hardware, to improve compatbility with old hardware, run game with -dx11 launch argument.
  • Control time of day with key bindings
  • Control cloud cover with key bindings
  • Control fog density

Key bindings:

  • Advance time of day: ALT + Y for finer control or SHIFT + Y for faster control
  • Reverse time of day: ALT + T for finer control or SHIFT + T for faster control
  • Increase fog density: ALT + P for finer control or SHIFT + P for faster control
  • Decrease fog density: ALT + O for finer control or SHIFT + O for faster control
  • Increase amount of clouds: ALT + L for finer control or SHIFT + L for faster control
  • Decrease amount of clouds: ALT + K for finer control or SHIFT + K for faster control

Videos:

Weather and time control HDR Output Settings comparison

Known issues:

  • None

Compatibility:

Installing the thing:

  • Download UE4SS experimental and unpack it to your game installation folder ./TokyoXtremeRacer/Binaries/Win64.
  • In the UE4SS folder open folder Mods and create there TXR_AdditionalSettings and in a newly created folder create scripts folder
  • In the scripts folder put attached main.lua file
  • In mods folder open mods.txt and add there TXR_AdditionalSettings : 1 line and save the file

Credits:

local UEHelpers = require("UEHelpers")
local GetKismetSystemLibrary = UEHelpers.GetKismetSystemLibrary
local ksl = GetKismetSystemLibrary()
local engine = FindFirstOf("Engine")
local canExecute = true
-- mod settings, change these to your liking
local HDROut = false -- Enable 10bit HDR Output, requires HDR enabled in Windows settings
local VSM = true -- Enable Virtual Shadow maps, more crisp and accurate shadows
local disableStreaming = true -- Disables textures streaming. Loads all texture assets on level load to reduce CPU overhead with a cost of memory usage. Requires 8GB or better.
local lowSpecMode = false -- Enable ultra low quality mode for low spec hardware, run the game with "-dx11"
-- from now on do not touch
--- @param cmd string
function ExecCmd(cmd)
if not ksl:IsValid() then
error("KismetSystemLibrary not valid\n")
end
ExecuteInGameThread(function()
ksl:ExecuteConsoleCommand(
engine,
cmd,
nil
)
end)
end
function getConsoleVar(cmd)
local value
if not ksl:IsValid() then
error("KismetSystemLibrary not valid\n")
end
value = ksl:GetConsoleVariableIntValue(cmd)
return value
end
function ExecuteDelayedFix()
if not canExecute then
return
end
canExecute = false
local delay = 50
while delay < 500 do
ExecuteWithDelay(delay, function()
if HDROut == true then
if getConsoleVar("r.AllowHDR") ~= 1 then ExecCmd("r.AllowHDR 1") end
if getConsoleVar("r.HDR.EnableHDROutput") ~= 1 then ExecCmd("r.HDR.EnableHDROutput 1") end
if getConsoleVar("r.HDR.Display.OutputDevice") ~= 3 then ExecCmd("r.HDR.Display.OutputDevice 3") end
if getConsoleVar("r.HDR.Display.ColorGamut") ~= 4 then ExecCmd("r.HDR.Display.ColorGamut 4") end
if getConsoleVar("r.HDR.UI.CompositeMode") ~= 1 then ExecCmd("r.HDR.UI.CompositeMode 1") end
if getConsoleVar("r.HDR.UI.Level") ~= 1 then ExecCmd("r.HDR.UI.Level 1") end
end
if VSM == true then
if getConsoleVar("r.Shadow.Virtual.Enable") ~= 1 then ExecCmd("r.Shadow.Virtual.Enable 1") end
if getConsoleVar("r.Shadow.Virtual.Cache") ~= 1 then ExecCmd("r.Shadow.Virtual.Cache 1") end
if getConsoleVar("r.Shadow.Virtual.Cache.StaticSeparate") ~= 1 then ExecCmd("r.Shadow.Virtual.Cache.StaticSeparate 1") end
if getConsoleVar("r.Shadow.Virtual.UseFarShadowCulling") ~= 1 then ExecCmd("r.Shadow.Virtual.UseFarShadowCulling 1") end
if getConsoleVar("r.Shadow.Virtual.SMRT.TexelDitherScaleLocal") ~= 8 then ExecCmd("r.Shadow.Virtual.SMRT.TexelDitherScaleLocal 8") end
end
if disableStreaming == true then
if getConsoleVar("r.TextureStreaming") ~= 0 then ExecCmd("r.TextureStreaming 0") end
end
if lowSpecMode == true then
if getConsoleVar("r.AllowPrecomputedVisibility") ~= 0 then ExecCmd("r.AllowPrecomputedVisibility 0") end
if getConsoleVar("r.AllowSimpleLights") ~= 0 then ExecCmd("r.AllowSimpleLights 0") end
if getConsoleVar("r.AllowStaticLighting") ~= 0 then ExecCmd("r.AllowStaticLighting 0") end
if getConsoleVar("r.AOQuality") ~= 0 then ExecCmd("r.AOQuality 0") end
if getConsoleVar("r.BloomQuality") ~= 0 then ExecCmd("r.BloomQuality 0") end
if getConsoleVar("r.ContactShadows") ~= 0 then ExecCmd("r.ContactShadows 0") end
if getConsoleVar("r.DetailMode") ~= 0 then ExecCmd("r.DetailMode 0") end
if getConsoleVar("r.DisableLODFade") ~= 1 then ExecCmd("r.DisableLODFade 1") end
if getConsoleVar("r.DistanceFields") ~= 0 then ExecCmd("r.DistanceFields 0") end
if getConsoleVar("r.EarlyZPass") ~= 0 then ExecCmd("r.EarlyZPass 0") end
if getConsoleVar("r.Fog") ~= 0 then ExecCmd("r.Fog 0") end
if getConsoleVar("r.HLOD") ~= 0 then ExecCmd("r.HLOD 0") end
if getConsoleVar("r.ShadowQuality") ~= 0 then ExecCmd("r.ShadowQuality 0") end
if getConsoleVar("r.SkyAtmosphere") ~= 0 then ExecCmd("r.SkyAtmosphere 0") end
if getConsoleVar("r.StaticMeshLODDistanceScale") ~= 5 then ExecCmd("r.StaticMeshLODDistanceScale 5") end
if getConsoleVar("r.Streaming.MipBias") ~= 4 then ExecCmd("r.Streaming.MipBias 4") end
if getConsoleVar("r.Streaming.PoolSize") ~= 1 then ExecCmd("r.Streaming.PoolSize 1") end
if getConsoleVar("r.Streaming.FullyLoadUsedTextures") ~= 0 then ExecCmd("r.Streaming.FullyLoadUsedTextures 0") end
if getConsoleVar("r.ViewDistanceScale") ~= 0.4 then ExecCmd("r.ViewDistanceScale 0.4") end
end
canExecute = true
end)
delay = delay * 2
end
end
NotifyOnNewObject("/Script/Engine.Level", function()
ExecuteDelayedFix()
end)
--fine adjustments
RegisterKeyBind(Key.Y, {ModifierKey.ALT}, function()
local tod = FindFirstOf("BP_Sky_C")
if tod:IsValid() then
local startTod = tod["Time of Day"]
startTod = startTod + 3
if startTod > 2359 then startTod = 0000 end
tod["Time of Day"] = startTod
end
end)
RegisterKeyBind(Key.T, {ModifierKey.ALT}, function()
local tod = FindFirstOf("BP_Sky_C")
if tod:IsValid() then
local startTod = tod["Time of Day"]
startTod = startTod - 3
if startTod < 0 then startTod = 2359 end
tod["Time of Day"] = startTod
end
end)
RegisterKeyBind(Key.P, {ModifierKey.ALT}, function()
local actor = FindFirstOf("BP_Sky_C")
local weather = actor['Ultra Dynamic Weather']
if weather:IsValid() then
if weather['Fog - Manual Override'] ~= true then weather['Fog - Manual Override'] = true end
weather["Fog"] = weather["Fog"] + 0.5
end
end)
RegisterKeyBind(Key.L, {ModifierKey.ALT}, function()
local actor = FindFirstOf("BP_Sky_C")
local weather = actor['Ultra Dynamic Weather']
if weather:IsValid() then
if weather['Cloud Coverage - Manual Override'] ~= true then weather['Cloud Coverage - Manual Override'] = true end
weather["Cloud Coverage"] = weather["Cloud Coverage"] + 0.1
end
end)
RegisterKeyBind(Key.O, {ModifierKey.ALT}, function()
local actor = FindFirstOf("BP_Sky_C")
local weather = actor['Ultra Dynamic Weather']
if weather:IsValid() then
if weather['Fog - Manual Override'] ~= true then weather['Fog - Manual Override'] = true end
local startFog = weather["Fog"]
startFog = startFog - 0.5
if startFog <= 0 then startFog = 0 end
weather["Fog"] = startFog
end
end)
RegisterKeyBind(Key.K, {ModifierKey.ALT}, function()
local actor = FindFirstOf("BP_Sky_C")
local weather = actor['Ultra Dynamic Weather']
if weather:IsValid() then
if weather['Cloud Coverage - Manual Override'] ~= true then weather['Cloud Coverage - Manual Override'] = true end
local startCoverage = weather["Cloud Coverage"]
startCoverage = startCoverage - 0.1
if startCoverage <= 0 then startCoverage = 0 end
weather["Cloud Coverage"] = startCoverage
end
end)
--quick adjustments
RegisterKeyBind(Key.Y, {ModifierKey.SHIFT}, function()
local tod = FindFirstOf("BP_Sky_C")
if tod:IsValid() then
local startTod = tod["Time of Day"]
startTod = startTod + 100
if startTod > 2359 then startTod = 0000 end
tod["Time of Day"] = startTod
end
end)
RegisterKeyBind(Key.T, {ModifierKey.SHIFT}, function()
local tod = FindFirstOf("BP_Sky_C")
if tod:IsValid() then
local startTod = tod["Time of Day"]
startTod = startTod - 100
if startTod < 0 then startTod = 2359 end
tod["Time of Day"] = startTod
end
end)
RegisterKeyBind(Key.P, {ModifierKey.SHIFT}, function()
local actor = FindFirstOf("BP_Sky_C")
local weather = actor['Ultra Dynamic Weather']
if weather:IsValid() then
if weather['Fog - Manual Override'] ~= true then weather['Fog - Manual Override'] = true end
weather["Fog"] = weather["Fog"] + 2
end
end)
RegisterKeyBind(Key.L, {ModifierKey.SHIFT}, function()
local actor = FindFirstOf("BP_Sky_C")
local weather = actor['Ultra Dynamic Weather']
if weather:IsValid() then
if weather['Cloud Coverage - Manual Override'] ~= true then weather['Cloud Coverage - Manual Override'] = true end
weather["Cloud Coverage"] = weather["Cloud Coverage"] + 0.5
end
end)
RegisterKeyBind(Key.O, {ModifierKey.SHIFT}, function()
local actor = FindFirstOf("BP_Sky_C")
local weather = actor['Ultra Dynamic Weather']
if weather:IsValid() then
if weather['Fog - Manual Override'] ~= true then weather['Fog - Manual Override'] = true end
local startFog = weather["Fog"]
startFog = startFog - 2
if startFog <= 0 then startFog = 0 end
weather["Fog"] = startFog
end
end)
RegisterKeyBind(Key.K, {ModifierKey.SHIFT}, function()
local actor = FindFirstOf("BP_Sky_C")
local weather = actor['Ultra Dynamic Weather']
if weather:IsValid() then
if weather['Cloud Coverage - Manual Override'] ~= true then weather['Cloud Coverage - Manual Override'] = true end
local startCoverage = weather["Cloud Coverage"]
startCoverage = startCoverage - 0.5
if startCoverage <= 0 then startCoverage = 0 end
weather["Cloud Coverage"] = startCoverage
end
end)
@supermariobrothers
Copy link

god-level work

do you think it'll be possible to add more weather effects?

@CruelSubrosa
Copy link

now iam racing in silent hill)) thank u

@PrzemekWolw
Copy link
Author

do you think it'll be possible to add more weather effects?

I think it's possible, but I'm blindly trying to make stuff work. Yesterday I was trying to get rain to work, but sadly no effects so far. I don't have any experience with Unreal engine modding :(

@twoninehundred
Copy link

ITS PERFECT BUT MY GAME KEEPS CRASHING PLZ HELP!!

@twoninehundred
Copy link

any fixes for crashing?

@TrIpMo
Copy link

TrIpMo commented Jan 29, 2025

Hello if you want to add rain, maybe take a look at this video, seems not so diificult.
https://www.youtube.com/watch?v=wkI7EBJ6mK8&t=611s

@TrIpMo
Copy link

TrIpMo commented Jan 29, 2025

Once you fixed the crashing, I will try this mod. Thank you for your work.

@LXZ993
Copy link

LXZ993 commented Jan 29, 2025

I love this mod, thank you for it 🫡.
Is there a possibility that you could add a free camera control or one that deactivates the UI?

@PrzemekWolw
Copy link
Author

any fixes for crashing?

Not yet. I will try to fix that this week.

Is there a possibility that you could add a free camera control or one that deactivates the UI?

Probably yes, but I haven't had any success so far

@BeeTLe-BeTHLeHeM
Copy link

BeeTLe-BeTHLeHeM commented Jan 29, 2025

I slightly edited your code to include a time-loop, using the content of the "time forward" function.

I've put the new code in the NotifyNewObject function:

NotifyOnNewObject("/Script/Engine.Level", function()
  ExecuteDelayedFix()

	local tod = FindFirstOf("BP_Sky_C")

	LoopAsync(10000, function()
		--print(tod:IsValid())
		if tod:IsValid() then
			period = period + 1
			
			if (period >= 10) then
				local startTod = tod["Time of Day"]
				startTod = startTod + 1
				period = 0
				if startTod > 2359 then 
					startTod = 0000 
				end
				tod["Time of Day"] = startTod
				print("Trigger time "..startTod.."\n")
			end
		end
		return false;
	end)

end)

"period" is a variable I defined at the start of the script as

local period = 0

With period max value at 10 and the LoopAsync at 10000 ms, the day/night change about every 3 minutes. Tinkering with the values one should find a good compromise, I suppose.

I was thinking to put a random value for every cycle to increase or decrease (50/50) the amount of clouds, but I don't know exactly what type of "random" method I can use on this script. Same thing could be done with the fog, maybe limiting it at the "dawn" time (first identifying the proper Tod value range obviously...)

Disclaimer: I'm not knowledgeable about lua and ue4ss lua (I'm a Java dev) so I don't know if LoopAsync is a decent way to wrap the timeloop code. So excuse me if I wrote some heresies.

@ROCK13X
Copy link

ROCK13X commented Jan 30, 2025

I wonder if camera shake can be variable instead of just turning it on and off?

@PrzemekWolw
Copy link
Author

It seems that latest update allows now to adjust camera shake settings. I will remove that feature from this mod then as it's no longer needed.

@ROCK13X
Copy link

ROCK13X commented Jan 31, 2025

It seems that latest update allows now to adjust camera shake settings. I will remove that feature from this mod then as it's no longer needed.

Yeah :) They've made it an adjustable option.

@twoninehundred
Copy link

please let us know when u fixed the crashing! would rlly love to use this mod but my game crashed 5 times ina row last time lol

@ROCK13X
Copy link

ROCK13X commented Feb 1, 2025

Funny thing. I played already 5 hours with this mod. The game crashed only once

@NEO-NoiseBomb
Copy link

Is it possible to re-enable texture streaming? I would like to use this mod but w/o lower framerate due to the disabled texture streaming.

@snakeseyes
Copy link

snakeseyes commented Feb 2, 2025 via email

@PrzemekWolw
Copy link
Author

PrzemekWolw commented Feb 2, 2025

Is it possible to re-enable texture streaming? I would like to use this mod but w/o lower framerate due to the disabled texture streaming.

Yes. Set "disableStreaming" to false in lua file

please let us know when u fixed the crashing! would rlly love to use this mod but my game crashed 5 times ina row last time lol

Try to update both my lua mod and ue4ss. I removed camera shake disable feature and game seems to be way more stable now.

@ROCK13X
Copy link

ROCK13X commented Feb 2, 2025

I slightly edited your code to include a time-loop, using the content of the "time forward" function.

I've put the new code in the NotifyNewObject function:

I've tried to paste the thing in the place where NotifyObject left empty but didn't get it to work properly. Also getting crashes when entering parking areas.
How I need to insert it properly to the script? xD

@BeeTLe-BeTHLeHeM
Copy link

I slightly edited your code to include a time-loop, using the content of the "time forward" function.
I've put the new code in the NotifyNewObject function:

I've tried to paste the thing in the place where NotifyObject left empty but didn't get it to work properly. Also getting crashes when entering parking areas. How I need to insert it properly to the script? xD

Forget that snippet... I've worked on the script these days, and I made a separate script to not mess with the original code. You can download from here: https://drive.google.com/file/d/1G7QEvv_LpgGJ4QqGO5pEEU0lPNxrS6GE/view?usp=sharing
Unzip in the mods folder and add the line in mods.txt
RawTimeLoop : 1

You should see the beginning of dawn after about 4 minutes.

I managed to decrease the number of script crashes, still give error sometime when exiting the driving session (parking or garage). In my case I was launching repeatedly a LoopAsync instruction, so I introduced a check to verify that the loop isn't already executed. Maybe the cause for the original script is something similar - I don't know.

@ROCK13X
Copy link

ROCK13X commented Feb 3, 2025

I managed to decrease the number of script crashes, still give error sometime when exiting the driving session (parking or garage). In my case I was launching repeatedly a LoopAsync instruction, so I introduced a check to verify that the loop isn't already executed. Maybe the cause for the original script is something similar - I don't know.

thanks for this work.
I wonder if the base time of day can be changed so the driving session won't always start at evening.

@silvia95guy
Copy link

"Create there TXR_AdditionalSettings"... txt file? Folder? Unclear.

@BeeTLe-BeTHLeHeM
Copy link

"Create there TXR_AdditionalSettings"... txt file? Folder? Unclear.

It's a folder, inside the UE4SS/Mods folder.
Inside TXR_AdditionalSettings you create the Scripts folder.

So you should have the following structure:

UE4SS/Mods/TXR_AdditionalSettings/Scripts

In the Scripts folder you put the lua file.

@PrzemekWolw
Copy link
Author

Added full compatibility with Dynamic Day/Night Cycle mod by Silent.

@twoninehundred
Copy link

was working pre crash fix now when i download it dosent seem to work at all idk if its because i have an older version of the game but it dosent change time of day or respond to commands. is there a new link?

@PrzemekWolw
Copy link
Author

was working pre crash fix now when i download it dosent seem to work at all idk if its because i have an older version of the game but it dosent change time of day or respond to commands. is there a new link?

I cannot reproduce this problem on my end. I am testing with the latest version of my code and game. You just need to update the main.lua contents.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment