Skip to content

Courage.Shaders#

require("Courage.Shaders") controls custom HLSL shaders registered by Rainfall. The game registers this module on the shared Luau VM at startup (before any mod entry file runs).

For HLSL syntax, uniforms, and worked examples, see the shader guides.

Loading the module#

local Shaders = require("Courage.Shaders")
-- or:
local Game = require("Courage.Game")
local Shaders = Game.shaders
import * as Shaders from "Courage.Shaders"
// or:
import * as Game from "Courage.Game"

const shaders = Game.shaders

Shader names#

Fragment mods live under mods/<mod-id>/assets/ (recursive). Vertex mods use the .vs.hlsl extension.

File on disk Registered name
mods/shader_demo/assets/red_tint.hlsl shader_demo/red_tint
mods/shader_demo/assets/filters/crt.hlsl shader_demo/filters/crt
mods/shaders/global_fx.hlsl global_fx (no mod prefix)

set_enabled and list() always use these logical names (mod-id/path/stem).

API#

Function Returns Description
Shaders.count() number Number of known custom shaders
Shaders.name(index) string? Logical name at index (1-based)
Shaders.is_vertex(index) boolean true for .vs.hlsl / vertex registrations
Shaders.is_enabled(index) boolean Whether index is marked enabled (before apply)
Shaders.set_enabled(name, enabled) boolean Toggle by logical name; false if name unknown
Shaders.apply() (none) Combine all enabled sources and send to Rainfall
Shaders.reload() (none) Rescan mods/ for .hlsl files
Shaders.list() { name, vertex, enabled }[] Snapshot of all shaders
Shaders.register_fragment(name, source) number Add/replace fragment shader for active mod
Shaders.register_fragment(modId, name, source) number Same, with explicit mod id prefix
Shaders.register_vertex(name, source) number Add/replace vertex shader for active mod
Shaders.register_vertex(modId, name, source) number Same, with explicit mod id prefix

register_* returns a 1-based index. Re-registering the same full name replaces the stored source in place.

Usage notes#

  • set_enabled only updates the in-memory selection. Call apply() after changing enabled shaders.
  • reload() rescans disk and preserves prior on/off state by name.
  • Two-argument register_* forms prefix the active mod's id from mod.json (set while your entry file and init run). Use Courage.Assets to resolve logical names from asset paths.

Minimal example#

local Shaders = require("Courage.Shaders")
local Assets = require("Courage.Assets")

local MyMod = mod("shader_demo")

function MyMod:init()
    Shaders.set_enabled(Assets("red_tint.hlsl"), true)
    Shaders.apply()
end

return MyMod
import * as Shaders from "Courage.Shaders"
import * as Assets from "Courage.Assets"

declare function mod(name: string): any

const MyMod = mod("shader_demo")

MyMod.init = function () {
    Shaders.set_enabled(Assets("red_tint.hlsl"), true)
    Shaders.apply()
}

export = MyMod