Skip to content

[Feature]: adopt general-purpose helpers that two first-party games keep re-writing #742

Description

What this is

DoxReloaded holds utility code that is not about DoxReloaded. We scanned the game for it. This issue lists what we found, ranked.

Every candidate below passes two tests. Its parameters and return use only primitives, System.* or UnityEngine.*. No game type appears. We also searched this package first, and we say what we searched.

Package read at 3.5.0. We propose the API. We do not ask you to take our code.

Ranked candidates

# Proposed API Evidence Searched
1 DurableFile.TryWriteAllText/TryWriteAllBytes/WriteAllTextAsync/TryDelete A second first-party game already has a hand copy. The DoxReloaded file says so in its own doc comment: "Ported from the sibling IshoBoy project's DurableFile". Writes a sibling .tmp, flushes to disk, then swaps, so a broken write cannot truncate the live file Core/Helper/FileHelper.cs has InitializePath and CopyFileAsync only. PathHelper, DirectoryHelper are path resolution. No atomic write
2 BitOps.PopCount/TrailingZeroCount/HighestSetBit/Log2/NextPowerOfTwo 7 copies in the game. Two NextPowerOfTwo bodies are character-identical (VisitedStateSet.cs:80, VisitedStateDepthMap.cs:143 — verified by diff). Two PopCount bodies are the same SWAR constants over long and ulong This package carries the same private copies: Core/DataStructure/BitSet.cs:603, ImmutableBitSet.cs:282, and IListExtensions.cs:3144/1069. A public helper removes 4 duplicates here too
3 WallMath.Median/Percentile/Mean/StandardDeviation over IReadOnlyList<T> Six independent Median bodies over four element types, plus Percentile, Quantile, two Mean, one StandardDeviation. Twelve definitions WallMath.cs, MathHelpers.cs, Geometry.cs, IEnumerableExtensions.cs, IListExtensions.cs. The only Median here is a private pivot helper
4 Texture2D RotateTexture90(Texture2D, bool), RotateTexture180(Texture2D), ExtractSpriteRect(Sprite) Pure GetPixels/permute/SetPixels. Preserves source.format and swaps width and height correctly SpriteHelpers.cs has MakeReadable only. Utils/TextureScale.cs scales. Editor/Sprites/* has no rotation
5 IRandom.NextIntSkewed(int min, int max, float target, int iterations = 3) The request that started this. Averages k uniform draws, then pulls toward a target, then clamps. Two copies already: one runtime, one bench NextIntAround/NextFloatAround take a centre and a variance. NextGaussian is unbounded. NextWeighted picks an item. None give a bounded draw biased to a target
6 Exact small-sample statistics: Clopper-Pearson, Fisher exact, sign test, Mantel-Haenszel odds ratio, chi-square survival 1400 lines that import only System, System.Collections.Generic, System.Linq, System.Text.Json. Ships its own self-test battery No statistics module
7 ShapeHelper.GenerateCircularCurvePoints and two arc variants Validates arguments and reuses a caller buffer Utils/CircleLineRenderer.cs computes segments privately for a LineRenderer. No reusable arc API
8 SemaphoreLeasereadonly struct : IDisposable for SemaphoreSlim Prevents two real bugs: a finally spanning the wait releases a slot it never took, and a Release that throws during teardown hides the real failure Only SingleThreadedThreadPool uses SemaphoreSlim, privately
9 PointerEventData.TryGetWorldPoint/TryGetLocalPoint Picks the right camera across Overlay, Camera and World canvases. Prefers the raycast hit. Clamps off-screen points grep -rl PointerEventData Runtime/ Editor/ returns zero files
10 WebGL localStorage binding plus its .jslib Complete key/value store with a PlayerPrefs fallback behind a define No localStorage, no __Internal, no DllImport in Runtime/ or Editor/
11 Span<T> overloads for the sort family The game carries its own introsort over Span<T> because this package has none 18 public sorts here. Every one takes this IList<T>
12 Smaller gaps: Sha256Hex(string), named command-line GetArgument(name), RectTransformBoxCollider2D sync, pixelDragThreshold by DPI, segment-vs-circle intersection point Each is one clean method Sha256Hex: this package has a private copy at Editor/Sprites/SpriteSheetExtractor.cs:4954. GetArgument: Environment.GetCommandLineArgs() is open-coded in 8 places here, all substring scans. Line2D.Intersects(Circle) returns bool; TryGetIntersectionPoint is line-vs-line

One thing to fix rather than adopt

IRandom.NextEnumExcept has overloads for 1, 2, 3, 4, and 4 + params. It has no plain params T[] overload. So a caller with a runtime-length array of fewer than four exclusions cannot call it. DoxReloaded wrote a local extension for exactly that, and the extension is unreachable, because an interface method wins over an extension method. A params T[] overload closes the gap and deletes our copy.

What we are not asking

We do not ask you to take candidates 6, 10 or 11 if they widen the package's scope too far. Say so and we will keep them local. We flag them because they are duplicated or absent, not because they must move.

Filed from DoxReloaded. Reviewer request: https://github.com/Ambiguous-Interactive/DoxReloaded/pull/803#discussion_r3952991525

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions