initial commit

This commit is contained in:
saarsena@gmail.com 2026-04-22 10:19:57 -04:00
commit c2bb3893a9
1038 changed files with 75846 additions and 0 deletions

View file

@ -0,0 +1,199 @@
# Setting Up a New Godot Project with FuncGodot + TrenchBroom
Step-by-step guide for using TrenchBroom as a level editor with Godot via the FuncGodot addon.
Tested on Linux with Godot 4.6, FuncGodot 2025.12, and TrenchBroom (v9 game config format).
---
## Overview
There are three things you configure, and they must agree with each other:
| What | Where it lives | What it controls |
|---|---|---|
| **FuncGodotLocalConfig** | `addons/func_godot/func_godot_local_config.tres` | Machine-specific paths (where to export configs, where your project lives on disk) |
| **Your FGD resource** | A `.tres` you create in your project | Entity definitions + the FGD filename used in TrenchBroom |
| **Your TrenchBroom GameConfig resource** | A `.tres` you create in your project | Game name, texture root, FGD reference — exports to TrenchBroom's games directory |
FuncGodotMapSettings also matters but has sane defaults. The critical thing is that paths line up.
---
## Step 1: Install FuncGodot
1. Copy the `addons/func_godot/` folder into your project's `addons/` directory (or install via AssetLib).
2. In Godot: **Project > Project Settings > Plugins** — enable FuncGodot.
3. Restart the editor if prompted.
---
## Step 2: Create Your Texture Directory
Put your textures in a **subdirectory** inside `res://textures/`. Do NOT put them directly in `res://textures/`.
```
your_project/
textures/
my_textures/ <-- subdirectory required
brick.png
stone.png
metal.png
```
**Linux users:** Make sure file extensions are lowercase (`.png` not `.PNG`). Both TrenchBroom and Godot are case-sensitive on Linux.
---
## Step 3: Create Your FGD Resource
Do NOT edit the default `addons/func_godot/fgd/func_godot_fgd.tres`. Create your own.
1. In the Godot FileSystem panel, right-click your project root.
2. **New Resource** > search for `FuncGodotFGDFile` > Create.
3. Save it as something like `my_game_fgd.tres` in your project root.
4. In the inspector, set:
- **FGD Name**: `my_game` (this becomes the `.fgd` filename — no spaces, no extension)
- **Base FGD Files**: Add `res://addons/func_godot/fgd/func_godot_fgd.tres` (this pulls in all the default entities like worldspawn, func_geo, etc.)
- **Entity Definitions**: Leave empty for now. Add your custom entities here later.
**Why this matters:** The FGD Name you set here becomes both the exported `.fgd` filename AND the filename referenced inside `GameConfig.cfg`. If these don't match, TrenchBroom silently falls back to a different FGD or fails to load entities.
---
## Step 4: Create Your TrenchBroom GameConfig Resource
1. In Godot FileSystem, right-click your project root.
2. **New Resource** > search for `TrenchBroomGameConfig` > Create.
3. Save it as something like `my_game_tb_config.tres` in your project root.
4. In the inspector, set:
- **Game Name**: Something unique to this project (e.g. `my_game`). This is the name shown in TrenchBroom's game list. **Do not reuse "FuncGodot"** — it will collide with other projects.
- **Textures > Textures Root Folder**: `textures` (this is relative to the game path, NOT a res:// path)
- **Entities > FGD File**: Point to your FGD resource from Step 3 (`res://my_game_fgd.tres`)
- Leave everything else at defaults unless you have a reason to change it.
---
## Step 5: Configure FuncGodotLocalConfig
This stores machine-specific paths in a JSON file outside your project, so it won't break when you move the project or work on a different machine.
1. Open `addons/func_godot/func_godot_local_config.tres` in the inspector.
2. Set these fields:
| Field | Value | Example |
|---|---|---|
| **Trenchbroom Game Config Folder** | The folder inside TrenchBroom's games directory for THIS game. Must be a full filesystem path. | `/home/you/.TrenchBroom/games/my_game` |
| **Map Editor Game Path** | Your Godot project root as a full filesystem path. TrenchBroom uses this to find textures. | `/home/you/godot_projects/my_game` |
| **FGD Output Folder** | Usually same as your project root. Only used for standalone FGD export. | `/home/you/godot_projects/my_game` |
3. Click **Export func_godot settings** (the save button) to write these to disk.
**Where this actually saves:** `~/.local/share/godot/app_userdata/<YourProjectName>/func_godot_config.json` on Linux. If you clone the project to a new machine, you'll need to redo this step.
---
## Step 6: Export the GameConfig to TrenchBroom
1. Click on your TrenchBroom GameConfig resource (`my_game_tb_config.tres`) in the inspector.
2. Click **Export GameConfig** (the button at the top of the inspector).
3. Check the Godot output panel — it should print paths for the icon, GameConfig.cfg, and FGD file.
This creates three files in your TrenchBroom games folder:
```
~/.TrenchBroom/games/my_game/
GameConfig.cfg <-- tells TrenchBroom about your game
my_game.fgd <-- entity definitions (name matches your fgd_name)
icon.png <-- 32x32 icon
```
---
## Step 7: Configure TrenchBroom
1. Open TrenchBroom.
2. Your game should appear in the game list on the welcome screen. Select it.
3. If it doesn't appear or textures don't load, go to **View > Preferences > Games**:
- Select your game name.
- Set **Game Path** to your Godot project root (same path as Map Editor Game Path from Step 5).
4. Create a new map. Choose **Valve** format (recommended — it has per-face UV axes).
Your textures should now appear in TrenchBroom's texture browser under `my_textures/brick`, `my_textures/stone`, etc.
---
## Step 8: Build a Map and Import into Godot
1. Build your map in TrenchBroom. Save the `.map` file inside your Godot project directory (e.g. `res://maps/my_level.map`).
2. Back in Godot, the `.map` file will auto-import as a resource.
3. Create a new 3D scene. Add a **FuncGodotMap** node.
4. In the inspector:
- **Local Map File**: Set to your `.map` file (`res://maps/my_level.map`)
- **Map Settings**: You can use the default (`addons/func_godot/func_godot_default_map_settings.tres`) or create your own FuncGodotMapSettings resource. Make sure `base_texture_dir` is `res://textures` and `entity_fgd` points to your FGD resource.
5. Click **Build Map** in the toolbar (or the button on the FuncGodotMap node).
---
## How the Paths Must Align
This is where things break if you're not careful. The texture name in the `.map` file must resolve to the same file in both TrenchBroom and Godot.
```
TrenchBroom resolves textures as:
<Game Path> / <textures_root_folder> / <subdirectory> / <texture>.png
/home/you/my_project / textures / my_textures / brick.png
Godot resolves textures as:
<base_texture_dir> / <texture_name_from_map> . <extension>
res://textures / my_textures/brick . png
The .map file stores: my_textures/brick
```
If `Game Path + textures_root_folder` doesn't point to the same physical directory as `base_texture_dir`, textures will show in TrenchBroom but not in Godot (or vice versa).
---
## Quick Checklist for New Projects
- [ ] FuncGodot addon installed and enabled
- [ ] Textures in a subdirectory of `res://textures/` with lowercase extensions
- [ ] Created your own FGD resource (not editing the addon default)
- [ ] `fgd_name` set to something unique
- [ ] Default FGD added to `base_fgd_files`
- [ ] Created your own TrenchBroom GameConfig resource
- [ ] `game_name` set to something unique (not "FuncGodot")
- [ ] `textures_root_folder` set to `textures`
- [ ] `fgd_file` pointing to your FGD resource
- [ ] FuncGodotLocalConfig paths set and exported:
- [ ] `trenchbroom_game_config_folder` = `~/.TrenchBroom/games/<your_game>`
- [ ] `map_editor_game_path` = your project root (full filesystem path)
- [ ] Clicked "Export GameConfig" on your TrenchBroom GameConfig resource
- [ ] In TrenchBroom: game path set to your Godot project root
- [ ] No leftover `~/.TrenchBroom/games/` directories from old projects with the same game name
---
## Troubleshooting
**Textures don't appear in TrenchBroom:**
- Check that the Game Path in TrenchBroom preferences points to your Godot project root.
- Verify `textures_root_folder` in your GameConfig resource matches your actual directory name.
- On Linux: file extensions must be lowercase (`.png` not `.PNG`).
- Re-export GameConfig after any changes.
**TrenchBroom loads wrong FGD / entities missing:**
- Check `~/.TrenchBroom/games/` for duplicate directories with the same `"name"` in their GameConfig.cfg. Delete stale ones.
- The FGD filename in `GameConfig.cfg` (`"definitions"` field) must match the actual `.fgd` file on disk. Both come from your FGD resource's `fgd_name` property — re-export to resync.
**Textures show in TrenchBroom but not in Godot after map build:**
- `base_texture_dir` in your FuncGodotMapSettings must be `res://textures` (matching the physical directory that TrenchBroom's game path + textures root points to).
- Texture names are case-sensitive on Linux. The name in the `.map` file must match the filename exactly.
- Check the Godot output panel for "Error: Texture load failed" messages.
**FuncGodotLocalConfig settings don't stick:**
- You must click "Export func_godot settings" after changing values. The `.tres` file itself doesn't store the data — it goes to a JSON file in Godot's user data directory.
- After cloning to a new machine, re-enter and re-export all local config settings.
**Map file not recognized by Godot:**
- The `.map` file must be inside your Godot project directory (under `res://`).
- FuncGodot must be enabled in Project Settings > Plugins.

View file

@ -0,0 +1,204 @@
# Weathered Wall Fragment Shader
## Setup
1. Create a new `ShaderMaterial` in Godot
2. Assign this shader code
3. Set your base wall texture in the `base_texture` slot
4. Apply the material to your FuncGodot map geometry
Every surface using this material will look different because the noise samples from **world position**, not UV space. Two walls with the same texture and UVs get completely different weathering patterns because they're at different world coordinates.
---
## Shader Code
```gdshader
shader_type spatial;
// Base texture
uniform sampler2D base_texture : source_color, filter_nearest, repeat_enable;
// === WEATHERING CONTROLS ===
// Gradient (rising damp)
uniform float gradient_strength : hint_range(0.0, 1.0) = 0.6;
uniform float gradient_exponent : hint_range(1.0, 5.0) = 3.0;
uniform float gradient_noise_warp : hint_range(0.0, 1.0) = 0.4;
// Hue shifting
uniform float shadow_cool_shift : hint_range(0.0, 0.15) = 0.06;
uniform float highlight_warm_shift : hint_range(0.0, 0.15) = 0.04;
// Surface grime (noise overlay)
uniform float grime_strength : hint_range(0.0, 1.0) = 0.3;
uniform float grime_scale : hint_range(0.5, 10.0) = 3.0;
// Noise scale for large weathering patterns
uniform float weather_scale : hint_range(0.1, 5.0) = 1.2;
// Stain blotches
uniform float stain_strength : hint_range(0.0, 1.0) = 0.35;
uniform float stain_scale : hint_range(0.5, 5.0) = 2.0;
// Overall intensity multiplier
uniform float weathering_intensity : hint_range(0.0, 2.0) = 1.0;
// ============================================================
// Noise functions (no external texture needed)
// ============================================================
vec2 hash22(vec2 p) {
p = vec2(dot(p, vec2(127.1, 311.7)),
dot(p, vec2(269.5, 183.3)));
return -1.0 + 2.0 * fract(sin(p) * 43758.5453123);
}
float noise(vec2 p) {
vec2 i = floor(p);
vec2 f = fract(p);
vec2 u = f * f * (3.0 - 2.0 * f);
return mix(mix(dot(hash22(i + vec2(0.0, 0.0)), f - vec2(0.0, 0.0)),
dot(hash22(i + vec2(1.0, 0.0)), f - vec2(1.0, 0.0)), u.x),
mix(dot(hash22(i + vec2(0.0, 1.0)), f - vec2(0.0, 1.0)),
dot(hash22(i + vec2(1.0, 1.0)), f - vec2(1.0, 1.0)), u.x), u.y);
}
float fbm(vec2 p, int octaves) {
float value = 0.0;
float amplitude = 0.5;
float frequency = 1.0;
for (int i = 0; i < octaves; i++) {
value += amplitude * noise(p * frequency);
frequency *= 2.0;
amplitude *= 0.5;
}
return value;
}
// ============================================================
// RGB <-> HSV conversion
// ============================================================
vec3 rgb2hsv(vec3 c) {
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
vec3 hsv2rgb(vec3 c) {
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
// ============================================================
// Main fragment
// ============================================================
void fragment() {
// Sample base texture
vec4 tex = texture(base_texture, UV);
vec3 color = tex.rgb;
// World position for noise - makes each wall unique
vec3 world_pos = (INV_VIEW_MATRIX * vec4(VERTEX, 1.0)).xyz;
vec2 wp = world_pos.xz;
// UV.y for vertical gradient (0 = top, 1 = bottom)
float v_pos = UV.y;
// ---- COARSE WEATHERING NOISE ----
float weather_noise = fbm(wp * weather_scale, 3) * 0.5 + 0.5;
// ---- FINE SURFACE GRIME ----
float grime_noise = fbm(wp * grime_scale + vec2(50.0, 50.0), 3);
// ---- STAIN BLOTCHES ----
float stain_noise = fbm(wp * stain_scale + vec2(100.0, 200.0), 4);
stain_noise = smoothstep(0.15, 0.45, stain_noise);
// Convert to HSV
vec3 hsv = rgb2hsv(color);
// ---- GRADIENT: RISING DAMP ----
float gradient = pow(v_pos, gradient_exponent);
float warped_gradient = gradient * mix(1.0, weather_noise * 1.6, gradient_noise_warp);
warped_gradient = clamp(warped_gradient, 0.0, 1.0);
float grad_effect = warped_gradient * gradient_strength * weathering_intensity;
hsv.z -= grad_effect * 0.35;
hsv.x += grad_effect * shadow_cool_shift;
hsv.y += grad_effect * 0.12;
// ---- HUE SHIFTING ----
float luminance = hsv.z;
float cool_warm = (luminance - 0.5) * 2.0;
hsv.x += mix(shadow_cool_shift, -highlight_warm_shift, cool_warm * 0.5 + 0.5)
* weathering_intensity;
// ---- SURFACE GRIME ----
float grime_effect = grime_noise * grime_strength * weathering_intensity * 0.08;
hsv.z -= grime_effect;
hsv.y += abs(grime_effect) * 0.5;
// ---- STAIN BLOTCHES ----
float stain_effect = stain_noise * stain_strength * weathering_intensity;
hsv.z -= stain_effect * 0.1;
hsv.x += stain_effect * 0.02;
// Clamp HSV
hsv.x = fract(hsv.x);
hsv.y = clamp(hsv.y, 0.0, 1.0);
hsv.z = clamp(hsv.z, 0.0, 1.0);
// Back to RGB
color = hsv2rgb(hsv);
ALBEDO = color;
}
```
---
## What Each Pass Does
**Rising damp gradient:** Runs on `UV.y` (top to bottom of the face) with the cubic exponent keeping the top clean. Coarse FBM noise warps the damp line so it's not perfectly horizontal — moisture follows porosity, not a ruler.
**Hue shifting:** Automatic based on luminance. Darker areas shift cool (blue-green), brighter areas shift warm (yellow). Same principle as palette ramps but continuous.
**Surface grime:** Fine-scale FBM that slightly varies value across brick faces. Every brick reads slightly different.
**Stain blotches:** Thresholded FBM that creates irregular dark patches, different on every wall.
---
## Uniform Reference
| Uniform | Default | What it does |
|---|---|---|
| `gradient_strength` | 0.6 | How dark the bottom gets |
| `gradient_exponent` | 3.0 | Curve shape (higher = top stays cleaner longer) |
| `gradient_noise_warp` | 0.4 | How much noise distorts the damp line |
| `shadow_cool_shift` | 0.06 | Blue shift in dark areas |
| `highlight_warm_shift` | 0.04 | Yellow shift in bright areas |
| `grime_strength` | 0.3 | Fine surface dirt intensity |
| `grime_scale` | 3.0 | Size of grime noise pattern |
| `weather_scale` | 1.2 | Size of large weather blotches |
| `stain_strength` | 0.35 | Dark stain patch intensity |
| `stain_scale` | 2.0 | Size of stain blotch pattern |
| `weathering_intensity` | 1.0 | Master dial — 0 = clean, 2 = ancient |
---
## Notes
- **UV.y assumption:** The gradient assumes UVs run top-to-bottom on wall faces. If FuncGodot generates UVs differently, swap `v_pos = UV.y` to `v_pos = 1.0 - (world_pos.y / wall_height)` or similar.
- **Performance:** The FBM loops are the most expensive part. Reduce octave counts if needed. On your Radeon 890M this should be fine.
- **Combining with Python script:** You can use the Python script for baking variant textures for your material browser in TrenchBroom (visual reference while editing), then apply this shader at runtime for the actual in-game look. Best of both worlds.