AI DISCLAIMER | Introduction | Features | Roadmap | Setup | Usage | Docs | Building & Contributing
Prism is a W.I.P modular source transpiler rewrite aimed to make it as simple as possible to turn language A into language B without relying on AI to do it for you (yes, I realize the irony of saying that). Currently supports Luau -> Java and a Luau Hytale modding API as a proof-of-concept.
This repo is in a very alpha state, so don't just expect major bugs, but ACTIVELY REPORT THEM!!! On the same vein, don't hesitate to ask or PR for features you want to see! This is a public repo, after all.
Until 1.0, Prism's API will likely be extremely malleable as I add more features. If you depend on this for whatever reason, remember to lock down versions in your dependency files, folks.
This repo (down to even its name) was almost entirely generated by AI because I don't have the intellect or time to learn how to make something of this scale. I don't even know how to code in Kotlin lol. However, that doesn't mean I told Claude "Make a general-purpose modular language translator" and screwed off. That would be stupid. In reality, I told Claude "make a general-purpose modular language translator" and tacked "make no mistakes" to the end because I'm not an AI rookie.
Unfortunately, I had to constantly work and micro-manage the AIs because they kept making mistakes even after being told not to. Smh... As such, I like to think I spent upwards of 3,000 Opus 4 credits over the course of 2ish months to get this hobby project to an admittedly buggy state. Planning-wise, this was refactored from the ground up 2-3 times, and many days were spent planning how every feature would work in this repo... and it's still nowhere near done. There are 6 planned implementation stages (or "layers," as the AIs decided to call it), and this repo is most of the way through layer 4 or so. You can see more details on what that sentence actually means further down in this readme.
Finally, thanks a ton to AWS' Kiro, who was the primary AI I used for this project, since Amazon amazingly gives me and other qualifying students Claude AI credits for free every month. No, they did not tell me to say that, as I doubt they even know who I am. However, 1000 (yes, 1,000) credits of AI to spend every month is the best deal since sliced bread and I figured that I shouldn't gatekeep it. For those eligible, you're welcome. To put in perspective how much that is, I'm sure this entire project could have been done with 1/3 of the credits that I ended up spending if I had a better grasp of how to manage these AIs near the beginning, but being dumb and learning from your mistakes is kinda what a student does. But regardless, check them out if you can!
Outside of Kiro, I used GitHub Copilot's Student plan, Zed, and ChatGPT to build out the program. For planning, I used Web ChatGPT 5.3 Instant (via school), Web Gemini 3.1 Pro (via school), and Web Claude Sonett (via free tier) to strengthen the design Kiro and I initially came up with every time I had to restart the project (which was 2 or 3 times). ChatGPT was critical for research/brainstorming since I had enough tokens/responses to endlessly debate/ideate with it, Claude was great for audits/gap-finding when I was able to get 1 response every 5 hours, and Gemini... well, Gemini sucked. Both on the web and through GitHub Copilot, Gemini sucked really badly. Don't use Gemini to ideate/code complex things. Finally, the wiki, some sections of the readme (with heavy corrections by me), and some of the docs were one-shotted by Cursor. Maybe they would have done more, but their monthly free rate limit was one-shotted alongside it. If it sucks, blame Cursor.
Prism is a modular, platform-agnostic source transpiler framework for programming languages. In better terms, it turns code A into code B.
Specifically, it parses source code, converts it to a language-agnostic Internal Representation (IR) nodes through interchangeable language modules, and emits source code in a target language via another plug-and-play backend.
Prism also supports templates, which let you flexibly translate code to fit whatever framework you want inside your conversion target of choice.
As a proof of concept, Prism currently only directly supports the transpilation of Luau source to Java source. To test the modular profile system, Java compilation also only supports generic compilation and Hytale plugin compilation. However, Prism is supposed to be completely modular, so theoretically any language or framework can be supported modularly without directly interacting with the core or other modules.
I'm sure this is a question that will be asked because it's one I asked myself as well. After thinking about it, 3 big reasons come to mind:
-
Because AI can only translate things that exist in both languages. If you want to use a library, mod a game, or use the endpoints in an application that aren't available in your language of choice, AI can't help you much there because there is no code for it to translate in the first place. Historically, that meant that you'd have to reinvent the syntax and functionality in your language of choice or ask an AI to do it for you. With Prism, you only need to do half of that, and assuming a target module exists, it won't even be that bad.
-
Because AI is too slow to satisfy the aspirations I want this repo to achieve. Specifically, I want the ability to seamlessly edit any language as if it were my favorite one. While a good bit of that is kinda possible with AI, the ability to debug code from a transpiled language via a fully-featured debugger is literally impossible. Machines interpret too fast, so you need a machine to do it for you.
-
Because AI is freaking expensive and unpredictable. At least when it's done via code, it will consistently fail instead of doing what it wants. Also, some people really don't like AI touching their stuff. Though as you might be able to guess, I am the farthest away from those "some people" even though I probably should.
Imagine a world where anyone from any coding language background can contribute to the same source. That will never happen without someone grumbling about the terrible code quality, but I'm determined to get as close to that idealism as I can. Eventually. Maybe. One day.
Prism is currently being rolled out in 6 "stages". As of writing, we are midway through stage after mostly being done with stage 4. Features-wise, this is what that means:
Core transpilation (Layer 0)
- Parse Luau source and generate generic Java output
- Select routes with
--routeand fall back across chained backends - Gate profile promotion using route capability manifests
- Intermediate output with
--stage ast|ir|codegen|complete - Stdin input with
--stdin --language luau
Compliance control plane (Layer 1)
--compliancemode with strictness enforcement- Route manifests (
--route-manifest) pinning implementation coordinates and capability overrides - Exclusion manifests (
--exclusion-manifest) with ISO-8601 expiry dates - Machine-readable compliance reports (
--report) with violation counts and excludedBy links - Source-language alias resolution through route manifests
- Three-step capability construction with override validation
Project discovery and map-reduce (Layer 2)
- Directory-mode transpilation with
--input <dir> - Deterministic source enumeration via normalized module IDs
- Module dependency graph construction with cycle detection from parser-produced IR
- Static export metadata indexing from parser-produced IR
- Immutable
ProjectTranspileContextinjected into every worker - Sequential reduce phase with duplicate plugin identity detection
Hytale profile — manifest-driven authoring (Layer 3D)
- All Hytale features authored through
return hytale.plugin { ... }manifest - Plugin entry point promotion from manifest metadata
- Command registration from manifest
commands = { ... }entries - Event handler promotion from manifest
events = { ... }entries - ECS component promotion from manifest
components = { ... }entries - ECS resource promotion from manifest
resources = { ... }entries - Registry entry promotion from manifest
registries = { ... }entries - Template 2.0 descriptor packs with deterministic override order (
--templates) - Multi-file output plans with slot contributions and resource outputs
- Hytale output remains API-mapping gated; compile verification arrives in Layer 5
--route java(without Hytale profile) produces generic Java with zero Hytale imports@prism/hytaleLuau stub for editor/tooling type support
Luau runtime semantics (Layer 4A)
- Truthiness:
if x then→if (Luau.isTruthy(x))— onlynil/falseare falsy - Table classification: sequential →
List.of(), keyed →Map.of(), mixed →LuauTable - Nil-delete:
t[k] = nil→t.remove(k)(nott.put(k, null)) - pairs/ipairs:
pairs(t)→.entrySet()iteration,ipairs(t)→ indexed iteration - Dynamic equality: non-literal
==/~=→Luau.equals(a, b) - Pattern matching:
string.match/string.find→Luau.match()/Luau.find() - Runtime capability validation against
prism-runtime-javamanifest
Loops, varargs, and runtime helpers (Layer 4B)
- Numeric for loops: int/double vars, zero/NaN step diagnostics, dynamic-sign guards
- Parallel assignment: all RHS into temporaries before any LHS write
- Multiple return / vararg:
TailExpandArgument,VarargExpression - String byte length, locale-independent case conversion
- Bitwise: unsigned-32 lowering with
& 0xFFFFFFFFLmask - Function references with higher-arity adapter capability
Transpilation policy (Layer 4C)
--assumption-level conservative|proven|inferred|aggressive--provenance none|reversible- Public
Luau.*facade for readable generated code - Directory-mode discovery uses frontend/IR-backed require/export extraction; regex is limited to legacy tests and non-semantic validation chores
- OutputPolishPass for post-generation validation
- Prism-Luau reverse contract documentation
Source-level conformance and boundary cleanup (Layer 4D)
- Hytale/profile nodes removed from core IR — carried as
IRNode.ExtensionArtifactwrappingHytaleModelNode target-javahas zero Hytale handling — fully generic Java emission- CLI uses ServiceLoader-based discovery — no hard-coded Hytale construction
- Template matching uses profile model kind names instead of core IR node types
- Event handler output uses Template 2.0 handler classes + registration slots
- Command output uses Template 2.0 command classes + registration slots
- Source-level conformance fixtures validate real
.luau→ compiled Java
Note that this is mostly just a high-level summary. For more details, check out the Changelog
As stated before, this repo is following a 6-layered implementation plan before it can be considered "1.0." That's not to say that this plan will be followed to a Tee (as feature creep and overscoping are things I'm terrible at), but if you want to know a rough approximation of the Repo's state, it looks like this:
-
Layer 1 - Compliance control plane (100%): Manifests, strictness, exclusion handling, and machine-readable reports.
- Manifest parsing/validation: 100%
- Strictness evaluator and exclusion matching: 100%
- Compliance report pipeline integration: 100%
-
Layer 2 - Project discovery + map/reduce (100%): Deterministic module indexing, context injection, and reduce-phase aggregation.
- Module normalization and discovery: 100%
- Dependency/export metadata extraction: 100%
- Shared contribution reduce pipeline: 100%
-
Layer 3 - Hytale authoring and profile expansion (100%):
hytale.plugin { ... }authoring model and profile feature anchors.- Manifest-driven Hytale recognizer: 100%
- Commands/events/components/resources/registries/assets promotion: 100%
- Generic Java isolation (
--route javastays Hytale-free): 100%
-
Layer 4 - Luau semantic fidelity + boundary cleanup (92%): Runtime semantics and source-level conformance mostly complete, with parity holes still open.
- 4A/4B runtime semantics (truthiness/tables/loops/varargs/strings/bitwise): 100%
- 4C transpilation policy and provenance: 100%
- 4D source-level conformance + boundary cleanup: 82%
- 4E Template 2.0 profile rendering: 100%
-
Layer 5 - Hytale API compile verification (23%): Partial classpath and compile-shape plumbing exists, but full feature-gated verification and CI policy are incomplete.
- API classpath/property integration: 65%
- Compile-compatibility fixture depth: 30%
- Hytale namespace/import parity gates: 20%
- CI artifact policy and drift checks: 0%
-
Layer 6 - Tooling bridge + optional AI fallback (0%): Not started.
- Observer/tooling bridge surface: 0%
- Optional AI fallback provider contracts: 0%
If you want to see the actual implementation plan itself, check out The Task Document.
Prerequisites | Quick Setup | Manual Setup
- Java 21+ — Required for building and running Prism. Temurin recommended.
- Rust/Cargo — Required for building the
full_moonCLI shim (Luau parser). Install via rustup orwinget install --id Rustlang.Rustup.
Verify your environment:
java -version # Should show 21+
rustc --version # Should show 1.x
cargo --version # Should show 1.x- Clone the repo
git clone https://github.com/Jediweirdo/Prism.git- Navigate inside it
cd [Insert Saved Repository Name Here]- Run the setup scripts inside it.
- On Windows, it's:
.\scripts\setup.ps1- And on linux/Mac, run this instead:
./scripts/setup.shThe setup script should automatically:
- verify Java and Rust/Cargo
- build
full_moon - prompt for
full_moonpath and optionalHytaleServer.jar - write
prism.local.properties - run tests
If not, see the Manual Setup instructions:
- Build the full_moon shim (Luau parser):
cd lang-luau/full-moon-cli
cargo build --releaseThe binary is built to lang-luau/full-moon-cli/target/release/full_moon.exe (Windows) or full_moon (Linux/Mac). The project-local path is configured in gradle.properties and passed to tests automatically.
- Optionally install to cargo bin (makes
full_moonavailable globally):
# Windows
Copy-Item lang-luau\full-moon-cli\target\release\full_moon.exe $env:USERPROFILE\.cargo\bin\full_moon.exe# Linux/Mac
cp lang-luau/full-moon-cli/target/release/full_moon ~/.cargo/bin/full_moon- Configure external tool paths (optional):
Rename prism.local.properties.example to prism.local.properties and customize:
prism.fullMoonPath=C:\\Users\\you\\.cargo\\bin\\full_moon.exe
prism.hytaleServerJarPath=C:\\path\\to\\HytaleServer.jar
prism.currentImplementationLayer=5The gradle.properties file contains default paths. prism.local.properties overrides are gitignored.
If you're wondering, prism.currentImplementationLayer is mainly for tests to ensure Prism only runs the tests that it's scoped to handle. Once full implementation is done and stable, it'll be deprecated.
- Hytale Server JAR (optional, for compile-compatibility tests):
If you have access to HytaleServer.jar, set prism.hytaleServerJarPath in prism.local.properties. This enables compile-compatibility tests that verify generated Java output compiles against the real Hytale API. The JAR is never committed to the repo.
- Build and test:
.\gradlew.bat build # Windows
.\gradlew.bat test # Run all testsCLI | Luau API | Hytale API | Wiki & Other Important Docs
.\gradlew.bat :cli:run --args="--input [mod name] --route [target backend] --output [Output Directory] --stage codegen"If --output isn't specified, it automatically outputs the transpiled Java file into the working directory
.\gradlew.bat :cli:run --args="--input my_mod.luau --route [Main target] --route [Target transpiler that runs if the main one fails] --stage codegen"Note that you can keep adding as many routes as you want, and they will keep falling back until there are no more left.
.\gradlew.bat :cli:run --args="--input [Input directory] --route [Main target] --output [Output Dir]".\gradlew.bat :cli:run --args="--input src/ --route java:hytale --route java --compliance --route-manifest route.json --exclusion-manifest exclusions.json --report report.json"| Flag | Description |
|---|---|
--input <file|dir> |
Source file or directory (required unless --stdin) |
--stdin |
Read source from terminal's stdin instead of making a new file (requires --language) |
--output <dir> |
Output directory (default: current directory) |
--language <id> |
Source language (inferred from extension if omitted) |
--route <target[:profile]> |
Target route (repeatable; first=primary, rest=fallbacks) |
--templates <dir> |
Template directory (repeatable; later overrides earlier) |
--stage <value> |
Stop after stage: ast | ir | codegen | complete |
--concurrency <n> |
Worker thread count (default: available processors) |
--verbose |
Print all pipeline events |
--compliance |
Enable compliance mode (strictness enforcement) |
--route-manifest <file> |
Route manifest JSON file |
--exclusion-manifest <file> |
Exclusion manifest JSON file |
--report <file> |
Write compliance report JSON to file |
--module-root <path=pkg> |
Source-root to package-prefix mapping (repeatable) |
--module-alias <a=path> |
Module alias to source-root mapping (repeatable) |
Prism preserves Luau-specific semantics in generated Java via the prism-runtime-java module:
-- truthiness.luau
local function process(value)
if value then -- Luau: only nil and false are falsy
print("truthy")
end
local t = {1, 2, 3} -- Sequential table → Java List
local d = {name = "Alice", age = 30} -- Keyed table → Java Map
d["name"] = nil -- Nil-assignment → removes entry
for k, v in pairs(d) do
print(k .. " = " .. tostring(v))
end
if value == other then -- Non-literal equality → runtime check
print("equal")
end
endGenerated Java (simplified):
public void process(Object value, Object other) {
if (Luau.isTruthy(value)) {
print("truthy");
}
var t = java.util.List.of(1.0, 2.0, 3.0);
var d = java.util.Map.of("name", "Alice", "age", 30.0);
d.remove("name");
for (var _entry : d.entrySet()) {
var k = _entry.getKey();
var v = _entry.getValue();
print((k + " = " + String.valueOf(v)));
}
if (Luau.equals(value, other)) {
print("equal");
}
}All Hytale features are authored through a single returned hytale.plugin { ... } manifest. See docs/reference/hytale-luau-authoring-model.md for the full reference.
-- my_mod.luau
local hytale = require("@prism/hytale")
local function greet(ctx: hytale.CommandContext, name: string)
ctx:reply("Hello " .. name)
end
local function playerJoin(event: hytale.PlayerJoinEvent)
print("Welcome, " .. event.player.name)
end
export type Health = {
hp: number,
maxHp: number,
}
local function newHealth(): Health
return { hp = 100, maxHp = 100 }
end
export type GameTime = {
elapsed: number,
tickRate: number,
}
local function newGameTime(): GameTime
return { elapsed = 0, tickRate = 20 }
end
return hytale.plugin {
group = "com.example",
name = "my-mod",
version = "1.0.0",
description = "An example Hytale mod",
entrypointClassName = "MyModPlugin",
packageName = "com.example.mod",
commands = {
greet = {
description = "Greets a player by name.",
permission = "example.greet",
execute = greet,
},
},
events = {
PlayerJoin = playerJoin,
},
components = {
Health = { create = newHealth },
},
resources = {
GameTime = { create = newGameTime },
},
}With --route java:hytale --route java:
- Plugin manifest →
MyModPlugin.javawithextends JavaPluginand slot-based registrations commands.greet→GreetCommand.javawithNAME/DESCRIPTION/PERMISSIONconstantsevents.PlayerJoin→PlayerJoinHandler.javawithEVENT_TYPEandhandle(...)components.Health→HealthComponent.javawithTYPEconstant and accessorsresources.GameTime→GameTimeResource.javawithTYPEconstant and accessorsassets.*→manifest.jsonentries +*.assetrefresource files
With --route java alone, all of the above produce generic Java with zero Hytale API imports.
By the time you're reading this, there's probably a GitHub Wiki page set up. If not, or if you can't see the original GitHub page, the Wiki is also housed in the mysteriously named wiki folder. That wiki should be more than enough to get you up to speed. But outside that, there are these files in the docs folder:
docs/architecture.md
If you want to see the planning and some of the future ambitions for this repo, check out:
.kiro/specs/prism-future-layers/docs/plans/prism-future-layers-spec.mddocs/plans/prism-vertical-slice-plan.md
There are also some extra stuff for other AIs/human contributors:
- Contributor/start here:
docs/README.md - End-user Luau/Hytale authoring:
docs/reference/hytale-luau-authoring-model.md - Extending Prism modules:
docs/reference/prism-extending-guide.md - Architecture and boundaries:
docs/reference/prism-module-and-node-ownership.md
.\gradlew.bat build # Build all modules (Windows)
.\gradlew.bat test # Run all tests
.\gradlew.bat :core:test
.\gradlew.bat :cli:test
.\gradlew.bat :target-java-hytale:testcore/ IR sealed hierarchy, pipeline contracts, compliance types
lang-luau/ Luau frontend (Luau → IR via full_moon)
full-moon-cli/ Rust shim wrapping full_moon for JSON-over-stdin protocol
prism-runtime-java/ Runtime helpers for generated Java (truthiness, equality, patterns)
target-java/ Generic Java backend (IR → Java via JavaPoet)
target-java-hytale/ Hytale profile backend + Freemarker templates
core-test/ Contract test harness (BackendContractTest, FrontendContractTest)
cli/ CLI entry point, worker pool, orchestration components
scripts/ Setup scripts (setup.ps1, setup.sh)
legacy/ Pre-rewrite docs, examples, and modules
See CONTRIBUTING.md for build, test, and contribution guidelines.