Inspiration

Real hardware is expensive, and actual progress takes time. So, we decided to gamify the experience and simulate some hardware (a spaceship) in a virtual environment, where users can write code to be run on the ship's central processing unit (CPU).

What it does

We have a web based code editor and a view of the universe. Players can write JavaScript code in the editor and deploy them onto the spaceship, similarly to flashing code onto Arduino's Erasable Programmable Read-Only Memory (EEPROM). The code then runs on the ship's CPU and has access to the ship's various hardware components (e.g. engine, sensors) through a General Purpose Input/Output (GPIO) interface.

How we built it

Excalibur.js, TypeScript, HTML, CSS, and free spaceship assets provided generously by AX Assets.

Challenges we ran into

Making physics work was tough because of Math™.

Accomplishments that we're proud of

  • Made physics work.
  • Built a complete prototype that demonstrated our ideas of this project.

What we learned

Game development

What's next for StellarScript

  • WebAssembly (WASM) interpreter based spaceship, allowing every modern programming language to be used
  • Allow users to assemble their own spaceship with different components (e.g. different engines, sensors, decorations)
  • Security improvements (e.g. run user code in a sandbox)
  • Multiplayer mode

Try it Out

The game is deployed at https://stellarscript.study. Only "Sandbox" mode is implemented at the time of writing this post.

We asked AI™ to write a sample code for controlling the spaceship and it actually works:

const ENGINE_LEFT = 0;
const ENGINE_RIGHT = 1;
const SENSOR_LEFT = 2;
const SENSOR_RIGHT = 3;
const WEAPON = 4;
const LOW = 0;
const HIGH = 1;

// This function is called every cycle forever.
function loop() {
  // Read sensor values
  const leftSensorValue = read(SENSOR_LEFT);
  const rightSensorValue = read(SENSOR_RIGHT);

  // Determine if an asteroid is detected
  const isAsteroidDetected = leftSensorValue === 1 || rightSensorValue === 1;

  // If an asteroid is detected, turn the appropriate engine on and shoot a bullet
  if (isAsteroidDetected) {
    if (leftSensorValue === 1) {
      // Asteroid is on the left side, turn left engine on and shoot a bullet
      write(ENGINE_LEFT, HIGH);
      write(ENGINE_RIGHT, LOW);
      write(WEAPON, HIGH);
    } else {
      // Asteroid is on the right side, turn right engine on and shoot a bullet
      write(ENGINE_RIGHT, HIGH);
      write(ENGINE_LEFT, LOW);
      write(WEAPON, HIGH);
    }
  } else {
    // No asteroid detected, move forward by turning both engines on
    write(ENGINE_LEFT, HIGH);
    write(ENGINE_RIGHT, HIGH);
  }
}

StellarScript Global Function References

  • delay(milliseconds: number): void: delay the execution by milliseconds.
  • g_has(name: string): boolean: check if a global variable named name exists.
  • g_get(name: string): any: get the value of the global variable named name.
  • g_set(name: string, value: any): void: set the value of the global variable named name to value. Global variables persist through different executions of the loop() function.
  • print(...args: any[]): void: print the provided values in the "Output" tab.
  • read(pin: number): read a value from the device at the specific GPIO pin. All device pins can be found in constants defined at the top of the code.
  • write(pin: number, value: number): write a value to the device at the specific GPIO pin. All device pins can be found in constants defined at the top of the code.

Links

Built With

Share this project:

Updates