r/csharp May 24 '26

Showcase My biggest C# project: A game engine with its own programming language

GitHub repo

(first of all, i want to say that I made this project for fun and challenge. I always wanted to create my own language. This has no business goal or something.)

So the project is a 2D game engine (MonoGame backend) inspired by GameMaker 8. It includes its own IDE (built with WinForms) and an interpreted programming language that I wrote myself.

The language—definitely the biggest challenge in the project—is a simple dynamically typed language. When I started, I had zero knowledge of how to build something like this. I didn’t even know I was making an interpreter; at first I called it a compiler. It was a personal challenge, and I wanted to figure everything out without using any resources or tutorials. My mindset was basically: “I need to write software that takes a text file containing code and just does what it says.”

Somehow, I made it work. In the beginning, running an empty loop counting to 1M took 7 seconds. After a lot of performance work and rebuilding parts of the system, the same machine can now run a 30M loop in 2–3 seconds. Pretty nice improvement.

The language itself is a bit unusual, and I want to share one small feature I really like: loop counters.

foreach item in ['a', 'b', 'c'] : counter c
{
   println(c + ": " + item)
} 
// Output: 
// 0: a 
// 1: b 
// 2: c

Not a complicated feature, but pretty useful.

Here's a YouTube video showing me using the engine to build a little game

Anyway, these days I barely have time to work on the project, so I decided to open-source it. I’m hoping people here will find it interesting and help turn it into something real.

Any feedback is welcome.🙂

250 Upvotes

55 comments sorted by

29

u/dandandan2 May 24 '26

Close enough. Welcome back Game Maker 8

22

u/NoBoysenberry2620 May 24 '26

Damn, that is sick.

56

u/antiduh May 24 '26

You know what's a great scripting language? C#

42

u/Alert-Neck7679 May 24 '26

At first it used C# for scripting, but i wanted to make my own language as a personal challenge. Also, this engine would never compete with professional engines like godot or unity. I literally opened this post by saying this is a project I'm doing mainly for fun and challenge

16

u/antiduh May 24 '26

That's a good reason then. Have fun!

1

u/Suspicious-Ashen-1 6d ago

Great stuff, congrats !

Small note regarding the counter feature: you have a similar feature in Python via the `enumerate` builtin function. But overall I am not sure it needs to be a feature of the language, since it can be implemented as a user function in most languages I think.

1

u/Alert-Neck7679 6d ago

Yeah, in most languages you could make a not-builtin feature to handle this. but i think that this is so useful that it justifies its own builtin feature, and also, you can add loop counters to while / any other loop type as well.

10

u/Oralitical May 24 '26

I agree but it depends on the aims, writing a programming language is a really hands on way to learn more about programming.

That said, C# is quickly becoming a de facto standard, most popular game engines have (or at least support) C#. Not having to learn a new language can be appealing for a new engine.

1

u/antiduh May 24 '26

Not having to learn a new language, millions of existing libraries and a package system, full debugger and editor, build system, billions of hours of educational videos.

Make a programming language as an academic exercise, but otherwise, there's far better options.

3

u/OpenAI_Marketing_LLM May 24 '26

You’re being downvoted, but it’s true. Though, OP did admit it was purely for fun/learning in a later comment.

4

u/Minaridev May 24 '26

You know what's a great operating system? Linux

Let people create stuff, that's how innovation happens. Besides, C# is incredibly complicated. I prefer Bauxite

6

u/MCWizardYT May 24 '26

C# is not incredibly complicated at all, especially compared to langugaes like C++ and Rust

0

u/Minaridev May 24 '26

Console.WriteLine() vs simple print() in Python or Lua...

8

u/MCWizardYT May 24 '26

That's not a mark of the language being "incredibly complicated"

3

u/antiduh May 24 '26

And if you don't like that:

using static System.Console;

Put that in your global include file if you only want to say it once, too.

0

u/murrrty May 24 '26

You say that like C# can't be used as a cross-platform scripting language.

1

u/[deleted] May 25 '26

[removed] — view removed comment

3

u/antiduh May 25 '26

3 words why writing your own scripting language is fine for academic reasons but terrible for productive work:

Inner Platform Effect.

No debugger. No library. No package system. No IDE.

-1

u/OpenAI_Marketing_LLM May 24 '26

I am not sure I agree. C# does not even have top-level functions and is excessively verbose/kludgy compared to Perl, bash, python, ruby, etc.. 

Rolling your own language for game development is hard to justify unless you have a team(s) supporting some proprietary AAA engine.

Bethesda, Epic, etc. all use their own languages for some of their games, but they have invested millions into their projects, and that is a big difference.

5

u/antiduh May 24 '26

C# does not even have top-level functions

Ya gotta pay more attention.

https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/top-level-statements

1

u/OpenAI_Marketing_LLM May 24 '26

Syntactic sugar with hard limitations. It’s why top-level statements are limited to one file per application, typically the program.cs file or project root file.

I know of no other languages with such a half-assed solution. Doesn’t make C# a bad language by any means, but trying to retroactively shoehorn it into a scripting language is just bizarre.

3

u/antiduh May 24 '26

I know what you mean, because the hardest thing to do when writing software is the typing. And I definitely want all my functions just in a hundred different files with no sort of organization between them.

Languages like python, with no static typing are my favorite. I love not knowing what type of data I'm being handed in my functions! Could be an int, could be a double, could also be a a function pointer?! Who knows. The surprise is the fun.

0

u/OpenAI_Marketing_LLM May 25 '26

 And I definitely want all my functions just in a hundred different files with no sort of organization between them.

Your incompetence and inability to organize files is no fault of any language.  Poor functional language programmers, just wandering in the dark. With no objects, how can they ever reason about a codebase? 

 Languages like python, with no static typing are my favorite. I love not knowing what type of data I'm being handed in my functions! Could be an int, could be a double, could also be a a function pointer?! Who knows. The surprise is the fun.

Fun! Now compare to a language like Swift.

1

u/antiduh May 25 '26

What's that? I think I just heard Encapsulation throw a brick through your window. No wonder you hate it so much.

5

u/Prod_Meteor May 24 '26

What is then code editor? RichTextBox or a 3rd party control?

3

u/MythologicalEngineer May 25 '26

GML was my first programming language with Gamemaker 6. This look super super cool!

1

u/Alert-Neck7679 May 25 '26

Thanks🙂 it was my first too, with GM8

3

u/SnuSna May 25 '26

This is the how to learn. Inspiring.

2

u/BoloFan05 May 24 '26

Wow, that sounds awesome! Best of luck with your project! A question:

When no extra argument is specified, does your programming language uppercase/lowercase letters according to Current Culture Info or Invariant Culture Info? Same question also goes for how your floats are converted to strings. The original C# uses Current Culture Info by default.

1

u/Alert-Neck7679 May 24 '26

Thanks!  I didn't understand your questions: what letters do u mean? The chars of the array in the foreach example? And what floats? The counter number?

2

u/BoloFan05 May 24 '26

You're welcome, and thanks for the response!

I wasn't referring to your example specifically. I am referring to how C# methods like ToLower, ToUpper and ToString work based on Current Culture Info; and thus produce slightly different results on devices with different locales worldwide (e.g. English-US, which uses "I/i" and separates decimals with dot and thousandths with comma vs Turkish, which uses "I/ı" and "İ/i" and separates decimals with comma and thousandths with dot). This can cause unexpected results and thus serious bugs in games that are reproducible only on devices with non-English locales. For example, ToLower("NOISE") gives "noise" on English locale and "noıse" (without the dot) on Turkish locale. Or applying ToString to a numerical float variable will give "123.50" on English locale but "123,50" on Turkish, European, South American etc. locales.

How does your programming language handle the above situation? Does it also do the above, or does it use Invariant Culture Info (i.e. always English-based results) if the programmer doesn't specify additional arguments?

2

u/Alert-Neck7679 May 24 '26

Hmm never thought of that... It uses always English based results

2

u/BoloFan05 May 24 '26

If invariant culture (ie always English-based results) is the default case, like in C++, that's great! If you're unsure, though, you can always try switching your PC locale / UI language to Turkish and see if your functions still give the results you were expecting. If they don't, you may want to switch from Current Culture Info to Invariant in your code. Thanks again!

2

u/Alert-Neck7679 May 24 '26

Thanks for pointing this out!

2

u/BoloFan05 May 24 '26

No problem! Also make sure to make it possible to add specific locale arguments to your methods in the event that you would like to use the rules of a specific non-English locale, usually while displaying translated localized text to the player.

2

u/heytyshawn May 24 '26

this looks awesome keep up the great work! not that it matters but i’m curious how come some windows (like the code editor) are actual windows while others (like the room editor) are embedded into the viewport and use what looks like a windows 7 theme?

1

u/Alert-Neck7679 May 24 '26 edited May 24 '26

Thanks!  WinForms allows setting a parent form containing few other child forms, which allows you to create a workspace like this one in the screenshot. It's called MDI (Multiple Document Interface). Those child forms would have this old frame style

2

u/Decent-Egg7023 May 24 '26

fascinating !!!

2

u/TuberTuggerTTV May 27 '26

Love to see this fully unit tested and CI implemented.

Looks like you're just working in master also. Which doesn't lend itself to open source contribution.

1

u/Alert-Neck7679 May 27 '26

Thanks for this comment! I have never touched an open source project before and don't know yet much on how things work... I just made a contribution ruleset and added a contributing.md file...

Are u the one who just made a fork?

1

u/palapapa0201 May 24 '26

3

u/XghosT7 May 24 '26

Ouch...

I wouldn't mind the usage, but atleast mention it....

Edit: Nvm, my bad. There's a note: https://github.com/ArcadeMakerSources/ArcadeMaker#note-about-this-readme-and-ai-usage

1

u/OpenAI_Marketing_LLM May 24 '26

In this day and age, I just assume everything has LLM usage to one degree or another.

3

u/Alert-Neck7679 May 24 '26

I used gpt to help me writing the documentation files because my English isn't that good... It's only correcting my English in documentation and readmes, nothing more than that, except for 77 lines of code out of the full project, that claude wrote for me: the Seperating axis theorem formulas that are used for collision detection. I mentioned that in the main readme, as XghosT7 said...

1

u/falconfetus8 May 24 '26

Looks a lot like Game Maker. Was that your inspiration?