godot-csharp-visualstudio: Extension Doesn't seem to be working in Godot 3.2.3RC4

OS/device including version: Windows 10

Issue description:

  1. Installed Godot CSharp extension
  2. Create new project in Godot 3.2.3 RC4
  3. Add a Node into the Scene
  4. Attach new C# script.
  5. Visual Studio opens

Expected: Expected to see Play In Editor, Launch, or Attach

Actual: Only see the Project name and it will not launch instead throwing an error of A project with an Output Type of Class Library cannot be started directly

Screenshots of issue: image image image

NOTES This worked just fine when using RC3. My guess is that when RC4 upgraded to the csproj sdk format, it broke compatibility.

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 7
  • Comments: 61 (8 by maintainers)

Commits related to this issue

Most upvoted comments

By the way, there’s a workaround you can use today to make the extension work. The idea is to use an old style C# project as placeholder to trigger the extension.

Add a new C# project to your solution. Make sure it’s an old style project, not Sdk style. Add the ProjectTypeGuids containing the Godot GUID, and add a project reference to your actual game project. Here’s an example:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{F97F64DA-67E2-448D-8516-2F7427C8B882}</ProjectGuid>
    <OutputType>Library</OutputType>
    <RootNamespace>StubProj</RootNamespace>
    <AssemblyName>StubProj</AssemblyName>
    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <Deterministic>true</Deterministic>
    <ProjectTypeGuids>{8F3E2DF0-C35C-4265-82FC-BEA011F4A7ED};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <ProjectReference Include="..\MyGame.csproj">
      <Project>{5957a55d-a731-4684-85cb-0bf023e5d393}</Project>
      <Name>MyGame</Name>
      <Private>False</Private>
    </ProjectReference>
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

Change the path, guid and name of the ProjectReference to point to your game project (or just remove that part and add the project reference from Visual Studio).

Set this project as the “Startup Project” in Visual Studio, either from the toolbar next to the launch button or right click the project and “Set as Startup Project”.

That should be enough to make it work. The launch button should be “Play in Editor” again.

The reason the placeholder project needs to reference your game project is because otherwise VS shows “No compatible code running” when a breakpoint hits.

Follow my findings I mentioned above. Basically you only need to add this:

 <PropertyGroup>
    <StartAction>Program</StartAction>
    <StartProgram>C:\Path\To\Godot.exe</StartProgram>
    <StartArguments>--path C:\Path\To\Godot\Project\</StartArguments>
  </PropertyGroup>

to your .csproj and you can start debugging. If you want to add the differen launch profiles you can setup the launchsettings.json.

But currently I’m more interested in getting the csp sample to work

I’ve pointed a few people at this issue who needed more info to successfully apply the workaround. So, I decided to try it out and document a full process to get the workaround in place.

Step by step workaround guide:

https://gist.github.com/31/302bab2630ddf8d90ab4aec0d358b538

I can confirm the workaround still works. I feel like a better solution. and something that’s needed regardless. is a generate vs project button in godot. Then it can just generate the proxy project for you.

I confirm this issue , Windows 3.2.3 RC 5

I’ll have a look. The ProjectTypeGuid was moved to the Sdk. I hope Visual Studio can support that.

Alright! That was it. This link: https://docs.godotengine.org/en/stable/getting_started/scripting/c_sharp/c_sharp_basics.html#configuring-vs-2019-for-debugging does not work with this fix. Uninstalled VSMonoDebugger and it started right up. Thank you @piratesephiroth and @31!

I remember trying the CpsExtension sample without success (it either didn’t compile or MEF threw exceptions due to missing stuff). I might give it another try soon with the information here (it seems they added this page a few months ago): https://github.com/dotnet/project-system/blob/main/docs/launch-profiles.md

Exciting news, maybe.

To update the research that @31 did (over a year ago now, lol) there have been some potentially useful things I’ve found. I’m not experienced enough to figure out the details of implementing this in a way that won’t drive me insane, but hopefully someone else is capable.

The most useful resource (probably, at least in the meantime) is this section of the CPS repo which seems to detail exactly what we need. Of course, the sample itself was last updated 3 years ago, so that might throw a wrench into the works.

The only other caveat is that they (I think) use a NuGet package as the qualifying parameter that makes the debug option show up, so I’m not certain if you could switch that to target the new SDK parameter in .csproj (or however else the Godot SDK project type manifests itself).

The full documentation for CPS is found here, which should help with any other issues that crop up, especially regarding the outdated-ness of the sample plugin.

More importantly, while I’m not sure of its compatibility with the existing plugin or the versions of .NET/Mono that Godot uses, Microsoft has basically abandoned CPS in favor of the .NET Project System which is built upon the former and definitely worth looking into, if nothing else.

Sorry for the delayed reply. It’s as @31 said, Visual Studio uses a new project system for Sdk style projects. I’ve tried about everything to get the extension working with the new VS project system, but nothing seems to work. In fact not even the samples worked (throwing composition exceptions that seem to indicate some of the DebugLaunchProviderBase imports cannot be satisfied). At this point I’m not sure if right now this new project system support the extensibility we need.

As that problem is unlikely to be solved soon, we will need to go with a workaround. I’ll make the extension load always to have Godot special code completion work, and I will add commands for launching the debugger similarly to @31’s workaround.

That should be enough to make the extension usable again, even if it’s a degraded experience. At least until we can make this work with the new project system.

It works in combination with @neikeq 's way of starting Godot. If you remove the “StartArguments” and move them into the “commandLineArgs” of the launchSettings.json file you can start your project with different arguments.

Looks like this:

{
  "profiles": {
    "Launch": {
      "commandName": "Project"
    },
    "PlayInEditor": {
      "commandName": "Project",
      "commandLineArgs": "--path [Path/to/godot/project]"
    }
  }
}

And in you .csproj:

<PropertyGroup>
	<StartAction>Program</StartAction>
	<StartProgram>[Path/to/Godot.exe]</StartProgram>
</PropertyGroup>

if you leave your commandLineArgs empty it just launches godot without a project.

Not sure if we can realize an “attach” functionality this way tho.

Edit: I think it should be possible that the extension creates the launchSettings.json and the entry in the .csproj for you

Addendum: Seems like “launchSettings.json” is the right thing to use… In your project, create a folder named “Properties” and place the file inside.

This is how it looks: grafik

Obviously, this doesn’t do anything yet… But maybe we can use this somehow.

Found something new. Maybe we this could help to solve the sdk style problem… https://docs.microsoft.com/en-us/visualstudio/ide/customize-build-and-debug-tasks-in-visual-studio?view=vs-2022

Maybe we could use a launch.vs.json to set the different debug targets. And then we would need to communicate it back to the extension.

Mabe there are events for that?

@neikeq Just a question related to this bug, since .net6 was merged into Godot 4, will Godot 4 suffer from this bug as well or was work done to solve this issue without the above workaround?

You know what? I forgot to mention the main project .csproj file doesn’t have a GUID in it:

This is normal as of Godot 3.2.3+, since it uses the new project system. I didn’t need any GUID in my ProjectReference for the workaround to work for me.

You know what? I forgot to mention the main project .csproj file doesn’t have a GUID in it: <Project Sdk="Godot.NET.Sdk/3.2.3"> <PropertyGroup> <TargetFramework>net472</TargetFramework> <RootNamespace>Platformer</RootNamespace> </PropertyGroup> </Project> The other projects I’ve made have them. I’m going to play around with it and see if I can figure out why, and see if that is the problem maybe. As for Rider @mudbug-z, I have it and Visual Studio/Resharper both. I like VS just a bit more, some hotkey or something Rider doesn’t have, I can’t remember. But it’s getting to the point where I will take just works over whatever I used to like more lol

Alright, last ditch effort, then I’ll start asking about how to get Rider to work. LOL I just started a brand new project in Godot. Empty. Made an object, attached a C# script. It created an .sln and .csproj, but the project file is as the last one. No GUID and just those 6 lines. Well, 5, doesn’t have a namespace yet. I tried 3.3 rc7 mono in case mine wasn’t new enough. Same outcome. Also tried setting this up with another project that had a full project file. Same error.

In case anyone is interested, JetBrains Rider works GREAT with Godot mono out of the box. Of course, it isn’t free. For me it is worth the cost.

Here’s my tutorial:

Important: The VSMonoDebugger extension will prevent this one from from working.
Please disable or remove it before trying this workaround.

Get the snippet neikeq posted above and paste it into a new text file. Now edit this “ProjectReference” block:

    <ProjectReference Include="..\MyGame.csproj">
      <Project>{5957a55d-a731-4684-85cb-0bf023e5d393}</Project>
      <Name>MyGame</Name>
      <Private>False</Private>
    </ProjectReference>
  • Change the Include attribute, from “…\MyGame.csproj” to a relative path that points to your game’s .csproj file. Just the file name is fine if you placed this stub project it in the same folder as he original project.
  • The Project, Name amd Private elements aren’t necessary, you can just delete those lines.

Now save the file as Stub.csproj or whatever.

Now open your project’s solution file in Visual Studio. Right click the solution in Solution Explorer and select “Add” -> “Existing Project”, then select your new Stub project file.

Now right-click the Stub project in Solution Explorer and select “Set as Startup project”. (you can also do that from the solution’s properties) “Play in Editor” should be visible at this point.

@juanpaexpedite You should have a Godot editor instance open editing the same project. If you already have and still get that error, then it’s a bug. But that would be a different issue to this one.

I dug into this, and I got something working again, but with a significantly degraded experience. 😕 Basically, I made a button that assumes the current startup project is a Godot project and launches the debugging session.


The problem seems to be the new project system, and not using ProjectTypeGuid at all anymore. The first hint I saw towards this was https://github.com/dotnet/project-system/issues/232:

~ProjectTypeGuids property~

<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

Used to indicate the project factories that should be used to open a project inside Visual Studio.

CPS completely removes the need for this, and this can be safely removed for projects that have opt’d into CPS.

There’s also this chart indicating a very different new system in use for .NET-Core-style projects: https://github.com/microsoft/VSProjectSystem#compare-mpfproj-and-visual-studio-project-system

Criteria MPFProj Visual Studio Project System (this repo)
Maturity Release Preview
Breaking changes in major updates None Expected
[…] […] […]
Used by project systems Desktop C#/VB/F# .NET Core C#/VB/F# and C++
[…] […] […]

They have a doc page for project flavoring: https://github.com/microsoft/VSProjectSystem/blob/master/doc/overview/extend_an_existing_project_type.md. But… as of writing, it’s TODO 😢:

Extend an existing project type

TODO

I wanted to try out using the new system, but I hit a wall trying to find docs or any kind of example that resembles what the Godot extension needs. Maybe someone will have more success than me here.


On to what I did… I added a basic Command template and wired in a few methods to assume the current default project is a Godot project, register it, and launch the debugging session:

image ^ This shows up as “Tools.DebugCommand” in the keybinding settings.

image

Branch/diff: button-assume-godot

This is my first time doing anything beyond F5ing a VS extension project, so I don’t have the experience to polish this up into something that might be usable broadly. Maybe the general approach of simply having our own set of launch buttons might be good enough for now? It’s good enough for me, and still way better than trying to use the Mono debugger manually.