Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 

Repository files navigation

A working Minecraft 1.8.9 server implemented entirely in Excel VBA. Real client with a real protocol and no server software. The process listening on port 25565 is EXCEL.EXE.

It handles the server list ping, login, world data and keep-alives. You join, you spawn on grass, you can walk around and place blocks. Your position updates a cell in the spreadsheet as you move, because at some point I decided 'that would be a fun little thing'.

Why

People have built Minecraft in Excel before. SethBling's version is from 2014 and it's great. Those are all clones of Minecraft though, running inside the spreadsheet, not a server.

I couldn't find anyone that has made Excel speak the actual protocol so a real client can connect to it. So now someone has. And if I'm not the first, it'd be interesting to see what came before.

What it does

Server list ping with MOTD, player count and a favicon

Offline-mode login, no encryption

Flat world, 5x5 chunks of bedrock, dirt and grass

Creative mode, so you can fly and place things

Keep-alives, so the session survives longer than 20 seconds

Live player position written into the sheet

What it doesn't do

Almost everything else. No block updates on the server side, no entities, no mobs, no real physics, no chat commands, no second player. Blocks you place exist only in your client. Walk away and come back and they're still there, because nothing is telling your client otherwise.

It's a server in the sense that a client connects to it and receives a world. Set your expectations accordingly.

Requirements

Windows, 64-bit Excel with VBA. Not Excel for Mac, its VBA is sandboxed and can't open sockets

Minecraft Java 1.8.9, protocol 47

Setup

Download ExcelMCServer.bas

New workbook, save as .xlsm

Alt+F11 for the VB Editor, then File > Import File, select the .bas

Ctrl+G for the Immediate window, type SetupWorkbook, Enter

Back in Excel, click START and allow the firewall prompt

Connect to the machine's IP on port 25565

Optional: I resized the Excel icon in paint on the VM so it's not going in here so put a 64x64 PNG called favicon.png in the same folder as the workbook and it'll show up in the server list. Must be exactly 64x64 or the client drops it.

How it works

The Declare PtrSafe block at the top binds to ws2_32.dll, which is Windows' sockets library. Every program on Windows that touches the network goes through it, Java included.

Everything else is written from nothing, because no VBA library for any of this exists:

VarInts. The protocol's variable width integer format. Needs an unsigned right shift, which VBA doesn't have, so URShift7 fakes it.

Packet framing. Length, then packet ID, then payload. TCP is a stream and not a sequence of messages, so packets arrive split across reads or several at once. DrainPackets buffers until a whole packet is present.

Endianness. The protocol is big-endian, x86 is little-endian, so every multi-byte number gets reversed. Doubles and floats go through CopyMemory because there's no other way to see their bytes in VBA.

State machine. Handshake, then either status or login, then play.

Chunks. The reason this targets 1.8.9 and not a current version. In 1.8, a chunk section is a flat array of (id << 4) | meta shorts, then block light, then sky light. 12,544 bytes for one section plus biome data, and you can send it uncompressed. Modern versions use palette-encoded, bit packed longs and expect zlib. VBA has no zlib. That's a whole different project.

Things that went wrong, for the benefit of anyone attempting this

CInt(25565 - 65536) overflows. VBA's Integer stops at -32768, and 25565 already fits in one, so the wrapping I'd written for high port numbers was both unnecessary and fatal.

VBA's \ operator truncates toward zero, so building big-endian bytes by division silently mangles negative numbers. Every chunk at a negative coordinate went to the wrong place.

A 12KB packet does not fit in a non-blocking socket's send buffer. The first version sent whatever fitted and threw away the rest, which was a fun one to debug.

Building a byte array by repeatedly concatenating it is fine at 30 bytes and unusable at 12,544. The chunk body is built once into a preallocated array and reused.

And many hours lost to macOS, which blocks apps from reaching the local network until you grant permission, and reports the refusal as NoRouteToHost. Every test from Terminal worked, because Terminal already had permission. I thought it was a code bug... wasn't a code bug.

Running it from a Mac

Windows in a VM. If Minecraft can't reach the VM and everything else can, that's the macOS local network permission, and the quickest fix is relaying through Terminal, which already has the grant:

socat TCP-LISTEN:25565,fork,reuseaddr TCP::25565

Then connect to localhost:25565.

Licence

MIT. Do what you like with it.

About

No description, website, or topics provided.

Resources

Stars

22 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages