# B3DV Information

B3DV is a simple, FOSS, 3D game, or prototype of a game, made by me with the sole purpose of practicing.
I originally started it out of boredom and texturawasd's suggestion, and have continued it since. It is heavily inspired in early iterations of Minecraft.
It is free & open source (see github repo)

It's written in pure C + Raylib, with few dependencies [see dependencies]; and (for now) features just a basic world the player can walk on, break and place blocks, and save (different worlds)

## Overview:

It is written in C because it's the only language I mostly know how to program in.
Also, since the codebase is not big and is rather simple, it's straightforward to keep it portable across operating systems.[see codebase explanation]
Features:
- Simple world with terrain
- Block placing/destroying
- Saving different worlds
- Simple commands (/tp, etc)
- Simple UI, with translated text to different languages
- Fully free and open source: BSD-3-Clause license
- Simplistic design throughout

Raylib does all the boilerplate work for me, (initialize a window, OpenGL) so I only implemented the game's logic:
The render loop, the world data handling, the rendering, the optimizations, the ui (menus)

I intend to KISS, hackable and extensible:
You can use any font you want if you put a .ttf file in ./assets/fonts/[name]/ttf/[yourfile.ttf];
Settings are simply stored in options.txt;
The build system is Just A Makefile™;
You can implement your own translation for the UI in any language you like (./assets/text/[lang]/[chat|credits|menu].txt),
as well as textures (./assets/textures/blocks);
Really, you can implement any changes you want to it. (hackable as I said)

## In-game commands

Commands that are usable via chat:
/select [stone|grass|dirt|wood|sand] - Select which kind of block to place
/tp [x y z] - Teleport player to coords X Y Z
/setblock [x y z [block]] - set a block at coords
/fly [enable|disable] - Toggle flight
/noclip [enable|disable] - Toggle noclip

## "How does it work?" Here's the explanation:

### Big Picture:

Imagine B3DV as a game engine with the following interconnected modules, top to bottom:
[User input (kb, mouse)]
[Menu (ui) system] & [World (physics, updates)]
[Rendering]

### Core components:

1 - Worlds:

Each world is saved as a folder with a `chunks` folder, the actual chunk data; and a world.txt file, containing data like last played timestamp and player position
The world isn't just an array/grid of blocks, but it is divided into manageable chunks.
It is an infinite 3D grid, but split into small boxes, that are loaded and unloaded dynamically.
Only the chunk that the player is in, and the adjacent ones are 'loaded' (meaning loaded into memory, so effectively, actually relevant) and are unloaded once the player is far enough from them.
This is crucial and is what allows infinite worlds in finite systems, just like in Minecraft for instance.

2 - The player:

The player has several properties:
- Physics:
Position relative to player's head's X Y Z coords;
Velocity how fast the player is moving;
Gravity: 35 m/s^2;
Jumping: apply upward force
Collision: The player is actually a cilinder, (radius 0.35, height 1.9mts) so they interact (collide) with blocks
- Features:
Flight mode: can fly (no gravity) (enabled with `/fly enable`)
No-clip (no collision) mode: stops interacting with blocks, enabled with `/noclip enable` (especially useful when combined with flight)
Block selection: The player struct has a selected block field, as of now it can only be changed with /select
Sneaking: the player can "sneak" or move slowly and not go down blocks
Sprinting: the player can sprint or move faster than normal walking

3 - The rendering system:

The whole shtick:
I've use many optimization techniques to bring the FPS above 30:
Distance culling, a.k.a. a limited render distance
Frustum culling: Only render blocks that are in front of the player, based on FOV; at the block level and chunk level (entire chunks can get skipped before individual blocks)
Back-pane culling: Don't draw back faces of blocks (back face meaning faces that the player can't see anyways)
Occlusion culling, a.k.a. don't draw blocks that are obscured from view anyways
and raycasing is used to see which block the player is going to break/place

4 - The menu system:

Think of the menu system as a state machine with different screens:
- Main menu: the start screen, buttons for entering a world, creating a new one, quit, and credits. Displays a backround picture (ranomized from .png files inside ./assets/mainmenubackground/*.png) and a randomized splash text
- World select screen
- World create screen
- Settings: set FPS limit and render distance, modifying options.txt
And the gameplay, (when there's no menu) and credits screen which is merely text display
The 'menu' is localized (translated to 11*) and the settings are persistent.

5 - Input & commands:

The game uses direct input for gameplay, Raylib takes care of that. Yeah that's it.

6 - The main loop:

The main loop which runs every frame, goes from line 200 to 1480, contains the game logic, as the following sequence, roughly:
- Handle input:
└─ Read keyboard & mouse -> update camera angle and process block placement/destruction
- Update player physics
└─ Apply gravity to player, handle jumping/flying, check collisions with blocks, update the player's position
- Update world
└─ Load chunks near the player, unload chunks far from the player, generate terrain for new chunks if needed
- Render
└─ Calculate which chunks to render,
└─ Calculate which blocks to render
└─ Calculate which faces to render
└─ render those, with their respective texture; if the player is pointing at it, highlight it with a wireframe
& draw hud and crosshair on top

## Changelog:

While a quick & dirty change log can be found in the repo (./versions.txt); here are the changes listed plainly [expand to see]:
Latest is 0.0.12b;
0.0.12b: add clouds :)
0.0.12: upload this information page
0.0.11c: polish handling of options.txt
0.0.11b: fixed chat input; chat no longer freezes physics; bug promoted to feature: opening chat perpetuates movement (afk walking)
0.0.11: chunk frustum culling
0.0.10e: added backround picture; more splash texts
0.0.10d: added randomized splash texts in main menu
0.0.10c: added randomized main menu background
0.0.10b: added chat output; flight had noclip; chat doesnt pause the game; fixed sprinting
0.0.10: added flight (/fly [enable|disable])
0.0.9k: added persistent settings (./options.txt)
0.0.9j: fixed text
0.0.9i-2: implemented updater
0.0.9i: general optimizations
0.0.9h: fixed windows build
0.0.9g: added settins in main menu: render distance, FPS limit, font choice; fixed some untranslated text
0.0.9f: world now saves player's position; tweaked wording: "Back to menu" -> "Save & Quit"; added translations: polish; dutch
0.0.9e: made window resizable
0.0.9d: fixed credits ui
0.0.9c: added translations: italian; na'vi
0.0.9b: added translations: french; german; portuguese; ukrainian; russian
0.0.9: added credits & info button to main menu; added translation: spanish
0.0.8d: added main menu; tidy up worlds system
0.0.8c: shifting is now smoother
0.0.8b: do not spawn the player inside blocks; player is a bit taller; added shifting; added sprinting; fixed speedometer
0.0.8: added depth limit -20; hindering the effects of The Great Decelerator; the eldritch creature that lives under the world and lags the game the lower you go. Frames sink into it's uncomprehensible sea of entropy like space dust into black holes.
0.0.7e: chunk optimizations
0.0.7d: more optimizations, compiler flags
0.0.7c: general optimizations
0.0.7b: fixed /select; tweaked lighting; fixed placing blocks that intersect the player; generate-textures.py fixed
0.0.7: added blocks textures; fixed worlds system again; !issues: /select command is still bugged
0.0.6b: fixed rendering; fixed chat up arrow functionality; tidy up
0.0.6: added terrain; camera-relative rendering so reality doesnt get messed up in far coords; !issues: rendering still gets messed up at 131071 (x or z, negative or positive) and rendering ceases to render in any negative coordinate
0.0.5b: tidy up
0.0.5: Added infinte worlds (chunks system); added block placing/breaking; fixed camera up/down angles; fixed movement; made player 2 blocks tall and better hitbox; fixed worlds system
0.0.4: Fixed face culling & occlusion; added worlds system; added chat and commands;
0.0.3: FOV-based Frustum Culling, Distance-based LOD, Face Culling & Occlusion, Spatial Hashing with Block Indices, Fog Effect for Distance Fading
0.0.2: Made slab bigger, bottom face of blocks now exists
0.0.1: Slab of stone blocks you can walk on

## Future features:

These are planned but I don't know when they'll be added. [expand to see]
- Lighting:
light levels to allow for more light sources than just the sun
plan to use 0-15 light levels
also smooth lighting, maybe probably
- In-game HUD UI:
a HUD to visually represent what block the player has selected, and allow regular gameplay without commands
- Sound (maybe)
- Optimizations:
lazy loading,
meshing,
and more.

## Build system:

It's just a makefile. run `make` and that's it. (linux)
You need raylib. And clang.
If you're on windows: why? go on a linux machine (or use WSL2) and use the "windows" make target. (Just run `make windows`)

### Dependencies:

clang, Raylib, and C standard library of course.
How to install:
Arch:
`sudo pacman -S --needed clang base-devel git raylib`
Debian:
`sudo apt update && sudo apt install clang build-essential git libraylib-dev`
Fedora:
`sudo dnf install clang @development-tools git raylib-devel`
RHEL:
`sudo dnf groupinstall "Development Tools"`
`sudo dnf install clang git raylib-devel`
`sudo dnf install epel-release`
Alpine:
`sudo apk add clang build-base git raylib-dev`
Void:
`sudo xbps-install -S clang base-devel git raylib-devel`
FreeBSD:
`sudo pkg install llvm git raylib gmake`
Windows:
Just use WSL.

### Credits:

Idea: Leandro Testa ("texturawasd")
update-version.py, organize-screeshots.py: Alina Kravetska
Raylib: Ramon Santamaria (raysan5)
Everything else: me
(BSD-3-Clause lic.)

(c) 2026 Jimena Neumann