Skip to content

Feature/sort facts by value#462

Merged
gabber235 merged 4 commits into
gabber235:developfrom
RenaudRl:feature/sort-facts-by-value
May 24, 2026
Merged

Feature/sort facts by value#462
gabber235 merged 4 commits into
gabber235:developfrom
RenaudRl:feature/sort-facts-by-value

Conversation

@RenaudRl
Copy link
Copy Markdown
Contributor

@RenaudRl RenaudRl commented May 23, 2026

https://typewriter.fibery.io/@public/Development/Features-91#Development/Features/Sort-tw-facts-by-Value-103

Summary by CodeRabbit

  • Bug Fixes

    • Facts are now consistently sorted by value (descending) across inspect, query, and list flows, improving prioritization and predictability.
  • Improvements

    • Display now uses precomputed, target-aware data for facts, ensuring listings, top‑10 outputs, and hover/suggest text show the correct value and timestamp consistently for the selected target.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 23, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Commands now pair readable facts with per-target FactData, sort inspect and query outputs by descending FactData.value, and render facts using a new FactData-aware formatting overload.

Changes

Fact Value Sorting and Formatting

Layer / File(s) Summary
Collect and sort facts by value
engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/command/TypewriterCommand.kt
facts inspect and facts query now build pairs of (ReadableFactEntry, FactData) using readForPlayersGroup(target) and sort those pairs by FactData.value descending before rendering.
Introduce FactData-aware formatting overload
engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/command/TypewriterCommand.kt
Adds FactData import and changes ReadableFactEntry.format(player) to ReadableFactEntry.format(player, data: FactData? = null) so callers can supply precomputed FactData; hover/click modify text uses the provided FactData when present.
sequenceDiagram
  participant TypewriterCommand
  participant ReadableFactEntry
  participant FactData
  TypewriterCommand->>ReadableFactEntry: call readForPlayersGroup(target)
  ReadableFactEntry->>FactData: return FactData (value, lastUpdate)
  TypewriterCommand->>TypewriterCommand: build (entry, FactData) list and sort by value desc
  TypewriterCommand->>ReadableFactEntry: call format(player, FactData) for rendering
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through code with careful paws,
Paired facts with numbers—no more flaws.
I sorted high to low with cheer,
And formatted each with data near.
Happy hops and tidy views appear!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Feature/sort facts by value' directly describes the main change: sorting facts by their FactData.value in descending order in both the facts inspect and facts query flows.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/command/TypewriterCommand.kt (1)

332-333: ⚖️ Poor tradeoff

Potential performance hit from repeated readForPlayersGroup calls during sorting (TypewriterCommand.kt ~332-333 and ~349-350)

  • ReadableFactEntry.readForPlayersGroup delegates to readForGroup; the default readForGroup can iterate the whole group.players and call readSinglePlayer per member, then sum values—so repeated selector calls during sortedByDescending can multiply that cost by the sort’s comparison behavior.
  • If the facts involved implement CachableFactEntry, readForGroup is backed by FactDatabase’s in-memory ConcurrentHashMap, making repeated reads much cheaper.
  • fact.format(target) calls readForPlayersGroup again per displayed fact, so some duplication remains.
⚡ Optional optimization if facts aren’t reliably `CachableFactEntry` (sort-key precompute)

For inspect command (~332-333):

-                val facts = page().entries.filterIsInstance<ReadableFactEntry>()
-                    .sortedByDescending { it.readForPlayersGroup(target).value }
+                val facts = page().entries.filterIsInstance<ReadableFactEntry>()
+                    .map { it to it.readForPlayersGroup(target).value }
+                    .sortedByDescending { it.second }
+                    .map { it.first }

For query/list command (~349-350):

-        val factEntries = Query.find<ReadableFactEntry>().toList()
-            .sortedByDescending { it.readForPlayersGroup(target).value }
+        val factEntries = Query.find<ReadableFactEntry>().toList()
+            .map { it to it.readForPlayersGroup(target).value }
+            .sortedByDescending { it.second }
+            .map { it.first }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/command/TypewriterCommand.kt`
around lines 332 - 333, The sort is repeatedly calling
ReadableFactEntry.readForPlayersGroup (which delegates to readForGroup and can
be expensive), causing performance issues; before calling
page().entries.sortedByDescending { ... } compute and cache each entry's score
by mapping entries to their readForPlayersGroup(target).value once (e.g., build
a List<Pair<ReadableFactEntry, Int>> or a Map) and sort by that cached score,
then use the cached score again when rendering (avoid calling
fact.format(target) if it re-invokes readForPlayersGroup, or pass the cached
score into formatting); this applies to the inspect and query/list usages around
page().entries.sortedByDescending and any subsequent fact.format(target) calls,
and leaves CachableFactEntry-backed paths unchanged while protecting non-cached
facts.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/command/TypewriterCommand.kt`:
- Around line 332-333: The sort is repeatedly calling
ReadableFactEntry.readForPlayersGroup (which delegates to readForGroup and can
be expensive), causing performance issues; before calling
page().entries.sortedByDescending { ... } compute and cache each entry's score
by mapping entries to their readForPlayersGroup(target).value once (e.g., build
a List<Pair<ReadableFactEntry, Int>> or a Map) and sort by that cached score,
then use the cached score again when rendering (avoid calling
fact.format(target) if it re-invokes readForPlayersGroup, or pass the cached
score into formatting); this applies to the inspect and query/list usages around
page().entries.sortedByDescending and any subsequent fact.format(target) calls,
and leaves CachableFactEntry-backed paths unchanged while protecting non-cached
facts.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: bf9cb82c-8b3c-4b7f-babb-d3eb9ff35bad

