Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 48 additions & 63 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,63 +1,48 @@
# AGENTS.md: Universal Principles for CSharp and General Programming

This guide provides universal, intelligent principles and patterns to master C# coding effectively, applicable across any project or repository.

## 🧠 Structured Reasoning

* **Single Responsibility Principle (SRP)**: Every class and method should have one clearly defined responsibility.
* **Explicit Intent**: Write self-descriptive methods and classes, avoiding ambiguous or overly general names.
* **Readability First**: Prioritize readability over cleverness. The intent of your code should be immediately clear to others.

## 🎯 Clarity & Explicitness

* Clearly specify the purpose, parameters, and return values of each method using XML documentation comments.
* Choose names that explicitly describe intent (e.g., `CalculateTotalPrice()` instead of `Calculate()` or `CalcTP()`).
* Favor descriptive variable names (`customerAge` rather than `ca`).

## 🔄 Iterative Improvement

* Implement incremental changes and continuously validate with unit tests.
* Regularly refactor code to simplify complexity and improve maintainability.
* Conduct periodic peer reviews to integrate diverse perspectives and catch overlooked issues.

## 🛡️ Robustness & Safety Nets

* Write unit tests covering critical paths and edge cases to ensure code stability and correctness.
* Leverage static code analysis tools like Roslyn analyzers and StyleCop to maintain high-quality standards.
* Use assertions liberally to document and enforce assumptions in code logic.

## 🏗️ Universal Design Patterns

* **Factory & Abstract Factory**: For managing object creation and reducing direct dependencies.
* **Strategy Pattern**: To encapsulate varying algorithms and make behaviors interchangeable.
* **Repository Pattern**: For abstracting data layer logic and enhancing testability.
* **Dependency Injection**: Use constructor injection to clearly define dependencies and improve modularity.

## ♻️ Maintainable Code Habits

* Avoid magic numbers; define constants or configuration settings instead.
* Keep methods short (ideally fewer than 30 lines) to enhance readability and testability.
* Organize methods logically within classes (constructors first, public methods next, followed by private methods).

## 🚦 Consistent Coding Style

* Adhere to established naming conventions:

* Methods & Variables: `PascalCase`
* Private fields & parameters: `camelCase`
* Constants: `UPPERCASE_WITH_UNDERSCORES`
* Consistently format your code using tools like `.editorconfig`.

## 📈 Performance Awareness

* Understand the performance implications of collections (prefer using `Dictionary` for key-value lookups over lists).
* Minimize object allocations, especially within loops or performance-critical paths.
* Favor efficient data structures and algorithms suited to the task at hand (e.g., HashSets for uniqueness checks).

## 🛠️ Continuous Learning & Reflection

* Periodically review code written previously to identify opportunities for improvement.
* Stay updated on language features and industry best practices.
* Learn from established open-source C# projects and communities.

By internalizing these universal principles, you build a solid foundation to become a proficient and thoughtful C# developer.
# Eclipse Agent Guide

This file is for Codex and other coding agents working in this repository. Keep changes narrow, evidence-led, and specific to Eclipse's V Rising client UI and Bloodcraft bridge runtime.

## Start Here

- Before acting, restate the exact problem, main non-goals, and the condition that should make you stop instead of pushing forward.
- Check the current branch and worktree before editing. Do not rebase, push, merge, delete, retarget, or rewrite branches unless explicitly asked.
- Prefer small, local changes that follow the existing Eclipse patterns. Avoid broad rewrites, style-only churn, or generic architecture cleanups.
- Treat adjacent repos such as Bloodcraft and Emberglass as evidence or integration partners. Do not move their ownership boundaries into Eclipse unless the task explicitly asks for that consumer-side change.

## Build And Verification

