Created
June 28, 2021 04:36
-
-
Save laverdet/b58d691cbd317d11f54324230fae49ea to your computer and use it in GitHub Desktop.
Screeps WebAssembly module demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let i32; | |
let u8; | |
let creeps; | |
export function initialize(wasm) { | |
const { memory } = wasm.exports; | |
const reset = () => { | |
i32 = new Int32Array(memory.buffer); | |
u8 = new Uint8Array(memory.buffer); | |
}; | |
reset(); | |
wasm.exports.memory.addGrowCallback?.(reset); | |
} | |
export function evaluate(string) { | |
return eval(String.fromCharCode(...u8.subarray(string, u8.indexOf(0, string)))); | |
} | |
export function getTime() { | |
return Game.time; | |
} | |
export function findCreeps(addr) { | |
creeps = Object.values(Game.creeps); | |
for (let ii = 0; ii < creeps.length; ++ii) { | |
i32[(addr >>> 2) + ii * 2] = creeps[ii].pos.x; | |
i32[(addr >>> 2) + ii * 2 + 1] = creeps[ii].pos.y; | |
} | |
return creeps.length; | |
} | |
export function dispatchMoveIntent(creep, direction) { | |
return creeps[creep].move(direction); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <ctime> | |
#include <iostream> | |
#include <random> | |
#define IMPORT(module, symbol) __attribute__((import_module(module), import_name(symbol))) | |
#define EXPORT extern "C" __attribute__((used)) | |
struct Creep { | |
int x, y; | |
}; | |
IMPORT("./binding.js", "evaluate") int evaluate(const char* source); | |
IMPORT("./binding.js", "getTime") int get_time(); | |
IMPORT("./binding.js", "findCreeps") int find_creeps(Creep creeps[]); | |
IMPORT("./binding.js", "dispatchMoveIntent") int dispatch_move_intent(int creep, int direction); | |
EXPORT void loop() { | |
// Initialize random | |
std::random_device rd; | |
std::mt19937 gen{rd()}; | |
std::uniform_int_distribution distrib(1, 8); | |
// Log current time, takes TZ environment into account | |
const auto time = std::time(nullptr); | |
char time_str[100]; | |
if (std::strftime(time_str, sizeof(time_str), "%c", std::localtime(&time))) { | |
std::cout << "Starting tick[" << get_time() << "] @ " << time_str << '\n'; | |
} | |
// Spawn creeps | |
evaluate("Game.spawns.Spawn1.createCreep([ MOVE ])"); | |
// Move creeps in a random direction | |
Creep creeps[16]; | |
const auto length = find_creeps(creeps); | |
for (int ii = 0; ii < length; ++ii) { | |
const auto move = distrib(gen); | |
std::cout << "Moving creep[" << creeps[ii].x << ", " << creeps[ii].y << "] -> " << move; | |
std::cout << " = " << dispatch_move_intent(ii, distrib(gen)) << '\n'; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export { loop } from './loop.wasm?TZ=CST+6'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# emcc: `-fwasm-exceptions` and node: `--experimental-wasm-eh` are available but not super well | |
# supported right now, so C++ exceptions will exit the wasm runtime via a JS exception. | |
CXX = em++ | |
LD = emcc | |
CXXFLAGS = -O3 -std=c++20 | |
EMFLAGS = -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s ALLOW_MEMORY_GROWTH=1 --no-entry | |
loop.wasm: loop.o | |
%.wasm: %.o | |
$(LD) -o $@ $^ $(EMFLAGS) | |
.PHONY: clean | |
clean: | |
$(RM) *.o *.wasm |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment