A beginner-friendly scripting language for game development.
Python-like syntax · Closures · Classes with Inheritance · Pattern Matching · Lambda Functions · Bytecode VM · Async/Await · World-Class REPL
Ipp is a dynamically-typed, interpreted scripting language designed to feel like Python and Lua combined, built specifically for game development scripting. It compiles to a custom bytecode VM and also runs on a tree-walking interpreter for rapid development.
v1.5.30 includes Emergency Bug Fixes: For-in loop, pi/e constants, let immutability, str method, static methods, continue in loops, and MultiVarDecl + Dict comprehension.
# Clone the repo
git clone https://github.com/authorss81/Ipp
cd Ipp
# Run a script
python main.py examples/hello_world.ipp
# Start the REPL
python main.pyNo dependencies required. Python 3.8+ only.
pip install ipp-lang
ipp repl
ipp run hello.ippNote: VSCode extension marketplace publish coming soon. Currently available for local installation.
Ipp includes a VSCode extension in vscode-extension/:
cd vscode-extension
npm install
npm run compile
code .Features:
- Syntax highlighting
- 15 code snippets (func, class, for, while, if, match, try, etc.)
- Task runner for
ipp runandipp check - LSP support: go-to-definition, completion, hover, rename
Commands:
ipp lsp— Start LSP serverF5— Run current file
Ipp has a world-class REPL with 30+ built-in commands:
██╗██████╗ ██████╗
██║██╔══██╗██╔══██╗
██║██████╔╝██████╔╝
██║██╔═══╝ ██╔═══╝
██║██║ ██║
╚═╝╚═╝ ╚═╝
Ipp v1.5.4.5
A scripting language for game development
──────────────────────────────────────────
❯ var x = 2 ** 10
→ 1024 0.1ms
❯ var name = "World"
❯ print("Hello, " + name + "!")
Hello, World!
- Builtins: Type
ht+ Tab →http_get,http_post,http_put, etc. - Variables: Type
my+ Tab →my_variable, etc. - Dict keys: Type
person["+ Tab →name,age,city - Fuzzy matching:
htgt→http_get,http_put - REPL commands:
.h+ Tab →.help,.history
| Category | Commands |
|---|---|
| Core | .help, .vars, .fns, .builtins, .modules, .types, .version, .clear |
| Session | .load, .save, .export, .session save/load/clear/export, .sessions |
| History | .history, .last, $_, .history $_ |
| Undo/Redo | .undo, .redo |
| Debugging | .debug start/stop, .break <line>, .watch <expr>, .locals, .stack |
| Inspection | .which <name>, .doc <fn>, .pretty <expr>, .json <expr>, .table <var> |
| Performance | .time <expr>, .profile |
| Shell | ! <cmd>, .pipe <cmd>, .cd <dir>, .ls [dir], .pwd |
| Customization | .theme dark/light/solarized, .prompt dir/time/full, .alias, .bind |
| Code | .edit, .format <expr>, .search <kw>, .examples, .tutorial, .plugin load |
.prompt ipp— Default prompt (❯).prompt dir— Show current directory ((Ipp) ❯).prompt time— Show current time ([14:30:00] ❯).prompt full— Show time + directory ([14:30:00] C:\Ipp ❯)
.theme dark— Dark theme (default).theme light— Light theme.theme solarized— Solarized theme
var x = 10 # mutable
let y = 20 # immutable binding
var name: string = "Ipp" # optional type annotationvar score = 0
score += 10
score *= 2
score -= 5func greet(name) {
return "Hello, " + name
}
# Named arguments
greet(name="Alice", greeting="Hi")
# Closures
func make_counter() {
var count = 0
return func() {
count = count + 1
return count
}
}
var counter = make_counter()
print(counter()) # 1
print(counter()) # 2var double = func(x) => x * 2
print(double(5)) # 10class Animal {
func init(name) {
this.name = name
}
func speak() {
print(this.name + " makes a sound")
}
}
class Dog : Animal {
func speak() {
print(this.name + " says woof!")
}
}
var dog = Dog("Rex")
dog.speak() # Rex says woof!var x = 2
match x {
case 1 => print("one")
case 2 => print("two")
case 3 => print("three")
default => print("other")
}try {
var result = risky_operation()
} catch e {
print("Error: " + e)
} finally {
print("Cleanup")
}var squares = [x*x for x in 1..10]
var evens = [x for x in 1..20 if x % 2 == 0]var name = user_name ?? "Anonymous"var status = age >= 18 ? "adult" : "minor"var a, b = [1, 2]
print(a) # 1
print(b) # 2class Vector {
func init(x, y) {
this.x = x
this.y = y
}
func __add__(other) {
return Vector(this.x + other.x, this.y + other.y)
}
}class Point {
func init(x, y) {
this.x = x
this.y = y
}
func __str__() {
return "(" + this.x + ", " + this.y + ")"
}
}
var p = Point(3, 4)
print(p) # (3, 4)print, len, type, input, exit, assert, str, int, float, bool, to_number, to_int, to_float, to_bool, to_string, abs, min, max, sum, range
sin, cos, tan, asin, acos, atan, atan2, log, log10, degrees, radians, pi, e, sqrt, pow, round, floor, ceil, lerp, clamp, distance, normalize, dot, cross, sign, smoothstep, move_towards, angle, factorial, gcd, lcm, hypot, floor_div
random, randint, randfloat, choice, shuffle
upper, lower, strip, split, join, replace, replace_all, starts_with, ends_with, find, index_of, char_at, substring, count, contains, split_lines, ascii, from_ascii
read_file, write_file, append_file, file_exists, delete_file, list_dir, mkdir
json_parse, json_stringify, xml_parse, xml_to_string, yaml_parse, yaml_to_string, toml_parse, toml_to_string, csv_parse, csv_parse_dict, csv_to_string, regex_match, regex_search, regex_replace, hash
md5, sha256, sha1, sha512, base64_encode, base64_decode, gzip_compress, gzip_decompress
keys, values, items, has_key, set, deque, ordict, PriorityQueue, Tree, Graph, uuid4, uuid1
http_get, http_post, http_put, http_delete, http_request, http_serve, ftp_connect, ftp_disconnect, ftp_list, ftp_get, ftp_put, smtp_connect, smtp_disconnect, smtp_send
websocket_connect, websocket_send, websocket_receive, websocket_close
url_parse, url_build, url_encode, url_decode, url_query_parse, url_query_build
time, sleep, clock, datetime, os_platform, os_cwd, env_get, env_set, path_dirname, path_basename
printf, sprintf, scanf, logger, thread, thread_sleep, thread_current, argparse
vec2, vec3, color, rect, complex
next, is_generator
async_run, create_task, is_coroutine, sleep
seed, normal, now, delta, format_duration, from_hex, to_hex, blend, hsl, ease_in, ease_out, bounce, spring, read_lines, words, truncate, pad_left, pad_right, reverse, binary_search, group_by, zip_with, find_all, sub, escape, glob, pathfind, neighbors, flood_fill, assert_eq, inspect
Ipp supports async/await with a built-in event loop:
async func fetch_data(url) {
print("Fetching:", url)
sleep(0.1)
return "data from " + url
}
var coro = fetch_data("https://example.com")
var result = async_run(coro)
print(result) # data from https://example.comasync func worker(name, delay) {
print(name, "started")
sleep(delay)
print(name, "finished")
return name + " done"
}
var r1 = async_run(worker("Worker1", 0.01))
var r2 = async_run(worker("Worker2", 0.02))| Function | Description |
|---|---|
async_run(coro) |
Run a coroutine and wait for result |
create_task(coro) |
Create and run a coroutine task |
is_coroutine(obj) |
Check if object is a coroutine |
sleep(seconds) |
Sleep for given seconds (awaitable) |
Ipp supports generator functions using the yield keyword:
func count_up() {
var i = 0
while i < 5 {
yield i
i = i + 1
}
}
var gen = count_up()
print(next(gen)) # 0
print(next(gen)) # 1
print(next(gen)) # 2func fibonacci(n) {
var a = 0
var b = 1
var count = 0
while count < n {
yield a
var temp = a
a = b
b = temp + b
count = count + 1
}
}
for n in fibonacci(10) {
print(n) # 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
}var gen = count_up()
print(is_generator(gen)) # true
print(is_generator(42)) # falsevar res = http_get("https://httpbin.org/get")
print(res["status"])
print(res["body"])
var post_res = http_post("https://httpbin.org/post", "data=value")func handler(method, path, headers, body) {
return (200, {"Content-Type": "text/plain"}, "Hello from Ipp!")
}
http_serve(handler, "localhost", 8080)var ftp = ftp_connect("ftp.example.com", "user", "pass")
var files = ftp_list(ftp)
ftp_get(ftp, "remote.txt", "local.txt")
ftp_disconnect(ftp)var smtp = smtp_connect("smtp.gmail.com", 587, true, "user@gmail.com", "password")
smtp_send(smtp, "user@gmail.com", "recipient@example.com", "Subject", "Body")
smtp_disconnect(smtp)var pq = PriorityQueue()
pq.push("low", 3)
pq.push("high", 1)
pq.push("medium", 2)
print(pq.pop()) # high
print(pq.pop()) # mediumvar root = Tree("root")
root.add_child(Tree("child1"))
root.add_child(Tree("child2"))
print(root.traverse_preorder())
print(root.traverse_bfs())var g = Graph()
g.add_edge("A", "B", 1)
g.add_edge("B", "C", 2)
g.add_edge("A", "C", 4)
print(g.shortest_path("A", "C")) # [A, B, C]| Version | Focus |
|---|---|
| v1.3.0 | String interpolation, REPL redesign |
| v1.3.1 | Performance optimization |
| v1.3.2 | VM upvalues, Set type, bug fixes |
| v1.3.3 | Bug fixes + Standard Library + Networking (HTTP/FTP/SMTP) |
| v1.3.4 | Comprehensive stdlib testing (130+ builtins) |
| v1.3.5 | Regex fix + REPL color fix |
| v1.3.6 | VM compatibility tests + REPL warning |
| v1.3.7 | REPL enhancements (.load, .save, .doc, .time, .which, .undo, .profile, .alias, .edit, .last) |
| v1.3.8 | HTTP Server, WebSocket, PriorityQueue, Tree, Graph |
| v1.3.9 | REPL error handling (smart suggestions, highlight fix, .colors fix) |
| v1.3.10 | REPL Intelligence (tab completion, debugger, pretty printing, shell integration, themes) |
| v1.4.0 | Generator functions (yield) + VM Bug Fixes (all 7 VM bugs fixed) |
| v1.4.1 | Error Documentation + Error Reference Guide (ERRORS.md) |
| v1.4.2 | Tutorial Documentation + Getting Started Guide (TUTORIAL.md) |
| v1.4.3 | PyPI Publishing + pip install ipp-lang |
| v1.5.0 | Async/Await + Coroutines + Event Loop + 31 New Builtins |
| v1.5.1 | VSCode Extension + LSP (snippets, task runner, hover, completion) |
| v1.5.2 | WASM Backend Infrastructure + Web Playground |
| v1.5.3 | 2D Canvas API (Tkinter) + WebGL Bindings |
| v1.5.4.3 | Easy Enhancements (.html, .hist, better errors) |
| v1.5.4.4 | Medium Features (.bg, .jobs, .plot, .async) |
| v1.5.4.5 | Advanced Features (.serve, .compare, REPL server) |
| v1.5.4.6 | Expert Features (Plugins, ML autocomplete) |
| v1.5.5 | 3D Math (vec4, mat4, quat) + Scene Graph (Scene, Node, Camera, Mesh, Light) |
| v1.5.6 | 3D Primitives (mesh_cube, mesh_sphere, mesh_plane) |
| v1.5.7 | 3D Visualization (wireframe, point cloud rendering via canvas) |
| v1.5.8 | Performance & Profiling (memory_info, benchmark, gc_stats) + Full OpenGL |
| v1.5.9 | Error Handling & Debugging (get_stack_trace, error_info, breakpoints) |
| v1.5.10 | Standard Library (math_degrees, math_gcd, fs_exists, date_timestamp) |
| v1.5.11 | Module System (module_cache_info, import_module, list_exports) |
| v1.5.12 | Documentation & Testing (doc, apidoc, test_report, benchmark_full) |
| v1.5.13 | Final Polish (cleanup_check, perf_tips, health_check, version_info) |
| v1.5.14 | Critical Bug Fixes (append, pop, insert, remove, clear + VM global_env fix) |
| v1.5.15 | Syntax Additions (Lambda with func keyword, Match expression, Enum, else in match) |
| v1.5.16 | VM/Performance (for-loop in VM works, .cache command, wasm_run function) |
| v1.5.17 | Missing Features (HTML templates, f-strings, decorator @, event_loop, future, Unicode fix) |
| v1.5.18 | PyPI Release Polish (workflow fix, documentation update) |
| v1.5.19 | Polish (OpenGL shaders, async completion) |
| v1.5.20 | Polish (OpenGL restored, data structures verified) |
| v1.5.21 | Emergency Fixes (for-in loop in VM) |
| v1.5.22 | Emergency Fixes (pi, e constants) |
| v1.5.23 | Emergency Fixes (let immutability) |
| v1.5.24 | Emergency Fixes (str method) |
| v1.5.25 | Emergency Fixes (static methods) |
| v1.5.26 | Emergency Fixes (continue in while/for loops + VM perf) |
| v1.5.27 | Emergency Fixes (continue in for-in loops) |
| v1.5.28 | Emergency Fixes (MultiVarDecl in VM) |
| v1.5.29 | Fixes (list comprehension in interpreter) |
| v1.5.30 | Emergency Fixes (dict comprehension) |
| v1.5.31 | Fixes (global cache hash collision) |
| v1.5.31 | Emergency Fixes (global cache hash collision) |
| v1.5.32 | Emergency Fixes (SET_INDEX stack fix) |
| v1.5.33 | Syntax (do-while) + Interpreter bug fix |
| v1.5.34 | Exception (multiple catch blocks) |
| v1.5.35 | Syntax (variadic parameters) |
| v1.5.36 | Syntax (f-strings) |
| v1.5.37 | Fix (VM import system) |
| v1.5.38 | Fix (spread operator) |
| v1.6.0 | Feature (operator overloading) |
| v1.6.1 | Feature (exception type hierarchy) |
| v1.6.2 | Feature (decorator execution) |
| v1.6.3 | Feature (multiple return values) |
| v1.6.4 | Feature (named function arguments) |
| v1.6.5 | Feature (property accessors) |
| v1.6.6 | Feature (signal/event system) |
| v1.6.7 | Feature (list slicing) |
| v1.6.8 | Feature (Matrix4x4 + Quaternion) |
| v1.6.9 | Feature (async/await in VM) |
| v1.6.10 | Fix (IppSet attribute) |
| v1.6.11 | Fix (TAIL_CALL crash) |
| v1.6.12 | Feature (fluent list methods) |
| v1.6.13 | Feature (string format) |
| v1.6.14 | Feature (bytecode caching) |
| v1.6.15 | Feature (static linter) |
| v1.7.0 | Interpreter (archive) |
| v1.7.1 | Testing (opcode unit tests) |
| v1.7.2 | Error Quality (line numbers + call stacks) |
| v1.7.3 | Package Manager (ippkg) |
| v1.7.4 | LSP (completion + diagnostics) |
| v1.7.5 | WASM Backend (real implementation) |
| v2.0.0 | Package Manager + Full Ecosystem + Game Engine |
# Run all regression tests
python tests/regression.py
# Run a single test
python main.py run tests/v1_3_10/test_repl_intelligence.ippAll 37 test suites pass with zero failures.
See CONTRIBUTING.md for guidelines.
Fork → Branch → Fix → Pull Request
MIT License — see LICENSE for details.