- Use this verification ladder unless the task is explicitly docs-only:
- `git diff --check`
- `dotnet restore Eclipse.csproj`
- `dotnet build Eclipse.csproj --configuration Release -p:DeployToClient=false --no-restore`
- `Eclipse.csproj` can copy build output to a local V Rising client plugin folder when deployment is enabled. Use `-p:DeployToClient=false` for compile checks that should not stage DLLs.
- Keep Codex tooling, probes, temporary receipts, and agent-only proof artifacts under `.codex/`.
- Runtime proof helpers and receipts live under `.codex/runtime-proofs/` and `.codex/runs/`; treat those receipts and logs as evidence, not as source files to polish during unrelated tasks.

## V Rising Modding Constraints

- Preserve BepInEx, Harmony, VampireReferenceAssemblies, IL2CPP, and V Rising client lifecycle assumptions unless the task is specifically to change them.
- Be careful around static initialization, world access, UI canvas/bootstrap timing, client readiness, and hotload/runtime-load entry points. Do not move runtime lookups earlier without proving the startup path still works.
- Eclipse initializes in stages: plugin load/config/patching first, then game/world readiness before client services and UI behavior are safe. Keep fallback paths explicit when Emberglass is unavailable or not ready.
- For Bloodcraft or Emberglass bridge work, separate registration, send, fallback, and runtime receipt evidence. Do not treat a queued or suppressed send as proof that the bridge actually delivered.
- Avoid importing framework behavior from Emberglass or server-side Bloodcraft code wholesale. Eclipse should stay a consumer UI mod unless the task explicitly changes that boundary.

## Release And Metadata Boundaries

- Keep the canonical version plain `X.Y.Z` in `Eclipse.csproj`, `thunderstore.toml`, and the top `CHANGELOG.md` entry.
- Do not commit branch-derived `-pre` or `-ft.*` versions. Those are CI outputs only.
- Defer final README, changelog, and Thunderstore wording until after build and focused verification when a feature branch is still being stabilized.
- For release workflow changes, keep GitHub prerelease and Thunderstore package-version handling distinct.

## Workflow And Review Guidance

- For GitHub Actions changes, prefer minimal reliability fixes and use YAML-aware validation. Do not run `bash -n` against workflow YAML.
- For PowerShell proof or release scripts, keep edits small and verify the exact script or test harness touched by the change.
- For UI/runtime changes, prefer source-backed or log-backed evidence over assumptions from history alone.

## Stop Conditions

- Stop if remote or GitHub state cannot be verified for a branch/merge-train task.
- Stop if the available evidence cannot distinguish Eclipse-owned behavior from Bloodcraft, Emberglass, stale installs, dependency mismatch, or local environment failure.
- Stop if verification fails in a way that would require broadening beyond the requested scope.
- Stop before advising public release, Thunderstore publication, or bridge/runtime success when build evidence, logs, or proof receipts do not support the claim.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## Unreleased

`1.3.16`
- hardened attribute UI initialization so runtime-loaded clients defer when the inventory attribute hierarchy is not ready
- collapsed Emberglass bridge progress receipts to one client log line per config/progress batch

`1.3.15`
- added release hygiene helper scripts for changelog/version bump review and metadata updates
- added CI coverage for the release hygiene nudge before build verification
Expand Down
2 changes: 1 addition & 1 deletion Eclipse.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<BepInExPluginGuid>io.zfolmt.Eclipse</BepInExPluginGuid>
<AssemblyName>Eclipse</AssemblyName>
<Version>1.3.15</Version>
<Version>1.3.16</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<LangVersion>preview</LangVersion>
Expand Down
53 changes: 49 additions & 4 deletions Services/CanvasService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -493,16 +493,32 @@ public static bool InitializeAttributeValues(InventorySubMenu inventorySubMenu)
}
*/

Transform attributeSectionsParent = inventorySubMenu.AttributesParentConsole.transform.parent.parent.GetChild(4).GetChild(0).GetChild(2).GetChild(0);
var attributeSections = attributeSectionsParent?
if (!TryGetAttributeSectionsParent(inventorySubMenu, out Transform attributeSectionsParent))
{
return false;
}

var attributeSections = attributeSectionsParent
.GetComponentsInChildren<CharacterAttributeSection>(false).Take(1)
.Concat(attributeSectionsParent.GetComponentsInChildren<CharacterAttributeSection>(false).Skip(2));
.Concat(attributeSectionsParent.GetComponentsInChildren<CharacterAttributeSection>(false).Skip(2))
.ToList();

if (attributeSections.Count == 0)
{
return false;
}

// Core.Log.LogWarning($"Found {attributeSections.Count()} attribute sections!");

foreach (CharacterAttributeSection section in attributeSections)
{
GameObject attributesContainer = section.transform.FindChild("AttributesContainer").gameObject;
Transform attributesContainerTransform = section.transform.FindChild("AttributesContainer");
if (attributesContainerTransform == null)
{
return false;
}

GameObject attributesContainer = attributesContainerTransform.gameObject;
var attributeEntries = attributesContainer.transform.GetComponentsInChildren<CharacterAttributeEntry>(false);
int index = 0;

Expand Down Expand Up @@ -546,11 +562,40 @@ public static bool InitializeAttributeValues(InventorySubMenu inventorySubMenu)
catch (Exception ex)
{
Core.Log.LogError($"Failed to initialize attribute values for section {section.name}: {ex}");
return false;
}
}

return true;
}
static bool TryGetAttributeSectionsParent(InventorySubMenu inventorySubMenu, out Transform attributeSectionsParent)
{
attributeSectionsParent = null;

Transform attributesParent = inventorySubMenu.AttributesParentConsole?.transform;
if (attributesParent?.parent?.parent == null)
{
return false;
}

Transform root = attributesParent.parent.parent;
return TryGetChild(root, 4, out Transform child)
&& TryGetChild(child, 0, out child)
&& TryGetChild(child, 2, out child)
&& TryGetChild(child, 0, out attributeSectionsParent);
}
static bool TryGetChild(Transform parent, int index, out Transform child)
{
child = null;

if (parent == null || parent.childCount <= index)
{
return false;
}

child = parent.GetChild(index);
return child != null;
}
}
public static class DataHUD
{
Expand Down
25 changes: 25 additions & 0 deletions Services/EmberglassEclipseBridge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ internal static class EmberglassEclipseBridge
static bool _unavailableLogged;
static bool _clientReadyLogged;
static bool _notReadyLogged;
static bool _progressReceiptLogged;
static MethodInfo _sendToServer;
static PropertyInfo _isReady;
static EventInfo _onReady;
Expand Down Expand Up @@ -124,6 +125,30 @@ static void OnServerMessagePacket(User sender, EclipseServerMessagePacket packet
return;
}

LogReceivedServerMessage(messageKind);
}

static void LogReceivedServerMessage(string messageKind)
{
if (string.Equals(messageKind, "configs", StringComparison.OrdinalIgnoreCase))
{
_progressReceiptLogged = false;
Core.Log.LogInfo("[EclipseBridge:Emberglass] configs received");
return;
}

if (string.Equals(messageKind, "progress", StringComparison.OrdinalIgnoreCase))
{
if (_progressReceiptLogged)
{
return;
}

_progressReceiptLogged = true;
Core.Log.LogInfo("[EclipseBridge:Emberglass] progress received");
return;
}

Core.Log.LogInfo($"[EclipseBridge:Emberglass] {messageKind} received");
}

Expand Down
2 changes: 1 addition & 1 deletion thunderstore.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ v-rising = ["oakveil-update", "mods", "client"]
[package]
namespace = "zfolmt"
name = "Eclipse"
versionNumber = "1.3.15"
versionNumber = "1.3.16"
description = "Client UI for Bloodcraft!"
websiteUrl = "https://github.com/mfoltz/Eclipse"
containsNsfwContent = false
Loading