• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

orion-ecs / keen-eye / 20395524465

20 Dec 2025 02:11PM UTC coverage: 62.297% (-0.5%) from 62.793%
20395524465

push

github

tyevco
Add voxel game sample with biome-based terrain generation

This sample demonstrates how to build a voxel-based game using KeenEyes ECS:

- Chunk-based world storage with 16x16x16 voxel chunks
- Simplex noise terrain generation with multiple biomes
  (Plains, Forest, Desert, Mountains, Tundra, Ocean)
- Temperature and moisture-based biome selection
- Feature placement (trees, cacti, plants) using deterministic noise
- Player movement with AABB collision against voxel terrain
- Chunk loading/unloading based on player view distance
- ASCII side-view visualization for terminal output

Key architecture patterns shown:
- Complex component types (VoxelData, HeightMap) using IComponent directly
- System dependencies via property injection
- Seeded procedural generation for reproducible worlds
- Chunk coordinate to world coordinate transformations

2719 of 3811 branches covered (71.35%)

Branch coverage included in aggregate %.

15597 of 25590 relevant lines covered (60.95%)

0.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.72
/src/KeenEyes.Debugging/DebugPlugin.cs
1
using KeenEyes.Capabilities;
2

3
namespace KeenEyes.Debugging;
4

5
/// <summary>
6
/// Plugin that adds debugging and profiling capabilities to a KeenEyes world.
7
/// </summary>
8
/// <remarks>
9
/// <para>
10
/// The DebugPlugin provides comprehensive debugging tools including system profiling,
11
/// entity inspection, memory tracking, and GC allocation monitoring. These tools use
12
/// SystemHooks for automatic integration without modifying individual systems.
13
/// </para>
14
/// <para>
15
/// All debugging features are exposed through extension APIs that can be retrieved
16
/// using <see cref="IWorld.GetExtension{T}"/>. Features can be enabled or disabled
17
/// individually through the configuration options.
18
/// </para>
19
/// </remarks>
20
/// <example>
21
/// <code>
22
/// // Install with default options (all features enabled)
23
/// using var world = new World();
24
/// world.InstallPlugin(new DebugPlugin());
25
///
26
/// // Access debugging tools
27
/// var profiler = world.GetExtension&lt;Profiler&gt;();
28
/// var inspector = world.GetExtension&lt;EntityInspector&gt;();
29
/// var memoryTracker = world.GetExtension&lt;MemoryTracker&gt;();
30
/// var gcTracker = world.GetExtension&lt;GCTracker&gt;();
31
///
32
/// // Run your simulation
33
/// world.Update(0.016f);
34
///
35
/// // Print profiling report
36
/// foreach (var profile in profiler.GetAllSystemProfiles())
37
/// {
38
///     Console.WriteLine($"{profile.Name}: {profile.AverageTime.TotalMilliseconds:F2}ms");
39
/// }
40
/// </code>
41
/// </example>
42
/// <param name="options">Configuration options for the debug plugin.</param>
43
public sealed class DebugPlugin(DebugOptions? options = null) : IWorldPlugin
1✔
44
{
45
    private readonly DebugOptions options = options ?? new DebugOptions();
1✔
46
    private EventSubscription? profilingHook;
47
    private EventSubscription? gcTrackingHook;
48

49
    /// <summary>
50
    /// Creates a new debug plugin with default options.
51
    /// </summary>
52
    public DebugPlugin() : this(null)
1✔
53
    {
1✔
54
    }
1✔
55

56
    /// <summary>
57
    /// Gets the name of this plugin.
58
    /// </summary>
59
    public string Name => "Debug";
1✔
60

61
    /// <inheritdoc />
62
    public void Install(IPluginContext context)
63
    {
1✔
64
        // Install EntityInspector if inspection capability is available (no performance overhead)
65
        if (context.TryGetCapability<IInspectionCapability>(out var inspectionCapability) && inspectionCapability is not null)
1✔
66
        {
1✔
67
            context.TryGetCapability<IHierarchyCapability>(out var hierarchyCapability);
1✔
68
            var inspector = new EntityInspector(context.World, inspectionCapability, hierarchyCapability);
1✔
69
            context.SetExtension(inspector);
1✔
70
        }
1✔
71

72
        // Get statistics capability for MemoryTracker
73
        if (context.TryGetCapability<IStatisticsCapability>(out var statsCapability) && statsCapability is not null)
1✔
74
        {
1✔
75
            var memoryTracker = new MemoryTracker(statsCapability);
1✔
76
            context.SetExtension(memoryTracker);
1✔
77
        }
1✔
78

79
        // Get the system hook capability for profiling and GC tracking
80
        ISystemHookCapability? hookCapability = null;
1✔
81
        if (options.EnableProfiling || options.EnableGCTracking)
1✔
82
        {
1✔
83
            if (!context.TryGetCapability<ISystemHookCapability>(out hookCapability))
1✔
84
            {
1✔
85
                throw new InvalidOperationException(
1✔
86
                    "DebugPlugin requires ISystemHookCapability for profiling or GC tracking. " +
1✔
87
                    "Disable these options or provide a world that supports system hooks.");
1✔
88
            }
89
        }
1✔
90

91
        // Conditionally install profiling
92
        if (options.EnableProfiling && hookCapability is not null)
1✔
93
        {
1✔
94
            var profiler = new Profiler();
1✔
95
            context.SetExtension(profiler);
1✔
96

97
            profilingHook = hookCapability.AddSystemHook(
1✔
98
                beforeHook: (system, dt) => profiler.BeginSample(system.GetType().Name),
1✔
99
                afterHook: (system, dt) => profiler.EndSample(system.GetType().Name),
1✔
100
                phase: options.ProfilingPhase
1✔
101
            );
1✔
102
        }
1✔
103

104
        // Conditionally install GC tracking
105
        if (options.EnableGCTracking && hookCapability is not null)
1✔
106
        {
1✔
107
            var gcTracker = new GCTracker();
1✔
108
            context.SetExtension(gcTracker);
1✔
109

110
            gcTrackingHook = hookCapability.AddSystemHook(
1✔
111
                beforeHook: (system, dt) => gcTracker.BeginTracking(system.GetType().Name),
1✔
112
                afterHook: (system, dt) => gcTracker.EndTracking(system.GetType().Name),
1✔
113
                phase: options.GCTrackingPhase
1✔
114
            );
1✔
115
        }
1✔
116
    }
1✔
117

118
    /// <inheritdoc />
119
    public void Uninstall(IPluginContext context)
120
    {
1✔
121
        // Dispose hooks
122
        profilingHook?.Dispose();
1✔
123
        gcTrackingHook?.Dispose();
1✔
124

125
        // Remove extensions
126
        context.RemoveExtension<EntityInspector>();
1✔
127
        context.RemoveExtension<MemoryTracker>();
1✔
128

129
        if (options.EnableProfiling)
1✔
130
        {
1✔
131
            context.RemoveExtension<Profiler>();
1✔
132
        }
1✔
133

134
        if (options.EnableGCTracking)
1✔
135
        {
1✔
136
            context.RemoveExtension<GCTracker>();
1✔
137
        }
1✔
138
    }
1✔
139
}
140

