Wasmcraft a compiler from WebAssembly to Minecraft Java Edition datapacks

Overview

Wasmcraft

Have you ever wanted to run C/C++/Rust/WebAssembly applications in Minecraft? No? Well, now you can!

Wasmcraft is a compiler from WebAssembly to Minecraft Java Edition datapacks. Since WebAssembly is a well-supported target for many languages, this means that you can run code written in e.g. C in Minecraft.

This was inspired by Sethbling's Atari 2600 Datapack and is the (much, much improved) spiritual successor to Langcraft.

Demonstration

Here is a short demonstration of a port of Minecraft 4k, compiled using wasmcraft, running in vanilla Minecraft. (That's right: Minecraft in Minecraft).

Alternatively, here is a video of the CHIP-8 Emulator from here running Pong.

Features

  • All integer operations supported
  • (Relatively) efficient code generation
  • Works most of the time

Usage

Let's say we want to run the following program:

/* foo.c */

#include "mcinterface.h"

// Since there is no standard library, we use `_start` instead of `main`
int _start() {
	for (int i = 0; i < 10; ++i) {
		print(i);
	}

	return 0;
}

First, compile it to WebAssembly:

clang foo.c -target wasm32 -nostdlib -o foo.wasm

Ensure you have Rust version >= 1.58 installed, which is very recent. To update Rust, run rustup update. Then, simply navigate to the wasmcraft2 directory and run:

cargo run --release -- ../foo.wasm ../nameofdatapack

This will create a datapack in the folder nameofdatapack, which can be directly placed in the datapacks folder of any Minecraft Java Edition world (this has only been tested on 1.18, but should work on older versions as well).

Note that due to limitations with Minecraft commands, this needs to fill a few chunks near 0, 0 with jukeboxes, so do NOT run this in a world with builds you don't want destroyed!

Run these commands:

/gamerule maxCommandChainLength 1000000 (This only needs to be run once per world)

/reload (This only needs to be run when the datapack is changed while the world is open)

/function wasmrunner:init

/function wasmrunner:_start

And you should see the numbers 0 to 9 printed out in the chat.

Limitations

  • Floating point operations are not supported (yet). Use fixed point operations instead, e.g. libfixmath
  • Bitwise operations and 64-bit divisions are absurdly slow.
  • 8-bit and 16-bit accesses are fairly slow, and all memory accesses have not-insignificant overhead.
  • Manual calls to sleep() have to be inserted in long-running code, because Minecraft can only run a limited number of commands per tick.
  • The API is very limited

License

Licensed under either of

  • MIT License
  • Apache License, Version 2.0
You might also like...
A console and web-based Gomoku written in Rust and WebAssembly
A console and web-based Gomoku written in Rust and WebAssembly

👋 rust-gomoku A console and web-based Gomoku written in Rust and WebAssembly Getting started with cargo & npm Install required program, run # install

WebAssembly development with Trunk & Vite.js

Trunk & Vite.js Demo Trunk is a WASM web application bundler for Rust, and Vite.js is next Generation Frontend Tooling. Ok, they are together now for

darkforest is a console and web-based Roguelike written in Rust and WebAssembly.
darkforest is a console and web-based Roguelike written in Rust and WebAssembly.

darkforest darkforest is a console and web-based Roguelike written in Rust and WebAssembly. Key Features TBA Quick Start TBA How To Contribute Contrib

WebAssembly to Lua translator, with runtime

This is a WIP (read: absolutely not ready for serious work) tool for translating WebAssembly into Lua. Support is specifically for LuaJIT, with the se

A Rust ESP stack trace decoder that can also runs in your browser thanks to WebAssembly
A Rust ESP stack trace decoder that can also runs in your browser thanks to WebAssembly

ESP Stack Trace Decoder A Rust ESP stack trace decoder that can also runs in your browser thanks to WebAssembly. It is composed of a ⌨️ Rust library,

Simple file sharing with client-side encryption, powered by Rust and WebAssembly
Simple file sharing with client-side encryption, powered by Rust and WebAssembly

Hako Simple file sharing with client-side encryption, powered by Rust and WebAssembly Not feature-packed, but basic functionalities are just working.

bn.js bindings for Rust & WebAssembly with primitive-types support

bn.rs bn.js bindings for Rust & WebAssembly with primitive-types support Write Rust code that uses BN use std::str::FromStr; use primitive_types::{H1

A handy calculator, based on Rust and WebAssembly.
A handy calculator, based on Rust and WebAssembly.

qubit 💥 Visit Website To Use Calculator Example 💥 Visit Website To Use Calculator 2 + 2

A simple compile-to-WebAssembly language rewritten in Rust

chasm A very simple compile-to-WebAssembly language You can play with chasm online. This is a rewrite in Rust of the compiler for the language chasm.

Comments
  • does not compile under linux

    does not compile under linux

    wasmcraft2, the thing itself does not compile on my machine. here's a rather meaningless, but kinda long error stack:

       Compiling wasmcraft v0.1.0 (/mnt/dev/wasmcraft2)
    error[E0432]: unresolved import `datapack_common::functions::command_components::Uuid`
     --> src/pack_emitter/mod.rs:4:89
      |
    4 | use datapack_common::functions::{Function, Command, command_components::{FunctionIdent, Uuid, SNbt}};
      |                                                                                         ^^^^ no `Uuid` in `functions::command_components`
    
    warning: unused import: `SimpleLivenessInfo`
     --> src/ssa/lir_emitter.rs:7:101
      |
    7 | use super::{SsaProgram, SsaFunction, SsaBasicBlock, BlockId, reg_alloc::*, liveness::{LivenessInfo, SimpleLivenessInfo}, call_graph::Call...
      |                                                                                                     ^^^^^^^^^^^^^^^^^^
      |
      = note: `#[warn(unused_imports)]` on by default
    
    warning: unused import: `ssa::liveness::print_live_ranges`
     --> src/ssa/reg_alloc.rs:3:46
      |
    3 | use crate::{lir::{Register, DoubleRegister}, ssa::liveness::print_live_ranges};
      |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    warning: unreachable statement
        --> src/pack_emitter/mod.rs:1507:2
         |
    1504 |       return;
         |       ------ any code following this expression is unreachable
    ...
    1507 | /     if dst != lhs {
    1508 | |         code.push(format!("scoreboard players operation {dst} = {lhs}"));
    1509 | |     }
         | |_____^ unreachable statement
         |
         = note: `#[warn(unreachable_code)]` on by default
    
    error[E0616]: field `call_stack` of struct `Interpreter` is private
       --> src/lib.rs:343:31
        |
    343 |         if let Some(frame) = interp.call_stack.iter().rev().next() {
        |                                     ^^^^^^^^^^ private field
        |
    help: a method `call_stack` also exists, call it with parentheses
        |
    343 |         if let Some(frame) = interp.call_stack().iter().rev().next() {
        |                                               ++
    
    error[E0609]: no field `func` on type `&(usize, usize)`
       --> src/lib.rs:344:21
        |
    344 |             indiv_time[frame.func] += 1;
        |                              ^^^^
    
    error[E0616]: field `call_stack` of struct `Interpreter` is private
       --> src/lib.rs:347:23
        |
    347 |         for frame in interp.call_stack.iter().rev() {
        |                             ^^^^^^^^^^ private field
        |
    help: a method `call_stack` also exists, call it with parentheses
        |
    347 |         for frame in interp.call_stack().iter().rev() {
        |                                       ++
    
    error[E0609]: no field `func` on type `&(usize, usize)`
       --> src/lib.rs:348:29
        |
    348 |             if !intrin_visited[frame.func] {
        |                                      ^^^^
    
    error[E0609]: no field `func` on type `&(usize, usize)`
       --> src/lib.rs:349:26
        |
    349 |                 intrin_visited[frame.func] = true;
        |                                      ^^^^
    
    error[E0609]: no field `func` on type `&(usize, usize)`
       --> src/lib.rs:350:28
        |
    350 |                 intrin_cum_times[frame.func] += 1;
        |                                        ^^^^
    
    error[E0609]: no field `func` on type `&(usize, usize)`
       --> src/lib.rs:353:27
        |
    353 |             if !intrin_funcs[frame.func] {
        |                                    ^^^^
    
    Some errors have detailed explanations: E0432, E0609, E0616.
    For more information about an error, try `rustc --explain E0432`.
    warning: `wasmcraft` (lib) generated 3 warnings
    error: could not compile `wasmcraft` due to 8 previous errors; 3 warnings emitted
    warning: build failed, waiting for other jobs to finish...
    
    opened by manen 4
Owner
null
Compiler infrastructure and toolchain library for WebAssembly

Binaryen Binaryen is a compiler and toolchain infrastructure library for WebAssembly, written in C++. It aims to make compiling to WebAssembly easy, f

WebAssembly 6.1k Dec 30, 2022
⚙️ Experimental JVM bytecode to WebAssembly compiler

⚙️ montera Final year university project: a highly experimental JVM bytecode to WebAssembly compiler ⚠️ Do NOT use this for serious projects yet! It's

MrBBot 7 Oct 24, 2022
Lumen - A new compiler and runtime for BEAM languages

An alternative BEAM implementation, designed for WebAssembly

Lumen 3.1k Dec 26, 2022
A prototype WebAssembly linker using module linking.

WebAssembly Module Linker Please note: this is an experimental project. wasmlink is a prototype WebAssembly module linker that can link together a mod

Peter Huene 19 Oct 28, 2022
Sealed boxes implementation for Rust/WebAssembly.

Sealed boxes for Rust/WebAssembly This Rust crate provides libsodium sealed boxes for WebAssembly. Usage: // Recipient: create a new key pair let reci

Frank Denis 16 Aug 28, 2022
WebAssembly on Rust is a bright future in making application runs at the Edge or on the Serverless technologies.

WebAssembly Tour WebAssembly on Rust is a bright future in making application runs at the Edge or on the Serverless technologies. We spend a lot of ti

Thang Chung 129 Dec 28, 2022
WebAssembly modules that use Azure services

This is an experimental repository containing WebAssembly modules running on top of WAGI (WebAssembly Gateway Interface, which allows you to run WebAssembly WASI binaries as HTTP handlers) and using Azure services.

null 7 Apr 18, 2022
WebAssembly Service Porter

WebAssembly Service Porter.

henrylee2cn 12 Dec 12, 2022
🚀Wasmer is a fast and secure WebAssembly runtime that enables super lightweight containers to run anywhere

Wasmer is a fast and secure WebAssembly runtime that enables super lightweight containers to run anywhere: from Desktop to the Cloud, Edge and IoT devices.

Wasmer 14.1k Jan 8, 2023
WAGI: WebAssembly Gateway Interface

Write HTTP handlers in WebAssembly with a minimal amount of work

null 724 Jan 6, 2023