| 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 |
SemaphoreLease — readonly 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), RectTransform→BoxCollider2D 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 |
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.*orUnityEngine.*. 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
DurableFile.TryWriteAllText/TryWriteAllBytes/WriteAllTextAsync/TryDeleteDurableFile". Writes a sibling.tmp, flushes to disk, then swaps, so a broken write cannot truncate the live fileCore/Helper/FileHelper.cshasInitializePathandCopyFileAsynconly.PathHelper,DirectoryHelperare path resolution. No atomic writeBitOps.PopCount/TrailingZeroCount/HighestSetBit/Log2/NextPowerOfTwoNextPowerOfTwobodies are character-identical (VisitedStateSet.cs:80,VisitedStateDepthMap.cs:143— verified bydiff). TwoPopCountbodies are the same SWAR constants overlongandulongCore/DataStructure/BitSet.cs:603,ImmutableBitSet.cs:282, andIListExtensions.cs:3144/1069. A public helper removes 4 duplicates here tooWallMath.Median/Percentile/Mean/StandardDeviationoverIReadOnlyList<T>Medianbodies over four element types, plusPercentile,Quantile, twoMean, oneStandardDeviation. Twelve definitionsWallMath.cs,MathHelpers.cs,Geometry.cs,IEnumerableExtensions.cs,IListExtensions.cs. The onlyMedianhere is a private pivot helperTexture2D RotateTexture90(Texture2D, bool),RotateTexture180(Texture2D),ExtractSpriteRect(Sprite)GetPixels/permute/SetPixels. Preservessource.formatand swaps width and height correctlySpriteHelpers.cshasMakeReadableonly.Utils/TextureScale.csscales.Editor/Sprites/*has no rotationIRandom.NextIntSkewed(int min, int max, float target, int iterations = 3)NextIntAround/NextFloatAroundtake a centre and a variance.NextGaussianis unbounded.NextWeightedpicks an item. None give a bounded draw biased to a targetSystem,System.Collections.Generic,System.Linq,System.Text.Json. Ships its own self-test batteryShapeHelper.GenerateCircularCurvePointsand two arc variantsUtils/CircleLineRenderer.cscomputes segments privately for aLineRenderer. No reusable arc APISemaphoreLease—readonly struct : IDisposableforSemaphoreSlimfinallyspanning the wait releases a slot it never took, and aReleasethat throws during teardown hides the real failureSingleThreadedThreadPoolusesSemaphoreSlim, privatelyPointerEventData.TryGetWorldPoint/TryGetLocalPointgrep -rl PointerEventData Runtime/ Editor/returns zero fileslocalStoragebinding plus its.jslibPlayerPrefsfallback behind a definelocalStorage, no__Internal, noDllImportinRuntime/orEditor/Span<T>overloads for the sort familySpan<T>because this package has nonethis IList<T>Sha256Hex(string), named command-lineGetArgument(name),RectTransform→BoxCollider2Dsync,pixelDragThresholdby DPI, segment-vs-circle intersection pointSha256Hex: this package has a private copy atEditor/Sprites/SpriteSheetExtractor.cs:4954.GetArgument:Environment.GetCommandLineArgs()is open-coded in 8 places here, all substring scans.Line2D.Intersects(Circle)returnsbool;TryGetIntersectionPointis line-vs-lineOne thing to fix rather than adopt
IRandom.NextEnumExcepthas overloads for 1, 2, 3, 4, and4 + params. It has no plainparams 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. Aparams 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