Loop and main() function
Posted by Ok-Presentation-94@reddit | learnprogramming | View on Reddit | 37 comments
Hi, I’ve seen that in C#, the Main() function only runs once.
In Unity, we have the Update() function, which allows code to run repeatedly in a loop.
So my question is: what is the equivalent in pure C#, without the Unity library?
Is wrapping Main() in a while loop a common practice to achieve the same behavior?
jlanawalt@reddit
Many languages derived from C (and B) have a main function as the designated every point for the program. As such, it is only called once per run. Even Unity has a main, and it has a gave engine with an Update effect hook.
To have exactly the same in pure C#, be ready to re-implement a game engine, or at least some kind of event driven system, or in its simplest some form of loop.
peterlinddk@reddit
A lot of the answers are somewhat misleading.
There is a massive difference between using a loop, and having a function like Update!
If you have a while-loop in your Main() function, like:
Then the Update function is called continously - meaning ALL THE TIME, taking up 100% of the CPU-time of the core that runs this program. And the speed of the program will depend on how long it takes for the code inside Update() to finish.
This is NOT how you should do it!
I don't know the best way to do this in C#, but no matter the language you'll need to setup some sort of multithreading, with a "render-thread" that executes once on every frame (e.g. 60 times a second), and then that code calls your Update() function.
That would give you the same behaviour of waiting a little while between each update.
The difference is really important, the first (the while-loop) is classical blocking code, whereas the second (with a thread or something calling Update() is event-driven code. And there's a lot that can't be done in one, but easy in the other, and vice versa.
kohugaly@reddit
This is kind of true, but not really. There is nothing stopping you from having a periodic timer inside Update() (or the loop that calls it), and performing blocking "wait" operation on it, to throttle the updates. It is entirely possible to have a single-threaded runtime that handles everything.
peterlinddk@reddit
If you by "have a single-threaded runtime" mean that the gameloop runs in a single thread, that asks the operating system or runtime environment to wait before calling Update() the next time, then sure, that is totally possible. Like calling sleep or something else.
What I mean is that you need to respect the threading, and not block the entire system with an infinite while-loop - that won't work.
Calling .sleep or using a system timer, or registering for a callback are all different ways of having another thread call your Update() function - even if you don't have more than that single thread in the code.
kohugaly@reddit
Technically, this is not true.
Blocking operations (sleep, waiting on system event/mutex/IO), work via interrupts. Your thread executes "software interrupt" instruction that puts the thread to sleep and jumps to system's interrupt handler. OS can then wake the thread once the requested operation is finished. This is distinctly different from "another thread call your Update() function".
Registering for a callback may or may not cause the callback to be executed in a different thread. For example on Windows the callback provided to ReadFileEx function will be executed on the same thread.
But I get your point. I'm just nitpicking about the difference between function calls and context switching via interupts.
vowelqueue@reddit
Yeah I’ve used frameworks that ran a single-threaded main event loop but had functionality to swap in different sleep strategies, e.g. sleep, yield, busy-spin. Supported running callbacks on a timer.
Frolo_NA@reddit
main() would have the loop and a call to Update()
ottawadeveloper@reddit
In generic code:
green_meklar@reddit
There isn't. You don't.
No. You put the stuff you want to loop in another function and call that in a while loop. Main is Main and shouldn't be manipulated to behave like something else.
WookiePub3@reddit
It is not as complicated as you might think, you will learn that basically all games run in a big while loop! Here is a C++ version you might find helpful: int main() { GameLoop* gameLoop = GameLoop::getGameLoop();
}
Traditional_Crazy200@reddit
I have never written a line of c#, but i am 100% sure wrapping main in a loop wouldnt even compile. I am not even sure how one would do that since you probably dont call main manually.
Even in unity, update probably runs inside main() since main is like the name suggests the main entry point of your program. There can only be one main, granted you are not in a multithreaded environment.
What you need to do is simply put the while loop inside the main function.
otac0n@reddit
You can call Main in C# just fine. Not that this guy wants to do that, but the compiler is A-OK with it.
oskaremil@reddit
☝🏾 this is the correct answer.
DerekB52@reddit
gameprogrammingpatterns.net
You want the section called 'game loop'
To answer your question in short,
class Game{static void Main(string[] args){while (true) {update();}}static void update(){//your game logic here}}flumphit@reddit
But you’d never actually call it Main(), right?
…right?
DerekB52@reddit
I might be confused. If you are asking if I would use the name Main, I don't know honestly. C# might require it, I can't remember, I don't really use C#.
If you are asking me if you need to call it, like Main(), then no, Main() will be called automatically when you launch your game, because that is its whole purpose. It is where code starts executing in a C# program.
ExtraTNT@reddit
You can split it like:
main{init(); while(1){update();}}
StewedAngelSkins@reddit
Yes, this is what Unity is doing internally. The engine just has certain spots in its main function where it calls into your code.
Traditional_Crazy200@reddit
the engine inserting your code inside main main is very different than continuously calling main through a loop. Id be very surprised if this is how unity actually does it. Is it true?
StewedAngelSkins@reddit
I read what they said backwards. It doesn't call main in a loop; rather, main contains a loop that calls the frame update logic. Technically there's also some frame timing stuff so it doesn't needlessly burn cycles on updates that aren't actually going to be drawn, but that's the basic idea.
Traditional_Crazy200@reddit
I thought so cause that sounded like black magic
StewedAngelSkins@reddit
Technically you can do this sort of thing in Python
but that's only because in Python the contents of the file itself is the entrypoint. But yeah in C# it would just be a syntax error.
Traditional_Crazy200@reddit
would be interesting to see what this assembles to
StewedAngelSkins@reddit
The python code? It's interpreted, so there's no assembly per se. But the Python interpreter/runtime kind of works like Unity in the sense that it has its own
mainfunction internally that calls into the code you write whenever the module is imported.Traditional_Crazy200@reddit
Interesting, no assembly, no binaries... I guess I'll dive into interpreters for a week lol
StewedAngelSkins@reddit
Python (the CPython interpreter specifically) is an interesting one to study.
Traditional_Crazy200@reddit
Appreciate the suggestion
Successful_Drawer467@reddit
Yeah that's exactly right, putting while loop inside Main is totally normal approach. I remember when I was switching from Unity to console applications, I was confused about same thing because Unity hides all the loop logic from you
Most game engines and frameworks work like this - they have their own main loop running and just call your functions at specific points. For console apps you just write something like `while(true)` or `while(condition)` inside Main and handle your program logic there. You can also use timers or async patterns if you need more control over timing, but basic while loop is good starting point for learning
The key difference is in Unity you're working inside their loop, but in pure C# you're creating your own loop structure
Afraid-Locksmith6566@reddit
you write main and the content of it is put in a while loop
Backtawen@reddit
yeah a while loop is exactly it, thats literally all unity’s game loop is under the hood
while(true) with a Thread.Sleep or a timer if you need consistent intervals.
samanime@reddit
Basically yeah, you just run it in a while() loop.
The simplest version is literally just:
A better version of a game loop is something like this:
Or a number of other variations.
But ultimately, it's just calling the "game loop" function repeatedly however makes sense for your program. This is also what Unity, Unreal, and pretty much every other game ever does.
StewedAngelSkins@reddit
Careful with that pattern. In languages without tail-call recursion it'll overflow your stack.
samanime@reddit
Huh, I've never run into any problems with it, but Googling around, it looks like .NET's flavor of C# can handle it fine (which is all I've ever used for C#), but maybe the base C# language doesn't... or something. Lots of different answers out there saying seemingly conflicting things. =p
Regardless, it does sound like you might be better off going with a loop-based pattern like this instead, just to be safe:
Thanks for the heads up.
StewedAngelSkins@reddit
Yeah writing it like that would be more conventional.
shaq-ille-oatmeal@reddit
yeah you’re thinking in the right direction, but the key difference is that Unity gives you a built in game loop, pure C# doesn’t
in normal C#,
Main()runs once and then the program ends unless you keep it alive, so if you want continuous execution you either create your own loop with something like a while loop or rely on higher level patterns depending on the type of appfor simple console apps, yes a while loop is totally fine and common if you need repeated execution
for more structured apps, people usually use things like timers, async loops, or event driven patterns instead of a raw infinite loop
so Unity’s
Update()is basically just a managed loop provided by the engine, in pure C# you either write that loop yourself or use frameworks that handle it for you 👍aleques-itj@reddit
There is a loop within Main() that effectively pumps all other parts of the engine, yes.
The game simulation will generally run X times a second (I think Unity ticks its simulation at 50hz) and the renderer will run as fast as possible. The renderer will interpolate state from the simulation to fill in the blanks.
Dazzling_Music_2411@reddit
No. Main is your entry point you only run it once.
Now, if you want to make some other function that you run repeatedly inside a loop, that's up to you.