Skip to content

fb new game && fb run game

Write it like BASIC. Ship it like C.

FutureBlitz is a language for making games and tools: plain words and a loop you own, compiled to one native executable through LLVM.

wave.fb
Import std.core

Struct Enemy
    Field name: String
    Field hp: Int
End Struct

Local wave = [Enemy("grunt", 30), Enemy("brute", 80),
              Enemy("boss", 250)]
For i, e In wave
    Print("{i + 1}. {e.name} with {e.hp} hp")
End For

$ fb run wave.fb
1. grunt with 30 hp
2. brute with 80 hp
3. boss with 250 hp

Small programs, real machine code

The same program, both ways

enemies.bb Blitz3D
Type Enemy
    Field name$
    Field hp
End Type

For i = 1 To 3
    e.Enemy = New Enemy
    e\name$ = "grunt " + i
    e\hp = 10 * i
Next

For e.Enemy = Each Enemy
    e\hp = e\hp - 15
    If e\hp <= 0
        Print e\name$ + " is gone"
        Delete e
    Else
        Print e\name$ + " has " + e\hp + " hp"
    EndIf
Next
enemies.fb FutureBlitz
Import std.core
Import std.collections

Class Enemy
    Field name: String
    Field hp: Int

    New(name: String, hp: Int)
        Self.name = name
        Self.hp = hp
    End New
End Class

Local enemies: Enemy[] = []
For i = 1 To 3
    enemies.Add(Enemy("grunt {i}", 10 * i))
End For

For e In enemies
    e.hp -= 15
    If e.hp <= 0
        Print("{e.name} is gone")
    Else
        Print("{e.name} has {e.hp} hp")
    End If
End For
enemies.RemoveAll(Function(e: Enemy) => e.hp <= 0)
$ fb run enemies.fb
grunt 1 is gone
grunt 2 has 5 hp
grunt 3 has 15 hp

The guide for Blitz3D users

Five small stories from making a game

Blitz3D came with a folder of samples that taught a generation. FutureBlitz has one too. Each output here was recorded by running the sample with fb when this site was built.

boss.fb
// A boss fight as a coroutine: each phase is a few lines that wait, and the game's
// frame loop ticks a Scheduler of its own, 60 times a second, so pausing it pauses the fight.
Import std.core
Import std.time

Class Boss
    Field name: String
    Field hp: Int = 300

    New(name: String)
        Self.name = name
    End New
End Class

Global frame = 0

Function Say(text: String)
    Print("frame {frame}: {text}")
End Function

Async Function Fight(boss: Boss)
    Say("{boss.name} wakes up")
    Await Wait(1.Seconds)
    While boss.hp > 150
        Say("{boss.name} swings its hammer ({boss.hp} hp)")
        Await Wait(750.Milliseconds)
    End While
    Say("{boss.name} is angry, and twice as fast")
    While boss.hp > 0
        Await Wait(375.Milliseconds)
    End While
    Say("{boss.name} falls")
End Function

Local boss = Boss("The Warden")
Local gameplay = Scheduler()
gameplay.Run(Fight(boss))
While !gameplay.IsIdle()
    frame += 1
    If frame % 20 == 0 Then boss.hp -= 20     // the player lands a hit
    gameplay.Tick(1.0 / 60.0)
End While
Say("the fight took {frame} frames")
$ fb run boss.fb
frame 0: The Warden wakes up
frame 60: The Warden swings its hammer (240 hp)
frame 105: The Warden swings its hammer (200 hp)
frame 150: The Warden swings its hammer (160 hp)
frame 195: The Warden is angry, and twice as fast
frame 310: The Warden falls
frame 310: the fight took 310 frames

A standard library of 206 modules

The C libraries std links in

SQLite, libcurl, nghttp2, mbedTLS, libuv, PCRE2, utf8proc, zlib-ng, minizip-ng, zstd, lz4, liblzma, xxHash, BLAKE3, Argon2, Monocypher, crypt_blowfish, libtommath, mpdecimal, stb_image, libwebp, nanosvg, md4c. A program links each one only when it calls what's built on it, statically, so a program that uses them is still one file, and fb lists the ones a build links, with their licenses.

Install it, then fb new

terminal

# Linux and macOS

curl -fsSL https://github.com/hlpdev/FutureBlitz/releases/latest/download/install.sh | sh

# Windows, in PowerShell

irm https://github.com/hlpdev/FutureBlitz/releases/latest/download/install.ps1 | iex

# then

fb new hello

cd hello

fb run

Hello, world!

No release is published yet, so the install lines work once the first one is. Until then, build fb from source.