readme
This commit is contained in:
220
docs/INTRODUCTION.MD
Normal file
220
docs/INTRODUCTION.MD
Normal file
@@ -0,0 +1,220 @@
|
||||
# 📄 Introduction into FastVoxel
|
||||
|
||||
## Surface generation
|
||||
|
||||
Default generator: `SimpleSurfaceGenerator`
|
||||
|
||||
It uses `fastnoise-lite` to create a heightmap, then fills voxel columns from the bottom up.
|
||||
|
||||
Files:
|
||||
|
||||
- `src/generation/generator.rs`
|
||||
- `src/generation/simple_heightmap.rs`
|
||||
|
||||
Generation uses traits, so you can plug in whatever mumbo jumbo nonsense you want later: caves, biomes, multiverse, whatever.
|
||||
|
||||
## Meshing
|
||||
|
||||
Multiple meshers exist because one was simply not enough to satisfy my unhealthy obsession with "doing it right this time."
|
||||
[engine development perfectionism disorder. there's no cure.]
|
||||
|
||||
- `CullingMesher` – basic visible-face meshing
|
||||
- `TexturedMesher` – UV-aware cube meshing (Minecraft basically)
|
||||
- `BinaryGreedyMesher` – experimental optimization attempt
|
||||
|
||||
Files:
|
||||
|
||||
- `src/meshing/mesher.rs`
|
||||
- `src/meshing/textured_mesher.rs`
|
||||
- `src/meshing/binary_greedy_mesher.rs`
|
||||
|
||||
The textured mesher is currently the most practical one because it respects UVs and etc. simply because you can define the material for it.
|
||||
It's not optimized though.
|
||||
|
||||
## Godot integration
|
||||
|
||||
The engine exposes several handy APIs for the editor:
|
||||
|
||||
- `WorldConfig` – generation settings
|
||||
- `VoxelRegistry` – voxel definitions and atlas stuff
|
||||
- `World` – main terrain node
|
||||
- `WorldPlugin` – editor plugin hooks
|
||||
|
||||
Files:
|
||||
|
||||
- `src/editor/world_config.rs`
|
||||
- `src/editor/voxel_registry.rs`
|
||||
- `src/editor/world_node.rs`
|
||||
- `src/editor/world_plugin.rs`
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
src/
|
||||
├── chunk/ # chunk data, columns, manager
|
||||
├── editor/ # Godot resources + editor plugin
|
||||
├── generation/ # terrain generators
|
||||
├── meshing/ # meshing algorithems
|
||||
├── rendering/ # mesh to Godot conversion
|
||||
├── terrain/ # I'm not so sure
|
||||
└── voxel/ # registry + older voxel logic
|
||||
```
|
||||
|
||||
## Build and Install
|
||||
|
||||
Requirements:
|
||||
|
||||
- Rust toolchain
|
||||
- Godot 4 project with GDExtension
|
||||
- Optional sibling project for `build.sh` to work.
|
||||
|
||||
### Build the extension
|
||||
|
||||
```
|
||||
cargo build --release
|
||||
```
|
||||
|
||||
### Helper script
|
||||
|
||||
`build.sh` builds & copies the extension to:
|
||||
|
||||
```
|
||||
../minekoloft/addons/fastvoxel/bin/linux
|
||||
```
|
||||
|
||||
Run with:
|
||||
|
||||
```
|
||||
./build.sh
|
||||
```
|
||||
|
||||
If your project is elsewhere, edit the path.
|
||||
|
||||
## Using It in Godot
|
||||
|
||||
Typical use:
|
||||
|
||||
1. build the Rust extension
|
||||
2. install addon in your Godot project
|
||||
3. create `WorldConfig`
|
||||
4. create `VoxelRegistry`
|
||||
5. add `World` node
|
||||
6. assign config + registry
|
||||
7. generate terrain
|
||||
8. Call the "update with player position" API every frame. Spam it. It returns early and won't yell at you.
|
||||
|
||||
### WorldConfig
|
||||
|
||||
Contains:
|
||||
|
||||
- chunk_size
|
||||
- render_distance
|
||||
- worker_threads
|
||||
- seed
|
||||
- frequency
|
||||
- terrain_height
|
||||
|
||||
Defaults:
|
||||
|
||||
- chunk: `32,32,32`
|
||||
- render dist: `8`
|
||||
- threads: `4`
|
||||
- seed: `1234`
|
||||
- freq: `0.03`
|
||||
- terrain height: `6`
|
||||
|
||||
### VoxelRegistry
|
||||
|
||||
Each voxel defines:
|
||||
|
||||
- type
|
||||
- atlas size
|
||||
- tile index per face (top, bottom, left, right, front, back)
|
||||
|
||||
Mesher uses this for UVs.
|
||||
|
||||
### Runtime API
|
||||
|
||||
World node provides:
|
||||
|
||||
- `generate_terrain()`
|
||||
- `regenerate_terrain()`
|
||||
- `clear_terrain()`
|
||||
- `update_from_gdscript(player_world_pos)`
|
||||
|
||||
GDScript example:
|
||||
|
||||
```gdscript
|
||||
@onready var world = $World
|
||||
@onready var player = $Player
|
||||
|
||||
func _ready():
|
||||
world.generate_terrain()
|
||||
|
||||
func _process(_delta):
|
||||
world.update_from_gdscript(player.global_position)
|
||||
```
|
||||
|
||||
## Engine-Level API Notes
|
||||
|
||||
### Generation trait
|
||||
|
||||
```rust
|
||||
pub trait SurfaceGenerator: Send + Sync {
|
||||
fn generate(&self, column: &mut ChunkColumn);
|
||||
fn sample_voxel(&self, pos: Vector3i) -> bool;
|
||||
}
|
||||
```
|
||||
|
||||
### Mesher trait
|
||||
|
||||
```rust
|
||||
pub trait Mesher: Send + Sync {
|
||||
fn generate_mesh(&self, chunk: &Chunk, mesh: &mut ChunkMesh);
|
||||
fn generate_mesh_with_registry(
|
||||
&self,
|
||||
chunk: &Chunk,
|
||||
registry: &VoxelRegistry,
|
||||
mesh: &mut ChunkMesh,
|
||||
);
|
||||
fn get_name(&self) -> &str;
|
||||
}
|
||||
```
|
||||
|
||||
### ChunkManager
|
||||
|
||||
Handles:
|
||||
|
||||
- chunk lifetime
|
||||
- generation around player
|
||||
- unloading distant chunks
|
||||
- meshing
|
||||
- sending meshes to renderer
|
||||
- attaching instances to scene
|
||||
|
||||
Basically the project's overworked intern.
|
||||
|
||||
## Current State
|
||||
|
||||
Mid-development, active refactors, might panic on unwrap.
|
||||
Direction is clear though:
|
||||
|
||||
- compact chunk storage
|
||||
- trait-based generation
|
||||
- modular meshing
|
||||
- Godot resource workflow
|
||||
- runtime streaming
|
||||
|
||||
## Why This Document Exists
|
||||
|
||||
Because why not? If you actually wanted to read the code, you wouldn't be here.
|
||||
|
||||
## Future Work
|
||||
|
||||
- finish terrain/world refactor
|
||||
- more screenshots
|
||||
- stable API for godot
|
||||
- multithreaded chunk gen (**GOD HELP**)
|
||||
- Better Godot material integration for voxel meshes (so things look less like programmer art).
|
||||
- fix the greedy meshing
|
||||
- sample Godot project
|
||||
Reference in New Issue
Block a user