I am writing a game which consists of two projects in a solution:
Engine.csproj The actual executeable, holding all my core engine code.
Content.csproj A library which holds the specifics of my game. It references Engine using a <ProjectReference>
to access the engine functionality.
On startup, the Content.dll is loaded by the Engine process.
For ease of development I want to just press play in my IDE and have the following done:
- Engine.csproj gets built
- Content.csproj gets built
- Engine.exe starts
I tried also referencing the Content.csproj in Engine.csproj, but that causes a cross dependency, which causes the building process to just loop forever.
The current bandaid is a "Before launch" setting in my Rider IDE. That sadly does not work for my colleagues who mostly use Visual Studio. So a non-ide-specific fix is needed.
2
Answers
~~I assume that Engine.csproj has a
ProjectReference
to Content.csproj. In your description it is flipped. (The .exe project should have theProjectReference
indicating that it depends on the .dll project.)~~[Update]
ProjectReference
to Engine. The .exe is copied to the output of the Content project.Content.dll
viaAssembly.LoadFile()
.In Visual Studio:
In the ‘Tools’ menu, choose ‘Options…’. In ‘Projects and Solutions -> Build and Run’, verify that the value of ‘On Run, when projects are out of date:’ is not ‘Never build’. The default is ‘Always build’.
In the Solution Explorer, right-click the Engine project and choose ‘Set as Startup Project’.
In the ‘Debug’ menu, choose ‘Start Without Debugging’. This will run the startup project (Engine). If Engine or its dependency of Content are out of date, a build will be performed before running.
[Update]
Neither project will work as a startup project. Instead, in the Content project create a ‘debug launch profile’. Choose the ‘executable’ type to specify running the engine.exe.
Non-IDE specific:
MSBuild is a build engine, not a general scripting tool.
I’d suggest creating a PowerShell script that executes MSBuild to build the solution and then executes your enigne.exe executable.
From within Visual Studio and from within Rider, the PowerShell script could be executed in a number of ways including running from the terminal window.
The way to solve circular dependencies like this is to introduce interfaces. Create a third library, containing interfaces for all your engine classes. This can be referenced from both your projects, is implemented by your engine, and used by your game. This way your library do not have to reference your engine project directly.
However, I would consider reversing the dependency, and have the engine as a library and your game as the exe-project. The engine will likely be much easier to reuse if it is a library.
If you are not planning on reusing the engine you could just consider putting everything into the same project, but different namespaces.