• Stars
    star
    10,151
  • Rank 3,245 (Top 0.07 %)
  • Language
    C
  • License
    MIT License
  • Created about 11 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A simple Minecraft clone written in C using modern OpenGL (shaders).

Craft

Minecraft clone for Windows, Mac OS X and Linux. Just a few thousand lines of C using modern OpenGL (shaders). Online multiplayer support is included using a Python-based server.

http://www.michaelfogleman.com/craft/

Screenshot

Features

  • Simple but nice looking terrain generation using perlin / simplex noise.
  • More than 10 types of blocks and more can be added easily.
  • Supports plants (grass, flowers, trees, etc.) and transparency (glass).
  • Simple clouds in the sky (they don't move).
  • Day / night cycles and a textured sky dome.
  • World changes persisted in a sqlite3 database.
  • Multiplayer support!

Download

Mac and Windows binaries are available on the website.

http://www.michaelfogleman.com/craft/

See below to run from source.

Install Dependencies

Mac OS X

Download and install CMake if you don't already have it. You may use Homebrew to simplify the installation:

brew install cmake

Linux (Ubuntu)

sudo apt-get install cmake libglew-dev xorg-dev libcurl4-openssl-dev
sudo apt-get build-dep glfw

Windows

Download and install CMake and MinGW. Add C:\MinGW\bin to your PATH.

Download and install cURL so that CURL/lib and CURL/include are in your Program Files directory.

Use the following commands in place of the ones described in the next section.

cmake -G "MinGW Makefiles"
mingw32-make

Compile and Run

Once you have the dependencies (see above), run the following commands in your terminal.

git clone https://github.com/fogleman/Craft.git
cd Craft
cmake .
make
./craft

Multiplayer

After many years, craft.michaelfogleman.com has been taken down. See the Server section for info on self-hosting.

Client

You can connect to a server with command line arguments...

./craft [HOST [PORT]]

Or, with the "/online" command in the game itself.

/online [HOST [PORT]]

Server

You can run your own server or connect to mine. The server is written in Python but requires a compiled DLL so it can perform the terrain generation just like the client.

gcc -std=c99 -O3 -fPIC -shared -o world -I src -I deps/noise deps/noise/noise.c src/world.c
python server.py [HOST [PORT]]

Controls

  • WASD to move forward, left, backward, right.
  • Space to jump.
  • Left Click to destroy a block.
  • Right Click or Cmd + Left Click to create a block.
  • Ctrl + Right Click to toggle a block as a light source.
  • 1-9 to select the block type to create.
  • E to cycle through the block types.
  • Tab to toggle between walking and flying.
  • ZXCVBN to move in exact directions along the XYZ axes.
  • Left shift to zoom.
  • F to show the scene in orthographic mode.
  • O to observe players in the main view.
  • P to observe players in the picture-in-picture view.
  • T to type text into chat.
  • Forward slash (/) to enter a command.
  • Backquote (`) to write text on any block (signs).
  • Arrow keys emulate mouse movement.
  • Enter emulates mouse click.

Chat Commands

/goto [NAME]

Teleport to another user. If NAME is unspecified, a random user is chosen.

/list

Display a list of connected users.

/login NAME

Switch to another registered username. The login server will be re-contacted. The username is case-sensitive.

/logout

Unauthenticate and become a guest user. Automatic logins will not occur again until the /login command is re-issued.

/offline [FILE]

Switch to offline mode. FILE specifies the save file to use and defaults to "craft".

/online HOST [PORT]

Connect to the specified server.

/pq P Q

Teleport to the specified chunk.

/spawn

Teleport back to the spawn point.

Screenshot

Screenshot

Implementation Details

Terrain Generation

The terrain is generated using Simplex noise - a deterministic noise function seeded based on position. So the world will always be generated the same way in a given location.

The world is split up into 32x32 block chunks in the XZ plane (Y is up). This allows the world to be β€œinfinite” (floating point precision is currently a problem at large X or Z values) and also makes it easier to manage the data. Only visible chunks need to be queried from the database.

Rendering

Only exposed faces are rendered. This is an important optimization as the vast majority of blocks are either completely hidden or are only exposing one or two faces. Each chunk records a one-block width overlap for each neighboring chunk so it knows which blocks along its perimeter are exposed.

Only visible chunks are rendered. A naive frustum-culling approach is used to test if a chunk is in the camera’s view. If it is not, it is not rendered. This results in a pretty decent performance improvement as well.

Chunk buffers are completely regenerated when a block is changed in that chunk, instead of trying to update the VBO.

Text is rendered using a bitmap atlas. Each character is rendered onto two triangles forming a 2D rectangle.

β€œModern” OpenGL is used - no deprecated, fixed-function pipeline functions are used. Vertex buffer objects are used for position, normal and texture coordinates. Vertex and fragment shaders are used for rendering. Matrix manipulation functions are in matrix.c for translation, rotation, perspective, orthographic, etc. matrices. The 3D models are made up of very simple primitives - mostly cubes and rectangles. These models are generated in code in cube.c.

Transparency in glass blocks and plants (plants don’t take up the full rectangular shape of their triangle primitives) is implemented by discarding magenta-colored pixels in the fragment shader.

Database

User changes to the world are stored in a sqlite database. Only the delta is stored, so the default world is generated and then the user changes are applied on top when loading.

The main database table is named β€œblock” and has columns p, q, x, y, z, w. (p, q) identifies the chunk, (x, y, z) identifies the block position and (w) identifies the block type. 0 represents an empty block (air).

In game, the chunks store their blocks in a hash map. An (x, y, z) key maps to a (w) value.

The y-position of blocks are limited to 0 <= y < 256. The upper limit is mainly an artificial limitation to prevent users from building unnecessarily tall structures. Users are not allowed to destroy blocks at y = 0 to avoid falling underneath the world.

Multiplayer

Multiplayer mode is implemented using plain-old sockets. A simple, ASCII, line-based protocol is used. Each line is made up of a command code and zero or more comma-separated arguments. The client requests chunks from the server with a simple command: C,p,q,key. β€œC” means β€œChunk” and (p, q) identifies the chunk. The key is used for caching - the server will only send block updates that have been performed since the client last asked for that chunk. Block updates (in realtime or as part of a chunk request) are sent to the client in the format: B,p,q,x,y,z,w. After sending all of the blocks for a requested chunk, the server will send an updated cache key in the format: K,p,q,key. The client will store this key and use it the next time it needs to ask for that chunk. Player positions are sent in the format: P,pid,x,y,z,rx,ry. The pid is the player ID and the rx and ry values indicate the player’s rotation in two different axes. The client interpolates player positions from the past two position updates for smoother animation. The client sends its position to the server at most every 0.1 seconds (less if not moving).

Client-side caching to the sqlite database can be performance intensive when connecting to a server for the first time. For this reason, sqlite writes are performed on a background thread. All writes occur in a transaction for performance. The transaction is committed every 5 seconds as opposed to some logical amount of work completed. A ring / circular buffer is used as a queue for what data is to be written to the database.

In multiplayer mode, players can observe one another in the main view or in a picture-in-picture view. Implementation of the PnP was surprisingly simple - just change the viewport and render the scene again from the other player’s point of view.

Collision Testing

Hit testing (what block the user is pointing at) is implemented by scanning a ray from the player’s position outward, following their sight vector. This is not a precise method, so the step rate can be made smaller to be more accurate.

Collision testing simply adjusts the player’s position to remain a certain distance away from any adjacent blocks that are obstacles. (Clouds and plants are not marked as obstacles, so you pass right through them.)

Sky Dome

A textured sky dome is used for the sky. The X-coordinate of the texture represents time of day. The Y-values map from the bottom of the sky sphere to the top of the sky sphere. The player is always in the center of the sphere. The fragment shaders for the blocks also sample the sky texture to determine the appropriate fog color to blend with based on the block’s position relative to the backing sky.

Ambient Occlusion

Ambient occlusion is implemented as described on this page:

http://0fps.wordpress.com/2013/07/03/ambient-occlusion-for-minecraft-like-worlds/

Dependencies

  • GLEW is used for managing OpenGL extensions across platforms.
  • GLFW is used for cross-platform window management.
  • CURL is used for HTTPS / SSL POST for the authentication process.
  • lodepng is used for loading PNG textures.
  • sqlite3 is used for saving the blocks added / removed by the user.
  • tinycthread is used for cross-platform threading.

More Repositories

1

primitive

Reproducing images with geometric primitives.
Go
12,316
star
2

nes

NES emulator written in Go.
Go
5,352
star
3

Minecraft

Simple Minecraft-inspired program using Python and Pyglet
Python
5,134
star
4

gg

Go Graphics - 2D rendering in Go with a simple API.
Go
4,245
star
5

ln

3D line art engine.
Go
3,228
star
6

pt

A path tracer written in Go.
Go
2,065
star
7

sdf

Simple SDF mesh generation in Python
Python
1,465
star
8

Quads

Computer art based on quadtrees.
Python
1,160
star
9

physarum

Physarum polycephalum slime mold simulation
Go
845
star
10

fauxgl

Software-only 3D renderer written in Go.
Go
842
star
11

hmm

Heightmap meshing utility.
C
551
star
12

Tiling

Tilings of regular polygons.
Python
478
star
13

rbgg

Isolate and remove the background gradient from images of paper.
Go
343
star
14

pack3d

Tightly pack 3D models.
Go
319
star
15

rush

Rush Hour puzzle goodies!
Go
281
star
16

axi

Library for working with the AxiDraw v3 pen plotter.
Python
266
star
17

PirateMap

Procedurally generate pirate treasure maps.
Python
259
star
18

simplify

3D mesh simplification in Go.
Go
242
star
19

ribbon

Ribbon diagrams of proteins in #golang.
Go
240
star
20

Punchcard

Generate GitHub-style punchcard charts with ease.
Python
240
star
21

terrarium

Some code for generating topographic contour maps.
Go
219
star
22

pg

Python OpenGL Graphics Framework
Python
207
star
23

dlaf

Diffusion-limited aggregation, fast.
C++
179
star
24

FeedNotifier

Feed Notifier is a Windows application that resides in the system tray and displays pop-up notifications on your desktop when new items arrive in your subscribed RSS or Atom feeds
Python
163
star
25

CellularForms

An implementation of Andy Lomas' Cellular Forms.
C++
152
star
26

density

Render millions of points on a map.
Go
147
star
27

MisterQueen

A chess engine written in C.
C
141
star
28

meshview

Performant 3D mesh viewer written in Go.
Go
132
star
29

delaunay

Fast Delaunay triangulation implemented in Go.
Go
113
star
30

GraphLayout

Graph drawing using simulated annealing for layout.
Python
110
star
31

Piet

Procedurally Generating Images in the Style of Piet Mondrian
Python
97
star
32

ease

Easing functions in #golang.
Go
85
star
33

AdventOfCode2018

My solutions to the Advent of Code 2018 problems.
Python
81
star
34

iMeme

iMeme is a popular meme generator for Mac OS X
Objective-C
71
star
35

DCPU-16

Python scripts for DCPU-16 emulation.
DCPU-16 ASM
70
star
36

xy

Various utilities for the Makeblock XY Plotter Robot Kit
Python
69
star
37

contourmap

Compute contour lines (isolines) for any 2D data in Go.
Go
67
star
38

demsphere

Generate 3D meshes of planets, moons, etc. from spherical DEMs. (WIP)
Go
66
star
39

GPS

Real-time GPS Satellite Positions in 3D
Python
64
star
40

slicer

Fast 3D mesh slicer written in Go.
Go
61
star
41

AllRGB

Scripts for creating AllRGB images.
Python
60
star
42

mol

Render ball-and-stick models of molecules.
Go
58
star
43

pixsort

Applying the traveling salesman problem to pixel art.
Go
57
star
44

Ricochet

Implementation of Ricochet Robot (Rasende Roboter) including a GUI and a solver
Python
53
star
45

domaincoloring

Domain coloring in Go.
Go
50
star
46

Scale

Beautiful Fractals for Mac OS X.
Objective-C
40
star
47

gorgb

Program to create "allRGB" images.
Go
38
star
48

HelloFlask

A boiler-plate starting point for a Flask web application, including SQLAlchemy, WTForms and Bootstrap.
CSS
37
star
49

Field

Creating computer art by simulating charged particle field lines.
Python
36
star
50

serve

Simple Go file server for command line development use, a la Python's SimpleHTTPServer.
Go
34
star
51

choppy

Chop 3D models in half with a user-defined slice plane.
Go
34
star
52

TWL06

Official Scrabble dictionary packaged into a convenient Python module.
Python
32
star
53

Sync

Code inspired by the book.
Python
31
star
54

tracer

Global illumination path tracer in C++
C++
29
star
55

maps

Work in progress. Render maps in #golang with a simple API.
Go
27
star
56

FutureBlocks

Tetris clone written in QBasic.
Visual Basic
26
star
57

AdventOfCode2019

My solutions for Advent of Code 2019.
Python
25
star
58

HiRISE

Convert HiRISE PDS IMG files to 3D meshes with normal maps.
Python
25
star
59

AdventOfCode2021

My solutions for Advent of Code 2021.
Python
24
star
60

lissaknot

Create 3D models of Lissajous knots.
Go
24
star
61

LoginServer

Online multiplayer game login server for secure user authentication.
Python
23
star
62

pyMeme

Cross-platform meme generator application.
Python
23
star
63

ShortUrl

Python module for generating tiny URLs.
Python
22
star
64

imview

Simple image viewer written in Go + OpenGL.
Go
21
star
65

HelloGL

Basic project structure for an OpenGL application.
C
21
star
66

AdventOfCode2020

My solutions for Advent of Code 2020
Python
20
star
67

PieSlice

Making simple wallpapers out of quarter circles.
Python
20
star
68

GameFrame

Game Frame Simulator
Objective-C
19
star
69

Manhattan

Rendering the buildings of Manhattan using OSM data and NYC shapefiles.
Python
19
star
70

Phrases

Source code for a simple website that generates random, two-word phrases.
HTML
18
star
71

poissondisc

Poisson Disc sampling in Go.
Go
16
star
72

SwtPacMan

Pac-Man clone written in 2005 using Java + SWT.
Java
16
star
73

Mapper

Web app for quickly plotting markers, polylines, polygons, heatmaps, etc. on a map.
JavaScript
15
star
74

Mazes

Maze generation and rendering using Python.
Python
15
star
75

Poker

Python poker hand evaluator
Python
12
star
76

GrayScott

Simple Gray Scott Reaction Diffusion model implemented in C++ and OpenCL
C++
12
star
77

WangTiling

Weighted Wang tiling.
Python
12
star
78

mc

Marching cubes algorithm implemented in #golang.
Go
11
star
79

thumbs

Go binary that watches a folder for images and generates thumbnails of them.
Go
11
star
80

Fireflies

Synchronizing fireflies using JavaScript and D3.
10
star
81

go-airspy

Go wrapper for the libairspy library.
Go
10
star
82

go-embree

Simple golang wrapper for embree using cgo
C++
9
star
83

DrMario

Dr Mario clone in Python and wxPython, including AI
Python
9
star
84

WellPlate

Python + wxPython user interface for 96 and 384 well plates.
Python
9
star
85

triangulate

Polygon triangulation via ear clipping in #golang.
Go
8
star
86

platformer

It's happening!
Go
8
star
87

AdventOfCode2022

My solutions for Advent of Code 2022.
Python
8
star
88

AdventOfCode2023

My solutions to the Advent of Code 2023 puzzles.
Python
7
star
89

Yellow

Visualization for 2015 NYC Yellow Taxi Trips
JavaScript
7
star
90

motion

Constant acceleration motion planner written in Go.
Go
7
star
91

wxSnow

Falling snowflakes on your Windows desktop.
Python
7
star
92

Turing

2-D Turing Machine
Python
7
star
93

colormap

Colormaps for Go.
Go
6
star
94

go-maps

Utilities for rendering maps in Go.
Go
6
star
95

slices2stl

Go
6
star
96

Fractal

Fractals in Python!
Python
6
star
97

TextEditor

Scintilla-based text editor written in Python and wxPython
Python
6
star
98

Boggle

Web-based Boggle clone written using Python and Flask
Python
5
star
99

michaelfogleman.com

Source code for my personal website.
HTML
5
star
100

CurveMesh

Python
5
star