Lesson 1 — What C# Actually Is
Why is C# the language driving the production of thousands of indie games using Unity and custom engines all around the world? In this lesson we learn what C# actually is, a compiled language that is typically managed in .NET environments. Along with being easy to use and highly legible, C# is memory safe, predictable, and has a standard set of libraries you can work with. While the language is highly explicit in its syntax, this lesson will explain the rationale behind such a decision.
Prerequisites
Before starting, you’ll need:
Unity Hub (free from unity.com/download)
An IDE: Either Visual Studio (recommended for Windows, free Community edition) or JetBrains Rider (cross-platform, paid but excellent). Unity Hub will prompt you to install Visual Studio during setup if you don’t have an editor yet.
What C# Actually Is
If you’ve never programmed, here’s the blunt truth: C# is not just a way to “make the computer do things.” It’s a language designed to run inside a managed environment called .NET. That environment gives you memory safety, a predictable way to load code, and a standard set of libraries. C# was created to fit that environment cleanly, not to be the flashiest programming language on the block.
The Core Idea (in plain terms)
Think of C# as the author and .NET as the publisher. You write C#; a compiler turns your words into a portable recipe (called IL—Intermediate Language). At runtime, .NET reads that recipe and cooks it into machine code for your computer. This two-step system is why C# code can be safe and consistent across different machines without you micromanaging the hardware.
That safety is not optional decoration. .NET checks types (what kind of data you’re using), manages memory automatically (garbage collection), and standardizes how code is packaged (assemblies). These rules are why C# programs from different teams and even different languages (like F# or VB) can work together without chaos.
What Makes C# Worth Learning
Clear structure. C# pushes you to define what data you have (types) and what actions you allow (methods). Because types are checked at compile-time and the compiler tells you exactly where things don’t match, you can trace problems back to their source before your program even runs. You get fewer “mystery errors” later.
Modern features when they earn their keep. Async/await for responsiveness, pattern matching for clarity, and generics for type-safe reusable code weren’t added to look cool—they solve recurring problems cleanly in the .NET world.
Stable design philosophy. From its first standard to today, C# aims for “practical, readable, safe,” not “minimal at any cost.” Its chief designer, Anders Hejlsberg, has repeatedly emphasized usefulness over purity. The language committee says “no” to features that would make code harder to understand or maintain.
Why “Hello, World” Is a Trap (but we’ll still do it)
Many tutorials start with:
Console.WriteLine(”Hello, World”);It prints a line. Useful, yes. But you should know that modern C# (version 9 and later, released in 2020) introduced a feature called top-level statements that hides some scaffolding to keep examples short. The compiler automatically generates an entry point method called Main and imports common namespaces behind the scenes. That’s convenient, but if everything is hidden, beginners fail to learn the shape of real programs in their first steps.
You can use the short form—it’s perfectly valid C#—but remember it stands on top of a more explicit structure.
The Full Picture
Here’s what the compiler generates behind the scenes when you write that one-line program:
using System;
internal static class Program
{
private static void Main(string[] args)
{
Console.WriteLine($”Hello, World with {args.Length} args.”);
}
}Let’s break down each piece:
using System;imports the System namespace, which containsConsole. Without this, you’d have to typeSystem.Console.WriteLineevery time. Namespaces organize related code into logical groups.internal static class Programdeclares a class—a container for related code.internalmeans “only visible to code in this project, not to other projects”staticmeans “this class doesn’t need to be instantiated (turned into an object) to use”Classes are fundamental organizing units in C#
private static void Main(string[] args)is the entry point—where your program begins executing.privatemeans only code inside this class can see this methodstaticmeans it exists at the class level, not on individual objectsvoidmeans it doesn’t return a valuestring[] argsis an array of strings containing command-line arguments (text you can pass to your program when you run it from a terminal)
Console.WriteLineoutputs text to the console window. The$”...”syntax is called string interpolation—it lets you embed expressions like{args.Length}directly in text.
You don’t need to memorize all this now. Just know that the simple one-liner is syntactic sugar—a shortcut that the compiler expands into this fuller structure automatically.
Readability first. Tricks later.
A Beginner’s Mental Model That Actually Scales
Here’s the three-step process that happens every time you run C# code:
You write C# in plain text files (
.csextension)Compiler creates IL + metadata and packages it inside an assembly (a
.dllor.exefile).NET runs it, handling memory, errors, and libraries in a consistent way
This model explains deployment (you ship assemblies, not source code), performance (the JIT compiler optimizes IL at runtime), and why mixed-language projects work (F#, VB, and C# all compile to the same IL format). You don’t need to memorize the acronyms now; you just need to know there is a disciplined system under the hood, and C# is designed to match it.
Philosophy in One Paragraph
C# is conservative with taste and aggressive with tooling. The language evolves only when the runtime and libraries can support the feature clearly and safely. That’s why features like generics (arrived in C# 2.0 after years of careful design) or async/await (C# 5.0) took the shape they did—and also why some flashy ideas from other languages are left out. Good design is saying “no” as often as “yes.” This philosophy means C# prioritizes long-term maintainability over short-term novelty.
Unity Companion Exercise — See C# Run in a Game Loop
Goal: Write one tiny C# script in Unity, see where it lives, and understand how Unity calls it. No prior programming knowledge required.
What you’ll learn: Unity discovers your C# code, compiles it into an assembly, and calls specific methods at specific times (like Start and Update). You don’t “run” your script directly; Unity does, following its engine rules.
Steps (10–15 minutes)
1. Create a project
Open Unity Hub → New project → Select “3D (URP)” or “3D Core” template. Name it CSharpLesson01. Unity will create a solution where your scripts live under the Assets/ folder.
2. Add a GameObject to hold your script
In the Hierarchy panel (usually left side), right-click → Create Empty. Rename it Greeter.
3. Create your first script
In the Project window (bottom panel), right-click in Assets/ → Create → C# Script → name it Greeter. Double-click to open it in your editor (Visual Studio or Rider).
4. Replace the template with this code
using UnityEngine;
public class Greeter : MonoBehaviour
{
// Called by Unity once when the object becomes active.
void Start()
{
Debug.Log(”Hello from C# inside Unity.”);
}
// Called by Unity every frame (typically 60-90 times per second).
void Update()
{
// Press space to print the current time.
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log($”Tick: {System.DateTime.UtcNow:O}”);
}
}
}5. Attach the script and run
Drag the
Greeterscript file from the Project window onto theGreeterGameObject in the Inspector panel (right side)Press the Play button (top center of Unity editor, triangle icon)
You’ll see “Hello from C# inside Unity.” appear in the Console window (bottom) when the scene starts
Press the Space bar to log timestamps
What Just Happened?
You wrote C#. Unity compiled it into an assembly behind the scenes (you’ll find it in Library/ScriptAssemblies/ if you’re curious). The engine invoked Start once when you pressed Play, then calls Update continuously—once per frame, typically 60-90 times per second depending on your computer’s performance.
Your script never calls these methods itself; Unity does, because your class inherits from MonoBehaviour, which is Unity’s contract for script behavior. Think of MonoBehaviour as a template that Unity knows how to work with. When Unity finds classes that inherit from it, Unity automatically calls special methods like Start, Update, FixedUpdate, and others at the right times.
This is the same “language plus environment” story from above, now in a game engine. Unity itself runs on .NET on most platforms. On mobile devices and consoles, Unity can use IL2CPP (Intermediate Language To C++)—a Unity-specific system that converts IL to C++ code, then compiles that to native machine code for better performance and broader platform support.
Stretch Exercise (2 minutes, optional)
Add a simple counter to see stateful code in action:
int _count;
void Update()
{
_count++;
if (_count % 300 == 0) // roughly every 5 seconds at 60 FPS
{
Debug.Log($”Frames so far: {_count}”);
}
}You’ve just written stateful code—code that remembers information between function calls. The _count variable persists across thousands of Update calls, and Unity manages its lifetime automatically. The language (C#) and the environment (Unity) cooperate to make this predictable.
Thanks for reading the first lesson in Code Quest where we learn about C# and Unity from 0 to expert. If you enjoy continuous learning about programming and game development, consider subscribing today. Our team appreciates the support!
Subscribe
Further Reading
Official Language Specification
ECMA-334: C# Language Specification — The formal international standard defining C# syntax and semantics. Dense but authoritative.
Microsoft Documentation
Introduction to C# and .NET — Official tour of C# features with interactive examples
What is .NET? — Overview of the .NET platform, runtime, and ecosystem
Understanding .NET assemblies — How code is packaged, versioned, and loaded
Top-level statements (C# 9) — The feature that hides
Mainin simple programs
Design Philosophy
Anders Hejlsberg - Modern C# and .NET (GOTO 2019) — 40-minute talk by C#’s chief designer discussing language evolution philosophy and decision-making
Unity Integration
Unity Scripting Reference — Complete API documentation for MonoBehaviour and Unity-specific classes
Unity Manual: Scripts as Behavior Components — How Unity discovers, compiles, and executes your scripts
Unity Manual: Compilation Pipeline — How Unity organizes scripts into assemblies
Recommended resources
Game Engines
Unreal Engine 5 Best Practices
Amazon · Book
Written by multi-award-winning Unreal generalist Tyson J. Butler-Boschma, Founder and Creative Director of Toybox Games Studios, this book addresses common challenges you face when advancing your expertise in lighting, environment design, and cinematic storytelling.
GameDev.net may earn a commission if you purchase through these links. This helps fund the site at no extra cost to you.
Related Tutorials
Balancing Game Development and Creative Direction in Indie Production
A practical look at how indie developers can balance creative direction with hands-on game development. This article co…
My Unreal Engine Development Process: From Core Idea to Playable Build
A practical overview of my Unreal Engine development process, covering how I move from a core game idea to a playable b…
Introducing LaneGraph: The Ultimate Road Network Solution for Unity
Discover the power of LaneGraph, a lightweight and flexible lane-based navigation system for Unity. LaneGraph makes it…
Retargeting Mixamo Characters with Root Motion In Unreal Engine 5.4.
I have always found Retargeting Mixamo Characters To have Root Motion is a serious lengthy Tast, Recently I stumbled up…
How To Make A SIMPLE Main Menu In Unity
In this tutorial for unity, i go over how to make a simple main menu for unity, it's an unlisted video because i do not…
Guide to Gameplay Balance
A perspective on competitive gameplay balance, from a background of "shooter" sandbox design.
Discussion