• Check out the results of the Techtree Contest #19!
  • Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

(WIP) Introducing SharpForge: a C# to Lua Toolchain

Level 4
Joined
Jun 28, 2009
Messages
49
Hi Hive,

I want to introduce a work-in-progress project I have been building: SharpForge, a C# scripting toolchain for Warcraft III: Reforged map development.

The goal is not to replace the World Editor, JASS/Lua knowledge, or the existing Warcraft III scripting ecosystem. SharpForge is intended to sit alongside an existing map workflow, allowing selected systems to be written in strongly typed C#, transpiled into plain Lua, bundled with existing Lua modules, and injected into a .w3x map.

This is still early and very much WIP, but it has reached the point where I would like feedback from people who have experience maintaining Warcraft III maps and Lua codebases.

What SharpForge Is​


SharpForge currently consists of several small tools:

  • sf-transpile: transpiles C# source files into Lua
  • sf-build: bundles Lua dependencies and can inject the generated bundle into a map
  • sf-jassgen: generates C# binding stubs from common.j / blizzard.j
  • a GUI wrapper for coordinating the tools

The generated Lua is meant to stay readable and predictable. SharpForge does not try to hide the Warcraft III API behind a new object model. For example, KillUnit(unit) remains KillUnit(unit), not something like unit.Kill().

Generated C# types are emitted under a configurable root table, so they can coexist with existing Lua modules and map globals without taking over the whole scripting environment.

Design Philosophy​


The main design principles are:

1. Do one thing and do it well

The transpiler only transpiles C# to Lua. The builder handles Lua bundling and map injection. JASS binding generation is a separate concern. I am trying to avoid one large magical build system that owns the entire map pipeline.

2. Integrate with existing workflows

World Editor still owns terrain, object data, placed units, and normal map editing. SharpForge is meant to fit into a source-controlled scripting workflow, not replace the editor.

3. Incremental migration

Existing Lua modules should keep working. New C# code can call Lua, Lua can call generated output, and a project can move one subsystem at a time instead of requiring a full rewrite.

4. Small runtime surface

SharpForge does not try to translate the whole .NET standard library into Lua. The runtime helpers are intentionally minimal, and only fit what real map authors need.

5. Plain and performant Lua output

The output should be direct Lua with an understandable, fine-tuned, and Lua-worldly structure, not an opaque VM or heavy compatibility layer.

6. Assisting in writing better code

SharpForge should help map authors avoid common Warcraft III scripting pitfalls without turning into a restrictive framework. Stable collection iteration, stable sorting, desync warnings, and warnings for mutating collections while iterating are all meant to make behavior more predictable across players and easier to reason about while debugging. The goal is not just to emit Lua that runs, but to guide projects toward code that is deterministic, maintainable, and less likely to fail in subtle multiplayer-only ways.

7. Better debugging

SharpForge should make failures easier to see, reproduce, and understand. Engine callbacks to be wrapped with pcall automatically so script errors do not silently break the map or disappear into Warcraft III’s runtime behavior, while still reporting the error clearly instead of hiding it. On top of that, optional debugging libraries can bring an inspector-style workflow to Warcraft III modding, closer to the kind of tooling Unity developers expect: live object state, clearer runtime visibility, and a more industrial-level of feedback than the community has traditionally had.

Lua Interop​


One important part of the project is interop with existing Lua code.

SharpForge supports raw Lua interop calls, such as requiring modules, reading/writing fields, calling global functions, and invoking Lua methods. It also supports typed wrapper classes for known Lua modules, so C# code can use a more IDE-friendly shape while still lowering to normal Lua calls.

This is important to me because I am currently using SharpForge to gradually develop one of my own Warcraft III Lua script projects. The project was originally written in Lua, and I do not want to throw that work away. Instead, I am moving suitable systems over step by step, while keeping existing Lua modules active and callable.

That migration experience is one of the main reasons SharpForge is designed around coexistence rather than replacement.

Current Status​


SharpForge already supports a growing subset of C# lowering, including classes, namespaces, static and instance methods, constructors, fields, properties, loops, conditionals, inheritance basics, interfaces, arrays, simple collection helpers, delegates/events in limited form, and some exception handling patterns.

There are still many areas that need more work, especially around deeper generics, broader async behavior, edge cases in lowering, diagnostics, and real-world ergonomics.