📥 Commits

Reviewing files that changed from the base of the PR and between c6674b8 and 9240119.

📒 Files selected for processing (1)
  • engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/command/TypewriterCommand.kt

Copy link
Copy Markdown
Owner

@gabber235 gabber235 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requested changes in CodeRabbit Change Stack

@RenaudRl RenaudRl force-pushed the feature/sort-facts-by-value branch from 9240119 to fe88c66 Compare May 23, 2026 13:25
@RenaudRl RenaudRl force-pushed the feature/sort-facts-by-value branch from fe88c66 to 65a0a1e Compare May 23, 2026 22:23
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/command/TypewriterCommand.kt`:
- Around line 343-344: The calls to ReadableFactEntry.format use the arguments
in the wrong order; change the call sites (the loop using "for ((fact, data) in
facts)" where sender.sendMini(fact.format(data, target)) is invoked and the
other invocation near the same area) to pass the Player/target first and
FactData second by replacing fact.format(data, target) with fact.format(target,
data) to match the signature private fun ReadableFactEntry.format(player:
Player, data: FactData? = null).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7c55cced-98a6-48ae-9729-521e5455fa81

📥 Commits

Reviewing files that changed from the base of the PR and between fe88c66 and 65a0a1e.

📒 Files selected for processing (1)
  • engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/command/TypewriterCommand.kt

@RenaudRl RenaudRl force-pushed the feature/sort-facts-by-value branch from 65a0a1e to 4756fb1 Compare May 24, 2026 02:36
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/command/TypewriterCommand.kt (1)

343-344: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Fix format(...) argument order to match the Kotlin signature.

Line 344 and Line 363 currently call format(data, target), but the declared signature is format(player: Player, data: FactData? = null). This won’t compile due to type mismatch.

Suggested fix
-                    sender.sendMini(fact.format(data, target))
+                    sender.sendMini(fact.format(target, data))
...
-            sender.sendMini(entry.format(data, target))
+            sender.sendMini(entry.format(target, data))
#!/bin/bash
set -euo pipefail

FILE="engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/command/TypewriterCommand.kt"

echo "Formatter declaration:"
rg -nP 'private\s+fun\s+ReadableFactEntry\.format\s*\(\s*player:\s*Player,\s*data:\s*FactData\?\s*=\s*null\s*\)' "$FILE"

echo
echo "Current call sites:"
rg -nP '\.format\s*\(\s*data\s*,\s*target\s*\)' "$FILE"

echo
echo "Expected call shape:"
rg -nP '\.format\s*\(\s*target\s*,\s*data\s*\)' "$FILE" || true

Also applies to: 362-363

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/command/TypewriterCommand.kt`
around lines 343 - 344, The calls to ReadableFactEntry.format currently pass
arguments in the wrong order (format(data, target)); change them to match the
declared signature format(player: Player, data: FactData? = null) by swapping
the arguments to format(target, data) at each call site (e.g., the loop using
for ((fact, data) in facts) and the other call around lines 362-363) so the
first argument is the Player (target) and the second is the FactData (data).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In
`@engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/command/TypewriterCommand.kt`:
- Around line 343-344: The calls to ReadableFactEntry.format currently pass
arguments in the wrong order (format(data, target)); change them to match the
declared signature format(player: Player, data: FactData? = null) by swapping
the arguments to format(target, data) at each call site (e.g., the loop using
for ((fact, data) in facts) and the other call around lines 362-363) so the
first argument is the Player (target) and the second is the FactData (data).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 65e7c032-36f2-4795-8eae-bd68ace18723

📥 Commits

Reviewing files that changed from the base of the PR and between 65a0a1e and 4756fb1.

📒 Files selected for processing (1)
  • engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/command/TypewriterCommand.kt

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/command/TypewriterCommand.kt (1)

363-363: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Fix reversed argument order—compilation error.

Line 363 passes entry.format(data, target) but the function signature at line 381 expects format(player: Player, data: FactData? = null). This tries to pass FactData as the Player parameter and will not compile.

🔧 Proposed fix
-            sender.sendMini(entry.format(data, target))
+            sender.sendMini(entry.format(target, data))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/command/TypewriterCommand.kt`
at line 363, The call to entry.format is using reversed arguments causing a type
mismatch: change the call at sender.sendMini(entry.format(data, target)) to pass
the Player first and FactData second so it matches the function signature
format(player: Player, data: FactData? = null), i.e. call entry.format(target,
data) (keep the surrounding sender.sendMini(...) unchanged).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In
`@engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/command/TypewriterCommand.kt`:
- Line 363: The call to entry.format is using reversed arguments causing a type
mismatch: change the call at sender.sendMini(entry.format(data, target)) to pass
the Player first and FactData second so it matches the function signature
format(player: Player, data: FactData? = null), i.e. call entry.format(target,
data) (keep the surrounding sender.sendMini(...) unchanged).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 75bb62ea-adfd-49dc-bed5-135ebc3799dd

📥 Commits

Reviewing files that changed from the base of the PR and between 4756fb1 and 7535429.

📒 Files selected for processing (1)
  • engine/engine-paper/src/main/kotlin/com/typewritermc/engine/paper/command/TypewriterCommand.kt

@RenaudRl RenaudRl force-pushed the feature/sort-facts-by-value branch from 7535429 to cc1677d Compare May 24, 2026 02:49
RenaudRl and others added 2 commits May 24, 2026 04:54
Replace nullable parameter with default value in parameter declaration,
removing the null-check indirection in the function body.
@gabber235 gabber235 merged commit ce016d6 into gabber235:develop May 24, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants