docs: community mapmaking documentation (7-file SDK guide)
- docs/mapmaking/00-index.md — SDK overview with workflow diagram - docs/mapmaking/01-getting-started.md — template setup & first map - docs/mapmaking/02-building-geometry.md — CSG guide & prefab reference - docs/mapmaking/03-lighting-and-env.md — LightmapGI baking guide - docs/mapmaking/04-validation.md — validator CLI & CI/CD usage - docs/mapmaking/05-packaging-and-shipping.md — .pck pipeline - docs/mapmaking/06-faq-and-troubleshooting.md — 30+ common issues - README.md — add mapmaking SDK link to features list
This commit is contained in:
@@ -0,0 +1,238 @@
|
||||
# FAQ & Troubleshooting
|
||||
|
||||
Common questions, issues, and solutions encountered while building maps.
|
||||
|
||||
## Template Project
|
||||
|
||||
### Q: Can I use the template project without the main game repo?
|
||||
|
||||
Yes. The template project at `client/map_template/` is a **standalone Godot
|
||||
project**. Copy it anywhere, open it in Godot, and start building. You only
|
||||
need the main repo for packaging (`pack_map.gd`) and the registry server
|
||||
(`map_registry_server.py`).
|
||||
|
||||
### Q: Why does Godot say "Import" instead of "Open"?
|
||||
|
||||
The template has its own `project.godot`, making it a separate project. Use
|
||||
**Import** to add it to your Godot project list. You're not opening a scene
|
||||
within an existing project.
|
||||
|
||||
### Q: How do I add the main game's assets to my map?
|
||||
|
||||
The template uses placeholder materials. For final maps:
|
||||
|
||||
1. Copy your map's `.tscn` into the main project under `client/maps/<name>/`
|
||||
2. Open it from the main project's scenes tab
|
||||
3. The main game's modular kit and PBR materials will be available
|
||||
4. Assign materials to your CSG/MeshInstance3D nodes from the main project's
|
||||
asset library
|
||||
|
||||
### Q: Can I use external models from Blender/Maya?
|
||||
|
||||
Yes. Export as `.glb` or `.obj` and import into Godot. Keep triangle counts
|
||||
within budget (≤ 50K total, ≤ 5K per mesh recommended). Place imported meshes
|
||||
as children of the map scene root.
|
||||
|
||||
## Geometry & CSG
|
||||
|
||||
### Q: My map has light leaks at the corners
|
||||
|
||||
Thin gaps between CSG blocks let light bleed through. Fix by overlapping CSG
|
||||
edges by **0.1 units** instead of butting them flush.
|
||||
|
||||
```
|
||||
Bad: Wall ends at x=10.0, floor ends at x=10.0 → gap
|
||||
Good: Wall extends to x=10.1, floor ends at x=10.0 → overlap
|
||||
```
|
||||
|
||||
### Q: Players can walk through walls
|
||||
|
||||
Make sure `use_collision = true` is set on all CSG geometry nodes. CSG nodes
|
||||
don't have collision by default — you must enable it.
|
||||
|
||||
### Q: My map renders as a grey box / no materials
|
||||
|
||||
Placeholder materials are normal during construction. For the final look, you
|
||||
need to:
|
||||
1. Copy the map to the main project (see above)
|
||||
2. Assign materials from the game's asset library
|
||||
3. Re-bake LightmapGI after materials are assigned
|
||||
|
||||
### Q: CSG performance is bad in the editor
|
||||
|
||||
This is normal. CSG is re-calculated every time you move a node. For testing,
|
||||
convert stable geometry to MeshInstance3D:
|
||||
- Right-click CSG parent → **Convert CSG to Mesh**
|
||||
- Keep a backup copy of the CSG hierarchy in another scene
|
||||
|
||||
### Q: How do I make a skybox?
|
||||
|
||||
Add a `WorldEnvironment` node and assign an Environment resource:
|
||||
1. Set **Background** mode to **Sky**
|
||||
2. Create a new **Sky** resource
|
||||
3. Assign a **PanoramaSky** or **ProceduralSky** material
|
||||
4. The sky appears behind your geometry
|
||||
|
||||
### Q: My map has no collision after CSG → Mesh conversion
|
||||
|
||||
When you convert CSG to MeshInstance3D, collision is not preserved. Add a
|
||||
`CollisionShape3D` as a child of each MeshInstance3D, or use Godot's
|
||||
**Mesh → Create Trimesh Collision** (right-click the MeshInstance3D).
|
||||
|
||||
## Lighting
|
||||
|
||||
### Q: My lightmap bake takes forever
|
||||
|
||||
Baking time depends on:
|
||||
- **texel_scale** — lower = higher resolution = longer bake (try 2.0 for testing)
|
||||
- **bounces** — fewer bounces = faster bake (use 1 for quick tests, 3 for final)
|
||||
- **Map size** — larger maps bake longer
|
||||
- **Light count** — more lights = more calculations
|
||||
|
||||
For quick iteration, use Low quality (0) during development and High quality (2)
|
||||
for the final bake.
|
||||
|
||||
### Q: Baked lighting is too dark
|
||||
|
||||
- Increase `bounces` to 3 (more light bounce = brighter interiors)
|
||||
- Add a low-intensity ambient fill (OmniLight3D with Static bake mode)
|
||||
- Lower the `texel_scale` for more lightmap resolution
|
||||
- Check that the DirectionalLight3D intensity is sufficient
|
||||
|
||||
### Q: Lightmap has visible seams
|
||||
|
||||
Seams appear where lightmap texels don't align. Fixes:
|
||||
- Lower `texel_scale` to 1.0 (higher resolution lightmaps)
|
||||
- Ensure CSG edges overlap (no gaps)
|
||||
- Convert CSG to MeshInstance3D before final bake
|
||||
|
||||
### Q: Shadows look blocky or jagged
|
||||
|
||||
This is Godot's shadow mapping at default resolution. For competitive clarity:
|
||||
- Keep `shadow_bias` at 0.1 (higher = softer shadows, fewer artefacts)
|
||||
- Directional shadow `max_distance` at 20–30 (shadows beyond this use lower
|
||||
resolution)
|
||||
|
||||
### Q: I see a sphere artifact on my ReflectionProbe
|
||||
|
||||
The ReflectionProbe has a `probe_mode` property — if set to **Reflection Probe**
|
||||
(sphere mode), it renders as a visible sphere in reflections. Change to **Box
|
||||
Probe** for interior spaces, or disable reflection visibility via the `visible`
|
||||
property on the probe's MeshInstance3D child (Godot 4.x).
|
||||
|
||||
### Q: Can I have a day/night cycle?
|
||||
|
||||
No. LightmapGI bakes lighting statically. Dynamic lighting is limited to
|
||||
≤ 4 real-time lights. Day/night cycles are outside the current scope.
|
||||
|
||||
## Validation
|
||||
|
||||
### Q: The validator says "No MeshInstance3D nodes found"
|
||||
|
||||
Your map is using CSG nodes that haven't been converted to meshes. The
|
||||
validator counts mesh triangles — CSG nodes are scanned as MeshInstance3D
|
||||
after conversion. Either:
|
||||
1. Convert CSG → Mesh for the area you want validated (right-click → Convert CSG to Mesh)
|
||||
2. This warning is expected during early construction stages
|
||||
|
||||
### Q: The validator fails with "Scene cannot be instantiated"
|
||||
|
||||
The scene depends on resources that don't exist in the template project. This
|
||||
usually happens when the map references game assets from the main project.
|
||||
Either:
|
||||
1. Run the validator from the **main game project** (`--path client` with the
|
||||
main `client/project.godot`), or
|
||||
2. Strip external dependencies — the map should be self-contained
|
||||
|
||||
### Q: The validator reports texture errors but my textures are 1024×1024
|
||||
|
||||
Check for textures with different aspect ratios. A 2048×512 texture fails
|
||||
because the larger dimension (2048) exceeds 1024. Resize or tile.
|
||||
|
||||
### Q: Can I skip certain validator checks?
|
||||
|
||||
Not directly. Run the validator, fix errors, then fix warnings. If a check
|
||||
produces a false positive, the `@tool` scripts are in
|
||||
`client/tools/validate_map/` — you can edit the constants (e.g.
|
||||
`MAX_TOTAL_TRIANGLES`) for custom pipelines.
|
||||
|
||||
## Packaging
|
||||
|
||||
### Q: The .pck file is very large
|
||||
|
||||
The `.pck` includes all dependencies of the scene. Large files mean:
|
||||
- High-resolution textures (use ≤ 1024×1024 per the budget)
|
||||
- High-poly meshes (stay under 50K triangles)
|
||||
- Embedded audio or other large assets
|
||||
|
||||
Run the validator first to check budgets.
|
||||
|
||||
### Q: I get "Failed to load pack" in-game
|
||||
|
||||
Possible causes:
|
||||
- `.pck` file is corrupted (check SHA-256 checksum)
|
||||
- The map scene or a dependency path changed between packaging and loading
|
||||
- The `.pck` was built with a different Godot version than the game
|
||||
- The resource path in the `.pck` conflicts with a path in the base game
|
||||
|
||||
**Solution:** Re-package the map from the same Godot version the game uses.
|
||||
Verify with `curl` that the download matches the server's checksum.
|
||||
|
||||
### Q: Can I update a map without changing the client version?
|
||||
|
||||
Yes. The `.pck` is additive content. Update the `.pck` on the registry server
|
||||
and increment the `version` field in the `.json` metadata. The client will
|
||||
re-download when it notices the version mismatch.
|
||||
|
||||
### Q: Can I host the registry server on a different port?
|
||||
|
||||
Yes. Use `--port <port>` or the `MAP_REGISTRY_PORT` environment variable.
|
||||
The client's `MapDownloader` has a `registry_url` property you can set.
|
||||
|
||||
### Q: Can I load more than one .pck at a time?
|
||||
|
||||
Yes. `ProjectSettings.load_resource_pack()` is additive. Multiple `.pck` files
|
||||
can be loaded simultaneously — each adds its resources to the global namespace.
|
||||
|
||||
### Q: The registry server returns 404 for my map
|
||||
|
||||
- Check that the `.pck` file is in the maps directory (default `./packed_maps/`)
|
||||
- Check the file extension is `.pck` (lowercase)
|
||||
- The server auto-scans every 5 seconds — wait or send SIGHUP to force a scan
|
||||
- Verify by listing: `curl http://localhost:8090/maps`
|
||||
|
||||
## General
|
||||
|
||||
### Q: Can I make a hostage rescue map?
|
||||
|
||||
The SDK is gameplay-agnostic. The groups `ct_spawn`, `t_spawn`, `bomb_site`,
|
||||
and `buy_zone` are the default set. You can add your own groups (e.g.,
|
||||
`hostage`, `hostage_zone`) — the game logic discovers them at runtime.
|
||||
Check the game's plugin API documentation for custom group support.
|
||||
|
||||
### Q: Can I use this SDK for a different game?
|
||||
|
||||
The SDK is designed for Tactical Shooter's Godot project structure. The
|
||||
packaging and validation scripts are reusable for any Godot map-authoring
|
||||
workflow, but the group conventions and gameplay nodes are game-specific.
|
||||
|
||||
### Q: The editor validator doesn't run
|
||||
|
||||
The `template_map.gd` script uses `@tool` and checks `Engine.is_editor_hint()`.
|
||||
Make sure:
|
||||
1. The script is attached to the root node of the scene
|
||||
2. You're editing the scene in the Godot editor (not running the game)
|
||||
3. The Output panel is visible (Window → Output)
|
||||
|
||||
### Q: How do I report a bug in the SDK?
|
||||
|
||||
Open an issue on the project's Gitea repository. Include:
|
||||
- SDK version (commit hash)
|
||||
- Godot version
|
||||
- Steps to reproduce
|
||||
- Log output (editor or CLI validator)
|
||||
|
||||
### Q: Can I contribute validator modules?
|
||||
|
||||
Yes. See [Validation — Adding a Custom Validator Module](04-validation.md#adding-a-custom-validator-module).
|
||||
Submit a pull request with your module and updated documentation.
|
||||
Reference in New Issue
Block a user