This project is no longer actively maintained!
This project is intended to become a Minecraft Classic clone using HTML 5 technologies, most notably WebGL and WebSockets. No third-party libraries are used, with the exception of glmatrix and socket.io. People who have written similar demos used libraries such as three.js, but it is both foolish and inefficient to use a 3D engine for rendering large amount of blocks.
- js/ - Includes the different modules that make up the functionality of WebCraft.
- media/ - Contains the graphics resources.
- style/ - Contains stylesheets for the HTML front-ends.
- singleplayer.html - The front-end for the singleplayer client.
- multiplayer.html - The front-end for the multiplayer client.
- server.js - The Node.js server code.
WebCraft follows a modular architecture where the World acts as the central data store. Other modules interact with the world to provide rendering, physics, and player control.
graph TD
subgraph Client
P[Player] -->|Updates Pos| W[World]
R[Renderer] -->|Reads Blocks| W
Phy[Physics] -->|Updates Blocks| W
P -->|Input| R
R -->|Picking| W
end
subgraph Network
N[Network Client] <-->|Sync| NS[Network Server]
end
W <--> N
NS <--> WS[World Server]
- World & Renderer: The
Worldnotifies theRendererwhen a block changes viaonBlockChanged, triggering a re-build of the affected chunk. - Physics: Divided into World Physics (gravity for sand/gravel, fluid flow) and Player Physics (collision resolution, jumping).
- Picking: Uses a unique color-buffer rendering technique to determine which block the mouse is hovering over in 3D space.
The two front-ends invoke the available modules to deliver the components necessary for the gameplay and graphics of either the singleplayer or multiplayer experience.
- World.js: The central state container. Manages the 3D block array and players.
- Blocks.js: Definitions for all block types, properties (gravity, fluid, transparency), and vertex generation logic.
- Render.js: WebGL renderer. Manages chunks (VBOs) for performance and handles the camera/picking.
- Physics.js: Simulates environmental effects like fluid spreading and block gravity.
- Player.js: Manages local player state, input (keyboard/mouse), and collision resolution.
- Network.js: Handles WebSocket synchronization between client and server.
- Helpers.js: Shared utilities like the
Vectorclass and collision primitives.
- Node.js (required for multiplayer server)
- A modern web browser with WebGL support.
- Clone the repository.
- Install dependencies (for the server):
npm install
- Singleplayer: Open
singleplayer.htmldirectly in your browser. (Note: Some browsers may require a local web server to load assets correctly). - Multiplayer:
- Start the server:
npm start
- Open
multiplayer.htmlin your browser.
- Start the server:
First a new world is created and the block structure is initialised.
var world = new World( 16, 16, 16 );
world.createFlatWorld( 6 );
The 6 in createFlatWorld here is the line between the ground and the first air layer.
Now that we have a world, we can set up a renderer, which will subsequently divide the world into chunks for rendering.
var render = new Renderer( "renderSurface" );
render.setWorld( world, 8 );
render.setPerspective( 60, 0.01, 200 );
The 8 here determines the XYZ size of one chunk. In this case the entire world consists out of 8 chunks.
To finish the code that deals with world management, we create the physics simulator.
var physics = new Physics();
physics.setWorld( world );
And finally, we add a local player to the game:
var player = new Player();
player.setWorld( world );
player.setInputCanvas( "renderSurface" );
player.setMaterialSelector( "materialSelector" );
That concludes the set-up code. The render loop can be constructed with a timer on a fixed framerate:
setInterval( function()
{
var time = new Date().getTime() / 1000.0;
// Simulate physics
physics.simulate();
// Update local player
player.update();
// Build a chunk
render.buildChunks( 5 );
// Draw world
render.setCamera( player.getEyePos().toArray(), player.angles );
render.draw();
while ( new Date().getTime() / 1000 - time < 0.016 );
}, 1 );
To see how the material selector and canvas can be set-up, have a look at singleplayer.html and style/main.css. Note that the player and physics modules are entirely optional, so you could just as well use this code as a base for making a Minecraft map viewer on your website.