Build A New Project
It may be easier for you to start a new game project by building one from “scratch” rather than starting with the “Hello, Murder!” project directly. This project will result in a bare Murder project, with no Git history and no components, entities or systems.
Git and .NET 8 are required. This tutorial uses command-line tools instead of Visual Studio.
-
Create a new project folder and navigate inside it.
We're going to call this "MyProject", but feel free to name it whatever you like. We'll highlight the lines that call out MyProject so be sure to change all references of "MyProject" to match your project name. -
Create a solution within this folder using the dotnet command-line utility.
dotnet new sln --name MyProject
-
Add a Directory.Build.props file. This is necessary for the Bang analyzers to work. (This is lifted from the hellomurder repo.)
<Project> <PropertyGroup> <Nullable>enable</Nullable> <LangVersion>preview</LangVersion> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> <ImplicitUsings>enable</ImplicitUsings> </PropertyGroup> <!-- Add beautiful Bang analyzers --> <ItemGroup> <ProjectReference Include="..\..\murder\bang\src\Bang.Analyzers\Bang.Analyzers.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <OutputItemType>Analyzer</OutputItemType> </ProjectReference> </ItemGroup> </Project>
-
This step is optional, but highly recommended.
Copy these files from the hellomurder repo, or create your own:
- .gitignore
- .editorconfig
- README.md
-
Initialize a git repository.
git init
-
Add Murder as a git submodule and update:
git submodule add ../../isadorasophia/murder git submodule update --init --recursive
-
Create a new folder, src, with two subfolders, MyProject and MyProject.Editor.
mkdir src mkdir src/MyProject mkdir src/MyProject.Editor
-
Create a new dotnet project in the src/MyProject folder. This will build a barebones Program.cs and MyProject.csproj file.
cd src/MyProject dotnet new console
-
Create a new file, src/MyProject/MyProjectGame.cs
using Murder; using Murder.Serialization; using System.Text.Json; namespace MyProject; /// <summary> /// <inheritdoc cref="IMurderGame"/> /// </summary> public class MyProjectGame : IMurderGame { /// <summary> /// <inheritdoc/> /// </summary> public string Name => "MyProject"; public JsonSerializerOptions Options => MyProjectSerializerOptionsExtensions.Options; }
-
The project now needs references to Murder, Bang, and Gum. Replace the contents of the barebones src/MyProject/MyProject.csproj file with the following:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>net8.0</TargetFramework> <PublishAot>true</PublishAot> <IsTrimmable>false</IsTrimmable> <JsonSerializerIsReflectionEnabledByDefault>false</JsonSerializerIsReflectionEnabledByDefault> <!-- Investigate if we need this --> <ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles> <GeneratorParentAssembly>Murder</GeneratorParentAssembly> </PropertyGroup> <!-- Resources --> <ItemGroup> <Content Include="resources\**" CopyToOutputDirectory="PreserveNewest" LinkBase="resources" /> <Content Include="packed\**" CopyToOutputDirectory="PreserveNewest" TargetPath="resources\%(RecursiveDir)\%(Filename)%(Extension)" /> </ItemGroup> <ItemGroup> <None Remove="resources\Icon.bmp" /> <None Remove="resources\Icon.ico" /> </ItemGroup> <ItemGroup> <EmbeddedResource Include="resources\Icon.bmp"> <LogicalName>Icon.bmp</LogicalName> </EmbeddedResource> <EmbeddedResource Include="resources\Icon.ico"> <LogicalName>Icon.ico</LogicalName> </EmbeddedResource> </ItemGroup> <ItemGroup> <ProjectReference Include="..\..\murder\src\Murder.Editor\Murder.Editor.csproj" /> <ProjectReference Include="..\..\murder\src\Murder\Murder.csproj" /> </ItemGroup> <ItemGroup> <!-- Pretty analyzers! --> <ProjectReference Condition="'$(Configuration)' == 'Debug'" Include="..\..\murder\bang\src\Bang.Analyzers\Bang.Analyzers.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <OutputItemType>Analyzer</OutputItemType> </ProjectReference> <!-- And generators! --> <ProjectReference Include="..\..\murder\bang\src\Bang.Generator\Bang.Generator.csproj"> <ReferenceOutputAssembly>true</ReferenceOutputAssembly> <OutputItemType>Analyzer</OutputItemType> </ProjectReference> <CompilerVisibleProperty Include="GeneratorParentAssembly" /> <!-- Serialization generator --> <ProjectReference Include="..\..\murder\src\Murder.Serializer\Murder.Serializer.csproj"> <ReferenceOutputAssembly>true</ReferenceOutputAssembly> <OutputItemType>Analyzer</OutputItemType> </ProjectReference> </ItemGroup> <ItemGroup> <!-- Do not trim our assemblies for Native AOT --> <TrimmerRootAssembly Include="Bang" /> <TrimmerRootAssembly Include="Murder" /> <TrimmerRootAssembly Include="MonoGame.Framework" /> <TrimmerRootAssembly Include="MyProject" /> </ItemGroup> <ItemGroup> <Compile Update="loc\LocalizedResources.Designer.cs"> <DesignTime>True</DesignTime> <AutoGen>True</AutoGen> <DependentUpon>LocalizedResources.resx</DependentUpon> </Compile> </ItemGroup> <ItemGroup> <Folder Include="Systems\Physics\" /> </ItemGroup> </Project>
-
Replace the contents of the barebones Program.cs file with the following:
using Murder; using Murder.Diagnostics; namespace MyProject { public static class Program { [STAThread] static void Main() { try { using Game game = new(new MyProjectGame()); game.Run(); } catch (Exception ex) when (GameLogger.CaptureCrash(ex)) { } } } }
-
Create a new folder at src/MyProject/resources folder. Copy these files from the src/HelloMurder/resources folder of the hellomurder repo, or create your own:
- app.manifest
- Icon.bmp
- Icon.ico
- icon.png
-
Create a new barebones Editor project in the src/MyProject.Editor folder:
cd ../MyProject.Editor dotnet new console
-
Create a new file, src/MyProject.Editor/MyProjectArchitect.cs
using Murder.Editor; namespace MyProject.Editor { public class MyProjectArchitect : MyProjectGame, IMurderArchitect { } }
-
Replace the contents of the barebones src/MyProject.Editor/Program.cs file with the following:
using Murder.Editor; namespace MyProject.Editor { public static class Program { [STAThread] static void Main() { using var editor = new Architect(new MyProjectArchitect()); editor.Run(); } } }
-
Additional dependencies are required. Replace the contents of the barebones src/MyProject.Editor/MyProject.Editor.csproj file with the following:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>net8.0</TargetFramework> <PublishReadyToRun>false</PublishReadyToRun> <TieredCompilation>false</TieredCompilation> <DefineConstants>$(DefineConstants);EDITOR</DefineConstants> </PropertyGroup> <!-- Set icon! --> <PropertyGroup> <ApplicationManifest>..\MyProject\resources\app.manifest</ApplicationManifest> <ApplicationIcon>..\MyProject\resources\Icon.ico</ApplicationIcon> </PropertyGroup> <ItemGroup> <EmbeddedResource Include="..\MyProject\resources\Icon.ico" Link="Resources\Icon.ico"> <LogicalName>Icon.ico</LogicalName> </EmbeddedResource> <EmbeddedResource Include="..\MyProject\resources\Icon.bmp" Link="Resources\Icon.bmp"> <LogicalName>Icon.bmp</LogicalName> </EmbeddedResource> </ItemGroup> <ItemGroup> <ProjectReference Include="..\..\murder\src\Murder.Editor\Murder.Editor.csproj" /> <ProjectReference Include="..\MyProject\MyProject.csproj" /> </ItemGroup> </Project>
-
Add the projects to the solution.
cd ../.. dotnet sln add src/MyProject dotnet sln add src/MyProject.Editor
-
An Aseprite file is needed to build an atlas and can be deleted later. This Aseprite file should be in the resources folder at the base project folder (note: not inside the src/ folder).
If you do not use aseprite, you can copy resources/images/tiles/walls.ase from the hellomurder repo.
-
Commit the contents to git before launching.
git add . git commit -m "Initial commit."
-
Launch src/MyProject.Editor
cd src/MyProject.Editor dotnet run
Launching the Editor will create a new “Editor Settings” file, with the name you set in MyProjectGame.cs, and a new “Game Profile” file named game_config in the src/MyProject/resources folder.
You now have a completely fresh project of your own! As mentioned above, this is a “bare” Murder project with no Git history and no components, entities or systems, so there’s nothing stopping you from deploying your own code.