141
/// <summary>
142
/// Configuration options for the debug plugin.
143
/// </summary>
144
/// <remarks>
145
/// These options control which debugging features are enabled and their behavior.
146
/// Features that are disabled have zero performance overhead.
147
/// </remarks>
148
public sealed record DebugOptions
×
149
{
150
    /// <summary>
151
    /// Gets or initializes a value indicating whether system profiling is enabled.
152
    /// </summary>
153
    /// <remarks>
154
    /// When enabled, the profiler tracks execution time for all systems and provides
155
    /// detailed timing metrics. Default is true.
156
    /// </remarks>
157
    public bool EnableProfiling { get; init; } = true;
1✔
158

159
    /// <summary>
160
    /// Gets or initializes a value indicating whether GC allocation tracking is enabled.
161
    /// </summary>
162
    /// <remarks>
163
    /// When enabled, tracks memory allocations per system to identify allocation hotspots.
164
    /// This has minimal overhead but may not capture all allocations in multi-threaded scenarios.
165
    /// Default is true.
166
    /// </remarks>
167
    public bool EnableGCTracking { get; init; } = true;
1✔
168

169
    /// <summary>
170
    /// Gets or initializes the phase filter for profiling hooks.
171
    /// </summary>
172
    /// <remarks>
173
    /// If specified, profiling will only track systems in the specified phase.
174
    /// If null, all systems in all phases are profiled. Default is null (profile all phases).
175
    /// </remarks>
176
    public SystemPhase? ProfilingPhase { get; init; } = null;
1✔
177

178
    /// <summary>
179
    /// Gets or initializes the phase filter for GC tracking hooks.
180
    /// </summary>
181
    /// <remarks>
182
    /// If specified, GC tracking will only monitor systems in the specified phase.
183
    /// If null, all systems in all phases are tracked. Default is null (track all phases).
184
    /// </remarks>
185
    public SystemPhase? GCTrackingPhase { get; init; } = null;
1✔
186
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc