Add comprehensive Godot HTML5 export guide and remove stub files
Some checks failed
Build and Push to Harbor / build-and-push (push) Has been cancelled
Some checks failed
Build and Push to Harbor / build-and-push (push) Has been cancelled
- Created detailed best practices guide for Godot HTML5/Web exports - Removed empty stub files (they mask problems rather than solving them) - Kept favicon.ico as it's a legitimate browser requirement - Guide covers export config, optimization, deployment, and troubleshooting
This commit is contained in:
447
GODOT_HTML5_EXPORT_GUIDE.md
Normal file
447
GODOT_HTML5_EXPORT_GUIDE.md
Normal file
@@ -0,0 +1,447 @@
|
||||
# Godot HTML5 Export Best Practices Guide
|
||||
|
||||
A comprehensive guide for exporting Godot games to HTML5/Web and deploying them properly.
|
||||
|
||||
## Table of Contents
|
||||
- [Pre-Export Checklist](#pre-export-checklist)
|
||||
- [Export Configuration](#export-configuration)
|
||||
- [Post-Export Optimization](#post-export-optimization)
|
||||
- [Deployment Best Practices](#deployment-best-practices)
|
||||
- [Common Issues & Solutions](#common-issues--solutions)
|
||||
- [Security Considerations](#security-considerations)
|
||||
|
||||
---
|
||||
|
||||
## Pre-Export Checklist
|
||||
|
||||
### 1. Set Project Icon
|
||||
**Location:** `Project → Project Settings → Application → Config → Icon`
|
||||
|
||||
```
|
||||
✅ Use a square PNG image (ideally 512x512 or 1024x1024)
|
||||
✅ Godot will auto-generate smaller sizes (16x16, 32x32, etc.)
|
||||
✅ This icon becomes your favicon and app icons
|
||||
```
|
||||
|
||||
**Why:** Prevents 404 errors for `/favicon.ico` and provides proper branding.
|
||||
|
||||
### 2. Configure Export Presets
|
||||
**Location:** `Project → Export → Add → HTML5`
|
||||
|
||||
#### Essential Settings:
|
||||
```
|
||||
Export Type: Regular (or Threads if you need SharedArrayBuffer)
|
||||
Export With Debug: OFF for production
|
||||
Texture Format: Compress for Smaller Downloads
|
||||
```
|
||||
|
||||
#### Head Include (Optional):
|
||||
Only add custom meta tags if needed:
|
||||
```html
|
||||
<meta name="description" content="Your game description">
|
||||
<meta name="keywords" content="game, webgl, godot">
|
||||
<meta name="author" content="Your Name">
|
||||
```
|
||||
|
||||
### 3. Audio Configuration
|
||||
**Location:** `Project → Project Settings → Audio`
|
||||
|
||||
```
|
||||
✅ Mix Rate: 44100 Hz (standard web audio)
|
||||
✅ Output Latency: 15ms (balance between quality and performance)
|
||||
✅ Enable Audio Input: Only if needed (requires user permissions)
|
||||
```
|
||||
|
||||
### 4. Display Settings
|
||||
**Location:** `Project → Project Settings → Display → Window`
|
||||
|
||||
```
|
||||
✅ Size: Set your target resolution (e.g., 1920x1080)
|
||||
✅ Resizable: Enable if you want responsive sizing
|
||||
✅ Stretch Mode: "2d" or "viewport" for web games
|
||||
✅ Stretch Aspect: "expand" or "keep" based on your needs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Export Configuration
|
||||
|
||||
### Recommended HTML5 Export Settings
|
||||
|
||||
#### 1. **Vram Texture Compression**
|
||||
Enable both formats for maximum compatibility:
|
||||
```
|
||||
✅ For Desktop: s3tc (DXT1/DXT5)
|
||||
✅ For Mobile: etc2 (or astc if targeting newer devices)
|
||||
```
|
||||
|
||||
#### 2. **Custom HTML Shell**
|
||||
Leave default unless you need:
|
||||
- Custom loading screens
|
||||
- Analytics integration
|
||||
- Special PWA features
|
||||
|
||||
#### 3. **Export Mode**
|
||||
- **Release:** Production builds (optimized, no debug symbols)
|
||||
- **Debug:** Development builds (larger, has debug info)
|
||||
|
||||
### 4. **Progressive Web App (PWA)**
|
||||
Enable if you want installable web apps:
|
||||
```
|
||||
Export → HTML5 → Progressive Web App: ON
|
||||
Offline Page: Enable for offline support
|
||||
Icon Sizes: Godot auto-generates these
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Post-Export Optimization
|
||||
|
||||
### 1. File Size Optimization
|
||||
|
||||
#### Compress WASM Files
|
||||
The `.wasm` file is usually the largest. Use Brotli or Gzip:
|
||||
|
||||
```bash
|
||||
# Using Brotli (best compression)
|
||||
brotli -9 YourGame.wasm
|
||||
|
||||
# Using Gzip (better compatibility)
|
||||
gzip -9 YourGame.wasm
|
||||
```
|
||||
|
||||
#### Nginx Configuration:
|
||||
```nginx
|
||||
# Enable compression for Godot files
|
||||
gzip on;
|
||||
gzip_types application/wasm application/javascript text/html;
|
||||
gzip_min_length 1000;
|
||||
|
||||
# Better: Use Brotli
|
||||
brotli on;
|
||||
brotli_types application/wasm application/javascript text/html;
|
||||
```
|
||||
|
||||
### 2. Caching Strategy
|
||||
|
||||
```nginx
|
||||
# Cache static assets aggressively
|
||||
location ~* \.(wasm|js|pck)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# Cache images
|
||||
location ~* \.(png|jpg|jpeg|gif|ico)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# Don't cache the HTML file
|
||||
location ~* \.html$ {
|
||||
expires -1;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Required HTTP Headers
|
||||
|
||||
For SharedArrayBuffer/Threads support:
|
||||
```nginx
|
||||
add_header Cross-Origin-Embedder-Policy "require-corp" always;
|
||||
add_header Cross-Origin-Opener-Policy "same-origin" always;
|
||||
```
|
||||
|
||||
**Note:** These are already in your nginx.conf - good job!
|
||||
|
||||
---
|
||||
|
||||
## Deployment Best Practices
|
||||
|
||||
### 1. Directory Structure
|
||||
|
||||
```
|
||||
your-game/
|
||||
├── index.html # Main entry (or YourGame.html)
|
||||
├── YourGame.js # Godot engine
|
||||
├── YourGame.wasm # Compiled game
|
||||
├── YourGame.pck # Game assets
|
||||
├── YourGame.worker.js # Service worker
|
||||
├── YourGame.icon.png # Favicon/Icon
|
||||
├── favicon.ico # Browser favicon (convert from icon)
|
||||
├── manifest.json # PWA manifest
|
||||
└── assets/ # Optional: separate assets folder
|
||||
```
|
||||
|
||||
### 2. Serving Files
|
||||
|
||||
#### Option A: Simple HTTP Server (Development)
|
||||
```bash
|
||||
# Python 3
|
||||
python3 -m http.server 8000
|
||||
|
||||
# Python 2
|
||||
python -m SimpleHTTPServer 8000
|
||||
|
||||
# Node.js (http-server)
|
||||
npx http-server -p 8000
|
||||
```
|
||||
|
||||
#### Option B: Production (Nginx/Caddy)
|
||||
Use your current Kubernetes deployment approach.
|
||||
|
||||
### 3. HTTPS Requirement
|
||||
|
||||
Modern browsers require HTTPS for:
|
||||
- SharedArrayBuffer (threads)
|
||||
- Service Workers (offline)
|
||||
- WebGL 2.0 features
|
||||
- Clipboard API
|
||||
- Gamepad API
|
||||
|
||||
**Your setup already has this via cert-manager + Let's Encrypt ✅**
|
||||
|
||||
---
|
||||
|
||||
## Common Issues & Solutions
|
||||
|
||||
### Issue 1: "SharedArrayBuffer is not defined"
|
||||
|
||||
**Cause:** Missing CORS headers or HTTP (not HTTPS)
|
||||
|
||||
**Solution:**
|
||||
```nginx
|
||||
add_header Cross-Origin-Embedder-Policy "require-corp" always;
|
||||
add_header Cross-Origin-Opener-Policy "same-origin" always;
|
||||
```
|
||||
|
||||
### Issue 2: Blank Screen or "Failed to load"
|
||||
|
||||
**Debug Steps:**
|
||||
1. Open browser DevTools (F12)
|
||||
2. Check Console for errors
|
||||
3. Check Network tab for failed requests
|
||||
|
||||
**Common Causes:**
|
||||
- Missing files (check all exports completed)
|
||||
- Wrong MIME types
|
||||
- File path mismatches (case-sensitive on Linux)
|
||||
|
||||
**Solution:** Verify nginx MIME types:
|
||||
```nginx
|
||||
types {
|
||||
application/wasm wasm;
|
||||
application/javascript js;
|
||||
text/html html;
|
||||
}
|
||||
```
|
||||
|
||||
### Issue 3: Audio Not Playing
|
||||
|
||||
**Cause:** Browsers require user interaction before playing audio
|
||||
|
||||
**Solution:** In Godot, show a "Click to Start" screen:
|
||||
```gdscript
|
||||
func _ready():
|
||||
# Don't autoplay audio
|
||||
# Wait for user input first
|
||||
pass
|
||||
|
||||
func _on_start_button_pressed():
|
||||
$AudioStreamPlayer.play()
|
||||
```
|
||||
|
||||
### Issue 4: Poor Performance
|
||||
|
||||
**Optimization Tips:**
|
||||
1. **Reduce Draw Calls:** Batch sprites, use TileMaps
|
||||
2. **Optimize Shaders:** Simple shaders = better performance
|
||||
3. **Texture Compression:** Use compressed textures
|
||||
4. **Object Pooling:** Reuse nodes instead of creating/destroying
|
||||
5. **Profile:** Use Godot's built-in profiler
|
||||
|
||||
### Issue 5: Large File Sizes
|
||||
|
||||
**Solutions:**
|
||||
1. **Enable Compression:** Gzip/Brotli on server
|
||||
2. **Optimize Assets:**
|
||||
- Convert PNGs to WebP
|
||||
- Compress audio (OGG Vorbis instead of WAV)
|
||||
- Use texture compression
|
||||
3. **Lazy Loading:** Load assets on-demand, not all at startup
|
||||
4. **Asset Streaming:** Use Godot's asset streaming features
|
||||
|
||||
---
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### 1. Content Security Policy (CSP)
|
||||
|
||||
If you need CSP headers:
|
||||
```nginx
|
||||
# Relaxed CSP for Godot games
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'wasm-unsafe-eval' 'unsafe-inline'; worker-src 'self' blob:; connect-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline';" always;
|
||||
```
|
||||
|
||||
### 2. X-Frame-Options
|
||||
|
||||
Prevent clickjacking:
|
||||
```nginx
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
```
|
||||
|
||||
**Your nginx.conf already has this ✅**
|
||||
|
||||
### 3. Input Validation
|
||||
|
||||
If your game has:
|
||||
- User-generated content
|
||||
- Multiplayer features
|
||||
- External data loading
|
||||
|
||||
**Always validate and sanitize inputs!**
|
||||
|
||||
---
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
Before deploying to production:
|
||||
|
||||
### Browser Compatibility
|
||||
- [ ] Chrome/Chromium (Latest)
|
||||
- [ ] Firefox (Latest)
|
||||
- [ ] Safari (Latest)
|
||||
- [ ] Edge (Latest)
|
||||
- [ ] Mobile browsers (iOS Safari, Chrome Mobile)
|
||||
|
||||
### Performance Testing
|
||||
- [ ] Load time < 10 seconds on 3G
|
||||
- [ ] 60 FPS on target hardware
|
||||
- [ ] Memory usage stable over time
|
||||
- [ ] No memory leaks after extended play
|
||||
|
||||
### Functionality Testing
|
||||
- [ ] Audio works (after user interaction)
|
||||
- [ ] Input (keyboard, mouse, touch, gamepad)
|
||||
- [ ] Fullscreen mode works
|
||||
- [ ] Save/Load functionality
|
||||
- [ ] All game mechanics work as expected
|
||||
|
||||
### Accessibility
|
||||
- [ ] Works without sound (visual feedback)
|
||||
- [ ] Keyboard-only controls (if applicable)
|
||||
- [ ] Colorblind-friendly (if applicable)
|
||||
|
||||
---
|
||||
|
||||
## Advanced: Custom Docker Build
|
||||
|
||||
For building in CI/CD (like your Kaniko setup):
|
||||
|
||||
### Dockerfile Example:
|
||||
```dockerfile
|
||||
FROM nginx:alpine
|
||||
|
||||
# Copy game files
|
||||
COPY htlm/ /usr/share/nginx/html/
|
||||
|
||||
# Copy custom nginx config
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
# Set proper permissions
|
||||
RUN chown -R nginx:nginx /usr/share/nginx/html
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8080
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/ || exit 1
|
||||
```
|
||||
|
||||
### nginx.conf (Your current one is excellent):
|
||||
```nginx
|
||||
server {
|
||||
listen 8080;
|
||||
server_name _;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index YourGame.html;
|
||||
|
||||
# Compression
|
||||
gzip on;
|
||||
gzip_types application/wasm application/javascript text/html;
|
||||
|
||||
# CORS for SharedArrayBuffer
|
||||
add_header Cross-Origin-Embedder-Policy "require-corp" always;
|
||||
add_header Cross-Origin-Opener-Policy "same-origin" always;
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
|
||||
# Caching
|
||||
location ~* \.(wasm|js|pck)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Resources
|
||||
|
||||
### Official Documentation
|
||||
- [Godot HTML5 Export Docs](https://docs.godotengine.org/en/stable/tutorials/export/exporting_for_web.html)
|
||||
- [Godot Web Editor](https://editor.godotengine.org/)
|
||||
|
||||
### Tools
|
||||
- [Godot Web Export Validator](https://pwa-directory.appspot.com/)
|
||||
- [WebPageTest](https://www.webpagetest.org/) - Performance testing
|
||||
- [Lighthouse](https://developers.google.com/web/tools/lighthouse) - PWA audit
|
||||
|
||||
### Community
|
||||
- [Godot Forums - HTML5 Export](https://godotengine.org/community)
|
||||
- [r/godot](https://reddit.com/r/godot)
|
||||
|
||||
---
|
||||
|
||||
## Your Current Setup Analysis
|
||||
|
||||
### What You're Doing Right ✅
|
||||
1. **Proper CORS Headers** for SharedArrayBuffer
|
||||
2. **Security Headers** (X-Frame-Options, X-Content-Type-Options)
|
||||
3. **Compression** enabled (gzip)
|
||||
4. **Proper MIME types** for .wasm files
|
||||
5. **Cache headers** for static assets
|
||||
6. **Service Worker** for offline support
|
||||
7. **GitOps deployment** with Flux
|
||||
8. **Container orchestration** with Kubernetes
|
||||
|
||||
### Recommendations
|
||||
1. ✅ **Keep the favicon.ico** (converted from your icon)
|
||||
2. ❌ **Don't create empty stub files** for scanner requests
|
||||
3. ✅ **Monitor logs** but ignore 404s for files your app doesn't use
|
||||
4. ✅ **Consider adding** a robots.txt to reduce scanner noise
|
||||
5. ✅ **Consider adding** rate limiting to prevent abuse
|
||||
|
||||
### About Those 404 Errors
|
||||
The files being requested (`support_parent.css`, `twint_ch.js`, `lkk_ch.js`) are:
|
||||
- **Not part of Godot exports**
|
||||
- **Not needed by your game**
|
||||
- **Requested by bots/scanners** looking for e-commerce vulnerabilities
|
||||
- **Safe to ignore** - they don't affect your game
|
||||
|
||||
**Best Practice:** Monitor real errors, ignore scanner noise in logs.
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
This guide is provided as-is for educational purposes.
|
||||
Feel free to adapt for your own projects.
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** November 2025
|
||||
**Godot Version:** 4.x (applicable to 3.x with minor changes)
|
||||
Reference in New Issue
Block a user