Skip to main content

Local Debugging Guide for Extend Override — C#

Last updated on April 10, 2026

This guide covers everything specific to debugging an Extend Override app written in C#. For general debugging concepts — environment setup, VS Code debug workflow, log reading, and common issues — see:

The examples in this guide use the matchmaking use case (matchmaking-function-grpc-plugin-server-csharp). The project structure and debugging steps are the same for every other Override use case — only the service file and proto differ. See the service file reference table at the end of this guide.


Project structure

matchmaking-function-grpc-plugin-server-csharp/
├── .env.template # Environment variable template
├── .vscode/
│ ├── launch.json # VS Code debug configuration
│ └── tasks.json # VS Code tasks (Build: App, etc.)
└── src/
├── plugin-arch-grpc-server-csharp.sln # Solution file
└── AccelByte.PluginArch.Demo.Server/
├── AccelByte.PluginArch.Demo.Server.csproj
├── Program.cs # Entry point — Kestrel / ASP.NET Core setup
├── appsettings.json # Server config, port assignments
├── Classes/
│ ├── AuthorizationInterceptor.cs # IAM token validation interceptor
│ ├── AppSettingConfigRepository.cs
│ └── DefaultAccelByteServiceProvider.cs
├── Model/
│ └── RuleObject.cs # GameRules model
├── Protos/
│ └── matchFunction.proto # Protobuf definition (MSBuild regenerates on build)
└── Services/
└── MatchFunctionService.cs # Your override logic
FileWhat it does
Program.csEntry point — configures Kestrel, registers gRPC services, wires the auth interceptor.
Services/MatchFunctionService.csYour override logic — extends MatchFunction.MatchFunctionBase, implements GetStatCodes, ValidateTicket, EnrichTicket, MakeMatches, BackfillMatches.
Classes/AuthorizationInterceptor.csValidates every incoming gRPC call's IAM token.
Protos/matchFunction.protoProtobuf definition — MSBuild Grpc.Tools regenerates C# stubs automatically on build.
appsettings.jsonPort bindings and application configuration.

Port numbers (configured in appsettings.json):

PortPurpose
6565gRPC server (HTTP/2) — receives calls from AGS
8080HTTP metrics endpoint (/metrics)

Running the service locally

From the terminal

# Export all variables from your .env file
export $(grep -v '^#' .env | xargs)

dotnet run --project src/AccelByte.PluginArch.Demo.Server

From VS Code

The repository does not ship with a dedicated run task separate from the debug launch. Use the terminal command above, or run the "Debug: App" launch configuration (which also builds and starts the app).

Confirming the service is up

You should see ASP.NET Core startup logs similar to:

info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://0.0.0.0:6565
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://0.0.0.0:8080
info: Microsoft.Hosting.Lifetime[0]
Application started.

Verify the gRPC server is reachable:

grpcurl -plaintext localhost:6565 list

Attaching the debugger

The repository ships with a ready-to-use launch configuration in .vscode/launch.json:

{
"name": "Debug: App",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "Build: App",
"program": "${workspaceFolder}/src/AccelByte.PluginArch.Demo.Server/bin/Debug/net8.0/AccelByte.PluginArch.Demo.Server.dll",
"args": [],
"cwd": "${workspaceFolder}/src/AccelByte.PluginArch.Demo.Server",
"stopAtEntry": false,
"envFile": "${workspaceFolder}/.env",
"console": "integratedTerminal",
"justMyCode": true
}

Follow the attaching the debugger steps in the common debugging guide, then select "Debug: App" from the dropdown.

The preLaunchTask: "Build: App" step compiles the project and regenerates any protobuf stubs before the debugger launches.

Stepping into framework code

"justMyCode": true skips .NET runtime and gRPC framework frames. Set it to false if you need to step into AuthorizationInterceptor.cs or ASP.NET Core gRPC middleware.

Other IDEs — attach to running process

Start the app with diagnostics enabled:

export $(grep -v '^#' .env | xargs)
DOTNET_EnableDiagnostics=1 dotnet run --project src/AccelByte.PluginArch.Demo.Server

Then attach from JetBrains Rider or Visual Studio using Run → Attach to process.


Where to put breakpoints

What you want to investigateFile and location
A specific gRPC method being calledServices/MatchFunctionService.cs — top of the relevant method
Streaming ticket processingServices/MatchFunctionService.cs — inside the while (await requestStream.MoveNext()) loop in MakeMatches
Rules parsingServices/MatchFunctionService.csJsonSerializer.Deserialize<GameRules>(rulesJson)
Auth / token validation failureClasses/AuthorizationInterceptor.cs — the interceptor entry point
Service not starting at allProgram.cs — the host builder and app.Run() call

For conditional breakpoint syntax, see the C# language guide.


Reading logs

The service uses ASP.NET Core's built-in ILogger. For jq log filtering (if JSON output is configured), see the C# language guide.

To activate development-mode logging set DOTNET_ENVIRONMENT=Development in your .env, which enables more verbose output from the ASP.NET Core host.


Testing the override manually

For grpcurl usage and triggering the overridden AGS feature, see Testing the override manually in the Override main guide.

The demo/ directory contains a Postman collection (*.postman_collection.json) with pre-built requests. Import it into Postman and update baseUrl and token for your local setup.


C#-specific troubleshooting

Proto changes have no effect

Symptom: You edited Protos/matchFunction.proto but the generated code stubs have not updated.

Cause: MSBuild Grpc.Tools regenerates C# stubs automatically on build, but a partial or cached build may skip regeneration.

Fix: Run a clean build:

dotnet clean src/AccelByte.PluginArch.Demo.Server
dotnet build src/AccelByte.PluginArch.Demo.Server

The preLaunchTask: "Build: App" in the VS Code launch config runs this automatically before each debug session.


PLUGIN_GRPC_SERVER_AUTH_ENABLED — auth rejects all calls

Symptom: Every gRPC call returns unauthenticated when testing locally.

Fix: Add PLUGIN_GRPC_SERVER_AUTH_ENABLED=false to your .env file. This disables the AuthorizationInterceptor so you can test without a valid token. Remember to re-enable it before deploying.


DOTNET_ENVIRONMENT and configuration sources

The app may read additional configuration from appsettings.json or appsettings.Development.json. Set DOTNET_ENVIRONMENT=Development in your .env to activate development-mode configuration and more verbose host logging.


Checking for port conflicts

See Checking for port conflicts in the C# language guide.


AI assistance

Each Override use case's app template ships with a Claude agent skill at .claude/skills/debugging-guide/SKILL.md. For AI prompting tips and MCP server details, see Debugging with AI assistance in the Override main guide.


Service file reference by use case

The debugging workflow above applies to all Override use cases. Only the service file and proto vary. Use this table to find your implementation file:

Use caseC# service fileProto file
MatchmakingServices/MatchFunctionService.csProtos/matchFunction.proto
Cloud Save ValidatorSee repo READMESee repo README
Lootbox RollSee repo READMESee repo README
Profanity FilterSee repo READMESee repo README
RevocationSee repo READMESee repo README
Rotating Shop ItemsSee repo READMESee repo README
Session DSMSee repo READMESee repo README
Session ManagerSee repo READMESee repo README
Challenge AssignmentSee repo READMESee repo README

For the repository link for each use case and language, see Extend Override repositories.


References