Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The easiest compiler for a Mindustry Game CPU architecture

I play in a fantastic sandbox tower-defence game Mindustry.

The cool thing is that you can use Game-embedded Processors blocks to control units. You can order them to build blocks, patrol the Map, surround the weakest enemy, heal friends and bring ammunition to turrets.

There are some examples how "programming" of such blocks looks like:

  • https://www.youtube.com/watch?v=6v8Fnt1NEs8
  • https://www.youtube.com/watch?v=ldkwofrGxyE
  • https://www.youtube.com/watch?v=UFK5m6qKT6U

Some "documentation" can be found here:

  • https://www.reddit.com/r/Mindustry/comments/ic9wrm/logic_in_60/
  • https://mindustrygame.github.io/wiki/logic/3-variables/
  • https://www.youtube.com/watch?v=EDfv_oM_TbE

The problem is that the Processor "language" is extremely primitive. There is only one control statement: jump-to-line-if-statement-is-true. There are no if/else statements, no for-loop, no functions and classes. So it's almost impossible to write anything complex using these instructions.

So my idea is to make my own simple compiler from "real" programming language (with if, else, for, function, struct/class) to these primitive instructions and then export it in the Game.

My first idea was to implement JVM or LLVM-IR VirtualMachine to run compiled bytecode in Mindustry, but it looks complex. There are a lot of instructions in these byte-codes.

Then I thought about implementing Lua or simplified Python interpreter, it looks possible but anyway it's a big work :-)

I'm curious about the easiest approach to do it :-) Maybe there are simplified JVM/LLVM-bytecode based on ~10 instructions or some example projects or running Lua/Python on Brainfuck or some limited architecture :-)

==== embedded cpu language ====

so control instructions set are:

  • read - read data from PermanentStorage address to the variable
  • write - write data from variable to PermanentStorage
  • set - set variable data
  • link - to get the i-th element from the array
  • operator op add result x y ~ result=x+y - set variable to the result of arifmethics operation + - * / < > % == min max etc
  • special variable @counter which is a line to the executing line, you can also set the value of this variable to jump to any specific line
  • jump cond lineNo - jump to line lineNo if cond is true

Also it's possible to do some sort of reusable procedures like

op add retAddr @counter 1 # Save where we will continue after the function returns by adding 1 to the counter
set @counter myFunc       # Jump to the line representing myFunc
...
set @counter retAddr      # Return to the line set earlier after the function is called
like image 543
vladimirfol Avatar asked Dec 26 '20 13:12

vladimirfol


People also ask

What programming language does Mindustry use?

Mindustry Logic (mlog) is a scripting language added in v6 for the purpose of introducing more advanced automation and strategy into the game. It is heavily inspired by Assembly languages, where there is only one instruction or operation at a time.


2 Answers

There is already a very useful compiler (called mindcode) for Mindustry: https://github.com/francois/mindcode

The Compiler can be used with this web application: http://mindcode.herokuapp.com/

like image 179
Tom Avatar answered Sep 19 '22 04:09

Tom


It's not possible to implement a full compiler for any language as dynamic memory management isn't really possible. However, https://pypi.org/project/minpiler/ is a good start.

Note the cavate from the site:

You won't be able to use most of the Python. All the restrictions arise from Mindustry processor architecture:

  1. There's no data structures, only scalar values are allowed (floats or opaque objects). The only exception are Memory cells that behave as fixed-size arrays of floats.
  2. You can't access variables indirectly, there're no pointers, no getattr.
  3. Subsequence of former, it's impossible to implement dynamic memory/stack (at least without Memory cells). This makes lists, iterators, classes, closures and other things impossible.
  4. Set of builtins is very restricted, you can only call what you have available in game (M.print, M.draw.clear, etc)
like image 29
Rick Avatar answered Sep 19 '22 04:09

Rick