So I would not describe this as production-ready yet. It is a toolchain under active development, and I am deliberately testing it against real Warcraft III Lua code rather than only toy examples.

Feedback I Am Looking For​


I would especially appreciate feedback on the project. Like Does the overall direction make sense for serious Warcraft III map development?

I am also interested in criticism. If there are parts of this idea that seem fragile, overcomplicated, or likely to fail in real map projects, I would rather hear that early.

Thanks for reading. I am sharing this as a WIP because Hive Workshop has many experienced Warcraft III modders and scripters, and I think this is the right place to get grounded feedback before pushing the toolchain further.
 
Last edited:
Does the overall direction make sense for serious Warcraft III map development?
This is cool so I have only respect for you, but all I want is an improved version of this :cry:

I just want to be able to write in Lua and have it work on old editor versions as Jass so that I can make maps that support as many people's setups as possible without me having to learn Jass 🫠

If you ever happen to go the extra step to subsequently convert the Lua to Jass, lmk! 😅
 
This is cool so I have only respect for you, but all I want is an improved version of this :cry:

I just want to be able to write in Lua and have it work on old editor versions as Jass so that I can make maps that support as many people's setups as possible without me having to learn Jass 🫠

If you ever happen to go the extra step to subsequently convert the Lua to Jass, lmk! 😅
Much appreciated for your reply. I'm actually quite hesitant about JASS. I actually started the project with the intention of transpiling C# to both Lua and JASS because I have a never-ending JASS (Zinc) map with bloated bugs. After quite a bit of research and questioning myself on software engineering management. I decided to stick with Lua first. If this is doable, I think I can make it work with JASS later. But of course, a lot harder.
 
Much appreciated for your reply. I'm actually quite hesitant about JASS. I actually started the project with the intention of transpiling C# to both Lua and JASS because I have a never-ending JASS (Zinc) map with bloated bugs. After quite a bit of research and questioning myself on software engineering management. I decided to stick with Lua first. If this is doable, I think I can make it work with JASS later. But of course, a lot harder.
Awesome. Thanks for the reply.

Yeah, since I use Lua for other game mod projects as well, I'm happy to use it, but I don't use Jass or C#, so I want to avoid having to learn those just to do stuff with wc3.

I can see the value in making a C# -> Jass converter b/c of map compatibility, but if you happen to implement it indirectly by actually doing a Lua -> Jass thing, then maybe other people down the line can also make tools for other languages that convert to Lua first, and then they'll automatically get Jass as well, and all roads can end in Jass haha. Although I'm actually just saying that b/c Lua --> Jass is what I personally really want 😅

Anyway, I'll be sure to follow your development of this and related projects👍
 
Could you elaborate a bit on the differences between this and WCSharp? Looks interesting!
WCSharp is a full set of C# solutions, including high-level wrappers and built-in systems. It's a framework.
SharpForge focuses on minimal C# to Lua transpiling. It's a restricted toolset.

WCSharp makes everything C# taste. item.Create
SharpForge keeps the original flavour. CreateItem

WCSharp is a general-purpose C# to Lua compiler. foreach (var kv in dict) -> for key, value in pairs(dict)
SharpForge emits fine-tuned Lua code to avoid common Warcraft III scripting pitfalls. Dictionary containers will have an extra array to ensure iteration order to avoid desync. Same for sorting.
SharpForge is also planned to have code linting to warn about dangerous code. GetLocalPlayer and then CreateUnit with it.
SharpForge flattens structs to reduce table allocation. Even struct usage is restricted due to this, but it's a tradeoff. struct Vector2 {float x; float y;} -> local __Vector2_x, __Vector2_y

WCSharp aims to enable C# developers to start new map modding real quick.
SharpForge respects incremental migration from lua to C#.

WCSharp: Interop may require additional work.
SharpForge: Interop is core design.

WCSharp empowers authors with ready-to-use and battle-tested libraries.
SharpForge focuses on better development and debugging (Unity inspector brought to wc3 modding).

I would like to share how this project came up. SharpForge is for people who are JASS and lua minded, but hate how weak JASS is and hate lua's dynamic typing. (TSTL was carefully reviewed, but they have chosen the wrong language - typescript has its own problems, which I wouldn't discuss here.) So you don't need to install VS, accessing C#'s community (NuGet) to develop maps with C# language.
 
Last edited:
Back
Top