Alice, video-game in C# / Unity3D

Alice in wonderland-themed roguelike. This is a project I started to pass time during the first months of the pandemic in 2020. Heavily inspired by the Binding of Isaac. Unity3D relies on C# as a core programming language, implementing Behaviors / Components then attached to GameObjects, a classical composition paradigm known as ECS. The assets are either hand-made or public domain (music, sound effects).

Play Alice on itch.io - it runs in the browser.
It's loud, so you may want to turn the volume down.

ASP.NET, Razor and Blazor

There are several technologies commonly used to implement web pages and applications in C#. Due to the naming, it can be a little confusing. Summary:

ASP.NET Core MVC
ASP.NET Core is a server-side web-application framework designed for web development to produce dynamic web pages. It is designed by Microsoft. In 2016 ASP.NET Core replaced the old ASP.NET. The vanilla ASP.NET development experience builds on the MVC approach and separation of concerns.
  • Models manages the data and business logic.
  • Views displays UI, presenting data from Models.
  • Controllers handles user input, interacts with the Model to update data, and selects the appropriate View to display.
Razor
Razor is a markup syntax, in .cshtml files, used in both the classic MVC approach (where it encodes the views), or in the Razor Pages approach. It is similar to JSX: a way to blend code logic with UI markup.
Razor Pages
Razor Pages is a page-centric alternative to the classical MVC paradigm of ASP.NET Core. Instead of using attribute routing, instead, Razor Pages specify route information through @page directives.
Blazor
Blazor is a .NET frontend web framework that supports both SSR and client interactions in a single programming framework.

Event-Sourcing in Domain-Driven-Design in C#

The core principle behind event sourcing is that State is transient, derived from a left-fold of previous immutable events in a sequential, append-only log. Reasons for this architecture include the following.

  1. full auditability, convenient debugging, state snapshots - since state is only a computation from the changes stored as events
  2. time-travel/state reconstruction - the timestamping of events makes a timeline to explore a-posteriori
  3. supporting CQRS patterns - the writes by default being early as possible, recording the request of state changes, reads always having to compute later, from the writes.

  public record InsLedger(string lid): Event;
  public record DelLedger(string lid): Event;
  public record InsLine(string lid, string iid, int dv) : Event;
  /* ... */
  var evs = (new List<Event> {
    new InsLedger("Louis"),
    new InsLine("Louis", 0, +5000), // initial deposit
    new InsLine("Louis", 1, -1500), // payment 1
    new InsLine("Louis", 2, -300), // payment 2 etc.})
  return evs.reduce(new Balance(), (balance, ev) => { /* ... */ })
  

In the snippet above, transaction events are defined - later, they are aggregated into a user balance state. Martin Fowler popularized the concept. See his talk on Youtube and his Event Sourcing article.