Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rc 1 #1851

Merged
merged 375 commits into from
Nov 4, 2024
Merged

Rc 1 #1851

merged 375 commits into from
Nov 4, 2024

Conversation

ponderingdemocritus
Copy link
Contributor

@ponderingdemocritus ponderingdemocritus commented Oct 15, 2024

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new BattleInfoLabel component for displaying ongoing battle information on the map.
    • Added useSettleRealm hook for managing realm settling functionality.
    • Implemented ExpandablePopup for displaying expandable content in the UI.
    • Added StarknetProvider for managing StarkNet connections.
    • Enhanced LeaderboardManager for improved guild ranking functionality.
    • Added KeyBoardKey component for customizable keyboard key rendering.
  • Improvements

    • Enhanced ArmyMovementManager for better account management and food cost calculations.
    • Refined MarketOrderPanel to utilize dynamic configurations for resource management.
    • Updated EntityResourceTable for improved resource calculations and rendering.
    • Improved PlayersPanel for better player management and guild interactions.
    • Enhanced BuildingPreview with sound feedback for position changes.
  • Bug Fixes

    • Fixed issues with visibility and interaction logic across various components, ensuring better user experience.
  • Styling Changes

    • Updated styles for buttons, tooltips, and various UI components for a more cohesive look.
    • Adjusted background colors and responsive styles for better visual presentation.
  • Deprecations

    • Removed unused components and functions related to guild management and player interactions.
    • Eliminated the GuildInvites, MyGuild, and Whitelist components to streamline guild functionalities.
    • Removed the ResourceWeight component as part of resource management restructuring.

Copy link

vercel bot commented Oct 15, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
eternum ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 4, 2024 0:21am
1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
eternum-landing ⬜️ Ignored (Inspect) Visit Preview Nov 4, 2024 0:21am

Copy link
Contributor

mentatbot bot commented Oct 15, 2024

You are out of MentatBot reviews. Your usage will refresh October 21 at 07:00 AM.

Copy link
Contributor

coderabbitai bot commented Oct 15, 2024

Warning

Rate limit exceeded

@ponderingdemocritus has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 7 minutes and 40 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 6f6c17a and 0683274.

Walkthrough

The pull request introduces significant modifications across various files, focusing on enhancing game mechanics, particularly in battle and resource management. Key changes include the addition of the DefenderPresent status in the ClaimStatus enum, updates to the BattleManager for improved claimability logic, and enhancements to the ProductionManager and ResourceChip components for better resource handling. The introduction of new hooks and components, such as useSettleRealm and BattleSimulationPanel, further enriches the functionality. Additionally, various UI components have been refactored for improved styling and responsiveness.

Changes

File Path Change Summary
client/src/dojo/modelManager/BattleManager.ts Added DefenderPresent to ClaimStatus, modified isClaimable, getTroopFullHealth, and getUpdatedArmy methods for enhanced claimability logic and troop health management.
client/src/dojo/modelManager/ProductionManager.ts Refactored methods to utilize multiplyByPrecision for calculations, removed currentTick parameter from netRate, and added timeUntilFinishTick for production timing.
client/src/ui/components/resources/ResourceChip.tsx Updated to include a tick prop, streamlined balance calculations, and enhanced rendering logic for resource management.
client/src/dojo/modelManager/ConfigManager.ts Introduced new properties for resource management and updated methods to retrieve configuration data dynamically.
client/src/ui/components/bank/LiquidityTable.tsx Added new import for useEntities, introduced playerStructureIds, and improved resource filtering logic.
client/src/ui/components/trading/MarketOrderPanel.tsx Enhanced resource management with configManager, updated UI components for better styling, and introduced new utility functions for calculating resource amounts.
client/src/ui/components/worldmap/battles/BattleSimulationPanel.tsx New component for simulating battles, managing troop inputs and displaying results.
client/src/hooks/helpers/use-settle-realm.tsx New hook for managing realm settling functionality, including state management for loading and error handling.
client/src/ui/components/worldmap/guilds/GuildMembers.tsx Refactored to include new functionalities for managing guild members, including inviting and removing players.
client/src/ui/components/worldmap/guilds/Guilds.tsx Updated to include new state management for creating and searching guilds, along with improved filtering logic.
client/src/ui/components/worldmap/leaderboard/LeaderboardPanel.tsx Removed component responsible for rendering leaderboard interface, focusing on guild management.
client/src/ui/components/worldmap/players/PlayersPanel.tsx Enhanced player management features, including searching and inviting players to guilds.
client/src/hooks/store/useLeaderBoardStore.tsx Removed interfaces for player and guild leaderboard data, focusing on managing hyperstructure events.
client/src/ui/elements/ExpandablePopup.tsx New component for displaying expandable popups with conditional rendering.
client/src/ui/elements/Button.tsx Updated button styles for improved visual consistency across the application.
client/src/ui/components/navigation/OSWindow.tsx Updated to include responsive design changes based on device type, enhancing user experience.
client/src/ui/components/resources/EntityResourceTable.tsx Refactored for improved resource calculations and rendering logic, utilizing configManager for dynamic values.
client/src/ui/components/worldmap/guilds/GuildsLeaderboard.tsx Removed component responsible for rendering guild leaderboard.
client/src/ui/components/worldmap/guilds/GuildsPanel.tsx Removed component managing tabbed interface for guild views.
client/src/ui/components/worldmap/guilds/MyGuild.tsx Removed component for managing guild functionalities.
client/src/ui/components/worldmap/guilds/Whitelist.tsx Removed component for managing guild player whitelists.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI
    participant BattleManager
    participant ResourceManager

    User->>UI: Selects a battle
    UI->>BattleManager: getAll()
    BattleManager-->>UI: Returns all battles
    UI->>User: Displays battles

    User->>UI: Requests troop details
    UI->>ResourceManager: getTroopFullHealth()
    ResourceManager-->>UI: Returns troop health
    UI->>User: Displays troop health
Loading

Possibly related PRs

  • fix: claim on structures + selected army #1847: This PR adds a new status, DefenderPresent, to the ClaimStatus enum in the BattleManager, which is directly related to the changes made in the main PR regarding claimability logic in the isClaimable method.
  • [client] armies rendering bugs #1836: The modifications in the ArmyManager class, particularly regarding army visibility and rendering, may relate to the overall battle management and claimability logic discussed in the main PR.
  • feat: move consts into config type, update func, cleanups #1843: The updates to the configuration management in this PR could indirectly affect how battle-related constants and configurations are handled, which ties back to the changes in the BattleManager class in the main PR.
  • Entity names #1830: While primarily focused on renaming and refactoring utility functions, the changes in this PR may impact how entities are managed, which could relate to the battle management logic in the main PR.

Poem

🐰 In the land where battles roar,
The BattleManager opens the door.
With troops and claims, we take our stand,
New strategies bloom across the land.
So gather your armies, let’s make our play,
For victory awaits at the break of day! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

Failed to generate code suggestions for PR

Copy link
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: 7

🧹 Outside diff range and nitpick comments (8)
client/src/ui/modules/chat/constants.tsx (1)

5-5: LGTM! Consider grouping color constants.

The addition of PASTEL_GREEN is consistent with the existing color scheme and naming convention. It's a valid pastel green color that complements the existing palette.

For improved code organization, consider grouping all color constants together at the top of the file, separated from other types of constants. This would enhance readability and make it easier to manage the color palette in the future.

import { shortString } from "starknet";

export const PASTEL_PINK = "#FFB3BA";
export const PASTEL_BLUE = "#BAE1FF";
export const PASTEL_GREEN = "#B5EAD7";
+
export const GLOBAL_CHANNEL = shortString.encodeShortString("global");
export const CHAT_STORAGE_KEY = "chat_tabs";
export const GLOBAL_CHANNEL_KEY = "global";
client/src/ui/modules/social/PlayerId.tsx (3)

Line range hint 18-23: LGTM: Improved type safety and state management.

The addition of type annotations for the MessageIcon props enhances code clarity and type safety. Extracting addTab from useChatStore centralizes chat tab management.

Consider using a type alias for the props to improve reusability:

type MessageIconProps = {
  playerName: string | undefined;
  selectedPlayer: ContractAddress;
};

export const MessageIcon = ({ playerName, selectedPlayer }: MessageIconProps) => {
  // ...
};

Also applies to: 27-27


31-37: LGTM: Improved tab management and tracking.

The handleClick function now uses addTab with a specific key generated by getMessageKey, enhancing tab management. The addition of lastSeen is a good improvement for potential activity tracking or read/unread functionality.

Consider adding a check for account.address to prevent potential errors:

const handleClick = () => {
  if (!playerName || !account.address) return;
  addTab({
    // ... existing code ...
  });
};

Line range hint 1-214: Overall changes improve type safety and chat functionality.

The modifications to this file enhance type safety, improve chat tab management, and introduce better tracking of user interactions. These changes align well with the PR objectives and the AI-generated summary.

Consider reviewing the PlayerId component for potential performance optimizations, such as memoizing complex computations or using React.memo for child components if they're pure and don't need frequent re-renders.

client/src/dojo/modelManager/__tests__/BattleManager.test.ts (2)

640-640: LGTM! Consider adding a comment for clarity.

The change from ClaimStatus.BattleOngoing to ClaimStatus.DefenderPresent accurately reflects the updated logic for determining structure claimability. This modification prioritizes the presence of a defender over the battle status.

Consider adding a brief comment explaining the rationale behind this change, such as:

// Prioritize defender presence over battle status for claimability
expect(isClaimable).toBe(ClaimStatus.DefenderPresent);

655-655: LGTM! Ensure consistency with previous test case.

The change to ClaimStatus.DefenderPresent is consistent with the updated logic for structure claimability, emphasizing the importance of the defender's presence.

For consistency with the previous test case, consider adding a similar comment:

// Prioritize defender presence over battle status for claimability
expect(isClaimable).toBe(ClaimStatus.DefenderPresent);
client/src/ui/modules/chat/Chat.tsx (1)

119-119: Use strict equality operator for consistency

In the comparison metadata.address == "0x0", it's recommended to use the strict equality operator === to avoid unintended type coercion.

Apply this diff to make the change:

-if (existingTab?.name === GLOBAL_CHANNEL_KEY || existingTab?.name === guildName || metadata.address == "0x0")
+if (existingTab?.name === GLOBAL_CHANNEL_KEY || existingTab?.name === guildName || metadata.address === "0x0")
client/src/ui/modules/military/battle-view/BattleActions.tsx (1)

150-156: Unnecessary non-null assertion with optional chaining

In the condition battleAdjusted?.entity_id! !== 0, the non-null assertion operator ! after entity_id is unnecessary because you're already using optional chaining with battleAdjusted?.entity_id. The ? operator ensures that if battleAdjusted is undefined, the expression short-circuits safely. Consider removing the ! for cleaner code.

Apply this diff to remove the unnecessary non-null assertion:

-if (battleAdjusted?.entity_id! !== 0 && battleAdjusted?.entity_id === selectedArmy!.battle_id) {
+if (battleAdjusted?.entity_id !== 0 && battleAdjusted?.entity_id === selectedArmy!.battle_id) {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 1490dfc and cff9d59.

📒 Files selected for processing (8)
  • client/src/dojo/modelManager/BattleManager.ts (2 hunks)
  • client/src/dojo/modelManager/tests/BattleManager.test.ts (2 hunks)
  • client/src/ui/modules/chat/Chat.tsx (10 hunks)
  • client/src/ui/modules/chat/ChatState.tsx (1 hunks)
  • client/src/ui/modules/chat/constants.tsx (1 hunks)
  • client/src/ui/modules/chat/types.tsx (0 hunks)
  • client/src/ui/modules/military/battle-view/BattleActions.tsx (5 hunks)
  • client/src/ui/modules/social/PlayerId.tsx (2 hunks)
💤 Files with no reviewable changes (1)
  • client/src/ui/modules/chat/types.tsx
🧰 Additional context used
🪛 Biome
client/src/ui/modules/chat/Chat.tsx

[error] 285-298: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (12)
client/src/ui/modules/social/PlayerId.tsx (1)

15-15: LGTM: Import statement updated for new functionality.

The addition of getMessageKey import aligns with the changes in message handling logic.

client/src/dojo/modelManager/BattleManager.ts (2)

59-59: LGTM: New ClaimStatus enum value added

The addition of DefenderPresent to the ClaimStatus enum improves the granularity of claim statuses. This change aligns well with the modifications in the isClaimable method, providing a more specific status when a defender is present.


279-279: LGTM: Enhanced claimability logic

The addition of the new condition if (defender.health.current > 0n) improves the isClaimable method by explicitly checking for a defender's presence with health. This change aligns well with the new DefenderPresent enum value and enhances the clarity of the claimability logic by providing a more specific status.

client/src/dojo/modelManager/__tests__/BattleManager.test.ts (1)

Line range hint 1-863: Overall, the changes improve test accuracy.

The modifications to the isClaimable test cases accurately reflect the updated logic for determining structure claimability. The changes prioritize the presence of a defender over the battle status, which is now consistently represented in the test assertions.

To further enhance the test suite:

  1. Consider adding a test case that explicitly checks the scenario where there's no defender but a battle is ongoing, to ensure the new logic handles all possible states correctly.
  2. Update the test descriptions to reflect the new behavior, e.g., "should return DefenderPresent if battle defence army has health" instead of the current description.
client/src/ui/modules/military/battle-view/BattleActions.tsx (8)

73-73: Correct use of nullish coalescing operator

Great job replacing the logical OR (||) with the nullish coalescing operator (??) in the initialization of localSelectedUnit. This change ensures that when ownArmyEntityId is 0, which is a valid ID, it doesn't default to 0 unintentionally.


77-77: Proper default value assignment using nullish coalescing operator

Using the nullish coalescing operator (??) to assign newLocalSelectedUnit ensures that if userArmiesInBattle is empty or entity_id is undefined, ownArmyEntityId is correctly used as the fallback value.


80-80: Updated dependencies in useEffect hook

Including ownArmyEntityId in the dependency array of the useEffect hook ensures that the effect runs whenever ownArmyEntityId changes, preventing potential issues with stale or incorrect localSelectedUnit values.


86-86: Added necessary dependency to useMemo hook

Adding userArmiesInBattle to the dependency array of the selectedArmy useMemo hook ensures that the memoized value updates correctly when the list of user armies changes.


197-197: Updated dependencies in claimStatus useMemo hook

By adding defenderArmy to the dependency array, you ensure that claimStatus is recalculated whenever defenderArmy changes. This keeps the claim status accurate with the current state.


202-202: Included currentArmiesTick in raidStatus dependencies

Adding currentArmiesTick to the dependency array of the raidStatus useMemo hook ensures that the raid status updates correctly in response to changes in army ticks.


207-207: Added currentTimestamp to battleStartStatus dependencies

Including currentTimestamp in the dependency array ensures that battleStartStatus is recalculated when the current time changes, keeping the battle start status accurate.


212-212: Updated dependencies in leaveStatus useMemo hook

By adding currentTimestamp to the dependency array, leaveStatus will now update appropriately when the current timestamp changes, ensuring the leave status remains accurate.

@@ -49,7 +49,7 @@ export const useChatStore = create<ChatState>()(
}),
hideTab: (tab: Tab) =>
set((state) => ({
tabs: state.tabs.map((t) => (t.address === tab.address ? { ...t, visible: false } : t)),
tabs: state.tabs.map((t) => (t.address === tab.address ? { ...t, displayed: false } : t)),
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Inconsistent Property Rename Detected

While the rename from visible to displayed in ChatState.tsx is correct, several other files still use the visible property. This inconsistency can lead to potential bugs and confusion.

Affected Files:

  • client/src/ui/elements/tab/tabs.tsx
  • client/src/ui/modules/navigation/LeftNavigationModule.tsx
  • client/src/ui/modules/navigation/RightNavigationModule.tsx
  • client/src/ui/modules/military/battle-view/EntityAvatar.tsx
  • client/src/ui/modules/military/battle-view/TopScreenView.tsx
  • client/src/ui/modules/military/battle-view/Battle.tsx
  • client/src/ui/modules/military/battle-view/BattleProgressBar.tsx
  • client/src/ui/modules/social/PlayerId.tsx
  • client/src/ui/modules/chat/types.tsx
  • client/src/ui/modules/chat/Chat.tsx
  • client/src/ui/modules/chat/InputField.tsx
  • client/src/ui/modules/chat/ChatTab.tsx

Recommended Actions:

  1. Uniform Rename: Update all instances of the visible property to displayed across the codebase to ensure consistency.
  2. Automate the Process: Consider using automated tools or scripts to facilitate the search and replace, minimizing the risk of manual errors.
  3. Review Dependencies: Check if any tests or components depend on the visible property and update them accordingly.
  4. Update Documentation: Ensure that all relevant documentation reflects the property rename to avoid future confusion.
🔗 Analysis chain

Approve the property rename, but verify consistency.

The change from visible to displayed in the hideTab method looks correct. This rename improves clarity about the tab's state.

However, to ensure consistency and prevent potential issues:

  1. Verify that this change is applied consistently across the entire codebase.
  2. Update any relevant documentation that might reference the visible property.
  3. Check if any components or tests are still relying on the visible property and update them accordingly.

To help verify the consistency of this change, you can run the following script:

This script will help identify any remaining occurrences of the visible property that might need updating, as well as confirm the new usage of displayed.

Would you like me to generate a more comprehensive script to automate the process of updating visible to displayed across the codebase?

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find occurrences of 'visible' property in TypeScript/JavaScript files

# Search for 'visible' property in TypeScript and JavaScript files
echo "Searching for 'visible' property in TypeScript and JavaScript files:"
rg --type-add 'web:*.{ts,tsx,js,jsx}' -t web 'visible:' -C 3

# Search for 'displayed' property to verify the new usage
echo "\nSearching for 'displayed' property in TypeScript and JavaScript files:"
rg --type-add 'web:*.{ts,tsx,js,jsx}' -t web 'displayed:' -C 3

Length of output: 13025

Comment on lines 290 to 299
<SelectItem
className="flex justify-between"
style={{ color: PASTEL_BLUE }}
key={index}
value={toHexString(player.address)}
>
{player.addressName}
</SelectItem>
))}
<SelectItem className="flex justify-between" value={GLOBAL_CHANNEL_KEY}>
<SelectItem className="flex justify-between " value={GLOBAL_CHANNEL_KEY} style={{ color: PASTEL_PINK }}>
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Refactor to use optional chaining for better readability

The condition players && players.sort... can be simplified using optional chaining players?.sort..., improving code readability.

Apply this diff to implement the change:

-{players &&
-  players
+{players?.
     .sort((a, b) => a.addressName.localeCompare(b.addressName))
     .filter((tab) => ContractAddress(tab.address) !== ContractAddress(account.address))
     .map((player, index) => (
       <SelectItem
         className="flex justify-between"
         style={{ color: PASTEL_BLUE }}
         key={index}
         value={toHexString(player.address)}
       >
         {player.addressName}
       </SelectItem>
     ))
}

Committable suggestion was skipped due to low confidence.

Comment on lines 102 to 114
try {
await battleManager.pillageStructure(selectedArmy!, structure!.entity_id);
toggleModal(
<ModalContainer size="half">
<Headline>Pillage History</Headline>
<PillageHistory structureId={structure!.entity_id} />
</ModalContainer>,
);
setBattleView(null);
setView(View.None);
} catch (error) {
console.error("Error during pillage:", error);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhanced error handling in handleRaid function

Good job adding a try-catch block around the asynchronous operation in the handleRaid function. This improves the robustness of the function by preventing unhandled promise rejections.

However, consider providing user feedback within the catch block to inform the user that an error has occurred during the raid. This could enhance the user experience by allowing them to take corrective action or retry the operation.

Comment on lines +121 to +142
try {
if (battleStartStatus === BattleStartStatus.ForceStart) {
await battle_force_start({
signer: account,
battle_id: battleManager?.battleEntityId || 0,
defending_army_id: defenderArmy!.entity_id,
});
} else {
await battle_start({
signer: account,
attacking_army_id: selectedArmy!.entity_id,
defending_army_id: defenderArmy!.entity_id,
});
}
setBattleView({
engage: false,
battleEntityId: undefined,
ownArmyEntityId: undefined,
targetArmy: defenderArmy?.entity_id,
});
} catch (error) {
console.error("Error during battle start:", error);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improved error handling in handleBattleStart function

Adding the try-catch block around the asynchronous battle_start and battle_force_start calls is a good practice to handle potential errors. To further enhance the user experience, consider displaying an error message to inform the user if the battle start fails.

Comment on lines +149 to +165
try {
if (battleAdjusted?.entity_id! !== 0 && battleAdjusted?.entity_id === selectedArmy!.battle_id) {
await battle_leave_and_claim({
signer: account,
army_id: selectedArmy!.entity_id,
battle_id: battleManager?.battleEntityId || 0,
structure_id: structure!.entity_id,
});
} else {
await battle_claim({
signer: account,
army_id: selectedArmy!.entity_id,
structure_id: structure!.entity_id,
});
}
} catch (error) {
console.error("Error during claim:", error);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Error handling enhancement in handleBattleClaim function

Including a try-catch block in the handleBattleClaim function strengthens error handling. To improve user experience, consider notifying the user about the error through UI feedback, such as a toast notification or modal dialog.

@@ -235,7 +245,7 @@
<div className="col-span-2 flex justify-center flex-wrap -bottom-y p-2 my-10 ">
<div className="grid grid-cols-2 gap-4 w-full">
<div
className={`flex flex-col gap-2 h-full w-full bg-[#FF621F] rounded-xl border-red/30 border-4 ${
className={`flex flex-col gap-2 h-full w-full bg-[#FF621F] rounded-xl border-red/30 ${
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid hardcoding color values in className

Consider using theme variables or predefined CSS classes instead of hardcoding hex color values like bg-[#FF621F] and border-red/30. This approach improves maintainability and ensures consistent styling across the application.

@@ -256,7 +266,7 @@
</Button>
</div>
<div
className={`flex flex-col gap-2 h-full w-full bg-[#377D5B] rounded-xl border-[#377D5B] border-4 ${
className={`flex flex-col gap-2 h-full w-full bg-[#377D5B] rounded-xl border-[#377D5B] ${
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use theme variables for color styling

Using hardcoded color values such as bg-[#377D5B] and border-[#377D5B] can make the code less maintainable. It's advisable to use theme-defined colors or CSS variables to promote consistency and ease future updates.

Copy link
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: 0

🧹 Outside diff range and nitpick comments (7)
client/src/hooks/helpers/useGetAllPlayers.tsx (2)

17-17: LGTM: Explicit return type improves type safety

The addition of the explicit return type Player[] for the getPlayers function enhances type safety and code readability. This change ensures that consumers of the hook can rely on the specific structure of the returned data.

Consider adding a JSDoc comment above the getPlayers function to provide more context about its purpose and usage. For example:

/**
 * Retrieves an array of unique players with their addresses and names.
 * @returns {Player[]} An array of unique Player objects.
 */
const getPlayers = (): Player[] => {
  // ... existing implementation ...
};

43-43: LGTM: Consistent type safety improvement

The addition of the explicit return type Player[] for the getPlayers function in useGetOtherPlayers is consistent with the change made in useGetAllPlayers. This enhances type safety and code readability across the file.

For consistency, consider adding a JSDoc comment above this getPlayers function as well, similar to the suggestion for useGetAllPlayers. For example:

/**
 * Retrieves an array of unique players, excluding the current user, with their addresses and names.
 * @returns {Player[]} An array of unique Player objects, excluding the current user.
 */
const getPlayers = (): Player[] => {
  // ... existing implementation ...
};
client/src/ui/modules/chat/ChatTab.tsx (1)

59-61: LGTM: Improved close button usability

The changes to the close button improve its usability and visibility:

  1. Adding p-0.5 padding increases the touch target size.
  2. Changing the icon size to w-3 h-3 makes it more visible.

These are good improvements for user interaction.

Consider adding a hover:text-red-500 class to the button for better visual feedback on hover:

- className="hover:bg-black/40 rounded-full p-0.5"
+ className="hover:bg-black/40 hover:text-red-500 rounded-full p-0.5"

This will make it clearer to users that the button is interactive and its purpose (closing/removing).

sdk/packages/eternum/src/types/common.ts (1)

368-372: LGTM! Consider using ID type for consistency.

The new Player interface looks good and provides a clear structure for representing player entities. It's well-integrated with the existing types in the file.

For consistency with other interfaces in the file, consider using the ID type (defined on line 226) for the entity_id property instead of number.

Here's a suggested minor improvement:

 export interface Player {
-  entity_id: number;
+  entity_id: ID;
   address: ContractAddress;
   addressName: string;
 }
client/src/ui/modules/chat/Chat.tsx (3)

Line range hint 23-166: Consider refactoring the Chat component for improved maintainability

The Chat component has been significantly enhanced with new features such as guild support and improved UI. However, its growing complexity suggests it might benefit from further modularization. Consider breaking it down into smaller, more focused sub-components to improve maintainability and readability.

For example, you could extract the tab rendering logic and the chat input field into separate components:

const TabList = ({ tabs, currentTab, account }) => {
  // Tab rendering logic
};

const ChatInput = ({ currentTab, salt }) => {
  // Input field logic
};

// Use in the main component
<TabList tabs={tabs} currentTab={currentTab} account={account} />
<ChatInput currentTab={currentTab} salt={salt} />

This approach would make the main Chat component more concise and easier to maintain.


Line range hint 168-298: Enhance Messages component for better maintainability and styling

The Messages component has been improved to handle guild messages and provide better visual differentiation between message types. However, there are a few areas that could be further enhanced:

  1. Consider extracting the inline styles into separate CSS classes or a styled-components approach. This would improve readability and maintainability.

  2. The message filtering logic in the useMemo hook is quite complex. Consider breaking it down into smaller, more focused functions for better readability and testability.

  3. The repeated ternary operator for determining message color could be simplified into a separate function:

const getMessageColor = (tabName: string, guildName: string | undefined) => {
  if (tabName === GLOBAL_CHANNEL_KEY) return CHAT_COLORS.GLOBAL;
  if (tabName === guildName) return CHAT_COLORS.GUILD;
  return CHAT_COLORS.PRIVATE;
};

These changes would make the component more maintainable and easier to understand.


310-409: Well-structured ChatSelect component with room for minor improvements

The new ChatSelect component is a great addition that enhances the channel selection experience. It's well-structured and handles different channel types effectively. Here are a few suggestions for minor improvements:

  1. Consider extracting the filteredPlayers logic into a separate useMemo hook to optimize performance, especially if the player list is large:
const filteredPlayers = useMemo(() => 
  players.filter(
    (player) =>
      player.addressName.toLowerCase().startsWith(searchInput.toLowerCase()) || player.addressName === selectedChannel
  ),
  [players, searchInput, selectedChannel]
);
  1. The handleTabChange function could be simplified by using a switch statement or object lookup for better readability:
const handleTabChange = (channel: string) => {
  const actions = {
    [GLOBAL_CHANNEL_KEY]: () => changeTabs(undefined, GLOBAL_CHANNEL_KEY),
    [guildKey]: () => changeTabs(undefined, guildKey, true),
    default: () => {
      const player = players.find((p) => p.addressName === channel);
      if (player) changeTabs(undefined, toHexString(player.address), true);
    }
  };
  (actions[channel] || actions.default)();
};

These changes would further improve the component's performance and readability.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between cff9d59 and 616a06f.

📒 Files selected for processing (7)
  • client/src/hooks/helpers/useGetAllPlayers.tsx (3 hunks)
  • client/src/hooks/store/useBlockchainStore.tsx (1 hunks)
  • client/src/ui/modules/chat/Chat.tsx (7 hunks)
  • client/src/ui/modules/chat/ChatState.tsx (2 hunks)
  • client/src/ui/modules/chat/ChatTab.tsx (1 hunks)
  • client/src/ui/modules/chat/constants.tsx (1 hunks)
  • sdk/packages/eternum/src/types/common.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • client/src/ui/modules/chat/ChatState.tsx
  • client/src/ui/modules/chat/constants.tsx
🧰 Additional context used
🔇 Additional comments (6)
client/src/hooks/helpers/useGetAllPlayers.tsx (2)

1-1: LGTM: Improved type safety with Player import

The addition of the Player type import from "@bibliothecadao/eternum" enhances type safety and aligns with TypeScript best practices. This change will help catch potential type-related errors early in the development process.


Line range hint 1-53: Overall: Excellent type safety improvements

The changes in this file consistently enhance type safety by explicitly defining return types and importing the Player type. These modifications improve code readability and help prevent potential type-related errors. The core logic of both hooks remains unchanged, which is good for maintaining existing behavior.

Consider implementing the suggested JSDoc comments to further improve code documentation and maintainability.

Great job on these improvements!

client/src/ui/modules/chat/ChatTab.tsx (2)

44-46: LGTM: Consistent height for chat tabs

The addition of h-8 class ensures a consistent height of 2rem (32px) for all chat tabs, which improves the overall UI consistency.


44-46: Verify the impact of padding change on tab layout

The padding has been changed from horizontal (px-2) to vertical (py-1). While this change may improve the vertical alignment, it's important to ensure it doesn't negatively impact the horizontal spacing or overall tab layout.

Please confirm that this change:

  1. Maintains proper alignment of the tab content
  2. Doesn't cause any text overflow issues
  3. Aligns well with the design specifications

If possible, provide before and after screenshots to visualize the impact of this change.

client/src/hooks/store/useBlockchainStore.tsx (1)

Line range hint 52-57: Consider the implications of always updating state

The condition for updating the state has been simplified from if (timestamp && timestamp !== currentTimestamp) to if (timestamp). This change means that the state will be updated every time a timestamp is fetched, regardless of whether it has changed.

While this simplifies the code and ensures that any changes in the timestamp are immediately reflected, it could lead to unnecessary state updates and potential re-renders if the timestamp hasn't actually changed.

Consider adding a local state to store the previous timestamp and only update the global state if the new timestamp is different:

const [prevTimestamp, setPrevTimestamp] = useState<number | undefined>(undefined);

// Inside the fetchBlockchainTimestamp function
if (timestamp && timestamp !== prevTimestamp) {
  setNextBlockTimestamp(timestamp);
  setCurrentDefaultTick(Math.floor(timestamp / Number(tickConfigDefault!.tick_interval_in_seconds)));
  setCurrentArmiesTick(Math.floor(timestamp / Number(tickConfigArmies!.tick_interval_in_seconds)));
  setPrevTimestamp(timestamp);
}

This approach would maintain the simplicity of the current implementation while potentially reducing unnecessary state updates and re-renders.

To verify the frequency of timestamp changes, we can add logging:

client/src/ui/modules/chat/Chat.tsx (1)

7-17: Improved imports and hook usage

The addition of new imports and the use of useCallback and useMemo hooks indicate efforts to optimize performance and introduce guild-related functionality. These changes are well-structured and align with React best practices.

Copy link
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

🧹 Outside diff range and nitpick comments (3)
client/src/ui/components/entities/Entity.tsx (1)

73-73: Approved: Enhanced offloading status message

The use of getEntityName(depositEntityId) improves the clarity of the offloading status message, providing users with more specific information. This is a good enhancement to the user experience.

However, consider handling potential edge cases where getEntityName might return undefined or an empty string. You could use a fallback value to ensure a meaningful message is always displayed:

<div className="flex ml-auto italic">
  Waiting to offload to {getEntityName(depositEntityId) || 'another entity'}
</div>

This ensures that even if there's an issue retrieving the entity name, the user still sees a informative message.

client/src/ui/components/bank/AddLiquidity.tsx (2)

60-61: LGTM: Improved balance handling.

The introduction of lordsBalance and resourceBalance variables centralizes balance retrieval, enhancing code readability and potentially improving performance by reducing redundant function calls.

Consider memoizing these values using useMemo to prevent unnecessary recalculations on re-renders:

const lordsBalance = useMemo(() => getBalance(entityId, Number(ResourcesIds.Lords)).balance, [entityId, getBalance]);
const resourceBalance = useMemo(() => getBalance(entityId, Number(resourceId)).balance, [entityId, resourceId, getBalance]);

127-127: LGTM: Accurate max value for Lords ResourceBar.

The use of divideByPrecision on lordsBalance for the max prop ensures that the maximum amount displayed in the Lords resource bar accurately reflects the current balance in a user-friendly format.

Consider extracting the precision division logic into a custom hook or utility function to promote reusability and consistency across the application. For example:

const useFormattedBalance = (balance: number) => useMemo(() => divideByPrecision(balance), [balance]);

// Usage in component
const formattedLordsBalance = useFormattedBalance(lordsBalance);

Then use formattedLordsBalance for the max prop.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 616a06f and cbc538d.

📒 Files selected for processing (5)
  • client/src/ui/components/bank/AddLiquidity.tsx (4 hunks)
  • client/src/ui/components/bank/ResourceBar.tsx (3 hunks)
  • client/src/ui/components/bank/Swap.tsx (3 hunks)
  • client/src/ui/components/entities/Entity.tsx (2 hunks)
  • client/src/ui/elements/NumberInput.tsx (2 hunks)
🧰 Additional context used
🔇 Additional comments (15)
client/src/ui/elements/NumberInput.tsx (2)

77-78: LGTM: Improved handling of maximum value

The changes in these lines enhance the component's behavior by ensuring that the input value doesn't exceed the specified max value when decimals are allowed. This improvement aligns the component's functionality more closely with its intended behavior and provides better control over the input range.


88-90: LGTM: Enhanced integer input handling

These changes significantly improve the handling of integer inputs:

  1. The use of Math.floor ensures that the input is always rounded down to the nearest integer.
  2. The Math.max and Math.min functions effectively clamp the value between min and max.
  3. The order of operations (floor first, then clamp) guarantees that the final value is always an integer within the specified range.

This implementation provides robust input validation and constraint handling, enhancing the overall reliability of the component.

client/src/ui/components/bank/ResourceBar.tsx (4)

Line range hint 30-31: LGTM: Addition of onFocus and onBlur props enhances component flexibility.

The new optional onFocus and onBlur props allow for custom event handling, improving the component's integration capabilities with parent components. These props are correctly passed to the NumberInput component, which is a good implementation.

Also applies to: 99-100


22-22: LGTM: Addition of max prop improves input configurability.

The new optional max prop with a default value of Infinity allows for a configurable maximum value for the input. This change enhances the component's flexibility while maintaining backward compatibility. Good implementation.

Also applies to: 34-34


97-97: LGTM: Correct usage of max prop in NumberInput component.

The max prop is correctly passed to the NumberInput component, which should apply the maximum value constraint to the input. This implementation is consistent with the prop's addition and default value.


22-22: Overall: Excellent enhancements to the ResourceBar component.

The changes to the ResourceBar component significantly improve its flexibility and configurability:

  1. The addition of onFocus and onBlur props allows for custom event handling.
  2. The new max prop with a default of Infinity enables configurable maximum input values.
  3. These props are correctly implemented in the component logic.

These enhancements maintain backward compatibility while providing more control to parent components. The implementation is clean, consistent, and follows React best practices.

Also applies to: 30-31, 34-34, 97-97, 99-100

client/src/ui/components/entities/Entity.tsx (2)

37-37: LGTM: Addition of getEntityName utility function

The addition of getEntityName to the destructured return of useEntitiesUtils is a good enhancement. It follows the existing pattern of using utility functions and will likely improve code readability when used.


Line range hint 1-145: Summary: Positive enhancements to Entity component

The changes made to the Entity component are well-implemented and improve both the component's functionality and the user experience. The addition of the getEntityName utility function and its usage in the status message provide more detailed information to the user.

These modifications are minimal, focused, and well-integrated into the existing code structure. They enhance the component's capabilities without introducing any significant issues or concerns.

Overall, this is a solid improvement to the Entity component.

client/src/ui/components/bank/AddLiquidity.tsx (4)

7-7: LGTM: New utility function import.

The addition of the divideByPrecision import is appropriate for handling precise calculations in liquidity operations.


63-63: LGTM: Simplified balance check.

The modification of the hasEnough condition improves code readability by utilizing the pre-calculated balance variables. This change maintains the same logical check while reducing complexity.


138-138: LGTM: Consistent max value handling for resource ResourceBar.

The use of divideByPrecision on resourceBalance for the max prop maintains consistency with the Lords ResourceBar modification, ensuring accurate and well-formatted maximum amounts for all resources.

If you implement the custom hook suggestion from the previous comment, remember to apply it here as well for consistency:

const formattedResourceBalance = useFormattedBalance(resourceBalance);

Then use formattedResourceBalance for the max prop.


Line range hint 1-168: Overall assessment: Improvements in balance handling and UI accuracy.

The changes in this file enhance the AddLiquidity component by improving balance retrieval, simplifying conditions, and ensuring accurate display of maximum resource amounts. The modifications are consistent and align well with the component's purpose.

Key improvements:

  1. Centralized balance retrieval
  2. Simplified balance check condition
  3. Accurate max value display for resource bars

Consider implementing the suggested optimizations:

  1. Memoize balance calculations
  2. Extract precision division logic into a custom hook

These changes will further improve performance and code maintainability.

client/src/ui/components/bank/Swap.tsx (3)

65-66: LGTM: Efficient balance memoization

The addition of memoized lordsBalance and resourceBalance variables is a good optimization. It prevents unnecessary recalculations and improves both performance and code readability. The dependencies in the useMemo hooks are correctly set, ensuring the values are updated when needed.


70-72: LGTM: Simplified and consistent balance check

The update to the hasEnough calculation is a good improvement. It now uses the memoized balance variables, which is more efficient and consistent with the earlier changes. The logic remains correct, ensuring that the user has sufficient resources for the transaction.


275-276: LGTM: Robust slippage calculation, but consider investigating negative amounts

The use of Math.abs() in the slippage calculation is a good defensive programming practice. It ensures the calculation works correctly even with negative amounts.

However, in normal operation, negative amounts shouldn't occur. While this change makes the code more robust, it might be masking an underlying issue.

Consider investigating why negative amounts might occur and add a comment explaining the rationale behind using Math.abs() here. If negative amounts are truly unexpected, you might want to add logging or error reporting for such cases.

To help investigate potential sources of negative amounts, you can run the following script:

This will help identify all locations where these amounts are being set or modified, which could potentially lead to negative values.

✅ Verification successful

To address the issue with the previous script, please run the following command to search for assignments or modifications to lordsAmount or resourceAmount in TypeScript files:


To locate all instances where lordsAmount or resourceAmount are set or modified in TypeScript files across the repository, please run the following script:


: Slippage calculation using Math.abs() confirmed as robust

The search confirmed that lordsAmount and resourceAmount are only assigned non-negative values throughout the codebase. Therefore, the use of Math.abs() in the slippage calculation is a reliable defensive measure.

No issues were found regarding the potential for negative amounts.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for places where lordsAmount or resourceAmount are set or modified
rg -t typescript -n '(lords|resource)Amount\s*=|set(Lords|Resource)Amount' src/

Length of output: 116


Script:

#!/bin/bash
# Search for places where lordsAmount or resourceAmount are set or modified in TypeScript files
rg -g '*.ts*' -n '(lords|resource)Amount\s*=|set(Lords|Resource)Amount' src/

Length of output: 123


Script:

#!/bin/bash
# Find all TypeScript files and search for assignments or method calls related to lordsAmount or resourceAmount
fd --type f --extension ts --extension tsx | xargs rg -n '(lords|resource)Amount\s*=|set(Lords|Resource)Amount'

Length of output: 1399

@@ -159,6 +162,7 @@ export const ResourceSwap = ({
resourceId={isLords ? ResourcesIds.Lords : resourceId}
setResourceId={setResourceId}
disableInput={disableInput}
max={isLords ? divideByPrecision(lordsBalance) : Infinity}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider consistent max value handling for all resources

While adding a max prop to the ResourceBar is a good idea to prevent overspending, the current implementation is inconsistent. It limits the input for Lords but not for other resources.

Consider updating the max prop to use resourceBalance for non-Lords resources:

-max={isLords ? divideByPrecision(lordsBalance) : Infinity}
+max={isLords ? divideByPrecision(lordsBalance) : divideByPrecision(resourceBalance)}

This change would ensure consistent behavior across all resource types and prevent users from inputting amounts greater than their available balance for any resource.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
max={isLords ? divideByPrecision(lordsBalance) : Infinity}
max={isLords ? divideByPrecision(lordsBalance) : divideByPrecision(resourceBalance)}

Copy link
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: 0

🧹 Outside diff range and nitpick comments (6)
client/src/ui/modules/entity-details/Entities.tsx (2)

10-10: LGTM: Simplified player structures retrieval

The use of the useEntities hook to directly access playerStructures is a clean and efficient approach. This change is consistent with the updated import and simplifies the component's logic.

Consider adding a comment explaining what playerStructures represents, especially if it's used in multiple places within the component. This can enhance code readability and maintainability.


Line range hint 1-24: Overall assessment: Improved code structure and maintainability

The changes in this file represent a positive refactoring effort:

  1. Introduction of the useEntities custom hook improves state management.
  2. Simplification of player structures retrieval enhances code readability.
  3. Consistent application of the new approach throughout the component.

These modifications align well with React best practices and should lead to more maintainable and potentially more performant code. The removal of explicit address handling suggests that this logic has been encapsulated within the useEntities hook, which is a good separation of concerns.

As the codebase evolves, consider documenting the responsibilities and usage of custom hooks like useEntities in a central location or in comments above the hook definition. This will help maintain consistency across the application and ease onboarding for new developers.

client/src/ui/modules/entity-details/CombatEntityDetails.tsx (2)

22-22: LGTM: Improved player structures access with a minor suggestion

The changes effectively implement the new useEntities hook:

  1. Direct destructuring of playerStructures simplifies the code.
  2. Usage in useOwnArmiesByPosition is correct.

Consider memoizing the result of playerStructures() if it's called frequently:

const memoizedPlayerStructures = useMemo(() => playerStructures(), [playerStructures]);

Then use memoizedPlayerStructures in the useOwnArmiesByPosition hook to potentially improve performance.

Also applies to: 28-28


Line range hint 19-165: LGTM: Component structure maintained with improved data access

The refactoring has been implemented smoothly:

  1. Overall component logic and structure remain intact.
  2. Changes are localized to data fetching, improving maintainability.
  3. The component continues to handle army selection, tab management, and sub-component rendering effectively.

Consider enhancing type safety by explicitly typing the useEntities hook return value:

const { playerStructures }: { playerStructures: () => PlayerStructure[] } = useEntities();

This would provide better IDE support and catch potential type mismatches early.

client/src/hooks/helpers/useEntities.tsx (2)

Line range hint 154-158: Fix incorrect dependencies in useMemo for getPlayerStructures

In the getPlayerStructures function, the dependency array for useMemo incorrectly includes otherRealms instead of playerStructures. This may cause the memoized value to not update correctly when playerStructures changes.

Apply this diff to correct the dependency array:

-    }, [otherRealms, filterFn]);
+    }, [playerStructures, filterFn]);

Line range hint 160-164: Fix incorrect dependencies in useMemo for getOtherStructures

Similarly, in the getOtherStructures function, the dependency array for useMemo incorrectly includes otherRealms instead of otherStructures. This could lead to stale data being returned.

Apply this diff to correct the dependency array:

-    }, [otherRealms, filterFn]);
+    }, [otherStructures, filterFn]);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between cbc538d and 44c2368.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • client/src/hooks/helpers/useEntities.tsx (1 hunks)
  • client/src/hooks/store/useMarketStore.tsx (0 hunks)
  • client/src/ui/modules/entity-details/CombatEntityDetails.tsx (2 hunks)
  • client/src/ui/modules/entity-details/Entities.tsx (1 hunks)
  • client/src/ui/modules/military/Military.tsx (1 hunks)
  • contracts/manifests/dev/deployment/manifest.json (1 hunks)
  • contracts/manifests/dev/deployment/manifest.toml (1 hunks)
💤 Files with no reviewable changes (1)
  • client/src/hooks/store/useMarketStore.tsx
✅ Files skipped from review due to trivial changes (1)
  • contracts/manifests/dev/deployment/manifest.json
🧰 Additional context used
🔇 Additional comments (8)
client/src/ui/modules/military/Military.tsx (3)

15-15: LGTM! Correct update of useMemo dependencies.

The update of the useMemo dependencies to include playerStructures is correct and consistent with the changes made to the data source. This ensures that the memoized value is recalculated appropriately when the player structures or entityId changes.


11-11: LGTM! Verify consistency of the new entity management approach.

The switch to using useEntities for retrieving player structures is a good improvement. It centralizes entity management and potentially simplifies the component's logic.

To ensure this new approach is consistently applied across the codebase, please run the following script:

#!/bin/bash
# Description: Check for consistency in entity management approach

# Test 1: Check for other usages of useEntities in the codebase
echo "Checking for useEntities usage across the codebase:"
rg "useEntities" --type typescript --type tsx

# Test 2: Check for any remaining usages of the old getPlayerStructures approach
echo "Checking for remaining usages of getPlayerStructures:"
rg "getPlayerStructures" --type typescript --type tsx

# Test 3: Verify the implementation of playerStructures in useEntities
echo "Verifying playerStructures implementation in useEntities:"
rg "playerStructures.*=" hooks/helpers/useEntities.ts

Also applies to: 14-14


1-1: LGTM! Consider verifying the impact of import changes.

The shift from useDojo to useEntities suggests an improvement in code organization and separation of concerns. This change looks good and aligns with best practices for custom hook usage in React.

To ensure this change doesn't negatively impact other parts of the codebase, please run the following script:

✅ Verification successful

Previous verification scripts encountered issues. Generating updated scripts to ensure accurate verification:


Previous verification encountered issues. Generating updated scripts to ensure accurate verification:


Import changes verified successfully.

  • Removed imports useDojo and getPlayerStructures are no longer used in Military.tsx.
  • useEntities is correctly exported from client/src/hooks/helpers/useEntities.tsx and properly utilized in the component.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining usages of removed imports

# Test 1: Check for any remaining usages of useDojo in this file
echo "Checking for useDojo usage in Military.tsx:"
rg "useDojo" client/src/ui/modules/military/Military.tsx

# Test 2: Check for any remaining usages of getPlayerStructures in this file
echo "Checking for getPlayerStructures usage in Military.tsx:"
rg "getPlayerStructures" client/src/ui/modules/military/Military.tsx

# Test 3: Check if useEntities is properly exported from the specified path
echo "Verifying useEntities export:"
rg "export.*useEntities" hooks/helpers/useEntities.ts

Length of output: 649


Script:

#!/bin/bash
# Description: Updated scripts to verify import changes in Military.tsx

# Test 1: Check for any remaining usages of useDojo in Military.tsx
echo "Checking for useDojo usage in Military.tsx:"
rg "useDojo" client/src/ui/modules/military/Military.tsx

# Test 2: Check for any remaining usages of getPlayerStructures in Military.tsx
echo "Checking for getPlayerStructures usage in Military.tsx:"
rg "getPlayerStructures" client/src/ui/modules/military/Military.tsx

# Test 3: Locate the useEntities hook to verify its export
echo "Locating useEntities hook in the codebase:"
FOUND_PATH=$(fd "useEntities\.tsx" hooks/)
if [ -z "$FOUND_PATH" ]; then
  echo "useEntities.tsx not found in hooks/ directory."
else
  echo "useEntities.tsx found at: $FOUND_PATH"
  echo "Verifying useEntities export:"
  rg "export .*useEntities" "$FOUND_PATH"
fi

Length of output: 697


Script:

#!/bin/bash
# Description: Updated scripts to verify import changes in Military.tsx

# Test 1: Check for any remaining usages of useDojo in Military.tsx
echo "Checking for useDojo usage in Military.tsx:"
rg "useDojo" client/src/ui/modules/military/Military.tsx

# Test 2: Check for any remaining usages of getPlayerStructures in Military.tsx
echo "Checking for getPlayerStructures usage in Military.tsx:"
rg "getPlayerStructures" client/src/ui/modules/military/Military.tsx

# Test 3: Locate the useEntities hook in the entire codebase
echo "Locating useEntities hook in the codebase:"
FOUND_PATH=$(rg -g "useEntities.tsx" --files)
if [ -z "$FOUND_PATH" ]; then
  echo "useEntities.tsx not found in the codebase."
else
  echo "useEntities.tsx found at: $FOUND_PATH"
  echo "Verifying useEntities export:"
  rg "export .*useEntities" "$FOUND_PATH"
fi

Length of output: 935

client/src/ui/modules/entity-details/Entities.tsx (2)

3-3: LGTM: Improved state management with custom hook

The change from importing getPlayerStructures to useEntities is a good refactoring step. Using a custom hook can provide better state management, reusability, and potentially easier testing. This change aligns well with React best practices.


14-14: Verify the behavior of playerStructures function

The change to use playerStructures() is consistent with the earlier modifications and simplifies the code. However, it's important to ensure that this function behaves as expected.

Please confirm that playerStructures() correctly returns the structures for the current player without needing an explicit address parameter. You may want to check the implementation of the useEntities hook to verify this behavior.

To help with verification, you can run the following script to examine the useEntities hook implementation:

client/src/ui/modules/entity-details/CombatEntityDetails.tsx (1)

3-3: LGTM: Import changes reflect refactoring of data access

The changes to the import statements are consistent with the described refactoring:

  1. Adding useEntities suggests a more centralized approach to accessing entity data.
  2. Importing ID from "@bibliothecadao/eternum" indicates more explicit type usage.

These changes should lead to improved code organization and type safety.

Also applies to: 13-13

contracts/manifests/dev/deployment/manifest.toml (2)

Line range hint 1-1016: LGTM for the rest of the file.

The change to the block_number is the only modification in this file. All other configurations, including world settings, contracts, and models, remain unchanged. This consistency is good for maintaining the overall structure and functionality of the deployment.


8-8: Block number has been decreased. Please clarify the reason for this change.

The block_number in the [world] section has been updated from 65 to 50. This change could potentially affect the deployment process or the initial state of the world contract.

Could you please provide more context on why this change was made? Are there any specific implications or benefits we should be aware of? Additionally, please confirm if this change is intentional and if it has been tested in a development environment.

✅ Verification successful

Block number update is isolated and does not affect other configurations.

The block_number in the [world] section has been updated from 65 to 50. Our search across configuration and deployment files shows no other references to these block numbers, indicating that this change is isolated.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any references to the old or new block number in other configuration files or deployment scripts.

echo "Searching for references to block numbers 65 and 50 in configuration and deployment files:"
rg --type toml --type yaml --type json -n '(block_number|block)\s*[=:]\s*(50|65)' ./contracts

Length of output: 357

Copy link
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: 4

🧹 Outside diff range and nitpick comments (33)
client/src/ui/modules/military/battle-view/TopScreenView.tsx (3)

19-19: LGTM! Consider using a design system variable for consistency.

The changes to the outer div's className improve the component's layout and styling. The shift from a semi-transparent black to a solid brown background color is noted.

Consider using a design system variable for the background color (e.g., bg-primary) instead of a specific color like bg-brown. This would improve consistency and make future theme changes easier.


20-20: LGTM! Consider adding an aria-label for improved accessibility.

The change from a <div> to an <h1> element improves the semantic structure of the component. The added mb-4 class enhances the spacing.

For better accessibility, consider adding an aria-label to the parent <div> to provide more context about the battle view. For example:

<div className="mx-auto bg-brown text-2xl p-4 flex flex-col w-72 text-center rounded-b-2xl" aria-label="Battle view controls">

21-23: LGTM! Consider capitalizing the button text for consistency.

The change from inline classes to a variant prop is a good move towards using a standardized button component. This improves consistency and makes global style updates easier.

For consistency with typical UI conventions, consider capitalizing the first letter of each word in the button text:

<Button variant="primary" onClick={() => setBattleView(null)}>
  Exit Battle View
</Button>
client/src/ui/modules/military/battle-view/EntityAvatar.tsx (1)

16-19: Improved category checks and mercenary detection

The refactored category checks using the isCategory helper function have improved code readability and consistency. The simplified mercenary check with optional chaining is also a safer approach.

For even better consistency, consider refactoring the mercenary check to use a similar pattern:

const isMercenary = isCategory("Mercenary", structure);

This would require adding a category for mercenaries in the Structure type, but it would make all structure type checks uniform.

client/src/ui/modules/military/battle-view/Troops.tsx (1)

51-55: LGTM! Consider using a relative unit for image width.

The changes to the TroopCard component look good overall:

  1. The transformation logic for the image has been simplified, which improves maintainability.
  2. Using an h4 for the troop name enhances the semantic HTML structure.

However, regarding the image width change:

Consider using a relative unit like rem instead of vw for the image width. This would maintain consistency across different viewport sizes while still allowing for responsiveness. For example:

- className={`w-[6vw] object-cover transform mx-auto p-2  ${!defending ? "scale-x-[-1]" : ""}`}
+ className={`w-24 object-cover transform mx-auto p-2  ${!defending ? "scale-x-[-1]" : ""}`}

This change sets the width to 24rem (384px at default font size), which is close to 6vw on a 1920px wide screen but will maintain a more consistent size across different screen widths.

client/src/ui/modules/LoadingScreen.tsx (2)

40-40: LGTM: Inner container background color updated correctly.

The background color of the inner content container has been successfully changed from semi-transparent black to semi-transparent brown. This change is consistent with the main container's color update and maintains the semi-transparency for better readability.

For consistency, consider extracting the color values into CSS variables or a theme configuration. This would make it easier to manage and update the color scheme across the application in the future.


Line range hint 1-54: Overall: Changes improve visual consistency.

The modifications to the LoadingScreen component successfully update the background colors from black to brown, enhancing the visual consistency of the loading screen. The changes are well-implemented and align with the provided summary.

To further improve the component:

  1. Consider extracting color values into a centralized theme configuration for easier management and consistency across the application.
  2. Evaluate the accessibility of the new color scheme, ensuring sufficient contrast for readability.
  3. If not already in place, implement a theming system to allow for easy switching between different color schemes or modes (e.g., light/dark mode).
client/src/ui/elements/BaseThreeTooltip.tsx (2)

Line range hint 30-33: Consider addressing the TODO comment

There's a TODO comment indicating a need for refactoring when the initial mouse position is available. It might be beneficial to create a task to address this in the future.

Would you like me to create a GitHub issue to track this TODO item?


Line range hint 25-29: Consider using CSS classes for positioning instead of inline styles

The component currently uses inline styles for positioning the tooltip. While this works, it might be worth considering the use of CSS classes for positioning. This could potentially improve maintainability and make it easier to apply consistent styling across the application.

Here's a potential approach:

  1. Define CSS classes for positioning in your stylesheet:
.tooltip-position {
  position: absolute;
  transition: left 0.1s, top 0.1s;
}
  1. Update the component to use this class and data attributes:
 <div
   ref={ref}
+  className={clsx("tooltip-position", "min-w-[215px] ml-3 mt-3 rounded-xl relative p-2 bg-brown/90 text-gold", position, className, {
     hidden: !visible,
   })}
 >
  1. Update the setTooltipPosition function:
const setTooltipPosition = (e: MouseEvent) => {
  if (ref.current) {
    ref.current.style.setProperty('--x', `${e.clientX}px`);
    ref.current.style.setProperty('--y', `${e.clientY}px`);
  }
};
  1. Update your CSS:
.tooltip-position {
  left: var(--x);
  top: var(--y);
}

This approach separates the positioning logic from the inline styles, potentially making the code more maintainable.

client/src/ui/components/trading/MarketResourceSideBar.tsx (2)

35-36: LGTM: Enhanced grid header with improved spacing and clarity

The changes improve the grid header's appearance and clarity:

  1. Adding py-2 to the grid container provides better vertical spacing.
  2. Including "Resource" text in the first column header clarifies its purpose.
  3. The px-2 class on the "Resource" text ensures proper alignment.

These modifications enhance the overall readability and user experience of the component.

Consider adding similar px-2 padding to the other column headers for consistent alignment across all columns.


Line range hint 1-78: Consider extracting price calculation logic for improved readability

The component's logic for calculating ask, bid, and AMM prices is sound, but it might benefit from some refactoring for improved readability and maintainability.

Consider extracting the price calculation logic into a separate function. This would make the render function cleaner and easier to understand. Here's a suggested refactoring:

const calculatePrices = (resource: Resource, resourceAskOffers: MarketInterface[], resourceBidOffers: MarketInterface[], marketManager?: MarketManager) => {
  const askPrice = resourceBidOffers
    .filter((offer) => (resource.id ? offer.makerGets[0]?.resourceId === resource.id : true))
    .reduce((acc, offer) => (offer.perLords > acc ? offer.perLords : acc), 0);

  const bidPrice = resourceAskOffers
    .filter((offer) => offer.takerGets[0].resourceId === resource.id)
    .reduce((acc, offer) => (offer.perLords < acc ? offer.perLords : acc), Infinity);

  const ammPrice = marketManager?.getMarketPrice() || 0;

  return {
    askPrice: askPrice === Infinity ? "0" : askPrice.toFixed(2),
    bidPrice: bidPrice === Infinity ? "0" : bidPrice.toFixed(2),
    ammPrice
  };
};

Then, in your render function:

const { askPrice, bidPrice, ammPrice } = calculatePrices(resource, resourceAskOffers, resourceBidOffers, marketManager);

This refactoring would make the component more modular and easier to maintain.

client/src/ui/elements/CircleButton.tsx (1)

Color scheme is mostly consistent across the application. However, the following instances use black color classes and should be reviewed for consistency:

  • client/src/ui/modules/stream/EventStream.tsx: Uses border-black/10
  • client/src/ui/elements/Button.tsx: Uses hover:text-black/90
🔗 Analysis chain

Line range hint 77-91: Verify color scheme consistency across the application.

The changes to the CircleButton component involve updating the color scheme from black to brown. While these changes appear intentional and consistent within this component, it would be beneficial to verify that this color scheme update is applied consistently across other components in the application.

To check for consistency, you can run the following script:

This script will help identify other components that might need similar color updates to maintain visual consistency throughout the application.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for usage of black and brown color classes across the application

echo "Checking for black color classes:"
rg --type tsx --type jsx 'bg-black|border-black|text-black'

echo "\nChecking for brown color classes:"
rg --type tsx --type jsx 'bg-brown|border-brown|text-brown'

Length of output: 337


Script:

#!/bin/bash
# Description: Check for usage of black and brown color classes across the application by searching .tsx and .jsx files

echo "Checking for black color classes:"
rg --glob '*.tsx' --glob '*.jsx' 'bg-black|border-black|text-black'

echo "\nChecking for brown color classes:"
rg --glob '*.tsx' --glob '*.jsx' 'bg-brown|border-brown|text-brown'

Length of output: 11470

client/src/ui/elements/Button.tsx (2)

20-20: LGTM! Consider minor adjustment for consistency.

The updated primary style aligns well with what appears to be a new brown and gold color scheme. This change enhances the visual consistency of the UI.

For even better consistency, consider changing from-yellow-600 to-yellow-700 and hover:from-yellow-700 hover:to-yellow-800 to use brown tones instead of yellow, if that matches the intended design.


20-31: Overall, the button styles have been successfully updated to a new color scheme.

The changes to the Button component styles reflect a shift from a black-based theme to a brown and gold theme. This update appears to be part of a broader effort to refine the UI's visual identity. The changes are largely consistent across different button variants, which should lead to a more cohesive user interface.

Key points:

  1. Background colors have been changed from black to brown.
  2. Hover states have been adjusted to use gold or lighter brown shades.
  3. The overall structure and functionality of the component remain intact.

These updates should enhance the visual consistency of the UI while maintaining the existing button behavior.

To further improve maintainability, consider extracting the color values (e.g., brown, gold) into CSS variables or a theme configuration file. This would make it easier to manage and update the color scheme across the entire application in the future.

client/src/index.css (1)

2-2: Ensure comprehensive testing of the new typography

The introduction of the "Bokor" font and its application to all heading elements represents a significant change to the application's visual design. To ensure a smooth transition and maintain design integrity, please:

  1. Conduct a thorough visual review of all pages and components that use headings.
  2. Test the new font across different browsers, devices, and screen sizes to ensure consistent rendering and readability.
  3. Consider creating before/after screenshots for the design team to review and approve.
  4. Update any design documentation or style guides to reflect this change.
  5. If this is part of a larger design overhaul, consider implementing the changes incrementally and documenting the process for the team.

Given the scope of this change, it might be beneficial to implement a theming system (if not already in place) that allows for easier global typography updates in the future. This could involve creating CSS custom properties (variables) for font families, which would make it easier to manage and update typography across the application.

Also applies to: 24-24, 33-33

client/src/ui/modules/navigation/SecondaryMenuItems.tsx (2)

64-64: Color change enhances UI consistency

The background color of the notification div has been changed from bg-black/90 to bg-brown/90. This modification likely improves the visual consistency with the game's overall color scheme.

Consider adding a comment explaining the reason for this specific color choice to help future developers understand the design decision.


Line range hint 1-124: Consider refactoring for improved maintainability

While the color change looks good, here are some suggestions to improve the overall component:

  1. The component has multiple responsibilities. Consider breaking it down into smaller, more focused components for better maintainability.

  2. Extract hardcoded values as constants. For example:

    const QUESTS_THRESHOLD = 8;

    Then use QUESTS_THRESHOLD instead of 8 in the condition.

  3. Improve type safety by replacing any with a proper type for quests:

    const completedQuests = quests?.filter((quest: Quest) => quest.status === QuestStatus.Claimed);
  4. The secondaryNavigation array could be defined outside the component to prevent unnecessary re-creation on each render.

Would you like me to provide more detailed refactoring suggestions for any of these points?

client/src/ui/modules/military/battle-view/BattleSideView.tsx (3)

86-89: LGTM! Consider extracting common classes.

The changes to the background and margin classes improve the component's styling and layout. The use of predefined color classes (bg-brown) is good for maintaining consistency.

Consider extracting the common classes into a separate variable or constant to improve readability and maintainability, especially if these classes are used in multiple components:

const commonClasses = "flex col-span-5 bg-brown mx-4 bg-hex-bg -mt-16";

// Usage
<div className={`${commonClasses} ${
  battleSide === BattleSide.Attack ? "flex-row" : "flex-row-reverse"
}`}>

Line range hint 91-94: LGTM! Consider adding a fallback for undefined values.

The conditional logic for the address prop is a good improvement, allowing different handling based on the battle side.

Consider adding a fallback value in case both account.address and battleEntityId are undefined:

address={battleSide === BattleSide.Attack 
  ? account.address 
  : battleEntityId?.toString() ?? 'unknown'}

This ensures that the EntityAvatar always receives a valid string value for its address prop.


Line range hint 102-111: Add a key prop to mapped elements.

The static analysis tool has identified a missing key property for elements in the iterable. This can lead to performance issues and unexpected behavior in React.

To resolve this, add a unique key to each mapped element. Since army.entity_id seems to be a unique identifier, you can use it as the key:

 {React.Children.toArray(
   ownSideArmies.map((army) => {
     if (!army) return;
     const addressName = getAddressNameFromEntity(army.entity_id);
     return (
-      <div className="flex justify-around px-2 py-1 rounded bg-brown/70 text-xs gap-2 border-gold/10 border">
+      <div key={army.entity_id} className="flex justify-around px-2 py-1 rounded bg-brown/70 text-xs gap-2 border-gold/10 border">
         <span className="self-center align-middle">{addressName}</span>
         <span className="self-center align-middle">{army?.name}</span>
         {army?.isMine && (
           <div className="h-6 border px-1 rounded self-center">

This change will resolve the warning and improve the component's performance and predictability.

🧰 Tools
🪛 Biome

[error] 102-102: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

client/src/ui/elements/ResourceIcon.tsx (1)

100-104: LGTM: Tooltip styling and text rendering improved.

The changes to the tooltip styling and text rendering logic are well-implemented:

  • The background color change to bg-brown likely improves consistency with the overall UI design.
  • The use of the tooltipText prop with a fallback to the resource name is a good implementation of the new feature.

Minor suggestion for consistency:

Consider updating the text color class for better contrast with the new brown background. For example:

- <span className="relative z-10 p-2 text-xs leading-none  whitespace-no-wrap rounded shadow-lg bg-gray-1000">
+ <span className="relative z-10 p-2 text-xs leading-none text-white whitespace-no-wrap rounded shadow-lg">

This removes the potentially conflicting bg-gray-1000 class and adds text-white for better readability against the brown background.

client/src/ui/modules/military/battle-view/BattleProgressBar.tsx (2)

146-146: LGTM: Enhanced progress bar styling

The addition of "relative h-6 mx-auto bg-opacity-40" classes improves the positioning and styling of the progress bar. This change enhances the visual presentation and layout of the component.

Consider adding a rounded class to give the progress bar rounded corners, which might improve its aesthetic appeal:

- <div className="relative h-6  mx-auto bg-opacity-40" style={{ background: gradient }}>
+ <div className="relative h-6 mx-auto bg-opacity-40 rounded" style={{ background: gradient }}>

161-161: LGTM: Improved battle information grid layout

The changes to the grid's className enhance the layout and styling of the battle information. The new classes ensure consistent width with the progress bar, create a clear 3-column layout, and improve readability with increased font size and padding.

For consistency with the progress bar, consider adding the rounded class to this div as well:

- <div className="mx-auto w-2/3 grid grid-cols-3 text-2xl bg-hex-bg px-4 py-2">
+ <div className="mx-auto w-2/3 grid grid-cols-3 text-2xl bg-hex-bg px-4 py-2 rounded">
client/tailwind.config.js (1)

48-48: Consider removing commented-out code.

The 'hex-bg' background image is commented out. If this image is no longer needed, consider removing the line entirely to keep the codebase clean. If it's intended for future use, please add a comment explaining why it's being kept.

client/src/ui/components/trading/MarketModal.tsx (1)

80-82: Improved tab labels with icons

The addition of icons to the tab labels enhances the UI and improves user experience. The consistent structure across all tabs is commendable.

Consider extracting this repeated structure into a separate component for better maintainability:

const TabLabel = ({ icon: Icon, text }: { icon: React.ComponentType, text: string }) => (
  <div className="flex relative group items-center gap-2">
    <Icon className="w-6 fill-current" />
    <div className="self-center">{text}</div>
  </div>
);

Then use it like:

label: <TabLabel icon={Scroll} text="Order Book" />

This would reduce repetition and make future changes easier.

Also applies to: 99-101, 117-119, 131-133, 145-147

client/src/ui/components/military/ArmyChip.tsx (1)

263-263: LGTM! Consider adding a focus state for keyboard navigation.

The change from bg-black to bg-brown for the selected army background looks good and likely improves the visual consistency with the rest of the application.

To enhance accessibility, consider adding a focus state for keyboard navigation. This can be achieved by adding a focus:ring-2 focus:ring-gold focus:outline-none class to the clickable div. For example:

-          className={`rounded cursor-pointer transition-all duration-300 ${
-            selectedArmy?.entity_id === army.entity_id ? "bg-gray-300" : "bg-brown"
-          }`}
+          className={`rounded cursor-pointer transition-all duration-300 focus:ring-2 focus:ring-gold focus:outline-none ${
+            selectedArmy?.entity_id === army.entity_id ? "bg-gray-300" : "bg-brown"
+          }`}

This will add a gold ring around the focused item when navigating with a keyboard, improving accessibility without affecting the visual design for mouse users.

client/src/ui/modules/chat/Chat.tsx (3)

30-32: LGTM: Enhanced Chat component with guild functionality

The changes to the Chat component successfully integrate guild functionality and improve the overall structure. The new useEffect hooks for scrolling and salt management are well-implemented. The updated changeTabs function now correctly handles guild tabs, and the rendering of tabs has been appropriately modified.

Consider adding comments to explain the purpose of the new useEffect hooks and the logic in the changeTabs function for better maintainability.

Also applies to: 51-64, 66-101, 103-111


310-409: LGTM: New ChatSelect component

The new ChatSelect component is a well-implemented addition to the Chat functionality. It provides:

  1. Efficient channel selection, including support for guild channels
  2. A search feature for filtering channels, enhancing user experience
  3. Proper handling of different channel types (global, guild, private)

Consider extracting the filtering logic (lines 341-344) into a separate function for better readability and potential reuse. For example:

const filterPlayers = (players: Player[], searchInput: string, selectedChannel: string) => {
  return players.filter(
    (player) =>
      player.addressName.toLowerCase().startsWith(searchInput.toLowerCase()) || player.addressName === selectedChannel
  );
};

Then use it in the component:

const filteredPlayers = filterPlayers(players, searchInput, selectedChannel);

Line range hint 1-409: Consider improving code organization and reusability

While the changes and additions to this file are generally well-implemented, there are a few areas where we could improve code organization and reusability:

  1. File size: The file has grown quite large. Consider splitting it into separate files for each main component (Chat, Messages, ChatSelect) to improve maintainability.

  2. Color styling: There's repetition in color styling logic (e.g., lines 147-151 and 275-279). Consider extracting this into a utility function:

const getChannelColor = (channelName: string, guildName: string | undefined) => {
  if (channelName === GLOBAL_CHANNEL_KEY) return CHAT_COLORS.GLOBAL;
  if (channelName === guildName) return CHAT_COLORS.GUILD;
  return CHAT_COLORS.PRIVATE;
};
  1. Type definitions: Consider moving type definitions (like the props for Messages and ChatSelect components) to a separate types file for better organization and potential reuse.

These changes would enhance the overall structure and maintainability of the code.

client/src/ui/components/trading/MarketOrderPanel.tsx (4)

163-174: Enhanced market price display and layout

The changes to the market price container improve the visual appearance and layout:

  1. Added rounded-xl class for consistency with other components.
  2. Adjusted padding and used flex layout for better organization of information.
  3. Included more details like the resource icon and number of bids/asks.

The background color change for the locked resources message from black to brown aligns better with the overall theme.

Consider adding a transition effect to the hover state of the market price container for a smoother user experience. For example:

- className={`text-2xl flex  font-bold  justify-between py-4 px-8 border-gold/10 border rounded-xl ${
+ className={`text-2xl flex font-bold justify-between py-4 px-8 border-gold/10 border rounded-xl transition-colors duration-200 ${
    !isBuy ? "bg-green/20 text-green" : "bg-red/20 text-red"
  }`}

Also applies to: 181-181, 200-202


378-380: Improved OrderRow layout and visual representation

The changes to the OrderRow component enhance its appearance and readability:

  1. Added rounded class for consistency with other components.
  2. Implemented a grid system for better organization of order details.
  3. Included ResourceIcon components to improve visual representation of resources.

These updates make the order information more accessible and visually appealing.

For consistency with other components, consider changing the rounded class to rounded-xl:

- className={`flex flex-col p-1  px-2  hover:bg-white/15 duration-150 border-gold/10 border relative rounded text-sm ${
+ className={`flex flex-col p-1 px-2 hover:bg-white/15 duration-150 border-gold/10 border relative rounded-xl text-sm ${
    isSelf ? "bg-blueish/10" : "bg-white/10"
  } ${isMakerResourcesLocked ? "opacity-50" : ""}`}

Also applies to: 389-390


601-603: Enhanced OrderCreation component layout and interaction

The changes to the OrderCreation component improve its usability and visual consistency:

  1. Added rounded-xl class to the main container for consistency with other components.
  2. Implemented flex layout with gap for better spacing and organization.
  3. Adjusted NumberInput components to allow for more intuitive user interaction, including setting maximum values based on available resources.

These updates enhance the user experience when creating new orders.

To improve code readability, consider extracting the repeated NumberInput setup into a separate component or custom hook. This would reduce duplication and make the code more maintainable. For example:

const ResourceInput = ({ label, value, onChange, max, resource }) => (
  <div className="w-1/3 gap-1 flex flex-col">
    <div className="uppercase text-sm flex gap-2 font-bold">
      <ResourceIcon withTooltip={false} size="xs" resource={resource} />
      {label}
    </div>
    <NumberInput
      value={value}
      className="w-full col-span-3"
      onChange={onChange}
      max={max}
    />
    <div className="text-sm font-bold text-gold/70">
      {currencyFormat(max * EternumGlobalConfig.resources.resourcePrecision, 0)} avail.
    </div>
  </div>
);

// Usage in OrderCreation
<ResourceInput
  label={isBuy ? "Buy" : "Sell"}
  value={resource}
  onChange={(value) => setResource(Number(value))}
  max={!isBuy ? resourceBalance / EternumGlobalConfig.resources.resourcePrecision : Infinity}
  resource={findResourceById(resourceId)?.trait || ""}
/>

This would make the OrderCreation component more concise and easier to maintain.

Also applies to: 609-615, 647-653


Line range hint 1-686: Overall UI enhancements and improved user interaction

The changes in this file significantly improve the visual consistency and user experience of the trading interface:

  1. Consistent use of rounded corners (rounded-xl) across components.
  2. Improved layout and spacing using flex and grid systems.
  3. Enhanced visual representation of resources using ResourceIcon components.
  4. Better user interaction with NumberInput components, including max value constraints.

These updates contribute to a more polished and user-friendly trading interface.

Consider implementing a theming system or design tokens to manage consistent styling across components. This would make it easier to maintain and update the UI in the future, especially if the application grows or requires different themes. For example, you could define a set of design tokens for colors, border radii, and spacing, and use them throughout the components instead of hardcoding values.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 44c2368 and d3bd7cb.

⛔ Files ignored due to path filters (5)
  • client/src/assets/icons/Coins.svg is excluded by !**/*.svg
  • client/src/assets/icons/Crown.svg is excluded by !**/*.svg
  • client/src/assets/icons/Scroll.svg is excluded by !**/*.svg
  • client/src/assets/icons/Sparkles.svg is excluded by !**/*.svg
  • client/src/assets/icons/Swap.svg is excluded by !**/*.svg
📒 Files selected for processing (49)
  • balancing/src/App.tsx (1 hunks)
  • client/src/index.css (3 hunks)
  • client/src/three/helpers/utils.ts (1 hunks)
  • client/src/ui/components/ModalContainer.tsx (1 hunks)
  • client/src/ui/components/bank/AddLiquidity.tsx (5 hunks)
  • client/src/ui/components/bank/ConfirmationPopup.tsx (1 hunks)
  • client/src/ui/components/bank/LiquidityResourceRow.tsx (1 hunks)
  • client/src/ui/components/bank/ResourceBar.tsx (4 hunks)
  • client/src/ui/components/bank/Swap.tsx (3 hunks)
  • client/src/ui/components/construction/SelectPreviewBuilding.tsx (3 hunks)
  • client/src/ui/components/entities/Entity.tsx (2 hunks)
  • client/src/ui/components/hints/Buildings.tsx (1 hunks)
  • client/src/ui/components/hints/HintModal.tsx (1 hunks)
  • client/src/ui/components/military/ArmyChip.tsx (1 hunks)
  • client/src/ui/components/military/ArmyManagementCard.tsx (1 hunks)
  • client/src/ui/components/structures/construction/StructureCard.tsx (3 hunks)
  • client/src/ui/components/trading/MarketModal.tsx (10 hunks)
  • client/src/ui/components/trading/MarketOrderPanel.tsx (5 hunks)
  • client/src/ui/components/trading/MarketResourceSideBar.tsx (1 hunks)
  • client/src/ui/containers/BaseContainer.tsx (1 hunks)
  • client/src/ui/elements/BaseThreeTooltip.tsx (1 hunks)
  • client/src/ui/elements/Button.tsx (1 hunks)
  • client/src/ui/elements/CircleButton.tsx (2 hunks)
  • client/src/ui/elements/ListSelect.tsx (1 hunks)
  • client/src/ui/elements/NumberInput.tsx (2 hunks)
  • client/src/ui/elements/ResourceIcon.tsx (1 hunks)
  • client/src/ui/elements/SecondaryPopup.tsx (2 hunks)
  • client/src/ui/elements/Select.tsx (2 hunks)
  • client/src/ui/elements/Tooltip.tsx (1 hunks)
  • client/src/ui/layouts/World.tsx (1 hunks)
  • client/src/ui/modules/LoadingScreen.tsx (1 hunks)
  • client/src/ui/modules/chat/Chat.tsx (7 hunks)
  • client/src/ui/modules/chat/ChatTab.tsx (1 hunks)
  • client/src/ui/modules/military/battle-view/Battle.tsx (1 hunks)
  • client/src/ui/modules/military/battle-view/BattleHistory.tsx (1 hunks)
  • client/src/ui/modules/military/battle-view/BattleProgressBar.tsx (2 hunks)
  • client/src/ui/modules/military/battle-view/BattleSideView.tsx (3 hunks)
  • client/src/ui/modules/military/battle-view/EntityAvatar.tsx (2 hunks)
  • client/src/ui/modules/military/battle-view/LockedResources.tsx (1 hunks)
  • client/src/ui/modules/military/battle-view/TopScreenView.tsx (1 hunks)
  • client/src/ui/modules/military/battle-view/Troops.tsx (2 hunks)
  • client/src/ui/modules/navigation/SecondaryMenuItems.tsx (1 hunks)
  • client/src/ui/modules/navigation/TopMiddleNavigation.tsx (5 hunks)
  • client/src/ui/modules/onboarding/Steps.tsx (1 hunks)
  • client/src/ui/modules/social/PlayerId.tsx (4 hunks)
  • client/src/ui/modules/stream/EventStream.tsx (2 hunks)
  • client/tailwind.config.js (2 hunks)
  • contracts/manifests/dev/deployment/manifest.json (1 hunks)
  • contracts/manifests/dev/deployment/manifest.toml (1 hunks)
✅ Files skipped from review due to trivial changes (9)
  • balancing/src/App.tsx
  • client/src/three/helpers/utils.ts
  • client/src/ui/components/ModalContainer.tsx
  • client/src/ui/components/bank/ConfirmationPopup.tsx
  • client/src/ui/components/hints/Buildings.tsx
  • client/src/ui/components/hints/HintModal.tsx
  • client/src/ui/components/military/ArmyManagementCard.tsx
  • client/src/ui/elements/SecondaryPopup.tsx
  • client/src/ui/modules/navigation/TopMiddleNavigation.tsx
🚧 Files skipped from review as they are similar to previous changes (7)
  • client/src/ui/components/bank/AddLiquidity.tsx
  • client/src/ui/components/bank/ResourceBar.tsx
  • client/src/ui/components/entities/Entity.tsx
  • client/src/ui/elements/NumberInput.tsx
  • client/src/ui/modules/chat/ChatTab.tsx
  • contracts/manifests/dev/deployment/manifest.json
  • contracts/manifests/dev/deployment/manifest.toml
🧰 Additional context used
🪛 Biome
client/src/ui/modules/military/battle-view/BattleProgressBar.tsx

[error] 145-145: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)


[error] 145-145: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

client/src/ui/modules/military/battle-view/BattleSideView.tsx

[error] 102-102: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

🔇 Additional comments (67)
client/src/ui/modules/military/battle-view/LockedResources.tsx (1)

12-12: Verify the intentional removal of background and border styles.

The background color (bg-[#1b1a1a], bg-hex-bg) and border (border-l-4 border-r-4 border-gold/20) classes have been removed from the outer div. While this simplifies the component's styling, it may affect its visual appearance.

Please confirm if this change is intentional and that the styling is being handled elsewhere (e.g., in a parent component or global stylesheet) to maintain visual consistency.

To verify the impact of this change, you can run the following command:

This will help ensure that the styling for LockedResources is properly managed elsewhere in the codebase.

client/src/ui/containers/BaseContainer.tsx (1)

20-20: Consider the impact of changing the background color

The background color class has been changed from "bg-black/90" to "bg-brown/90". While this change may align with updated design requirements, please consider the following points:

  1. Ensure this change is consistent with the overall design system and color palette of the application.
  2. Verify that the new brown background provides sufficient contrast with the text and other elements within the container for accessibility purposes.
  3. Check if this change affects the visibility of the border gradient, as it might be less noticeable on a brown background compared to a black one.
  4. Confirm that this change has been approved by the design team and is intentional.

To ensure consistency across the codebase, let's check for other occurrences of the previous background color:

This will help identify if similar changes need to be made elsewhere for consistency.

client/src/ui/modules/military/battle-view/EntityAvatar.tsx (3)

13-14: Great addition of helper functions!

The introduction of getStructureCategory and isCategory functions is a good refactoring decision. These helper functions improve code readability and maintainability by abstracting the category checking logic. The use of optional chaining in getStructureCategory is also a good practice for handling potential undefined values.


35-35: Good code organization

The addition of a blank line before the return statement improves code readability by clearly separating the logic section from the JSX.


37-46: Verify layout changes and consider animation reusability

The changes to the motion.img component look good overall. Here are some points to consider:

  1. The image size has increased from 44 to 56 units. Please verify that this change doesn't negatively impact the layout.
  2. Moving animation variants inline improves code locality, which is good. However, if these animations are used elsewhere, consider keeping them in a separate constant for reusability.
  3. The -mt-12 class applies a negative top margin. While this might be intentional for layout purposes, please ensure it doesn't cause any unexpected layout issues.

To verify the layout changes, please review the component in various screen sizes and contexts where it's used.

client/src/ui/modules/military/battle-view/Troops.tsx (2)

49-49: LGTM! Improved visual design.

The updates to the TroopCard component's main div enhance its visual appearance and interactivity. The addition of background color, text color, rounded corners, padding, hover effect, and transition duration contribute to a more polished and consistent design.


17-31: LGTM! Verify troop type changes.

The changes to the TroopRow component look good. The simplification of the className prop and the updates to the count prop are appropriate. However, please confirm that the troop type changes (Knight instead of Crossbowman, and Crossbowman instead of Paladin) align with the intended game design.

To ensure consistency across the codebase, please run the following script:

✅ Verification successful

Verified: Troop type changes are consistent.

No remaining references to the old troop order were found in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining references to the old troop order

# Test: Search for Crossbowman as the first troop or Paladin as the second troop
rg --type typescript 'TroopCard.*Crossbowman.*TroopCard.*Paladin'

Length of output: 102


Script:

#!/bin/bash
# Description: Check for any remaining references to the old troop order

# Test: Search for Crossbowman as the first troop or Paladin as the second troop in .tsx files
rg --type tsx 'TroopCard.*Crossbowman.*TroopCard.*Paladin'

Length of output: 88


Script:

#!/bin/bash
# Description: Check for any remaining references to the old troop order

# Test: Search for Crossbowman as the first troop or Paladin as the second troop in .ts and .tsx files
rg 'TroopCard.*Crossbowman.*TroopCard.*Paladin' -g '*.ts' -g '*.tsx'

Length of output: 70

client/src/ui/modules/LoadingScreen.tsx (1)

38-38: LGTM: Background color change implemented correctly.

The background color of the main container has been updated from black to brown as intended. This change aligns with the summary and improves the visual consistency of the loading screen.

client/src/ui/elements/BaseThreeTooltip.tsx (1)

56-56: Background color change from black to brown

The background color of the tooltip has been changed from bg-black/90 to bg-brown/90. This modification alters the visual appearance of the tooltip from a semi-transparent black to a semi-transparent brown.

To ensure consistency across the application, let's verify if this color change is part of a broader design update:

This will help us understand if this is an isolated change or part of a larger design update.

✅ Verification successful

Background color change is consistently applied across multiple components

The change from bg-black/90 to bg-brown/90 has been implemented in several files, indicating it is part of a broader design update.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for other occurrences of bg-brown/90 and bg-black/90 in the codebase

echo "Occurrences of bg-brown/90:"
rg --type tsx --type jsx "bg-brown/90" -c

echo "Occurrences of bg-black/90:"
rg --type tsx --type jsx "bg-black/90" -c

Length of output: 269


Script:

#!/bin/bash
# Description: Check for other occurrences of bg-brown/90 and bg-black/90 in tsx and jsx files

echo "Occurrences of bg-brown/90:"
rg "bg-brown/90" --glob "*.tsx" --glob "*.jsx" -c

echo "Occurrences of bg-black/90:"
rg "bg-black/90" --glob "*.tsx" --glob "*.jsx" -c

Length of output: 1015

client/src/ui/components/structures/construction/StructureCard.tsx (4)

31-31: LGTM: Background color change enhances visual consistency.

The change from bg-black/30 to bg-brown/30 for the main container's background color appears to be a deliberate design decision. This modification likely improves the visual consistency with the overall color scheme of the application.

To ensure this change aligns with the intended design, please verify the visual appearance in the context of the entire application. You may want to check if similar color updates are needed in other components for consistency.


44-44: LGTM: Overlay color change maintains design consistency.

The modification from bg-black/70 to bg-brown/70 for the overlay's background color is consistent with the previous change, maintaining the new color scheme throughout the component.

Please ensure that the content within this overlay (specifically the "Need More Resources" message and the Silo icon) remains clearly visible and readable against the new brown background. You may want to test this with various screen settings to confirm optimal contrast and legibility.


66-66: LGTM: ResourceIcon background color change completes the design update.

The change from bg-black/10 to bg-brown/10 for the ResourceIcon's background completes the consistent application of the new color scheme throughout the component.

To ensure optimal user experience, please verify that the ResourceIcon remains clearly visible against this new brown background, especially given the low opacity (10%). Test with various icons and screen settings to confirm that the subtle background effect enhances rather than hinders the icon's visibility.


Line range hint 31-66: Summary: Consistent color scheme update enhances visual design.

The changes in this file consistently update the color scheme from black to brown across various elements of the StructureCard component. This modification appears to be part of a broader design update to enhance visual consistency throughout the application.

While these changes improve the aesthetic coherence, it's crucial to ensure that:

  1. The new color scheme maintains or improves readability and contrast for all content.
  2. The changes align with the overall design system and accessibility guidelines of the application.
  3. Similar updates are applied consistently across other components if necessary.

To fully validate these changes:

  1. Test the component with various content and screen settings to ensure optimal visibility and readability.
  2. Review the component in the context of the entire application to confirm design consistency.
  3. Consider conducting a brief accessibility audit to ensure the new color scheme meets all necessary contrast requirements.
client/src/ui/components/trading/MarketResourceSideBar.tsx (1)

33-33: LGTM: Improved styling for better visual appeal

The addition of bg-brown, rounded-2xl, and p-1 classes enhances the component's appearance, providing a distinct background color, rounded corners, and appropriate padding. These changes align well with modern UI practices and likely improve the overall user experience.

client/src/ui/elements/Tooltip.tsx (1)

37-37: Verify the design consistency of the new tooltip background color.

The background color of the tooltip has been changed from black to brown (bg-black/90 to bg-brown/90). While this change doesn't affect the functionality, it's important to ensure it aligns with the overall design system and maintains sufficient contrast for accessibility.

To verify the consistency and impact of this change:

  1. Check if this color change is part of a broader design update.
  2. Ensure the new brown background provides sufficient contrast with the text color for readability.
  3. Verify if this change is applied consistently across all instances of tooltips in the application.

Please review the results of this script to ensure the color change is consistent with the overall design and doesn't introduce any inconsistencies.

client/src/ui/elements/CircleButton.tsx (2)

77-77: Styling update for non-active button state.

The background and border colors for the non-active button state have been updated. This change appears to be a deliberate styling decision, likely to better align with the overall design theme of the application.


91-91: Consistent styling update for disabled button state.

The overlay color for the disabled button state has been changed from black to brown, maintaining consistency with the previous styling update. This change enhances the overall visual coherence of the button component across its various states.

client/src/ui/elements/Button.tsx (2)

21-21: LGTM! Consistent with the new color scheme.

The change from bg-black to bg-brown in the default style is consistent with the updates made to the primary style, reinforcing the new color scheme.


22-22: LGTM! Consistent opacity levels maintained.

The enabledStyle changes from black to brown while maintaining the same opacity levels (10% for normal state, 30% for hover state). This update is consistent with the overall shift in color scheme and preserves the original design intent.

client/src/index.css (2)

24-24: Consider the design implications of changing heading fonts

The font for all heading elements (h1-h6) and their corresponding classes (.h1-.h6) has been changed from "Sedan" to "Bokor". While this change may be intentional, please consider the following:

  1. Does this change align with the overall design system of the application?
  2. Have you tested the readability and appearance of "Bokor" across different screen sizes and devices?
  3. Are there any specific headings that should retain the previous font for design purposes?
  4. Has the design team approved this global change to heading typography?

To ensure consistency, check if there are any other places in the codebase where "Sedan" is still being used for headings:

#!/bin/bash
# Search for "Sedan" font usage in heading-related styles
rg --type css --type typescript 'font-family:.*Sedan.*h[1-6]'

This will help identify any inconsistencies in heading styles across the application.

Also applies to: 33-33


2-2: Verify the necessity of the new "Bokor" font import

The addition of a new font import can impact the application's load time. Please confirm that the "Bokor" font is essential for the design and consider the following:

  1. Is this font being used extensively throughout the application to justify the additional resource load?
  2. Have you considered using font subsetting to reduce the file size if only specific characters are needed?
  3. Is there a fallback strategy in place for users with slow internet connections?

To check the usage of the "Bokor" font across the project, run the following command:

This will help determine if the font is used beyond the changes in this file.

✅ Verification successful

"Bokor" font usage verified

The "Bokor" font is only used in client/src/index.css, as per the changes. No additional usage found across the project.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for "Bokor" font usage in CSS and TSX files
rg --type css --type typescript "font-family:.*Bokor" -g '!index.css'

Length of output: 192


Script:

#!/bin/bash
# Search for "Bokor" font usage in CSS, TS, and TSX files excluding index.css
rg "font-family:.*Bokor" -g "*.css" -g "*.ts" -g "*.tsx" --ignore-file index.css

Length of output: 244


Script:

#!/bin/bash
# Search for "Bokor" font usage in CSS, TS, and TSX files excluding client/src/index.css
rg "font-family:.*Bokor" -g "*.css" -g "*.ts" -g "*.tsx" -g "!client/src/index.css"

Length of output: 85

client/src/ui/elements/ListSelect.tsx (1)

63-63: Verify the intentionality of background color change

The background color for the Listbox.Options component is now always set to "bg-brown", regardless of the props.style value. This change removes the ability to have a black background when props.style === "black".

  1. If this change is intentional to standardize the appearance:

    • Consider removing the conditional statement entirely, as it no longer affects the outcome.
  2. If this change is unintentional:

    • Revert to the previous implementation to maintain the ability to have different background colors based on props.style.

Please confirm if this change aligns with the intended design and functionality of the ListSelect component.

client/src/ui/modules/military/battle-view/BattleHistory.tsx (1)

79-79: Approve CSS class change with a suggestion for visual verification.

The change from mb-4 to my-4 for the event wrapper div is a reasonable adjustment. It will provide equal vertical spacing above and below each event entry, potentially improving readability and visual separation.

To ensure this change aligns with the overall design and doesn't negatively impact the layout, please verify the following:

  1. Check that the added top margin doesn't create unintended spacing at the beginning of the list.
  2. Confirm that the change doesn't cause any overflow issues in the parent container.
  3. Ensure the new spacing is consistent with the design system and other similar components.

Consider reviewing this change with the design team if it significantly alters the visual appearance of the battle history.

client/src/ui/modules/military/battle-view/Battle.tsx (2)

70-80: Summary: Design updates enhance battle view aesthetics and responsiveness.

The changes in this file focus on improving the visual design and layout flexibility of the Battle component. The new styling with bg-brown and bg-hex-bg classes, along with the shift to a minimum height, should result in a more thematically consistent and responsive battle view. The repositioning of the BattleProgressBar component might affect its relation to other elements, so it's worth testing the layout across different screen sizes to ensure a good user experience.

These modifications don't alter the component's core functionality but do enhance its visual presentation. Consider updating related components or views to maintain consistency across the application.


70-80: Styling and structure changes improve flexibility and theme consistency.

The modifications to the battle view container enhance the component's flexibility and visual consistency:

  1. Changing from bg-[#1b1a1a] to bg-brown aligns the color scheme with what seems to be an updated design system.
  2. Adding bg-hex-bg introduces a hexagonal background pattern, which is thematically appropriate for a battle view.
  3. Switching from h-[35vh] to min-h-[40vh] allows for more responsive behavior, accommodating varying content sizes.
  4. Relocating the BattleProgressBar component inside this container might affect its positioning. Ensure this doesn't negatively impact the overall layout or user experience.

To ensure consistency across the codebase, let's check for other occurrences of the old background color:

Also, let's verify the usage of the new bg-brown and bg-hex-bg classes:

✅ Verification successful

Background color updates are consistent and isolated.

The old background color class bg-[#1b1a1a] is no longer present in the codebase, confirming that the change in Battle.tsx is isolated. The new classes bg-brown and bg-hex-bg are consistently used across multiple components, ensuring visual consistency and adherence to the updated design system.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other occurrences of the old background color
rg --type tsx --type jsx 'bg-\[#1b1a1a\]'

Length of output: 71


Script:

#!/bin/bash
# Check for other usages of the new background classes
rg --type tsx --type jsx 'bg-brown'
rg --type tsx --type jsx 'bg-hex-bg'

Length of output: 128


Script:

#!/bin/bash
# Search for other occurrences of the old background color
rg 'bg-\[#1b1a1a\]' -g '*.tsx' -g '*.jsx'

Length of output: 43


Script:

#!/bin/bash
# Check for other usages of the new background classes
rg 'bg-brown' -g '*.tsx' -g '*.jsx'
rg 'bg-hex-bg' -g '*.tsx' -g '*.jsx'

Length of output: 13607

client/src/ui/elements/Select.tsx (3)

69-69: LGTM: Background color update for SelectContent

The change from bg-black/90 to bg-brown/90 for the SelectContent background looks good. This update likely improves the visual consistency with the overall design theme.

To ensure visual consistency, please verify this change in the context of the entire UI. Consider checking:

  1. If the new brown background contrasts well with the text color.
  2. If it aligns with other dropdown menus or similar UI elements in the application.

107-107: LGTM: Layout improvement for SelectItem

The addition of justify-between to the SelectItem's className is a good improvement. This change will create better spacing between the item text and the check icon, enhancing the overall layout of the dropdown items.

To ensure the layout improvement is effective:

  1. Please verify that the text and check icon are properly aligned at the edges of the dropdown.
  2. Check if this change maintains consistency with other similar UI elements in the application.
  3. Ensure that the layout works well with various text lengths in the dropdown items.

You may want to test this with different screen sizes to confirm the responsiveness of the new layout.


Line range hint 1-132: Summary: Minor style improvements to Select component

The changes made to the Select component are purely cosmetic and should enhance its visual appeal:

  1. The background color of SelectContent has been updated to a brown shade, potentially improving theme consistency.
  2. The layout of SelectItem has been adjusted to better space out its contents.

These changes don't introduce any new functionality or potential bugs. However, it's crucial to verify that these updates maintain visual consistency with the rest of the application and work well across different screen sizes and content lengths.

To ensure these changes integrate well with the overall UI:

  1. Test the Select component with various content types and lengths.
  2. Verify the appearance on different screen sizes and devices.
  3. Check for consistency with other UI elements and the overall design language of the application.
client/src/ui/layouts/World.tsx (1)

87-87: LGTM! Verify design consistency.

The change from "bg-black" to "bg-brown" for the loading overlay background looks good. This modification only affects the visual appearance and doesn't introduce any functional changes.

Please confirm that this color change aligns with the overall design system and color scheme of the application. If it's part of a broader design update, consider updating other relevant components for consistency.

client/src/ui/elements/ResourceIcon.tsx (3)

Line range hint 27-27: LGTM: Addition of tooltipText property enhances component flexibility.

The new optional tooltipText property in the Props type is a good addition. It allows for custom tooltip text, improving the component's reusability and flexibility.


Line range hint 89-89: LGTM: Function signature updated correctly.

The ResourceIcon component function signature has been properly updated to include the new tooltipText property. This change is consistent with the Props type modification and maintains the existing default behavior for withTooltip.


Line range hint 1-110: Overall assessment: Changes improve component flexibility and UI consistency.

The modifications to the ResourceIcon component are well-implemented and enhance its functionality:

  1. The addition of the tooltipText property improves reusability.
  2. The tooltip styling changes likely contribute to better UI consistency.
  3. The implementation maintains the existing structure while adding new features.

These changes are approved, with a minor suggestion for text color adjustment in the tooltip for optimal readability.

client/src/ui/modules/military/battle-view/BattleProgressBar.tsx (1)

139-139: LGTM: Improved component layout

The change to set the width to 2/3 and center the component horizontally improves the overall layout and positioning. This adjustment enhances the visual presentation of the battle progress bar.

client/src/ui/modules/stream/EventStream.tsx (5)

11-11: LGTM: Import statements reorganized.

The changes in the import statements are minor reorganizations that don't affect the functionality of the code. The Minimize icon import and the @dojoengine/recs imports have been moved to different lines. This change is acceptable and doesn't introduce any issues.

Also applies to: 18-18


172-174: Styling change: Minimize button background updated.

The background color of the minimize button has been changed from a black shade to a brown shade. This change is part of a broader shift in the color scheme of the component. While it doesn't affect functionality, it does alter the visual appearance of the EventStream component.


177-179: Styling change: Hidden event stream container background updated.

The background color of the event stream container when hidden has been changed from a light black shade to a light brown shade. This change is consistent with the overall color scheme update and only affects the appearance when the event stream is minimized. The functionality remains unchanged.


181-181: Styling changes: Event stream container and items updated.

The background colors of the event stream container and individual event items have been updated:

  1. Main container background changed from bg-black/40 to bg-brown/40 and added bg-hex-bg.
  2. Hover effect on event items changed from hover:bg-black/20 to hover:bg-brown/20.

These changes are part of the overall shift from black to brown in the color scheme and may significantly alter the visual appearance of the component. The addition of bg-hex-bg might introduce a new visual pattern to the background.

While these changes don't affect functionality, it's recommended to verify the new look in a staging environment to ensure it meets the desired design requirements.

To verify the visual changes, please review the component in a staging environment and confirm that the new color scheme aligns with the intended design. You may want to check:

  1. The overall appearance of the event stream container
  2. The visibility and readability of event items
  3. The effectiveness of the hover effect on event items
  4. The impact of the bg-hex-bg class on the background appearance

Also applies to: 188-188


Line range hint 1-203: Summary of changes and suggestions for next steps.

The changes in this file are primarily visual, shifting the color scheme of the EventStream component from black to brown. This includes updates to the background colors of the main container, the minimize button, and the hover effects on event items. The functionality of the component remains unchanged.

Suggestions for next steps:

  1. Provide context: It would be helpful to understand the reasoning behind these color changes. Consider adding a comment in the code or updating the PR description to explain the design decision.
  2. Verify design: Ensure that these changes have been reviewed and approved by the design team.
  3. Cross-browser testing: Verify that the new colors render consistently across different browsers and devices.
  4. Accessibility check: Confirm that the new color scheme maintains sufficient contrast ratios for readability and meets accessibility standards.
  5. Performance impact: Although unlikely, verify that the addition of the bg-hex-bg class doesn't introduce any performance issues, especially on lower-end devices.

Overall, the changes appear to be a consistent update to the component's visual style. Once the above points are addressed, this update should be ready for merging.

To address these suggestions, please:

  1. Update the PR description with the context for these changes.
  2. Confirm that the design team has approved these changes.
  3. Perform cross-browser testing and report the results.
  4. Run an accessibility check on the new color scheme and report the results.
  5. Monitor performance metrics, particularly on lower-end devices, to ensure no significant impact from the bg-hex-bg class.
client/tailwind.config.js (4)

65-65: LGTM! Verify UI appearance with updated colors.

The color updates for gold, red, brown, dark, and green look good. These changes will likely impact the overall appearance of the UI.

Please ensure that these color changes have been tested across different components and pages to maintain visual consistency and meet design requirements.

Also applies to: 70-70, 76-76, 78-78, 83-83


Line range hint 239-252: LGTM! Use the 'no-scrollbar' utility judiciously.

The new 'no-scrollbar' utility class is a good addition for hiding scrollbars across different browsers. This can enhance the UI aesthetics in certain scenarios.

While this utility is useful, please ensure it's used judiciously. Hiding scrollbars can impact user experience and accessibility, especially for users who rely on scrollbars for navigation. Consider the following:

  1. Use this utility only when necessary and when alternative navigation methods are available.
  2. Ensure that the content is still accessible and navigable, especially for keyboard users.
  3. Test the implementation across different devices and screen sizes to prevent content from becoming inaccessible.

To verify proper usage, you can search for applications of this new utility:

#!/bin/bash
# Search for usage of the 'no-scrollbar' utility
rg --type tsx --type ts 'no-scrollbar' src/

Line range hint 1-261: Overall, the changes look good but require careful testing.

The updates to the Tailwind configuration file include several color changes, the addition of a new 'enemy' color, and a new utility class for hiding scrollbars. These changes can significantly impact the UI appearance and functionality.

To ensure these changes are implemented correctly and don't introduce any unintended side effects:

  1. Conduct a thorough visual review of all affected components and pages.
  2. Test the application across different browsers and devices to verify cross-browser compatibility.
  3. Perform accessibility testing, especially for areas where the 'no-scrollbar' utility is applied.
  4. Update any relevant documentation or style guides to reflect these new color values and utilities.

Consider running a comprehensive UI test suite if available:

#!/bin/bash
# Run UI tests (replace with your actual test command)
npm run test:ui

86-86: LGTM! Ensure consistent usage of the new 'enemy' color.

The addition of the 'enemy' color is a good improvement for better visual distinction. The comment explaining its purpose is helpful.

To maintain consistency, please ensure that this new color is used appropriately across all relevant components where enemy entities are displayed. Consider running a search to find potential places where this color should be applied:

✅ Verification successful

The previous shell script encountered errors. Here is a corrected version to search for potential usages of the new 'enemy' color:


The previous shell script encountered issues with unrecognized file types. Here is a corrected version to search for potential usages of the new 'enemy' color:


The previous search targeted a non-existent directory. Here is a corrected script to search within the client/ directory for potential usages of the new 'enemy' color:


Consistent usage of the new 'enemy' color confirmed.

The new 'enemy' color #46201D is appropriately used in ArmyInfoLabel.tsx, enhancing visual distinction without introducing inconsistencies.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for potential places to apply the new 'enemy' color
rg --type tsx --type ts 'enemy|opponent|foe' src/

Length of output: 273


Script:

#!/bin/bash
# Search for potential places to apply the new 'enemy' color
rg --type tsx --type ts 'enemy|opponent|foe' src/

Length of output: 79


Script:

#!/bin/bash
# Search for potential places to apply the new 'enemy' color
rg 'enemy|opponent|foe' --glob '*.ts' --glob '*.tsx' src/

Length of output: 104


Script:

#!/bin/bash
# Search for potential places to apply the new 'enemy' color within the client directory
rg 'enemy|opponent|foe' --glob '*.ts' --glob '*.tsx' client/

Length of output: 3126

client/src/ui/components/bank/LiquidityResourceRow.tsx (1)

228-228: LGTM! Consider verifying visual consistency.

The change from bg-black/70 to bg-brown/70 for the background color is approved. This modification enhances the visual appearance of the InputResourcesPrice component.

To ensure visual consistency across the application, please verify that this color change aligns with the overall design system. You may want to check if similar components use the same background color for consistency.

client/src/ui/components/trading/MarketModal.tsx (6)

1-5: LGTM: New icon imports enhance UI elements

The addition of these SVG icons (Coins, Crown, Scroll, Sparkles, and Swap) is a good improvement. They will likely enhance the visual representation of tab labels, making the UI more intuitive and visually appealing.


162-163: LGTM: Enhanced modal container styling

The updates to the modal container improve its visual appeal and structure. The addition of a border, rounded corners, and a dark background creates a more defined and aesthetically pleasing container. The use of a grid layout provides a flexible and responsive structure for the modal content.


Line range hint 175-183: Simplified Select component styling

The removal of specific background styling from the SelectContent component is a good step towards more consistent theming. This change allows the component to inherit default styles, which can lead to better overall design coherence.

However, it's important to verify that the inherited styles still provide sufficient contrast and visibility for the select options.

Please check that the select dropdown is still clearly visible and usable with the inherited styles in various color schemes (e.g., light and dark modes if applicable).


202-216: LGTM: Improved header layout and structure

The changes to the header section enhance both the visual appeal and the semantic structure of the component:

  1. Centering the title and using an h1 element improves the visual hierarchy and semantic meaning.
  2. The repositioning of the hint modal toggle button likely creates a better balance in the layout.

These changes contribute to a more polished and user-friendly interface.


223-227: LGTM: Improved tab list layout

The use of a flex layout for the tab list is a good improvement. This change ensures consistent spacing and alignment of tabs, likely enhancing the responsiveness of the layout. It contributes to a more polished and flexible user interface.


Line range hint 1-240: Overall assessment: Significant UI improvements with no major issues

The changes to the MarketModal component focus on enhancing the user interface and improving the overall layout. Key improvements include:

  1. Addition of intuitive icons to tab labels
  2. Improved modal container styling
  3. Simplified Select component styling
  4. Enhanced header layout and structure
  5. Improved tab list layout using flex

These changes contribute to a more visually appealing and user-friendly interface without introducing any significant logic changes or potential bugs. The component's core functionality remains intact while its presentation has been notably improved.

Consider implementing the suggested TabLabel component to further improve code maintainability. Also, ensure that the Select component's inherited styles provide sufficient contrast and visibility in all relevant color schemes.

client/src/ui/components/bank/Swap.tsx (4)

65-66: LGTM: Efficient balance calculation with memoization

The addition of memoized lordsBalance and resourceBalance variables is a good optimization. It prevents unnecessary recalculations and simplifies balance retrieval throughout the component.


70-71: LGTM: Simplified and consistent balance check

The updated hasEnough calculation correctly utilizes the new memoized balance variables. This change improves code consistency and readability while maintaining the correct logic for checking if the user has sufficient balance for the swap.


275-276: LGTM: Robust slippage calculation

The addition of Math.abs() in the slippage calculation is a good defensive programming practice. It ensures that the calculation works correctly regardless of the sign of the input values, making the component more robust against potential edge cases.


165-165: 🛠️ Refactor suggestion

Consider consistent max value handling for all resources

While adding a max prop to the ResourceBar is a good idea to prevent overspending, the current implementation is inconsistent. It limits the input for Lords but not for other resources.

Consider updating the max prop to use resourceBalance for non-Lords resources:

-max={isLords ? divideByPrecision(lordsBalance) : Infinity}
+max={isLords ? divideByPrecision(lordsBalance) : divideByPrecision(resourceBalance)}

This change would ensure consistent behavior across all resource types and prevent users from inputting amounts greater than their available balance for any resource.

client/src/ui/modules/onboarding/Steps.tsx (7)

35-37: LGTM! Verify visual appearance of updated StepContainer.

The changes to the StepContainer's styling look good. The background color has been updated from black to brown, and new visual effects have been added (border-gradient, animatedBackground).

Please ensure that these visual changes align with the overall design system and provide a cohesive user experience across the onboarding process.


Line range hint 65-219: LGTM! Naming component remains unchanged.

The Naming component's functionality appears to be unchanged. It continues to handle address naming, account management, and related UI interactions effectively.


Line range hint 221-229: Significant change in StepTwo: Verify SettleRealmComponent functionality.

The StepTwo component has been completely replaced with a new SettleRealmComponent. This change likely introduces new functionality related to realm selection or settlement.

Could you provide more information about the SettleRealmComponent? It's important to ensure that this change aligns with the overall onboarding flow and user experience objectives.


Line range hint 231-296: LGTM! Consistent layout and informative content in Steps Three, Four, and Five.

The changes to StepThree, StepFour, and StepFive components look good. They now use a consistent ContainerWithSquire layout and provide important game information to new players.

Please review the content of each step to ensure it provides complete and clear information about the game world and mechanics. Consider having a game designer or content writer review these sections to optimize the onboarding experience.


Line range hint 307-319: LGTM! Engaging final step with clear call-to-action.

The changes to the StepSix component look good. The addition of the ResourceIcon and the message about quests provide a visually engaging and informative final step in the onboarding process.

Please ensure that the NavigateToRealm component functions correctly and provides a smooth transition from the onboarding process to the actual gameplay. Test this transition thoroughly to avoid any potential issues that could disrupt the user experience.


Line range hint 321-348: LGTM! Smooth transition to gameplay implemented.

The NavigateToRealm component effectively handles the transition from onboarding to the game world. The use of state management and custom event dispatch suggests a well-thought-out approach to managing this transition.

Please ensure that:

  1. The 'ACCOUNT_CHANGE_EVENT' is properly handled across the application.
  2. The 250ms timeout before navigation is necessary and doesn't cause any noticeable delay for users.
  3. Error handling is in place in case the navigation or state updates fail.

Line range hint 1-348: Overall improvements to onboarding process and user experience.

The changes to the Steps.tsx file significantly enhance the onboarding process. Key improvements include:

  1. Consistent styling and layout across steps.
  2. Introduction of new components like SettleRealmComponent and ContainerWithSquire.
  3. Clear progression through the onboarding steps with informative content.
  4. Smooth transition from onboarding to gameplay.

These changes should result in a more engaging and informative onboarding experience for new players.

To ensure the best possible user experience:

  1. Conduct thorough end-to-end testing of the entire onboarding flow.
  2. Verify that all new components (e.g., SettleRealmComponent) function as intended.
  3. Review the content of each step for clarity and completeness.
  4. Test the final transition to gameplay across different devices and network conditions.
client/src/ui/modules/chat/Chat.tsx (2)

7-7: LGTM: New imports and hook usage

The new imports and the use of the useCallback hook are appropriate for the changes made to the component. The addition of useGuilds and CHAT_COLORS aligns well with the new guild functionality and chat color management.

Also applies to: 10-10, 14-14, 17-17


205-208: LGTM: Improved Messages component with guild support

The Messages component has been successfully updated to handle guild messages. The changes include:

  1. Proper identification of guild messages
  2. Updated message key generation to include guild messages
  3. Appropriate color styling based on the channel type (global, guild, or private)

These modifications enhance the component's functionality and visual representation of different message types.

Also applies to: 219-222, 273-279

client/src/ui/components/trading/MarketOrderPanel.tsx (1)

59-61: Improved UI with rounded corners

The addition of the rounded-xl class to the main container enhances the visual consistency with other components in the UI.

client/src/ui/components/construction/SelectPreviewBuilding.tsx (1)

350-350: Consistent color scheme update applied.

The background color classes have been updated from black to brown (e.g., bg-black/30 to bg-brown/30) for both the main container and the overlay. This change is consistently applied and likely improves the visual design without affecting functionality.

Also applies to: 367-367, 390-390

client/src/ui/modules/social/PlayerId.tsx (3)

15-15: Import 'getMessageKey' for chat tab key generation

The getMessageKey function is properly imported from "../chat/utils" to generate unique keys for chat tabs.


27-27: Retrieve 'addTab' from chat store

The addTab function is correctly retrieved from the chat store using useChatStore, ensuring proper tab management.


127-127: Update background color for player name display

The background color class is updated to bg-brown/20, enhancing the visual consistency of the player name display.

Comment on lines +30 to 31
"px-6 py-2 bg-brown font-semibold text-lg uppercase tracking-wider shadow-md hover:from-yellow-700 hover:to-yellow-800 focus:outline-none border-2 outline-gold hover:bg-gold border-y hover:border-gold hover:bg-brown/90 bg-brown/40 hover:text-black/90",
loadingStyle: "relative",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

LGTM, but hover text color inconsistency noted.

The opaque style changes align well with the new color scheme, switching from black to brown. However, there's an inconsistency in the hover text color:

  • The primary style uses hover:text-brown
  • The opaque style uses hover:text-black/90

Consider changing hover:text-black/90 to hover:text-brown in the opaque style for consistency with the primary style, unless this difference is intentional.

@@ -139,7 +139,7 @@ export const BattleSideView = ({
{showBattleDetails && battleEntityId ? (
<BattleHistory battleSide={battleSide} battleId={battleEntityId} />
) : (
<TroopRow troops={ownSideTroopsUpdated} />
<TroopRow defending={battleSide === BattleSide.Defence} troops={ownSideTroopsUpdated} />
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Potential Issue: defending prop is used but not defined in TroopRow component.

It appears that the defending prop is being passed to the TroopRow component in BattleSideView.tsx, but this prop is not defined in the component's props within Troops.tsx or Combat.tsx. This might lead to TypeScript errors or unintended behavior during runtime.

  • Ensure that the defending prop is properly defined in the TroopRow component's prop types in Troops.tsx and Combat.tsx.
  • Verify that the TroopRow component utilizes the defending prop as intended.
🔗 Analysis chain

LGTM! Please provide context on the defending prop usage.

The addition of the defending prop to TroopRow is a good way to pass contextual information about the battle side.

Could you please provide more context on how the defending prop is used within the TroopRow component? This information would help ensure that the prop is being utilized effectively and that the component's behavior aligns with the intended design.

To assist in verifying the usage, you can run the following script:

This will help us understand how the defending prop is defined and used within the TroopRow component.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the TroopRow component definition and its usage of the 'defending' prop
ast-grep --lang typescript --pattern 'const TroopRow = ({ defending, $_ }: { defending: boolean, $_ }) => { $$$ }'

Length of output: 116


Script:

#!/bin/bash
# Search for the TroopRow component defined as a class-based component
ast-grep --lang typescript --pattern 'class TroopRow extends React.Component<$$_, $$_> { $$$ }'

Length of output: 97


Script:

#!/bin/bash
# Search for all occurrences of 'TroopRow' in TypeScript files
rg 'TroopRow' --glob '*.tsx'

Length of output: 609


Script:

#!/bin/bash
# Verify if the 'TroopRow' component definitions include the 'defending' prop
rg 'TroopRow\s*=\s*\(\{[^}]*defending[^}]*\}' --glob '*.tsx' client/src/ui/modules/military/battle-view/Troops.tsx client/src/ui/components/hints/Combat.tsx

Length of output: 158

@@ -136,14 +136,14 @@ export const BattleProgressBar = ({
<motion.div
initial="hidden"
animate="visible"
className=""
className="w-2/3 mx-auto"
variants={{
hidden: { y: "100%" },
visible: { y: "0%", transition: { duration: 0.5 } },
}}
>
{!isNaN(Number(attackingHealthPercentage)) && !isNaN(Number(defendingHealthPercentage)) && (
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Replace isNaN with Number.isNaN for improved type safety

The static analysis tool has flagged the use of the global isNaN function. This function attempts type coercion, which can lead to unexpected results. It's recommended to use Number.isNaN instead for improved type safety and more predictable behavior.

Please apply the following change:

- {!isNaN(Number(attackingHealthPercentage)) && !isNaN(Number(defendingHealthPercentage)) && (
+ {!Number.isNaN(Number(attackingHealthPercentage)) && !Number.isNaN(Number(defendingHealthPercentage)) && (

This change will ensure more reliable NaN checks and improve the overall robustness of the code.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{!isNaN(Number(attackingHealthPercentage)) && !isNaN(Number(defendingHealthPercentage)) && (
{!Number.isNaN(Number(attackingHealthPercentage)) && !Number.isNaN(Number(defendingHealthPercentage)) && (
🧰 Tools
🪛 Biome

[error] 145-145: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)


[error] 145-145: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

Comment on lines +31 to +37
addTab({
name: playerName,
key: getMessageKey(account.address, selectedPlayer),
address: toHexString(selectedPlayer),
displayed: true,
lastSeen: new Date(),
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure 'account.address' is defined before using in 'getMessageKey'

In the handleClick function, getMessageKey is called with account.address and selectedPlayer without verifying if account.address is defined. To prevent potential runtime errors, consider adding a check to ensure account.address is defined before using it.

Copy link
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: 6

🧹 Outside diff range and nitpick comments (5)
sdk/packages/eternum/src/constants/global.ts (2)

98-103: LGTM! Consider using an enum for mercenary types.

The new constants for mercenaries provide more flexibility by defining lower and upper bounds. The naming convention is consistent and clear, and the use of underscores for large numbers improves readability.

Consider using an enum for mercenary types to improve type safety and reduce the likelihood of typos:

enum MercenaryType {
  Knights = 'knights',
  Paladins = 'paladins',
  Crossbowmen = 'crossbowmen',
}

export const MERCENARIES_BOUNDS = {
  [MercenaryType.Knights]: { lower: 1_000, upper: 10_000 },
  [MercenaryType.Paladins]: { lower: 1_000, upper: 10_000 },
  [MercenaryType.Crossbowmen]: { lower: 1_000, upper: 10_000 },
};

This approach would centralize the mercenary types and their bounds, making it easier to maintain and extend in the future.


191-196: LGTM! Consider using camelCase for consistency.

The updated mercenaries section in the EternumGlobalConfig object aligns well with the new constants defined earlier. The structure is more flexible, allowing for different ranges for each mercenary type.

For consistency with TypeScript conventions, consider using camelCase for the property names:

mercenaries: {
  knightsLowerBound: MERCENARIES_KNIGHTS_LOWER_BOUND,
  knightsUpperBound: MERCENARIES_KNIGHTS_UPPER_BOUND,
  paladinsLowerBound: MERCENARIES_PALADINS_LOWER_BOUND,
  paladinsUpperBound: MERCENARIES_PALADINS_UPPER_BOUND,
  crossbowmenLowerBound: MERCENARIES_CROSSBOWMEN_LOWER_BOUND,
  crossbowmenUpperBound: MERCENARIES_CROSSBOWMEN_UPPER_BOUND,
  // ... rest of the mercenaries config
},

This would maintain consistency with the rest of the TypeScript codebase.

contracts/src/utils/testing/config.cairo (2)

184-202: LGTM! Consider using a struct for improved readability.

The changes to set_mercenaries_config provide more granular control over troop counts by specifying lower and upper bounds for each troop type. This implementation allows for dynamic configuration of mercenary troops, which can be beneficial for gameplay balancing.

To improve code readability and maintainability, consider creating a struct to encapsulate the troop bounds:

struct TroopBounds {
    lower: u32,
    upper: u32,
}

struct MercenariesConfig {
    knights: TroopBounds,
    paladins: TroopBounds,
    crossbowmen: TroopBounds,
}

// Usage:
let config = MercenariesConfig {
    knights: TroopBounds { lower: 0, upper: 4_000_000 },
    paladins: TroopBounds { lower: 0, upper: 4_000_000 },
    crossbowmen: TroopBounds { lower: 0, upper: 4_000_000 },
};

IMercenariesConfigDispatcher { contract_address: config_systems_address }
    .set_mercenaries_config(config, mercenaries_rewards);

This approach would make the function call cleaner and easier to maintain as the number of parameters grows.


Line range hint 206-215: LGTM! Consider using a struct for consistency.

The use of named parameters in set_settlement_config significantly improves code readability by clearly indicating what each value represents. This change enhances the maintainability of the code without altering its functionality.

For consistency with the previous suggestion and to further improve code organization, consider creating a struct for the settlement configuration:

struct SettlementConfig {
    radius: u32,
    angle_scaled: u32,
    center: u32,
    min_distance: u32,
    max_distance: u32,
    min_scaling_factor_scaled: u64,
    min_angle_increase: u32,
    max_angle_increase: u32,
}

// Usage:
let config = SettlementConfig {
    radius: 50,
    angle_scaled: 0,
    center: 2147483646,
    min_distance: 1,
    max_distance: 5,
    min_scaling_factor_scaled: 1844674407370955161,
    min_angle_increase: 30,
    max_angle_increase: 100,
};

ISettlementConfigDispatcher { contract_address: config_systems_address }
    .set_settlement_config(config);

This approach would maintain consistency with other configuration structures and make it easier to add or modify settlement parameters in the future.

sdk/packages/eternum/src/config/index.ts (1)

486-489: Ensure consistent formatting for 'crossbowmen' parameters

The key-value pairs for crossbowmen_lower_bound and crossbowmen_upper_bound are split across multiple lines, whereas the previous entries for knights and paladins are on single lines. For consistency and improved readability, consider formatting the 'crossbowmen' parameters similarly.

Apply this diff to adjust the formatting:

-        crossbowmen_lower_bound:
-          config.config.mercenaries.crossbowmen_lower_bound * config.config.resources.resourcePrecision,
-        crossbowmen_upper_bound:
-          config.config.mercenaries.crossbowmen_upper_bound * config.config.resources.resourcePrecision,
+        crossbowmen_lower_bound: config.config.mercenaries.crossbowmen_lower_bound * config.config.resources.resourcePrecision,
+        crossbowmen_upper_bound: config.config.mercenaries.crossbowmen_upper_bound * config.config.resources.resourcePrecision,
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between d3bd7cb and 43456ea.

📒 Files selected for processing (10)
  • contracts/src/models/config.cairo (1 hunks)
  • contracts/src/systems/config/contracts.cairo (2 hunks)
  • contracts/src/systems/dev/contracts/bank.cairo (1 hunks)
  • contracts/src/systems/map/contracts.cairo (2 hunks)
  • contracts/src/utils/testing/config.cairo (1 hunks)
  • sdk/packages/eternum/src/config/index.ts (1 hunks)
  • sdk/packages/eternum/src/constants/global.ts (2 hunks)
  • sdk/packages/eternum/src/provider/index.ts (1 hunks)
  • sdk/packages/eternum/src/types/common.ts (2 hunks)
  • sdk/packages/eternum/src/types/provider.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • sdk/packages/eternum/src/types/common.ts
🧰 Additional context used
🔇 Additional comments (5)
sdk/packages/eternum/src/types/provider.ts (1)

545-550: Approve changes to SetMercenariesConfigProps interface with considerations

The modifications to the SetMercenariesConfigProps interface provide more granular control over mercenary configurations by introducing separate lower and upper bounds for each troop type. This change enhances flexibility in setting mercenary parameters.

Please ensure that all usages of SetMercenariesConfigProps in the codebase have been updated to reflect these changes. Additionally, verify if the removal of the Troops type from this interface affects any other parts of the codebase.

sdk/packages/eternum/src/provider/index.ts (2)

1084-1105: Improved granularity in mercenary configuration

The changes to the set_mercenaries_config function enhance the flexibility of mercenary configuration by allowing specific bounds for different troop types (knights, paladins, crossbowmen). This granular control is a positive improvement over the previous generic 'troops' parameter.

The implementation correctly includes all new parameters in the function signature and the calldata construction. This change aligns well with the provided AI-generated summary.


1084-1105: Verify impact on related components

While the changes to set_mercenaries_config are well-implemented, it's important to ensure that all components interacting with this function are updated to accommodate the new parameter structure.

Please run the following script to identify potential areas that may need updates:

✅ Verification successful

Impact on related components verified

All calls to set_mercenaries_config have been updated to accommodate the new parameter structure, and no references to the old troops parameter were found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find usages of set_mercenaries_config to ensure they're updated

# Search for calls to set_mercenaries_config
echo "Searching for calls to set_mercenaries_config:"
rg "set_mercenaries_config" --type typescript --type javascript

# Search for references to the old 'troops' parameter
echo "Searching for references to the old 'troops' parameter:"
rg "troops.*set_mercenaries_config" --type typescript --type javascript

Length of output: 437


Script:

#!/bin/bash
# Description: Find usages of set_mercenaries_config to ensure they're updated

# Search for calls to set_mercenaries_config in TypeScript and JavaScript files
echo "Searching for calls to set_mercenaries_config:"
rg "set_mercenaries_config" -g "*.ts" -g "*.tsx" -g "*.js" -g "*.jsx"

# Search for references to the old 'troops' parameter in TypeScript and JavaScript files
echo "Searching for references to the old 'troops' parameter:"
rg "troops\s*,\s*set_mercenaries_config" -g "*.ts" -g "*.tsx" -g "*.js" -g "*.jsx"

Length of output: 701

contracts/src/systems/dev/contracts/bank.cairo (1)

82-82: LGTM! Simplified mercenary addition improves maintainability

Replacing the previous logic with a single call to InternalMapSystemsImpl::add_mercenaries_to_structure enhances code readability and maintainability by abstracting the mercenary addition process.

contracts/src/systems/map/contracts.cairo (1)

172-176: Implementation Enhancement Looks Good

The addition of transferring rewards to the mine structure enhances the functionality by ensuring the mine entity receives the appropriate rewards upon discovery.

Comment on lines 254 to 257
let tx_info = starknet::get_tx_info();
let salt_one: u256 = tx_info.transaction_hash.into();
let salt_two: u256 = starknet::get_block_timestamp().into();
let salt_three: u256 = tx_info.nonce.into();
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential Security Issue: Use of Predictable Salts for Randomness

Using tx_info.transaction_hash, starknet::get_block_timestamp(), and tx_info.nonce as salts for random number generation can lead to predictable outputs. Transaction hashes, timestamps, and nonces can be influenced or predicted by malicious actors, potentially allowing them to manipulate the random troop counts.

Consider using a more secure and unpredictable source of randomness. For example, you might use a verifiable random function (VRF) or another blockchain-provided randomness beacon that is resistant to manipulation.

Comment on lines 259 to 279
let random_knights_amount: u64 = random::random(
salt_one.low,
mercenaries_config.knights_upper_bound.into() - mercenaries_config.knights_lower_bound.into()
)
.try_into()
.unwrap()
+ mercenaries_config.knights_lower_bound;
let random_paladins_amount: u64 = random::random(
salt_two.low,
mercenaries_config.paladins_upper_bound.into() - mercenaries_config.paladins_lower_bound.into()
)
.try_into()
.unwrap()
+ mercenaries_config.paladins_lower_bound;
let random_crossbowmen_amount: u64 = random::random(
salt_three.low,
mercenaries_config.crossbowmen_upper_bound.into() - mercenaries_config.crossbowmen_lower_bound.into()
)
.try_into()
.unwrap()
+ mercenaries_config.crossbowmen_lower_bound;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Random Troop Counts May Be Predictable and Manipulable

The random troop counts for knights, paladins, and crossbowmen are generated using salts derived from transaction and block data:

  • salt_one.low from transaction_hash
  • salt_two.low from block_timestamp
  • salt_three.low from nonce

Since these values can be predicted or manipulated, the resulting troop counts may not be truly random, potentially impacting game balance and fairness.

Recommend updating the random number generation process to use a secure and unbiased source of randomness. For instance, consider:

  • Utilizing on-chain randomness provided by the blockchain protocol that is designed to be unpredictable and tamper-resistant.
  • Implementing a commit-reveal scheme where randomness is derived from player commitments.
  • Using randomness provided by an oracle service if available and appropriate for your application's trust model.

Comment on lines 394 to 399
knights_lower_bound: u64,
knights_upper_bound: u64,
paladins_lower_bound: u64,
paladins_upper_bound: u64,
crossbowmen_lower_bound: u64,
crossbowmen_upper_bound: u64,
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider encapsulating troop bounds into a nested structure for better organization

The addition of individual lower and upper bounds for each troop type enhances configuration granularity. However, grouping these bounds into a nested structure can improve maintainability and scalability, especially if more troop types are added in the future.

Apply this refactor:

 pub struct MercenariesConfig {
     #[key]
     config_id: ID,
-    knights_lower_bound: u64,
-    knights_upper_bound: u64,
-    paladins_lower_bound: u64,
-    paladins_upper_bound: u64,
-    crossbowmen_lower_bound: u64,
-    crossbowmen_upper_bound: u64,
+    knights_bounds: TroopBounds,
+    paladins_bounds: TroopBounds,
+    crossbowmen_bounds: TroopBounds,
     rewards: Span<(u8, u128)>
 }
 
+pub struct TroopBounds {
+    lower_bound: u64,
+    upper_bound: u64,
+}

Committable suggestion was skipped due to low confidence.

Comment on lines 153 to 162
fn set_mercenaries_config(
ref world: IWorldDispatcher,
knights_lower_bound: u64,
knights_upper_bound: u64,
paladins_lower_bound: u64,
paladins_upper_bound: u64,
crossbowmen_lower_bound: u64,
crossbowmen_upper_bound: u64,
rewards: Span<(u8, u128)>
);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider encapsulating troop bounds into a struct for clarity

The function set_mercenaries_config has multiple parameters for troop bounds, which can make the signature lengthy and harder to maintain. Consider encapsulating the troop bounds into a dedicated struct to enhance readability and maintainability.

Apply this diff to refactor the function signature:

 fn set_mercenaries_config(
     ref world: IWorldDispatcher,
-    knights_lower_bound: u64,
-    knights_upper_bound: u64,
-    paladins_lower_bound: u64,
-    paladins_upper_bound: u64,
-    crossbowmen_lower_bound: u64,
-    crossbowmen_upper_bound: u64,
+    troop_bounds: TroopBounds,
     rewards: Span<(u8, u128)>
 );

Define the TroopBounds struct as:

struct TroopBounds {
    knights_lower_bound: u64,
    knights_upper_bound: u64,
    paladins_lower_bound: u64,
    paladins_upper_bound: u64,
    crossbowmen_lower_bound: u64,
    crossbowmen_upper_bound: u64,
}

Comment on lines 657 to 693
fn set_mercenaries_config(
ref world: IWorldDispatcher,
knights_lower_bound: u64,
knights_upper_bound: u64,
paladins_lower_bound: u64,
paladins_upper_bound: u64,
crossbowmen_lower_bound: u64,
crossbowmen_upper_bound: u64,
rewards: Span<(u8, u128)>
) {
assert_caller_is_admin(world);

set!(world, (MercenariesConfig { config_id: WORLD_CONFIG_ID, troops, rewards }));
assert!(
knights_lower_bound < knights_upper_bound, "knights_lower_bound must be lower than knights_upper_bound"
);
assert!(
paladins_lower_bound < paladins_upper_bound,
"paladins_lower_bound must be lower than paladins_upper_bound"
);
assert!(
crossbowmen_lower_bound < crossbowmen_upper_bound,
"crossbowmen_lower_bound must be lower than crossbowmen_upper_bound"
);

set!(
world,
(MercenariesConfig {
config_id: WORLD_CONFIG_ID,
knights_lower_bound,
knights_upper_bound,
paladins_lower_bound,
paladins_upper_bound,
crossbowmen_lower_bound,
crossbowmen_upper_bound,
rewards
})
);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Refactor repetitive assertions to improve maintainability

The assertions checking the lower and upper bounds for each troop type are repetitive. Consider refactoring them into a loop to reduce code duplication and enhance readability.

Apply this diff to refactor the assertions:

+            let troop_bounds = [
+                ("knights", knights_lower_bound, knights_upper_bound),
+                ("paladins", paladins_lower_bound, paladins_upper_bound),
+                ("crossbowmen", crossbowmen_lower_bound, crossbowmen_upper_bound),
+            ];
+            for (name, lower_bound, upper_bound) in troop_bounds {
+                assert!(
+                    lower_bound < upper_bound,
+                    "{}_lower_bound must be lower than {}_upper_bound",
+                    name, name
+                );
+            }
-
             assert!(
                 knights_lower_bound < knights_upper_bound, "knights_lower_bound must be lower than knights_upper_bound"
             );
             assert!(
                 paladins_lower_bound < paladins_upper_bound,
                 "paladins_lower_bound must be lower than paladins_upper_bound"
             );
             assert!(
                 crossbowmen_lower_bound < crossbowmen_upper_bound,
                 "crossbowmen_lower_bound must be lower than crossbowmen_upper_bound"
             );

Committable suggestion was skipped due to low confidence.

Copy link
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: 41

🧹 Outside diff range and nitpick comments (51)
client/src/ui/elements/StaminaResourceCost.tsx (1)

Line range hint 1-48: Overall changes improve maintainability while preserving functionality

The modifications to the StaminaResourceCost component enhance its maintainability and align it with what appears to be a broader architectural shift towards centralized configuration management. The core functionality and interface of the component remain intact, which is commendable.

However, there's room for improvement in error handling:

Consider adding error handling for cases where configManager.getTravelStaminaCost() or configManager.getExploreStaminaCost() might return undefined or unexpected values. This could prevent potential runtime errors and improve the component's robustness.

Example:

const travelCost = configManager.getTravelStaminaCost() ?? 0;
const exploreCost = configManager.getExploreStaminaCost() ?? 0;
const costs = travelLength * (isExplored ? -travelCost : -exploreCost);
client/src/ui/components/resources/RealmResourcesIO.tsx (2)

21-21: LGTM: Centralized resource input management

The use of configManager.resourceInputs aligns well with the move towards centralized configuration management. This change improves maintainability and flexibility of the resource input data.

Consider using object destructuring for a more concise syntax:

const { resourceInputs } = configManager;

26-28: LGTM: Updated resource consumption calculation

The changes correctly implement the new resource input data source while maintaining the existing filtering logic. This aligns well with the centralized configuration approach.

Consider memoizing the resourcesConsumed calculation to optimize performance, especially if realm or resourcesInputs don't change frequently:

import { useMemo } from 'react';

// ...

const resourcesConsumed = useMemo(() => {
  if (!realm) return [];
  return [...new Set(
    resourcesProduced.flatMap((resourceId) => 
      resourcesInputs[resourceId]
        .filter((input) => input.resource !== ResourcesIds["Wheat"] && input.resource !== ResourcesIds["Fish"])
        .map((input) => input.resource)
    )
  )];
}, [realm, resourcesInputs, resourcesProduced]);

This optimization would prevent unnecessary recalculations on each render.

client/src/ui/components/hints/GettingStarted.tsx (3)

1-1: Improved configuration management approach

The changes in the import statements reflect a shift towards a more centralized and flexible configuration management system. By using configManager and TickIds, the code becomes more maintainable and easier to update across the application.

Consider documenting this new approach in the project's README or developer documentation to ensure consistent usage across the codebase.

Also applies to: 3-3


11-11: Improved flexibility in time cycle calculation

The updated calculation for the Eternum Day duration uses the new configuration management system, which provides better flexibility and maintainability. This change aligns well with the updated import statements.

Consider extracting the calculation into a separate constant or function for improved readability:

const SECONDS_IN_MINUTE = 60;
const eternumDayInMinutes = configManager.getTick(TickIds.Armies) / SECONDS_IN_MINUTE;

Then use eternumDayInMinutes in the template string. This would make the code more self-documenting and easier to maintain.


Line range hint 1-58: Overall improvement in configuration management and maintainability

The changes in this file represent a positive step towards more flexible and maintainable code. By centralizing configuration management and using dynamic retrieval of tick intervals, the code becomes more adaptable to future changes. The core functionality of the GettingStarted component remains intact, ensuring that the user experience is preserved while improving the underlying implementation.

As the project continues to evolve, consider applying similar refactoring techniques to other components that may still be using global constants or hard-coded configuration values. This will ensure consistency across the codebase and make future updates easier to manage.

config/index.ts (4)

Line range hint 8-14: Approve environment variable checks with a suggestion for improvement.

The addition of environment variable checks improves the robustness of the configuration setup. However, the error message could be more informative.

Consider updating the error message to include all checked variables:

- throw new Error("VITE_PUBLIC_MASTER_ADDRESS is required");
+ throw new Error("VITE_PUBLIC_MASTER_ADDRESS, VITE_PUBLIC_MASTER_PRIVATE_KEY, and VITE_PUBLIC_NODE_URL are required");

Line range hint 19-23: Approve manifest and node URL selection with a suggestion.

The conditional selection of manifest and node URL based on the VITE_PUBLIC_DEV environment variable improves flexibility between development and production environments.

Consider making the development node URL configurable:

- const nodeUrl = VITE_PUBLIC_DEV === "true" ? "http://127.0.0.1:5050/" : VITE_PUBLIC_NODE_URL;
+ const nodeUrl = VITE_PUBLIC_DEV === "true" ? (process.env.VITE_PUBLIC_DEV_NODE_URL || "http://127.0.0.1:5050/") : VITE_PUBLIC_NODE_URL;

This change would allow developers to override the default development URL if needed.


Line range hint 25-34: Approve user confirmation for non-dev environments with a suggestion.

The addition of a user confirmation prompt for non-development environments is a good safety measure to prevent accidental configuration of production environments.

Consider using an asynchronous input method or environment variable for confirmation in environments where prompt might not be available or suitable:

import readline from 'readline';

// ... (existing code)

if (!VITE_PUBLIC_DEV) {
  if (process.env.VITE_CONFIRM_PRODUCTION !== 'true') {
    const rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout
    });

    await new Promise<void>((resolve, reject) => {
      rl.question(
        "You are about to set the configuration for a non-development environment. Are you sure you want to proceed? (yes/no) ",
        (answer) => {
          rl.close();
          if (answer.toLowerCase() !== "yes") {
            console.log("Configuration setup cancelled.");
            process.exit(0);
          }
          resolve();
        }
      );
    });
  }
}

This approach provides more flexibility and can work in various environments.


Line range hint 43-56: Approve configuration setup with suggestions for improvement.

The conditional modification of the setupConfig object based on the VITE_PUBLIC_DEV environment variable allows for different configurations in development and production environments, which is a good practice.

Consider the following improvements for more flexibility:

  1. Use environment variables for development-specific values:
const setupConfig: Config =
  VITE_PUBLIC_DEV === "true"
    ? {
        ...EternumGlobalConfig,
        stamina: {
          ...EternumGlobalConfig.stamina,
          travelCost: Number(process.env.VITE_DEV_TRAVEL_COST) || 0,
          exploreCost: Number(process.env.VITE_DEV_EXPLORE_COST) || 0,
        },
        battle: {
          graceTickCount: Number(process.env.VITE_DEV_GRACE_TICK_COUNT) || 0,
          delaySeconds: Number(process.env.VITE_DEV_DELAY_SECONDS) || 0,
        },
      }
    : EternumGlobalConfig;
  1. Create a separate development config file to manage these values:
import devConfig from './devConfig';

const setupConfig: Config =
  VITE_PUBLIC_DEV === "true"
    ? {
        ...EternumGlobalConfig,
        ...devConfig,
      }
    : EternumGlobalConfig;

These changes would make the development configuration more maintainable and flexible.

client/src/ui/elements/StaminaResource.tsx (1)

31-31: Updated stamina cost retrieval method

The change from EternumGlobalConfig.stamina.travelCost to configManager.getTravelStaminaCost() is consistent with the new configuration management approach. This modification:

  1. Aligns with the centralized configuration management introduced earlier.
  2. Potentially allows for more dynamic or context-dependent stamina cost calculations.

Consider extracting the travel stamina cost into a variable for improved readability:

const travelStaminaCost = configManager.getTravelStaminaCost();
const staminaColor = staminaAmount < travelStaminaCost ? "bg-red" : "bg-yellow";

This change would make the code more self-documenting and easier to understand at a glance.

client/src/ui/components/hints/Realm.tsx (1)

Line range hint 1-33: Summary: Good refactoring, but verify precision handling.

The changes in this file are part of a larger refactoring effort to use configManager for realm upgrade costs, which improves flexibility and maintainability. However, the removal of precision handling (via multiplyByPrecision) needs careful consideration.

To ensure the refactoring is complete and consistent:

  1. Verify that configManager.realmUpgradeCosts provides correctly scaled values that don't require additional precision handling.
  2. Check if precision handling is needed in the ResourceCost component or anywhere else where these costs are displayed or used in calculations.
  3. Consider adding a comment explaining why precision handling is no longer needed at this level, if that's indeed the case.

These steps will help maintain accuracy in cost representations and calculations throughout the application.

client/src/ui/elements/ArmyCapacity.tsx (2)

22-22: Approved: Consistent use of configManager

The update to use configManager.getExploreReward() is consistent with the new import and represents an improvement in configuration management. This change maintains the existing logic while potentially allowing for more dynamic configuration of the explore reward.

For improved readability, consider extracting the explore reward into a constant at the beginning of the component:

const exploreReward = BigInt(configManager.getExploreReward());

Then use this constant in the comparison:

if (remainingCapacity < exploreReward) return CapacityColor.MEDIUM;

This would make the code more self-documenting and easier to maintain.


Incomplete Migration from EternumGlobalConfig to configManager Detected

The verification revealed that EternumGlobalConfig is still used extensively across multiple files in the codebase. This indicates that the refactoring to configManager is not yet fully implemented.

Actions Required:

  • Complete Refactoring: Ensure that all instances of EternumGlobalConfig are replaced with configManager to maintain consistency.
  • Automated Search and Replace: Utilize automated tools or scripts to identify and update remaining usages systematically.
  • Update Documentation: Reflect the changes in the project documentation to guide future development and onboarding.
  • Review Dependencies: Verify that replacing EternumGlobalConfig does not adversely affect other parts of the application.
🔗 Analysis chain

Line range hint 2-22: Overall: Positive change with potential for broader impact

The changes in this file represent a positive step towards more flexible and maintainable configuration management. The shift from EternumGlobalConfig to configManager is well-implemented and consistent within this component.

To ensure consistency across the entire application:

  1. Verify that similar changes have been made in other components that previously used EternumGlobalConfig.
  2. Consider updating the project documentation to reflect this new approach to configuration management.
  3. If not already done, consider adding unit tests to verify the correct usage of configManager throughout the application.

To help verify the consistent usage of configManager across the project, you can run the following script:

This will help identify any places where the old EternumGlobalConfig might still be in use, and confirm the adoption of configManager across the project.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for remaining usage of EternumGlobalConfig and new usage of configManager

echo "Checking for remaining usage of EternumGlobalConfig:"
rg --type typescript --type tsx "EternumGlobalConfig"

echo "\nChecking for new usage of configManager:"
rg --type typescript --type tsx "configManager"

Length of output: 381


Script:

#!/bin/bash
# Description: Check for remaining usage of EternumGlobalConfig and new usage of configManager in .ts and .tsx files

echo "Checking for remaining usage of EternumGlobalConfig in .ts and .tsx files:"
rg "EternumGlobalConfig" --glob "*.ts" --glob "*.tsx"

echo "\nChecking for new usage of configManager in .ts and .tsx files:"
rg "configManager" --glob "*.ts" --glob "*.tsx"

Length of output: 36272

client/src/ui/components/worldmap/structures/StructureLabel.tsx (2)

42-42: Approve calculation change and suggest documentation

The modification in the immunityEndTimestamp calculation is a good improvement. It uses the new tick management system, which appears to offer more flexibility and specificity in handling game timings.

Consider adding a brief comment explaining the calculation, especially the significance of getBattleGraceTickCount(). This would enhance code readability and maintainability. For example:

// Calculate immunity end timestamp based on battle grace period and army tick interval
const immunityEndTimestamp = (
  Number(structure?.created_at || 0) +
  configManager.getBattleGraceTickCount() * configManager.getTick(TickIds.Armies)
);

Line range hint 12-22: Consider safeguarding against negative timer values

While the current implementation aligns with the previous learning that negative timer values don't need special handling, it might be beneficial to add a small safeguard to ensure only non-negative values are displayed.

Consider modifying the formatTime call in the ImmunityTimer component:

- <div className="text-lg font-bold text-white animate-pulse">{formatTime(timer)}</div>
+ <div className="text-lg font-bold text-white animate-pulse">{formatTime(Math.max(0, timer))}</div>

This change ensures that even if a negative value somehow occurs, the displayed time will always be non-negative, improving robustness without significantly altering the existing behavior.

client/src/ui/components/hints/Transfers.tsx (2)

25-25: Improved donkey capacity retrieval

The use of configManager.getCapacityConfig(CapacityConfigCategory.Donkey) is a good improvement:

  1. It centralizes configuration management.
  2. It allows for easier updates to capacity values.
  3. The use of CapacityConfigCategory.Donkey enhances code readability and type safety.

Consider extracting the capacity calculation to a constant for improved readability:

const donkeyCapacityKg = configManager.getCapacityConfig(CapacityConfigCategory.Donkey) / GRAMS_PER_KG;

Then use it in the JSX:

<strong>{donkeyCapacityKg} kg</strong>

28-34: Improved resource weight retrieval and display

The use of configManager.getResourceWeight(ResourcesIds.<Resource>) is a good improvement:

  1. It centralizes configuration management for resource weights.
  2. It allows for easier updates to weight values.
  3. The use of ResourcesIds enum enhances code readability and type safety.

The layout changes with additional div wrappers improve the structure of the resource weight display.

For consistency, consider applying the same structure to all resource weight displays:

<div className="flex mt-4 justify-center w-full gap-8 font-bold border p-2">
  <div>Lords: {`${configManager.getResourceWeight(ResourcesIds.Lords) / GRAMS_PER_KG} kg/unit`}</div>
  <div>Food: {`${configManager.getResourceWeight(ResourcesIds.Wheat) / GRAMS_PER_KG} kg/unit`}</div>
  <div>Resource: {`${configManager.getResourceWeight(ResourcesIds.Wood) / GRAMS_PER_KG} kg/unit`}</div>
</div>

This removes the ml-2 classes and makes the structure more uniform.

client/src/ui/components/trading/RealmProduction.tsx (2)

Line range hint 44-48: LGTM with a minor suggestion: Improved resource consumption logic.

The updated logic for calculating consumed resources is more specific and potentially more efficient. It correctly uses the new resourcesInputs structure and explicitly filters out "Wheat" and "Fish".

Consider extracting the filter condition into a separate constant or function for improved readability:

const isConsumedResource = (input) => 
  input.resource !== ResourcesIds["Wheat"] && 
  input.resource !== ResourcesIds["Fish"];

return resourcesInputs[resourceId]
  .filter(isConsumedResource)
  .map((input) => input.resource);

This change would make the logic more self-documenting and easier to maintain.

🧰 Tools
🪛 Biome

[error] 32-69: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


Line range hint 1-48: Overall assessment: Improved configuration and resource management.

The changes in this file significantly enhance the RealmProduction component by:

  1. Introducing centralized configuration management through configManager.
  2. Improving resource input handling with a more flexible approach.
  3. Refining the logic for calculating consumed resources.

These modifications contribute to better maintainability, flexibility, and potentially improved performance. The component's core functionality remains intact while adopting a more robust approach to resource management.

To further improve the component:

  1. Consider extracting the resource filtering logic into a separate utility function for reusability.
  2. If the configManager is used extensively, consider creating a custom hook for accessing configuration, which could simplify testing and provide a consistent interface across components.
🧰 Tools
🪛 Biome

[error] 32-69: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

client/src/ui/components/trading/TradeHistoryEvent.tsx (2)

3-4: Approved: Import changes enhance modularity and flexibility.

The updated import statement now includes the divideByPrecision function alongside currencyIntlFormat. This change, combined with the removal of the EternumGlobalConfig import (not visible in the provided code), suggests an improvement in how resource amounts are processed. This approach enhances modularity and flexibility by moving the precision handling logic to a utility function.

Consider documenting the divideByPrecision function to ensure its purpose and usage are clear to other developers working on the project.


45-48: Approved: Improved resource amount formatting.

The changes in the TradeHistoryEvent component enhance the way resource amounts are formatted and displayed. Using the divideByPrecision function instead of directly accessing EternumGlobalConfig.resources.resourcePrecision improves modularity and maintainability.

To further improve readability, consider extracting the formatted amounts into variables before using them in the JSX. For example:

const formattedTakenAmount = currencyIntlFormat(divideByPrecision(trade.event.resourceTaken.amount), 2);
const formattedGivenAmount = currencyIntlFormat(divideByPrecision(trade.event.resourceGiven.amount), 2);

// Then in JSX
<div>{`${formattedTakenAmount} for ${formattedGivenAmount}`}</div>

This approach would make the JSX more concise and easier to read.

client/src/ui/components/hints/Buildings.tsx (2)

12-13: Improved building data retrieval logic

The changes enhance the robustness and maintainability of the building data retrieval logic. However, there are a couple of suggestions for further improvement:

  1. Replace isNaN with Number.isNaN for safer number checking:
if (Number.isNaN(Number(buildingId))) continue;
  1. Consider using a type guard instead of type assertion for better type safety:
if (typeof buildingId === 'number' && BuildingType[buildingId as keyof typeof BuildingType]) {
  // Rest of the logic
}

The use of configManager methods for retrieving building costs and configurations is a good practice for centralized management.

Also applies to: 15-20

🧰 Tools
🪛 Biome

[error] 13-13: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)


Line range hint 27-32: Simplified building cost mapping

The updated cost mapping logic is more straightforward and aligns with the use of configManager for retrieving building costs. This change improves code readability and maintainability.

Consider a minor optimization:

building_resource_type: configManager.getResourceBuildingProduced(buildingId),
cost_of_building: buildingCosts.map(({ amount, ...rest }) => ({ ...rest, amount })),

This approach uses object destructuring and spread operators to create a new object for each cost item, potentially improving performance for larger datasets.

🧰 Tools
🪛 Biome

[error] 13-13: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

client/src/ui/components/worldmap/armies/ActionInfo.tsx (1)

100-100: Approve change with suggestions for optimization and error handling

The change from a static config value to configManager.getExploreReward() improves flexibility and centralization of configuration management. However, consider the following suggestions:

  1. Optimize performance by memoizing the result of getExploreReward() using useMemo to prevent unnecessary recalculations on each render.
  2. Add error handling in case configManager is undefined or getExploreReward() fails.

Here's an example of how you could implement these suggestions:

const exploreReward = useMemo(() => {
  try {
    return configManager.getExploreReward();
  } catch (error) {
    console.error('Failed to get explore reward:', error);
    return 0; // or some default value
  }
}, []);

// Then in your JSX:
<div>+{exploreReward} Random resource</div>

This approach ensures the reward is only calculated when necessary and provides a fallback in case of errors.

client/src/ui/components/worldmap/leaderboard/LeaderboardPanel.tsx (1)

35-35: Approved: Calculation updated to use dynamic configuration.

The change from a hardcoded constant to configManager.getHyperstructureConfig().pointsForWin improves flexibility and maintainability. This modification allows for easier updates to the points required for a win without changing this specific file.

Consider extracting the configuration value to a local constant for improved readability:

-    return Math.min((playerPoints / configManager.getHyperstructureConfig().pointsForWin) * 100, 100);
+    const pointsForWin = configManager.getHyperstructureConfig().pointsForWin;
+    return Math.min((playerPoints / pointsForWin) * 100, 100);

This change would make the calculation more readable and potentially more performant if the function is called multiple times.

client/src/ui/components/structures/construction/StructureConstructionMenu.tsx (2)

41-41: Improved precision handling in balance check

The use of multiplyByPrecision standardizes precision handling, aligning with the overall shift towards using configManager. This change improves consistency across the application.

Consider extracting the balance check logic into a separate utility function for better reusability and testability.


88-93: Improved configuration management in StructureInfo

The changes to cost retrieval and perTick calculation align with the centralized configuration management approach. The use of configManager.getHyperstructureConfig() provides a more flexible way to access hyperstructure-specific configurations.

Consider creating a custom hook for hyperstructure-related calculations to further improve code organization and reusability.

client/src/dojo/modelManager/__tests__/__BattleManagerMock__.ts (1)

153-170: Approve the addition of generateMockTroopConfig with suggestions for improvement.

The new generateMockTroopConfig function is a valuable addition for creating consistent mock troop configurations in tests. However, consider the following improvements:

  1. Use more realistic values for some parameters to better represent actual game scenarios.
  2. Add JSDoc comments to explain the purpose and usage of the function.
  3. Consider making some values configurable through function parameters for more flexible testing.

Here's an example of how you could implement these suggestions:

/**
 * Generates a mock troop configuration for testing purposes.
 * @param {Object} overrides - Optional. Override specific configuration values.
 * @returns {Object} A mock troop configuration object.
 */
export const generateMockTroopConfig = (overrides = {}) => {
  const defaultConfig = {
    health: 100,
    knightStrength: 10,
    paladinStrength: 15,
    crossbowmanStrength: 8,
    advantagePercent: 1200, // 20% advantage
    disadvantagePercent: 800, // 20% disadvantage
    maxTroopCount: 500000,
    pillageHealthDivisor: 8,
    baseArmyNumberForStructure: 3,
    armyExtraPerMilitaryBuilding: 1,
    maxArmiesPerStructure: 7,
    battleLeaveSlashNum: 25,
    battleLeaveSlashDenom: 100,
    battleTimeScale: 1000,
  };

  return { ...defaultConfig, ...overrides };
};

This implementation allows for more realistic default values and the flexibility to override specific values in tests when needed.

client/src/ui/components/worldmap/structures/StructureListItem.tsx (1)

64-65: Improved immunityEndTimestamp calculation.

The updated calculation of immunityEndTimestamp using configManager methods enhances flexibility and maintainability. It also introduces a more type-safe approach with TickIds.Armies.

Consider adding a brief comment explaining the calculation for improved readability:

// Calculate immunity end timestamp based on creation time, grace period, and army tick interval
const immunityEndTimestamp =
  Number(structure?.created_at) + configManager.getBattleGraceTickCount() * configManager.getTick(TickIds.Armies);
sdk/packages/eternum/src/types/common.ts (1)

369-373: New Player interface looks good, minor suggestion for consistency

The addition of the Player interface is a good improvement, providing a clear structure for player data. It includes essential properties like entity_id, address (using ContractAddress type, which is good for blockchain integration), and addressName for human-readable identification.

For consistency with other parts of the codebase, consider using the ID type alias for the entity_id property:

export interface Player {
  entity_id: ID;
  address: ContractAddress;
  addressName: string;
}

This change would align the Player interface with the usage of ID type throughout the rest of the file.

client/src/hooks/helpers/useRealm.tsx (2)

227-228: LGTM: Improved hasCapacity calculation

The use of configManager.getBasePopulationCapacity() instead of a hardcoded value improves the flexibility and maintainability of the code. This change allows for easier updates to the base population capacity without modifying the component logic.

Consider extracting the capacity calculation into a separate variable for improved readability:

const totalCapacity = population.capacity + configManager.getBasePopulationCapacity();
hasCapacity: !population || totalCapacity > population.population,

292-293: LGTM: Consistent hasCapacity calculation in getRealms

The modification to use configManager.getBasePopulationCapacity() in the getRealms function maintains consistency with the useGetRealm function. This change ensures that the base population capacity is sourced from a centralized configuration across the application.

For consistency and improved readability, consider applying the same extraction of the capacity calculation as suggested for the useGetRealm function:

const totalCapacity = population.capacity + configManager.getBasePopulationCapacity();
hasCapacity: !population || totalCapacity > population.population,
client/src/hooks/helpers/useStructures.tsx (1)

234-236: LGTM: Improved speed configuration retrieval

The modification to use configManager.getSpeedConfig(DONKEY_ENTITY_TYPE) instead of EternumGlobalConfig.speed.donkey is a good improvement. It centralizes configuration management and enhances maintainability.

Consider adding a comment explaining the calculation for better readability:

// Calculate travel time in hours, rounded down
const timeToTravel = Math.floor(
  ((distanceFromPosition / configManager.getSpeedConfig(DONKEY_ENTITY_TYPE)) * 3600) / 60 / 60
);
client/src/ui/components/trading/TransferBetweenEntities.tsx (3)

1-1: Improved configuration management and type safety.

The changes to the import statements are good improvements:

  1. Using configManager instead of a global config enhances modularity and flexibility.
  2. Importing DONKEY_ENTITY_TYPE increases type safety and code readability.

Consider grouping related imports together. For example, you could move the configManager import next to other project-specific imports for better organization.

Also applies to: 10-10


84-85: Enhanced flexibility in speed configuration.

The use of configManager.getSpeedConfig(DONKEY_ENTITY_TYPE) is a good improvement:

  1. It allows for dynamic configuration of speed values.
  2. The use of DONKEY_ENTITY_TYPE improves code clarity and type safety.

Consider adding error handling in case the speed configuration is not found for the given entity type. For example:

const speed = configManager.getSpeedConfig(DONKEY_ENTITY_TYPE) ?? defaultSpeed;

This ensures the component doesn't break if the configuration is missing.


Line range hint 1-285: Overall improvement in code quality and maintainability.

The changes in this file represent a positive step towards better code organization and flexibility:

  1. The shift to using configManager allows for more dynamic and centralized configuration management.
  2. The introduction of DONKEY_ENTITY_TYPE improves type safety and code readability.
  3. These changes enhance the maintainability of the code without altering the core functionality of the component.

As the project evolves, consider further modularizing the configuration management. You might want to create a dedicated configuration service that encapsulates all config-related logic, making it easier to manage and test configuration changes across the application.

client/src/ui/components/hyperstructures/StructureCard.tsx (1)

Line range hint 1-250: Overall: Good refactoring to use configurable maximum troop count.

The changes in this file consistently replace the hardcoded MAX_TROOPS_PER_ARMY constant with a dynamic maxTroopCountPerArmy value obtained from the configManager. This refactoring improves the flexibility and maintainability of the codebase by allowing for configuration changes without modifying the component code.

The modifications are well-implemented and don't introduce any apparent issues. They maintain consistency with the existing codebase while enhancing its adaptability.

Consider extracting the maxTroopCountPerArmy calculation to a higher-level component or a custom hook if it's used in multiple components. This could further reduce redundancy and improve maintainability. For example:

// In a new file, e.g., hooks/useTroopConfig.ts
import { configManager } from "@/dojo/setup";

export const useTroopConfig = () => {
  const maxTroopCountPerArmy = configManager.getTroopConfig().maxTroopCount;
  return { maxTroopCountPerArmy };
};

// In your component
import { useTroopConfig } from '@/hooks/useTroopConfig';

const { maxTroopCountPerArmy } = useTroopConfig();

This approach would centralize the configuration retrieval and make it easier to manage and update across multiple components if needed.

sdk/packages/eternum/src/config/index.ts (1)

482-489: Approve changes and suggest refactoring to reduce duplication

The changes to use lower and upper bounds for troop counts add more flexibility to the mercenary configuration, which is good. However, the code is still repetitive and could benefit from refactoring to improve maintainability.

Consider refactoring the code to reduce duplication, as suggested in the past review. Here's an example of how you could do this:

const troopTypes = ['knights', 'paladins', 'crossbowmen'];
const bounds = ['lower_bound', 'upper_bound'];

const troopBounds = Object.fromEntries(
  troopTypes.flatMap(troop => 
    bounds.map(bound => [
      `${troop}_${bound}`,
      config.config.mercenaries[`${troop}_${bound}`] * config.config.resources.resourcePrecision
    ])
  )
);

const tx = await config.provider.set_mercenaries_config({
  signer: config.account,
  ...troopBounds,
  rewards: config.config.mercenaries.rewards.map((reward) => ({
    resource: reward.resource,
    amount: reward.amount * config.config.resources.resourcePrecision * config.config.resources.resourceMultiplier,
  })),
});

This refactored version reduces duplication and makes it easier to add new troop types in the future if needed.

client/src/ui/components/trading/MarketOrderPanel.tsx (3)

263-263: Improved OrderRow component

The changes to the OrderRow component bring several improvements:

  1. Updated styling with rounded corners for better visual consistency.
  2. Improved travel time calculation using configManager, enhancing maintainability.
  3. Updated display logic for resource amounts, likely improving clarity.

These changes contribute to a more consistent and maintainable codebase.

However, consider extracting the complex ternary operations (e.g., lines 305-306, 312-313) into separate variables or functions for improved readability.

Consider refactoring complex ternary operations for better readability:

const getInputValue = () => {
  const baseAmount = isBuy ? offer.makerGets[0].amount : offer.takerGets[0].amount;
  const ratio = isBuy ? resourceBalanceRatio : lordsBalanceRatio;
  return divideByPrecision(baseAmount) * ratio;
};

const inputValue = getInputValue();

Also applies to: 305-306, 312-313, 318-318, 377-379, 382-384, 388-389


452-452: Enhanced OrderCreation component and improved donkey calculation

The changes to the OrderCreation component and the addition of the calculateDonkeysNeeded function bring several improvements:

  1. Updated styling with rounded corners for better visual consistency.
  2. Improved accuracy in calculating maximum values for NumberInput components using divideByPrecision.
  3. Introduction of calculateDonkeysNeeded function, which improves code organization and reusability.

These changes contribute to a more consistent, accurate, and maintainable codebase.

Consider adding a comment to explain the logic behind the calculateDonkeysNeeded function, especially the use of CapacityConfigCategory.Donkey.

Add a comment to explain the calculateDonkeysNeeded function:

// Calculate the number of donkeys needed based on the order weight
// and the capacity config for donkeys
const calculateDonkeysNeeded = (orderWeight: number): number => {
  return Math.ceil(divideByPrecision(orderWeight) / configManager.getCapacityConfig(CapacityConfigCategory.Donkey));
};

Also applies to: 457-457, 550-550, 594-594, 607-607, 639-639, 682-684


Line range hint 1-684: Overall improvements to MarketOrderPanel component

The changes made to the MarketOrderPanel component and its sub-components bring significant improvements:

  1. Enhanced configuration management with the introduction of configManager.
  2. Improved visual consistency across all components with the addition of rounded corners and better layout structures.
  3. More accurate calculations and display logic for resource amounts and prices.
  4. Better code organization with the introduction of the calculateDonkeysNeeded function.
  5. Updated styling for locked resources and market price displays, improving user experience.

These changes collectively contribute to a more maintainable, consistent, and user-friendly interface for market orders.

To further enhance the code:

  1. Consider adding more comments to explain complex logic, especially in areas dealing with resource calculations and conversions.
  2. Look for opportunities to extract repeated logic into reusable functions, particularly for price and resource amount calculations.
  3. Ensure that all error cases are properly handled, especially when dealing with user inputs and API calls.

To improve the overall architecture:

  1. Consider creating a separate utility file for common functions like calculateDonkeysNeeded and other resource-related calculations.
  2. Evaluate the possibility of using React Context or a state management library to handle shared state, which could simplify prop drilling in nested components.
  3. Implement proper error boundaries to gracefully handle and display any runtime errors that may occur during rendering or data fetching.
client/src/ui/components/resources/ResourceWeight.tsx (3)

Line range hint 14-25: Fix potential infinite loop due to useEffect dependencies

Including resourceWeight and donkeyBalance in the dependency array of the useEffect hook may cause an infinite loop. These state variables are updated within the useEffect, which triggers a re-render and re-runs the useEffect again. To prevent this, remove resourceWeight and donkeyBalance from the dependency array.

Apply this diff to fix the dependency array:

 useEffect(() => {
   // existing code
-}, [resources, entityId, resourceWeight, donkeyBalance, setCanCarry]);
+}, [resources, entityId, setCanCarry]);

87-87: Consistent labeling: Rename 'Food' to 'Wheat'

Since you're using ResourcesIds.Wheat to fetch the resource weight, consider renaming the label from 'Food' to 'Wheat' for consistency and clarity.

Apply this diff to update the label:

-<div>Food: {`${configManager.getResourceWeight(ResourcesIds.Wheat) / GRAMS_PER_KG} kg/unit`}</div>
+<div>Wheat: {`${configManager.getResourceWeight(ResourcesIds.Wheat) / GRAMS_PER_KG} kg/unit`}</div>

89-90: Clarify label from 'Resource' to 'Wood'

The label 'Resource' is generic and may cause confusion. Since the resource is specifically 'Wood', update the label to reflect this for better clarity.

Apply this diff to change the label:

-<div className="ml-2">
-  Resource: {`${configManager.getResourceWeight(ResourcesIds.Wood) / GRAMS_PER_KG} kg/unit`}
+</div>
+<div className="ml-2">
+  Wood: {`${configManager.getResourceWeight(ResourcesIds.Wood) / GRAMS_PER_KG} kg/unit`}
</div>
client/src/ui/components/hints/Resources.tsx (1)

73-75: Avoid using 'any'; specify a proper type for 'cost'.

Using (cost: any) reduces type safety. Defining a specific type for cost enhances code reliability and maintainability.

If there's an existing type for cost, apply it:

-        cost: configManager.resourceInputs[resourceId].map((cost: any) => ({
+        cost: configManager.resourceInputs[resourceId].map((cost: CostType) => ({

Alternatively, define an appropriate interface for CostType that matches the structure of the cost objects.

client/src/ui/components/hints/TheMap.tsx (1)

5-5: Remove unnecessary empty import statement

The import statement at line 5 is empty and doesn't import anything:

import {} from "@/ui/utils/utils";

This is unnecessary and can be safely removed to clean up the code.

Apply this diff to remove the unused import:

-import {} from "@/ui/utils/utils";
client/src/hooks/helpers/useQuests.tsx (1)

Line range hint 114-212: Incomplete Dependencies in useMemo Hook

In the useMemo starting at line 114, several variables used within the memoization function (buildingQuantities, hasAnyPausedBuilding, hasDefensiveArmy, hasAttackingArmy, hasTraveled, fragmentMines, hyperstructureContributions, hyperstructures, playerPillages) are not included in the dependencies array. This might lead to stale or incorrect quest statuses if any of these variables change.

Consider updating the dependencies array to include all relevant variables:

 return useMemo(
   () => ({
     // ... quest statuses
   }),
   [
     structureEntityId,
     questClaimStatus,
     unclaimedQuestsCount > 0 ? entityUpdate : null,
     unclaimedQuestsCount > 0 ? orders : null,
+    buildingQuantities,
+    hasAnyPausedBuilding,
+    hasDefensiveArmy,
+    hasAttackingArmy,
+    hasTraveled,
+    fragmentMines,
+    hyperstructureContributions,
+    hyperstructures,
+    playerPillages,
   ],
 );
client/src/ui/utils/utils.tsx (1)

292-293: Ensure tickIntervalInSeconds is valid to prevent division by zero

While the default value of tickIntervalInSeconds is set to 1 using the || 1 fallback, consider explicitly handling cases where configManager.getTick(TickIds.Armies) might return 0 to prevent potential division by zero errors.

You might want to ensure that tickIntervalInSeconds is always greater than zero before performing the division:

const tickIntervalInSeconds = configManager.getTick(TickIds.Armies);
const validTickInterval = tickIntervalInSeconds && tickIntervalInSeconds > 0 ? tickIntervalInSeconds : 1;
return Number(time / validTickInterval);
client/src/dojo/modelManager/BattleManager.ts (1)

61-61: Rephrase enum value for clarity

The message "An army's defending the structure" could be clearer. Consider rephrasing to "An army is defending the structure" for better readability and to avoid the contraction in a user-facing string.

Apply this diff to update the message:

-      DefenderPresent = "An army's defending the structure",
+      DefenderPresent = "An army is defending the structure",
client/src/ui/components/hints/WorldStructures.tsx (1)

98-98: Correct typo: 'shareholers' should be 'shareholders'

There's a typo in the text. 'shareholers' should be corrected to 'shareholders' to maintain professionalism and clarity.

Apply this diff to fix the typo:

-                  <br />A new set of shareholers can be set every{" "}
+                  <br />A new set of shareholders can be set every{" "}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 43456ea and 0e25f47.

📒 Files selected for processing (59)
  • client/src/dojo/contractComponents.ts (5 hunks)
  • client/src/dojo/modelManager/ArmyMovementManager.ts (6 hunks)
  • client/src/dojo/modelManager/BattleManager.ts (8 hunks)
  • client/src/dojo/modelManager/ConfigManager.ts (1 hunks)
  • client/src/dojo/modelManager/LeaderboardManager.ts (5 hunks)
  • client/src/dojo/modelManager/MarketManager.ts (5 hunks)
  • client/src/dojo/modelManager/ProductionManager.ts (4 hunks)
  • client/src/dojo/modelManager/tests/BattleManager.test.ts (4 hunks)
  • client/src/dojo/modelManager/tests/BattleManagerMock.ts (1 hunks)
  • client/src/dojo/modelManager/utils/LeaderboardUtils.test.ts (0 hunks)
  • client/src/dojo/modelManager/utils/LeaderboardUtils.ts (2 hunks)
  • client/src/hooks/helpers/useHyperstructures.tsx (2 hunks)
  • client/src/hooks/helpers/useQuests.tsx (3 hunks)
  • client/src/hooks/helpers/useRealm.tsx (3 hunks)
  • client/src/hooks/helpers/useStructures.tsx (2 hunks)
  • client/src/three/systems/SystemManager.ts (4 hunks)
  • client/src/ui/components/bank/LiquidityResourceRow.tsx (4 hunks)
  • client/src/ui/components/bank/Swap.tsx (9 hunks)
  • client/src/ui/components/construction/SelectPreviewBuilding.tsx (12 hunks)
  • client/src/ui/components/hints/Buildings.tsx (2 hunks)
  • client/src/ui/components/hints/Combat.tsx (6 hunks)
  • client/src/ui/components/hints/GettingStarted.tsx (1 hunks)
  • client/src/ui/components/hints/Realm.tsx (2 hunks)
  • client/src/ui/components/hints/Resources.tsx (3 hunks)
  • client/src/ui/components/hints/TheMap.tsx (6 hunks)
  • client/src/ui/components/hints/Transfers.tsx (2 hunks)
  • client/src/ui/components/hints/WorldStructures.tsx (4 hunks)
  • client/src/ui/components/hyperstructures/HyperstructurePanel.tsx (5 hunks)
  • client/src/ui/components/hyperstructures/StructureCard.tsx (4 hunks)
  • client/src/ui/components/military/ArmyList.tsx (4 hunks)
  • client/src/ui/components/military/ArmyManagementCard.tsx (6 hunks)
  • client/src/ui/components/quest/questDetails.tsx (7 hunks)
  • client/src/ui/components/resources/EntityResourceTable.tsx (2 hunks)
  • client/src/ui/components/resources/RealmResourcesIO.tsx (2 hunks)
  • client/src/ui/components/resources/ResourceChip.tsx (2 hunks)
  • client/src/ui/components/resources/ResourceWeight.tsx (3 hunks)
  • client/src/ui/components/structures/construction/StructureConstructionMenu.tsx (3 hunks)
  • client/src/ui/components/trading/MarketOrderPanel.tsx (15 hunks)
  • client/src/ui/components/trading/RealmProduction.tsx (2 hunks)
  • client/src/ui/components/trading/TradeHistoryEvent.tsx (2 hunks)
  • client/src/ui/components/trading/TransferBetweenEntities.tsx (3 hunks)
  • client/src/ui/components/worldmap/armies/ActionInfo.tsx (3 hunks)
  • client/src/ui/components/worldmap/armies/ArmyInfoLabel.tsx (3 hunks)
  • client/src/ui/components/worldmap/leaderboard/LeaderboardPanel.tsx (2 hunks)
  • client/src/ui/components/worldmap/structures/StructureLabel.tsx (2 hunks)
  • client/src/ui/components/worldmap/structures/StructureListItem.tsx (2 hunks)
  • client/src/ui/elements/ArmyCapacity.tsx (2 hunks)
  • client/src/ui/elements/StaminaResource.tsx (2 hunks)
  • client/src/ui/elements/StaminaResourceCost.tsx (2 hunks)
  • client/src/ui/modules/entity-details/BuildingEntityDetails.tsx (5 hunks)
  • client/src/ui/modules/navigation/TopMiddleNavigation.tsx (10 hunks)
  • client/src/ui/modules/onboarding/Steps.tsx (4 hunks)
  • client/src/ui/utils/realms.tsx (2 hunks)
  • client/src/ui/utils/utils.tsx (6 hunks)
  • config/index.ts (1 hunks)
  • sdk/packages/eternum/src/config/index.ts (2 hunks)
  • sdk/packages/eternum/src/constants/global.ts (5 hunks)
  • sdk/packages/eternum/src/constants/hyperstructure.ts (0 hunks)
  • sdk/packages/eternum/src/types/common.ts (3 hunks)
💤 Files with no reviewable changes (2)
  • client/src/dojo/modelManager/utils/LeaderboardUtils.test.ts
  • sdk/packages/eternum/src/constants/hyperstructure.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • client/src/dojo/modelManager/tests/BattleManager.test.ts
  • client/src/ui/components/bank/LiquidityResourceRow.tsx
  • client/src/ui/components/bank/Swap.tsx
  • client/src/ui/components/construction/SelectPreviewBuilding.tsx
  • client/src/ui/components/military/ArmyManagementCard.tsx
  • client/src/ui/modules/navigation/TopMiddleNavigation.tsx
🧰 Additional context used
📓 Learnings (1)
client/src/ui/components/worldmap/structures/StructureLabel.tsx (1)
Learnt from: aymericdelab
PR: BibliothecaDAO/eternum#1818
File: client/src/ui/components/worldmap/structures/StructureLabel.tsx:47-0
Timestamp: 2024-10-11T20:13:27.277Z
Learning: In `StructureLabel.tsx`, when `timer` is negative, the immunity message is not shown, so handling negative `timer` values isn't necessary.
🪛 Biome
client/src/ui/components/hints/Buildings.tsx

[error] 13-13: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

🔇 Additional comments (107)
client/src/ui/elements/StaminaResourceCost.tsx (2)

1-1: Approved: Import changes reflect shift in configuration management

The changes in the import statements, specifically the addition of configManager and the removal of EternumGlobalConfig, indicate a transition to a more centralized configuration management approach. This change aligns well with the modifications in the stamina cost calculation logic.

Also applies to: 4-4


26-26: Approved: Enhanced flexibility in stamina cost calculation

The modification in stamina cost calculation logic, utilizing configManager.getTravelStaminaCost() and configManager.getExploreStaminaCost(), introduces greater flexibility in configuration management. This approach allows for potential dynamic adjustments to costs while maintaining the existing logic for differentiating between travel and explore scenarios.

client/src/ui/components/resources/EntityResourceTable.tsx (4)

1-1: LGTM: Import changes enhance configuration management and precision.

The addition of configManager and multiplyByPrecision imports aligns with the goal of improving the calculation of maximum storehouse capacity. These changes suggest a move towards centralized configuration management and more precise calculations.

Also applies to: 3-3


19-20: LGTM: Improved calculation of maxStorehouseCapacityKg.

The refactored calculation of maxStorehouseCapacityKg offers several improvements:

  1. It uses configManager.getCapacityConfig, allowing for more flexible and centralized configuration management.
  2. The addition of multiplyByPrecision ensures accurate calculations, mitigating potential floating-point precision issues.
  3. The new implementation is more maintainable and aligns with best practices for configuration management.

These changes enhance the overall reliability and flexibility of the storehouse capacity calculation.


Line range hint 1-48: LGTM: Changes integrate well with existing component structure.

The modifications to the EntityResourceTable component have been seamlessly integrated:

  1. The overall structure and logic flow of the component remain intact.
  2. Performance optimizations using useMemo are preserved.
  3. The rendering logic for resource elements continues to work harmoniously with the updated calculations.

This integration demonstrates a good balance between introducing improvements and maintaining the existing, well-functioning parts of the component.


Line range hint 1-48: Summary: Enhancements to EntityResourceTable improve precision and maintainability.

The changes to EntityResourceTable.tsx successfully achieve the following:

  1. Introduce centralized configuration management through configManager.
  2. Enhance precision in storehouse capacity calculations using multiplyByPrecision.
  3. Improve code maintainability and flexibility.

These modifications align well with the PR objectives and the AI-generated summary. They enhance the component's functionality without introducing breaking changes or disrupting its overall structure. The continued use of performance optimizations like useMemo ensures that the component remains efficient.

Great job on these improvements!

client/src/ui/components/resources/RealmResourcesIO.tsx (2)

1-1: LGTM: Import changes improve modularity

The addition of configManager import and removal of RESOURCE_INPUTS_SCALED suggest a move towards centralized configuration management. This change enhances modularity and maintainability of the codebase.


Line range hint 1-53: Overall: Positive changes improving modularity and maintainability

The modifications to this component demonstrate a shift towards more centralized configuration management, which is a positive change for maintainability and flexibility. The core functionality of the component remains intact, with improvements in how resource data is accessed and processed.

The suggestions provided (destructuring syntax and memoization) are optional optimizations that could further enhance the code's readability and performance.

Great job on these improvements!

config/index.ts (1)

62-62: Approve the increased delay with a request for clarification.

The delay before setting up the bank has been increased from 15 to 20 seconds, which is reflected in both the console log message and the timeout duration.

Could you provide more context on why this delay is necessary and why it was increased? This information would be valuable as a comment in the code for future maintenance.

Consider adding a comment explaining the reason for the delay:

// Add a 20-second delay before setting up the bank
// This delay is necessary because [reason for the delay]
console.log("Waiting for 20 seconds before setting up the bank...");
await new Promise((resolve) => setTimeout(resolve, 20000));
client/src/ui/utils/realms.tsx (1)

1-1: Approve import changes: Improved modularity with centralized configuration

The introduction of configManager import and removal of constant imports (BASE_POPULATION_CAPACITY and BUILDING_POPULATION) indicate a positive shift towards centralized configuration management. This change enhances modularity and maintainability by allowing easier updates to configuration values without modifying multiple files.

client/src/ui/elements/StaminaResource.tsx (2)

2-2: Improved configuration management

The addition of configManager import is a positive change. It replaces the use of a global configuration object with a centralized configuration manager, which is a better practice in software development.

This change:

  1. Enhances modularity and flexibility in managing configurations.
  2. Makes the code more testable by allowing easier mocking of configuration values.
  3. Centralizes configuration management, reducing the risk of inconsistencies across the application.

Line range hint 1-62: Overall impact: Improved configuration management without functional changes

The changes in this file represent a positive step towards better configuration management:

  1. The core functionality of the StaminaResource component remains intact.
  2. The transition from a global config object to a centralized config manager improves modularity and maintainability.
  3. The changes are consistent throughout the file.

These modifications enhance the code quality without altering the component's behavior.

To ensure that these changes haven't inadvertently affected other parts of the codebase, please run the following verification script:

This script will help ensure that the migration to configManager.getTravelStaminaCost() is complete and consistent across the entire codebase.

✅ Verification successful

Verification Successful: Configuration Migration Complete

All references to EternumGlobalConfig.stamina.travelCost have been successfully migrated to configManager.getTravelStaminaCost(). The usage of configManager.getTravelStaminaCost() is consistent across the codebase, ensuring improved maintainability and configuration management without affecting the component's functionality.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining references to EternumGlobalConfig.stamina.travelCost

# Test: Search for any remaining references to EternumGlobalConfig.stamina.travelCost
# Expect: No results, indicating complete migration to configManager.getTravelStaminaCost()
rg --type typescript "EternumGlobalConfig\.stamina\.travelCost"

# Test: Verify consistent usage of configManager.getTravelStaminaCost()
# Expect: Results showing consistent usage across the codebase
rg --type typescript "configManager\.getTravelStaminaCost\(\)"

Length of output: 200


Script:

#!/bin/bash
# Description: Check for any remaining references to EternumGlobalConfig.stamina.travelCost and verify consistent usage of configManager.getTravelStaminaCost()

# Test: Search for any remaining references to EternumGlobalConfig.stamina.travelCost
# Expect: No results, indicating complete migration to configManager.getTravelStaminaCost()
rg --type ts --type tsx "EternumGlobalConfig\.stamina\.travelCost"

# Test: Verify consistent usage of configManager.getTravelStaminaCost()
# Expect: Results showing consistent usage across the codebase
rg --type ts --type tsx "configManager\.getTravelStaminaCost\(\)"

Length of output: 192


Script:

#!/bin/bash
# Description: Check for any remaining references to EternumGlobalConfig.stamina.travelCost 
# and verify consistent usage of configManager.getTravelStaminaCost()

# Test: Search for any remaining references to EternumGlobalConfig.stamina.travelCost
# Expect: No results, indicating complete migration to configManager.getTravelStaminaCost()
rg -g "*.ts" -g "*.tsx" "EternumGlobalConfig\.stamina\.travelCost"

# Test: Verify consistent usage of configManager.getTravelStaminaCost()
# Expect: Results showing consistent usage across the codebase
rg -g "*.ts" -g "*.tsx" "configManager\.getTravelStaminaCost\(\)"

Length of output: 1099

client/src/ui/components/hints/Realm.tsx (2)

29-33: Approved, but consider precision handling.

The changes align well with the new import structure, using configManager.realmUpgradeCosts instead of the hardcoded REALM_UPGRADE_COSTS. This approach is more flexible and maintainable.

However, the removal of multiplyByPrecision raises a concern about precision handling. Let's verify if precision is handled elsewhere:

#!/bin/bash
# Description: Check for precision handling in related files.

# Test 1: Search for precision-related functions in utility files
rg --type typescript '(multiplyByPrecision|divideByPrecision|formatPrecision)' client/src/ui/utils/

# Test 2: Check if ResourceCost component handles precision
ast-grep --lang typescript --pattern 'const ResourceCost = ({ resourceId, amount, size }: ResourceCostProps) => {
  $$$
}'

If precision is not handled elsewhere, consider adding a comment or TODO to address this in the future to ensure accurate cost representation.


1-4: LGTM! Verify usage of new import.

The changes to the imports look good. The shift from hardcoded REALM_UPGRADE_COSTS to configManager suggests a more flexible approach to managing realm upgrade costs.

Let's verify the usage of configManager in the file:

✅ Verification successful

Verified usage of configManager.

The configManager.realmUpgradeCosts is properly utilized within the Realm.tsx component.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of configManager in the file.

# Test: Search for configManager usage
rg --type typescript 'configManager\.realmUpgradeCosts' client/src/ui/components/hints/Realm.tsx

Length of output: 261


Script:

#!/bin/bash
# Description: Search for all usages of configManager in Realm.tsx using ripgrep and ast-grep.

# Using ripgrep to find any occurrence of configManager in Realm.tsx
rg 'configManager' client/src/ui/components/hints/Realm.tsx

# Using ast-grep to find import statements and usages of configManager
ast-grep --lang typescript --pattern 'import { configManager } from $_;' client/src/ui/components/hints/Realm.tsx

ast-grep --lang typescript --pattern '$_configManager$_' client/src/ui/components/hints/Realm.tsx

Length of output: 863

client/src/ui/elements/ArmyCapacity.tsx (1)

2-2: Approved: Improved configuration management

The introduction of configManager from "@/dojo/setup" is a positive change. This shift from a static configuration (previously EternumGlobalConfig) to a dynamic configuration manager can provide more flexibility in managing application settings. It potentially allows for runtime configuration changes or environment-specific configurations, which can be beneficial for maintainability and adaptability of the application.

client/src/ui/components/worldmap/structures/StructureLabel.tsx (1)

Line range hint 1-70: Summary of changes and overall assessment

The modifications to StructureLabel.tsx represent a positive step towards improved modularity and configuration management. The shift from EternumGlobalConfig to a more specific tick management system using TickIds and configManager methods suggests a more flexible approach to handling game timings.

Key points:

  1. The import changes and calculation modifications are consistent and well-implemented.
  2. The core functionality of the component remains intact.
  3. The new approach potentially allows for more granular control over different aspects of the game timing.

These changes should enhance the maintainability and flexibility of the code. Good job on the refactoring effort!

client/src/ui/components/hints/Transfers.tsx (2)

1-1: Improved import management and configuration centralization

The changes to the import statements are well-considered:

  1. Adding configManager import centralizes configuration management.
  2. Including CapacityConfigCategory and ResourcesIds in the existing import improves type safety.
  3. Removing direct imports from global config enhances maintainability.

These modifications align with best practices for React component development.

Also applies to: 5-5


Line range hint 1-34: Consistent and improved Transfers component

The changes to the Transfers component are well-implemented:

  1. The overall structure and functionality of the component remain intact.
  2. Configuration retrieval is improved without affecting the component's core logic.
  3. The modifications enhance maintainability and align with best practices.

These changes are consistent with the component's purpose and the AI-generated summary.

To ensure no unintended changes were introduced, run the following verification:

These checks will help confirm that all intended changes have been properly implemented and no unintended references or hardcoded values remain.

✅ Verification successful

To address the issues with the previous verification scripts, please run the following updated shell scripts:

These updated commands omit the --type flag and directly search within the specified file using its path and standard TypeScript file extensions. This should provide the necessary verification without encountering the previous file type recognition issues.


Transfers Component Verified Successfully

The verification confirms that:

  1. No references to EternumGlobalConfig or WEIGHTS_GRAM remain.
  2. All resource weight retrievals utilize configManager.
  3. No hardcoded weight or capacity values are present.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify that no unexpected changes were made to the Transfers component

# Check for any remaining references to EternumGlobalConfig or WEIGHTS_GRAM
rg --type typescript 'EternumGlobalConfig|WEIGHTS_GRAM' client/src/ui/components/hints/Transfers.tsx

# Verify that all resource weight retrievals use configManager
rg --type typescript 'configManager\.getResourceWeight\(ResourcesIds\.' client/src/ui/components/hints/Transfers.tsx

# Check for any remaining hardcoded weight or capacity values
rg --type typescript '\d+(\.\d+)?\s*(kg|g)' client/src/ui/components/hints/Transfers.tsx

Length of output: 417


Script:

#!/bin/bash
# Verify that no unexpected changes were made to the Transfers component

# Check for any remaining references to EternumGlobalConfig or WEIGHTS_GRAM
rg 'EternumGlobalConfig|WEIGHTS_GRAM' client/src/ui/components/hints/Transfers.tsx

# Verify that all resource weight retrievals use configManager
rg 'configManager\.getResourceWeight\(ResourcesIds\.' client/src/ui/components/hints/Transfers.tsx

# Check for any remaining hardcoded weight or capacity values
rg '\d+(\.\d+)?\s*(kg|g)' client/src/ui/components/hints/Transfers.tsx

Length of output: 577

client/src/ui/components/trading/RealmProduction.tsx (2)

1-1: LGTM: Import changes enhance configuration management.

The addition of configManager import and removal of RESOURCE_INPUTS_SCALED suggest a move towards more centralized and flexible configuration management. This change is likely to improve maintainability and consistency across the application.


39-40: LGTM: Improved resource input management.

The use of configManager.resourceInputs for declaring resourcesInputs aligns well with the centralized configuration approach. This change enhances flexibility in managing resource inputs and promotes consistency across the application.

client/src/ui/components/hints/Buildings.tsx (3)

1-1: Improved configuration management

The changes to the import statements reflect a shift towards centralized configuration management using configManager. This approach enhances maintainability and flexibility by centralizing building-related configurations.

Also applies to: 5-5


26-26: Consistent use of configManager for resource type retrieval

The change to use configManager.getResourceBuildingProduced(buildingId) for retrieving the building resource type is consistent with the overall approach of centralized configuration management. This enhances maintainability and flexibility in managing building-related data.


62-62: Updated image background color

The CSS class change from "bg-black/40" to "bg-brown/40" for the building image is a minor visual update. This change likely improves the aesthetic appeal of the component without affecting its functionality.

client/src/ui/components/worldmap/leaderboard/LeaderboardPanel.tsx (2)

2-2: LGTM: Import statement added correctly.

The import of configManager from "@/dojo/setup" is properly formatted and consistent with the project structure. This import is necessary for the subsequent changes in the file.


Line range hint 16-121: Consider performance optimization and test updates.

While the changes improve flexibility, consider the following suggestions:

  1. Performance Optimization: Memoize the pointsForWin value to prevent unnecessary recalculations.
const pointsForWin = useMemo(() => configManager.getHyperstructureConfig().pointsForWin, []);
  1. Test Updates: Ensure that unit tests for this component are updated to mock the configManager and verify the calculation with different configuration values.

To verify the impact of these changes, please run the following script:

This script will help identify if there are existing tests for the LeaderboardPanel and if they include mocks for the configManager. The results will guide further testing efforts.

client/src/ui/components/structures/construction/StructureConstructionMenu.tsx (3)

1-9: Improved modularity with configManager

The changes to the import statements reflect a shift towards using configManager for accessing configuration values, which improves modularity and maintainability. The addition of multiplyByPrecision suggests an enhancement in precision handling for calculations.


48-48: Centralized structure cost management

The use of configManager.structureCosts[building] for cost retrieval centralizes the management of structure costs. This change improves maintainability and consistency across the application.


Line range hint 1-126: Overall improvement in configuration management and code consistency

The changes in this file demonstrate a significant shift towards centralized configuration management using configManager. This approach enhances modularity, maintainability, and consistency across the application. Key improvements include:

  1. Standardized precision handling with multiplyByPrecision.
  2. Centralized structure cost management.
  3. Flexible access to hyperstructure-specific configurations.

These changes contribute to a more robust and maintainable codebase. Consider implementing the suggested refactoring to further improve code organization and reusability.

client/src/ui/components/military/ArmyList.tsx (6)

2-2: LGTM: Centralized configuration management

The addition of configManager import is a good practice. It centralizes configuration management, which can improve maintainability and consistency across the application.


12-12: LGTM: Updated imports

The removal of EternumGlobalConfig import and addition of BuildingType to the existing import statement from "@bibliothecadao/eternum" align well with the changes in the component's logic. This update maintains clean and relevant imports.


46-47: LGTM: Centralized troop configuration

The introduction of troopConfig using configManager.getTroopConfig() is a good approach. It centralizes troop-related configurations, which can make the code more maintainable and easier to update in the future.


52-61: LGTM: Updated maxAmountOfAttackingArmies calculation

The calculation of maxAmountOfAttackingArmies has been successfully updated to use troopConfig properties. This change maintains the original logic while utilizing the new centralized configuration approach. The code remains clear and consistent with the rest of the changes.


101-101: LGTM: Dynamic max armies display

The update to use troopConfig.maxArmiesPerStructure in the display message is a good improvement. It ensures that the UI always reflects the current configuration, making the component more maintainable and less prone to inconsistencies if the max armies value changes in the future.


Line range hint 1-155: Overall assessment: Excellent refactoring

The changes in this file demonstrate a well-executed refactoring to use centralized configuration management. The consistent use of configManager and troopConfig throughout the component improves maintainability and makes the code more robust to future configuration changes. The logic of the component remains intact while benefiting from these improvements. Great job on this refactoring!

client/src/ui/components/resources/ResourceChip.tsx (2)

1-1: LGTM: Improved import statements for better configurability.

The changes in the import statements reflect a shift from using static data (WEIGHTS_GRAM) to a more dynamic configuration approach using configManager. This change enhances the flexibility and maintainability of the resource weight management system.

Also applies to: 3-3


41-41: LGTM: Enhanced flexibility in resource weight calculation.

The updated maxAmountStorable calculation now uses configManager.getResourceWeight(resourceId) instead of a static WEIGHTS_GRAM object. This change:

  1. Aligns with the new import statements.
  2. Allows for more dynamic resource weight management.
  3. Maintains backwards compatibility with the fallback value of 1000.
  4. Improves system flexibility, enabling easier updates to resource weights without modifying the component.

This approach enhances the maintainability and scalability of the resource management system.

client/src/dojo/modelManager/ProductionManager.ts (5)

1-1: LGTM: Import of multiplyByPrecision utility function.

The addition of the multiplyByPrecision utility function to the imports is a good practice. It centralizes precision calculations, which can help maintain consistency and reduce errors throughout the codebase.


77-83: LGTM: Improved getStoreCapacity method implementation.

The changes to the getStoreCapacity method are well-implemented:

  1. Using multiplyByPrecision centralizes precision handling.
  2. configManager.getCapacityConfig improves maintainability by removing hard-coded values.
  3. The use of gramToKg function makes the capacity calculations more intuitive.

These modifications enhance the clarity and maintainability of the code while preserving the original logic.


103-105: LGTM: Improved balance calculation in _balance method.

The modifications to the balance calculation are well-implemented:

  1. Consistent use of multiplyByPrecision for precision handling.
  2. Utilization of configManager.getResourceWeight improves configurability and removes hard-coded values.

These changes enhance the maintainability and flexibility of the code while preserving the original calculation logic.


192-192: LGTM: Updated resource inputs source in _inputs_available method.

The change to use configManager.resourceInputs instead of RESOURCE_INPUTS_SCALED is a good improvement:

  1. It aligns with the overall strategy of using configManager for resource-related configurations.
  2. This modification enhances maintainability by centralizing resource input configurations.
  3. The core logic of the method remains intact, ensuring that functionality is preserved.

This update contributes to a more consistent and maintainable codebase.


Line range hint 1-238: Overall assessment: Excellent improvements to maintainability and configurability.

The changes made to the ProductionManager class are well-implemented and consistent throughout the file. Key improvements include:

  1. Centralized precision handling using the multiplyByPrecision utility function.
  2. Increased use of configManager for resource-related configurations, removing hard-coded values.
  3. Improved clarity in capacity and weight calculations.

These modifications enhance the overall maintainability, flexibility, and readability of the code while preserving the core functionality. Great job on these updates!

client/src/ui/components/worldmap/structures/StructureListItem.tsx (1)

12-12: Improved import structure and configuration management.

The addition of ResourcesIds, StructureType, and TickIds imports from "@bibliothecadao/eternum" and the removal of EternumGlobalConfig suggest a move towards more modular and centralized configuration management. This change enhances maintainability and reduces direct dependencies on global configurations.

sdk/packages/eternum/src/types/common.ts (2)

328-333: Improved mercenary configuration structure

The new structure for the mercenaries property in the Config interface provides more granular control over troop counts. By introducing upper and lower bounds for each troop type (knights, paladins, and crossbowmen), this change allows for:

  1. Greater flexibility in mercenary recruitment.
  2. The ability to introduce variability in mercenary composition.
  3. Fine-tuning of mercenary strength based on game balance requirements.

This is a positive change that enhances the configurability of the mercenary system.


Line range hint 1-373: Overall, good improvements to types and interfaces

The changes in this file enhance the game's type system by:

  1. Improving the configurability of the mercenary system with more granular control over troop counts.
  2. Adding a clear Player interface for managing player data.

These modifications contribute to better type safety and more flexible game mechanics. The code maintains good overall structure and consistency with the existing codebase.

client/src/dojo/modelManager/MarketManager.ts (6)

2-2: LGTM: Import statements updated correctly.

The changes in the import statements are consistent with the shift from using EternumGlobalConfig to configManager. This update suggests a move towards a more centralized configuration management approach, which can improve maintainability and flexibility.

Also applies to: 4-4


92-92: LGTM: Fee rate denominator source updated.

The change to obtain feeRateDenom from configManager.getBankConfig().lpFeesDenominator is consistent with the overall shift towards using configManager. The core logic of the method remains intact, ensuring that the functionality is preserved while improving configuration management.


117-117: LGTM: Fee rate denominator source updated.

The update to retrieve feeRateDenom from configManager.getBankConfig().lpFeesDenominator aligns with the overall transition to using configManager. The core functionality of the method is preserved, maintaining the integrity of the input price calculation while improving configuration management.


143-143: LGTM: Fee rate denominator source updated.

The modification to fetch feeRateDenom from configManager.getBankConfig().lpFeesDenominator is in line with the overall transition to configManager. The core logic for calculating Lords input for resource output remains intact, ensuring that the functionality is preserved while improving configuration management.


175-175: LGTM: Fee rate denominator source updated.

The update to retrieve feeRateDenom from configManager.getBankConfig().lpFeesDenominator aligns with the overall transition to using configManager. The core functionality for calculating resource input for Lords output is maintained, preserving the method's integrity while improving configuration management.


Line range hint 1-265: Summary: Improved configuration management in MarketManager

The changes in this file consistently replace EternumGlobalConfig with configManager for obtaining the fee rate denominator. This shift towards a more centralized configuration management approach through configManager can lead to improved maintainability and flexibility in the codebase.

Key points:

  1. Import statements have been updated to reflect the change.
  2. All methods using feeRateDenom now obtain it from configManager.getBankConfig().lpFeesDenominator.
  3. The core functionality of the MarketManager class and its methods remains intact.

These changes are well-implemented and should make future updates to configuration values easier to manage.

client/src/hooks/helpers/useRealm.tsx (1)

2-2: LGTM: Import of configManager

The addition of configManager import from @/dojo/setup is a good practice. It centralizes configuration management and allows for more flexible and maintainable code.

client/src/hooks/helpers/useStructures.tsx (1)

7-7: LGTM: Import addition for DONKEY_ENTITY_TYPE

The addition of DONKEY_ENTITY_TYPE to the import statement is appropriate, as it's now being used in the useStructuresFromPosition function. This change aligns with the shift in how speed configuration is retrieved for the donkey entity type.

client/src/ui/modules/onboarding/Steps.tsx (3)

5-5: LGTM: New import added correctly

The new import for configManager is correctly placed and necessary for the changes in the StepFive component.


36-36: Background color change: Verify visual consistency

The background color has been changed from bg-black/90 to bg-brown. This change looks good and might improve the overall visual theme.

Please verify that this color change is consistent with the design system and doesn't negatively impact the readability or contrast of the content within the container.


355-358: Configuration management update: Verify configManager functionality

The changes from EternumGlobalConfig.tick.armiesTickIntervalInSeconds to configManager.getTick(TickIds.Armies) look good. This update likely improves the flexibility of configuration management in the game.

Please ensure that:

  1. The configManager.getTick(TickIds.Armies) method is correctly implemented and returns the expected value.
  2. The TickIds.Armies constant is properly defined and imported if necessary.
  3. This change is consistent across all components that previously used EternumGlobalConfig.tick.armiesTickIntervalInSeconds.

You can verify this by running the following script:

✅ Verification successful

Configuration management update: Verified configManager functionality

All changes have been successfully implemented:

  • EternumGlobalConfig.tick.armiesTickIntervalInSeconds is no longer used.
  • configManager.getTick(TickIds.Armies) is consistently implemented across the codebase.
  • TickIds.Armies is properly defined and imported where necessary.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining usage of EternumGlobalConfig.tick.armiesTickIntervalInSeconds
rg "EternumGlobalConfig\.tick\.armiesTickIntervalInSeconds" --type typescript

# Check for the correct usage of configManager.getTick
rg "configManager\.getTick\(TickIds\.Armies\)" --type typescript

# Verify the import and usage of TickIds
rg "import.*TickIds" --type typescript
rg "TickIds\.Armies" --type typescript

Length of output: 368


Script:

#!/bin/bash
# Search for any remaining usage of EternumGlobalConfig.tick.armiesTickIntervalInSeconds in .ts and .tsx files
fd -e ts -e tsx --exec rg "EternumGlobalConfig\.tick\.armiesTickIntervalInSeconds"

# Check for the correct usage of configManager.getTick in .ts and .tsx files
fd -e ts -e tsx --exec rg "configManager\.getTick\(TickIds\.Armies\)"

# Verify the import and usage of TickIds in .ts and .tsx files
fd -e ts -e tsx --exec rg "import.*TickIds"
fd -e ts -e tsx --exec rg "TickIds\.Armies"

Length of output: 2973

client/src/ui/components/hyperstructures/StructureCard.tsx (4)

1-1: LGTM: Import statement for configManager added.

The import of configManager from "@/dojo/setup" has been correctly added. This is likely used to replace the hardcoded MAX_TROOPS_PER_ARMY constant with a configurable value, which improves the flexibility of the codebase.


159-160: LGTM: Dynamic maxTroopCountPerArmy constant added.

The addition of maxTroopCountPerArmy using configManager.getTroopConfig().maxTroopCount is a good improvement. It replaces the hardcoded MAX_TROOPS_PER_ARMY constant with a configurable value, enhancing the flexibility of the codebase. This change allows for easier adjustments to the maximum troop count without modifying the component code.


189-189: LGTM: Remaining troops calculation updated with dynamic maxTroopCountPerArmy.

The calculation for remaining troops has been correctly updated to use the dynamic maxTroopCountPerArmy instead of the hardcoded constant. This change maintains the existing logic while improving flexibility. The consistent use of BigInt ensures compatibility with the rest of the codebase.


250-250: LGTM: Warning message updated with dynamic maxTroopCountPerArmy.

The warning message for maximum troops per attacking army has been correctly updated to use the dynamic maxTroopCountPerArmy. The use of formatNumber function ensures that the displayed value is properly formatted for readability. This change maintains consistency with the new configurable maximum troop count.

client/src/ui/components/trading/MarketOrderPanel.tsx (3)

2-2: Improved configuration management

The addition of configManager and the use of DONKEY_ENTITY_TYPE instead of EternumGlobalConfig suggests a move towards more centralized and maintainable configuration management. This change is likely to improve the overall structure and flexibility of the application.

Also applies to: 15-15


60-62: Enhanced UI consistency

The addition of rounded-xl to the className improves the visual consistency of the MarketResource component, aligning it with the overall design aesthetic of the application.


164-165: Improved UI and user experience

The updates to the MarketOrders component enhance the visual appeal and improve the user experience:

  1. The market price display now has a more flexible layout with improved padding and rounded corners.
  2. The background color for the locked resources message has been changed to brown, which likely aligns better with the overall theme.
  3. The layout for displaying resource information has been restructured for better clarity.

These changes contribute to a more intuitive and visually consistent interface.

Also applies to: 169-175, 177-177, 182-182, 201-203

client/src/dojo/modelManager/utils/LeaderboardUtils.ts (3)

15-16: Approved: Use of ClientConfigManager instance

Initializing configManager using the singleton instance enhances consistency by ensuring that the configuration is managed centrally.


28-30: Approved: Retrieving pointsOnCompletion from configuration

Fetching pointsOnCompletion via configManager ensures that the point values are centralized and configurable, enhancing maintainability.


32-32: Consider verifying the accumulation of points for large contributions

When calculating total completion points, if contribution.amount can be a large bigint, ensure that summing these values does not introduce precision errors when converted to number.

To verify if there are any potential issues with large values, you can search for usages of contribution.amount and check how they are handled elsewhere in the codebase:

This script searches for all instances of contribution.amount to help you review its handling and ensure consistency.

client/src/ui/components/hints/Resources.tsx (4)

1-1: LGTM!

The import of configManager is correctly added and used appropriately in the code.


6-6: LGTM!

The imports from @bibliothecadao/eternum are appropriate and necessary for the functionality.


37-38: LGTM!

The calculation for storage capacity using configManager.getCapacityConfig and EternumGlobalConfig.resources.resourceMultiplier is accurate and correctly implemented.


71-71: LGTM!

The usage of configManager.getResourceOutputs(resourceId) appropriately retrieves the resource output amounts.

client/src/hooks/helpers/useHyperstructures.tsx (1)

2-3: Imports added are appropriate for the updated functionality

The addition of configManager, divideByPrecision, and toHexString imports is necessary for the new logic implementation and seems correct.

client/src/ui/components/worldmap/armies/ArmyInfoLabel.tsx (2)

16-16: Updated import statement to use TickIds

The import of TickIds from @bibliothecadao/eternum aligns with the updated configuration management approach, enhancing modularity and maintainability.


113-113: Verify the correctness of the remainingCapacity check

Ensure that configManager.getExploreReward() returns the expected value for this comparison. If remainingCapacity is miscalculated or the reward value is incorrect, it may prevent users from exploring when they should be able to.

Consider checking the values returned by configManager.getExploreReward() and confirm that remainingCapacity is accurately computed. If necessary, adjust the logic to align with the intended functionality.

client/src/ui/components/hints/TheMap.tsx (2)

2-2: Good practice: Centralizing configuration with configManager

Importing configManager and using it to retrieve configuration values enhances maintainability by centralizing the configuration logic.


47-48: Efficient retrieval of stamina costs

Using configManager.getTravelStaminaCost() and configManager.getExploreStaminaCost() improves code clarity and ensures stamina costs are sourced from a single point of truth.

client/src/ui/components/hyperstructures/HyperstructurePanel.tsx (5)

3-3: Correctly imported configManager for dynamic configurations

The addition of configManager improves the component's flexibility by accessing dynamic configuration values.


15-16: Utility functions imported appropriately

The import of multiplyByPrecision and other utility functions ensures accurate computations and enhances code reuse.


65-65: Enhanced precision in amount calculation using multiplyByPrecision

Applying multiplyByPrecision(amount) ensures that contribution amounts are correctly scaled according to the system's precision requirements.


86-86: Replaced static costs with dynamic configuration

Utilizing configManager.hyperstructureTotalCosts instead of hardcoded values increases maintainability and allows for dynamic updates to hyperstructure costs.


204-204: Utilized dynamic pointsPerCycle from configManager

Switching to configManager.getHyperstructureConfig().pointsPerCycle ensures consistency with the global configuration and enhances flexibility.

sdk/packages/eternum/src/constants/global.ts (4)

11-11: Added RESOURCE_RARITY to imports

The constant RESOURCE_RARITY is now imported, making it available for use in this file.


20-21: New constants for population configuration IDs

The constants BUILDING_CATEGORY_POPULATION_CONFIG_ID and POPULATION_CONFIG_ID have been added, which will be useful for identifying population-related configurations.


99-104: Defined mercenary troop count bounds

The lower and upper bounds for mercenary troops (KNIGHTS, PALADINS, CROSSBOWMEN) have been set appropriately.


133-133: Included resourceRarity in resources configuration

resourceRarity has been added to the resources configuration, enhancing resource management capabilities.

client/src/ui/modules/entity-details/BuildingEntityDetails.tsx (4)

22-22: Import Addition Approved

The addition of divideByPrecision to the imports is appropriate and correctly supports precision handling in balance checks.


201-201: Proper Calculation of Immunity End Timestamp

The calculation of immunityEndTimestamp accurately utilizes configManager.getBattleGraceTickCount() and configManager.getTick(TickIds.Armies) to determine the immunity period.


221-228: Resource Balance Comparison Updated Correctly

The checkBalance function now properly uses divideByPrecision to ensure that the resource balance comparison accounts for the correct precision. This enhances the accuracy of resource checks before upgrading the realm level.


308-308: Dynamic Retrieval of Upgrade Costs

Replacing REALM_UPGRADE_COSTS with configManager.realmUpgradeCosts improves flexibility by retrieving the realm upgrade costs dynamically from the configuration manager. This change enhances maintainability and ensures the costs are always up-to-date.

client/src/hooks/helpers/useQuests.tsx (6)

2-2: Approved: Added Import for SetupResult

The import of SetupResult from @/dojo/setup is appropriate and necessary for the updated function signatures.


9-9: Approved: Added Import for Account and AccountInterface

The import of Account and AccountInterface from "starknet" is correct and required for handling account-related functionalities.


74-74: Approved: Updated Function Signature for useQuestDependencies

The function useQuestDependencies now accepts setup and account as parameters, improving modularity and making dependencies explicit.


77-79: Approved: Entity Query for EntityOwner

The use of useEntityQuery with HasValue(setup.components.EntityOwner, { entity_owner_id: structureEntityId || 0 }) is appropriate for fetching entities owned by the specified structure.


83-89: Approved: Updated Quest Dependencies Initialization

The initialization of quest dependencies with the updated parameters enhances the functionality and ensures that quests are accurately reflected based on the current state.


Line range hint 254-254: Approved: Function useBuildingQuantities

The function useBuildingQuantities with the signature (structureEntityId: ID | undefined) remains consistent and correctly retrieves building quantities based on the provided structureEntityId.

client/src/dojo/modelManager/ArmyMovementManager.ts (6)

17-17: Import statement of getComponentValue and Entity is appropriate.

The import from @dojoengine/recs ensures that getComponentValue and Entity are available for use in the updated code.


97-97: Stamina check now correctly uses dynamic value from configuration.

The condition stamina.amount < configManager.getExploreStaminaCost() dynamically retrieves the explore stamina cost, ensuring flexibility.


112-112: Dynamic explore reward check implemented correctly.

Using configManager.getExploreReward() makes the reward value configurable and adaptable.


121-121: Calculation of max stamina steps now uses dynamic travel stamina cost.

The updated formula ensures that changes in travel stamina cost in the configuration are reflected in the calculation.


250-250: Optimistic stamina update now uses dynamic explore stamina cost.

Passing configManager.getExploreStaminaCost() ensures the stamina cost is consistent with the configuration.


289-289: Optimistic stamina update for travel now correctly calculates total cost.

The multiplication of configManager.getTravelStaminaCost() by pathLength correctly computes the total stamina cost for the travel action.

client/src/ui/utils/utils.tsx (1)

1-2: Imports added for ClientComponents and ClientConfigManager

The new imports are necessary for the updated functionality and are correctly referenced in the code.

client/src/ui/components/quest/questDetails.tsx (1)

210-210: Use of configManager enhances maintainability

Replacing hardcoded values with configManager methods improves maintainability and ensures that configuration changes propagate correctly throughout the application.

Also applies to: 247-267, 286-286, 323-343

client/src/dojo/modelManager/ConfigManager.ts (1)

224-231: Check for undefined weightConfig before accessing properties

In getResourceWeight (lines 224-231), if weightConfig is undefined, accessing weightConfig?.weight_gram will result in undefined, and the method will return 0.

Ensure that this behavior is intentional and that returning 0 is appropriate when weightConfig is not found. If not, consider handling the undefined case explicitly.

Run the following script to verify if any weightConfig instances could be undefined:

client/src/dojo/contractComponents.ts (3)

554-560: Addition of new properties in HyperstructureConfig is correct

The new properties points_per_cycle, points_for_win, and points_on_completion are appropriately added with correct types RecsType.BigInt. The metadata types array has been updated correspondingly to include "u128" types, which accurately reflect the properties' types.

Also applies to: 565-565


1238-1258: TravelFoodCostConfig component added correctly

The TravelFoodCostConfig component has been introduced with the correct properties and types. The metadata accurately reflects the types of the properties, ensuring consistency between the component definition and its metadata.


1301-1301: Metadata types in TroopConfig updated correctly

The types array in the metadata has been updated to include the new property max_troop_count, with the type "u64", which accurately reflects the property's type RecsType.Number.

client/src/ui/components/hints/WorldStructures.tsx (2)

1-1: Import statement added correctly

The configManager is properly imported from "@/dojo/setup", ensuring access to configuration data.


91-93: Dynamic configuration enhances flexibility

Using configManager.getHyperstructureConfig().pointsPerCycle ensures that the points per tick are dynamically retrieved, improving maintainability by avoiding hard-coded values.

Comment on lines +70 to +73
const buildingPopulation = configManager.getBuildingPopConfig(building).population;
const basePopulationCapacity = configManager.getBasePopulationCapacity();

return (realm?.population || 0) + buildingPopulation <= basePopulationCapacity + (realm?.capacity || 0);
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Inconsistent Usage of Configuration Constants Detected

While the changes to the hasEnoughPopulationForBuilding function are aligned with the centralized configManager approach, several parts of the codebase still directly use BASE_POPULATION_CAPACITY and BUILDING_POPULATION. To ensure full consistency and maintainability, please refactor these instances to utilize configManager.

Affected areas:

  • sdk/packages/eternum/src/constants/global.ts
  • balancing/src/components/modules/building-table.tsx
🔗 Analysis chain

Approve changes: Consistent use of centralized configuration

The modifications to hasEnoughPopulationForBuilding function align well with the new centralized configuration management approach. The use of configManager to retrieve building population and base population capacity enhances consistency and maintainability.

Suggestion for improvement:
Consider specifying the type of the realm parameter for better type safety. For example:

export const hasEnoughPopulationForBuilding = (realm: RealmInterface, building: number) => {
  // ... (rest of the function)
};

Let's verify if configManager is used consistently across the codebase:


Let's re-run the verification with adjusted search parameters to ensure consistent usage of configManager across .ts, .tsx, and .js files:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistent usage of configManager across the codebase

# Test 1: Search for direct uses of BASE_POPULATION_CAPACITY or BUILDING_POPULATION
echo "Checking for direct uses of BASE_POPULATION_CAPACITY or BUILDING_POPULATION:"
rg --type typescript --type javascript 'BASE_POPULATION_CAPACITY|BUILDING_POPULATION'

# Test 2: Search for uses of configManager methods
echo "Checking for uses of configManager methods:"
rg --type typescript --type javascript 'configManager\.(getBuildingPopConfig|getBasePopulationCapacity)'

# Test 3: Check for any remaining imports of BASE_POPULATION_CAPACITY or BUILDING_POPULATION
echo "Checking for imports of BASE_POPULATION_CAPACITY or BUILDING_POPULATION:"
rg --type typescript --type javascript 'import.*BASE_POPULATION_CAPACITY|import.*BUILDING_POPULATION'

Length of output: 818


Script:

#!/bin/bash
# Description: Check for consistent usage of configManager across the codebase using file extensions

# Test 1: Search for direct uses of BASE_POPULATION_CAPACITY or BUILDING_POPULATION
echo "Checking for direct uses of BASE_POPULATION_CAPACITY or BUILDING_POPULATION in .ts, .tsx, .js files:"
rg -g "*.ts" -g "*.tsx" -g "*.js" 'BASE_POPULATION_CAPACITY|BUILDING_POPULATION'

# Test 2: Search for uses of configManager methods
echo "Checking for uses of configManager methods in .ts, .tsx, .js files:"
rg -g "*.ts" -g "*.tsx" -g "*.js" 'configManager\.(getBuildingPopConfig|getBasePopulationCapacity)'

# Test 3: Check for any remaining imports of BASE_POPULATION_CAPACITY or BUILDING_POPULATION
echo "Checking for imports of BASE_POPULATION_CAPACITY or BUILDING_POPULATION in .ts, .tsx, .js files:"
rg -g "*.ts" -g "*.tsx" -g "*.js" 'import.*BASE_POPULATION_CAPACITY|import.*BUILDING_POPULATION'

Length of output: 3633

import { useMemo } from "react";
import useUIStore from "../../../../hooks/store/useUIStore";
import { TickIds } from "@bibliothecadao/eternum";
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Remaining usages of EternumGlobalConfig Found

The verification revealed that EternumGlobalConfig is still in use across multiple files in the codebase. This indicates that the refactoring to TickIds is not yet complete and may lead to inconsistencies.

  • Files still using EternumGlobalConfig:
    • sdk/packages/eternum/src/utils/index.ts
    • client/src/ui/components/hyperstructures/StructureCard.tsx
    • client/src/dojo/modelManager/ConfigManager.ts
    • (and others as listed in the shell script output)

Please ensure that all instances of EternumGlobalConfig are appropriately updated to maintain consistency and prevent potential issues.

🔗 Analysis chain

Approve import change and verify usage

The import change from EternumGlobalConfig to TickIds suggests a move towards a more modular configuration system. This is generally a good practice for maintainability and flexibility.

To ensure this change is consistent across the codebase, please run the following script:

This will help ensure that the refactoring has been applied consistently throughout the project.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of TickIds and absence of EternumGlobalConfig

# Test 1: Check for any remaining usage of EternumGlobalConfig
echo "Checking for any remaining usage of EternumGlobalConfig:"
rg "EternumGlobalConfig" --type typescript

# Test 2: Verify the usage of TickIds
echo "Verifying the usage of TickIds:"
rg "TickIds" --type typescript

Length of output: 339


Script:

#!/bin/bash
# Description: Verify the usage of TickIds and absence of EternumGlobalConfig by searching .ts and .tsx files

# Test 1: Check for any remaining usage of EternumGlobalConfig
echo "Checking for any remaining usage of EternumGlobalConfig in .ts and .tsx files:"
rg "EternumGlobalConfig" --glob "*.ts" --glob "*.tsx"

# Test 2: Verify the usage of TickIds
echo "Verifying the usage of TickIds in .ts and .tsx files:"
rg "TickIds" --glob "*.ts" --glob "*.tsx"

Length of output: 11690

Comment on lines +18 to +22
Number(resourceQuantity / BigInt(configManager.getResourcePrecision())) *
configManager.getResourceRarity(resourceType);
const totalContributableAmount = configManager.getHyperstructureTotalContributableAmount();

return effectiveContribution / totalContributableAmount;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential loss of precision when converting bigint to number

In the calculation of effectiveContribution, converting a bigint to a number using Number() can lead to loss of precision for large values exceeding Number.MAX_SAFE_INTEGER. This may result in inaccurate computations of contribution percentages.

Consider performing calculations using bigint arithmetic and converting to number only once you're certain the value is within the safe integer range. Here's a possible refactor:

-  const effectiveContribution =
-    Number(resourceQuantity / BigInt(configManager.getResourcePrecision())) *
-    configManager.getResourceRarity(resourceType);
-  const totalContributableAmount = configManager.getHyperstructureTotalContributableAmount();
-  return effectiveContribution / totalContributableAmount;
+  const effectiveContribution =
+    (resourceQuantity * BigInt(configManager.getResourceRarity(resourceType))) /
+    BigInt(configManager.getResourcePrecision());
+  const totalContributableAmount = BigInt(configManager.getHyperstructureTotalContributableAmount());
+  return Number(effectiveContribution) / Number(totalContributableAmount);

This refactor maintains precision during calculations by using bigint throughout and converts to number only when necessary.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Number(resourceQuantity / BigInt(configManager.getResourcePrecision())) *
configManager.getResourceRarity(resourceType);
const totalContributableAmount = configManager.getHyperstructureTotalContributableAmount();
return effectiveContribution / totalContributableAmount;
const effectiveContribution =
(resourceQuantity * BigInt(configManager.getResourceRarity(resourceType))) /
BigInt(configManager.getResourcePrecision());
const totalContributableAmount = BigInt(configManager.getHyperstructureTotalContributableAmount());
return Number(effectiveContribution) / Number(totalContributableAmount);

@@ -27,7 +21,7 @@ export const TravelInfo = ({
const [resourceWeight, setResourceWeight] = useState(0);
const [donkeyBalance, setDonkeyBalance] = useState(0);
const neededDonkeys = Math.ceil(
divideByPrecision(resourceWeight) / Number(EternumGlobalConfig.carryCapacityGram[CapacityConfigCategory.Donkey]),
divideByPrecision(resourceWeight) / configManager.getCapacityConfig(CapacityConfigCategory.Donkey),
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle potential division by zero

When calculating neededDonkeys, ensure that configManager.getCapacityConfig(CapacityConfigCategory.Donkey) does not return zero to avoid a division by zero error. Consider adding error handling or a default value to handle this scenario gracefully.

Apply this diff to add a safeguard:

 const neededDonkeys = Math.ceil(
-  divideByPrecision(resourceWeight) / configManager.getCapacityConfig(CapacityConfigCategory.Donkey),
+  divideByPrecision(resourceWeight) / Math.max(configManager.getCapacityConfig(CapacityConfigCategory.Donkey), 1),
 );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
divideByPrecision(resourceWeight) / configManager.getCapacityConfig(CapacityConfigCategory.Donkey),
divideByPrecision(resourceWeight) / Math.max(configManager.getCapacityConfig(CapacityConfigCategory.Donkey), 1),

@@ -70,13 +64,13 @@ export const Resources = () => {
const ResourceTable = () => {
const resourceTable = useMemo(() => {
const resources = [];
for (const resourceId of Object.keys(RESOURCE_INPUTS_SCALED) as unknown as ResourcesIds[]) {
for (const resourceId of Object.keys(configManager.resourceInputs) as unknown as ResourcesIds[]) {
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid unsafe casting; improve type safety when iterating over resource IDs.

Casting Object.keys(configManager.resourceInputs) to ResourcesIds[] using as unknown as is unsafe because Object.keys returns an array of strings, which may not align with the ResourcesIds enum values.

Consider mapping the keys to numbers and asserting them as ResourcesIds to enhance type safety:

-for (const resourceId of Object.keys(configManager.resourceInputs) as unknown as ResourcesIds[]) {
+for (const key of Object.keys(configManager.resourceInputs)) {
+  const resourceId = Number(key) as ResourcesIds;

This ensures that resourceId is correctly typed and avoids unsafe casting.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for (const resourceId of Object.keys(configManager.resourceInputs) as unknown as ResourcesIds[]) {
for (const key of Object.keys(configManager.resourceInputs)) {
const resourceId = Number(key) as ResourcesIds;

Comment on lines +985 to +998
RealmLevelConfig: (() => {
return defineComponent(
world,
{ level: RecsType.Number, required_resources_id: RecsType.Number, required_resource_count: RecsType.Number },
{
metadata: {
namespace: "eternum",
name: "RealmLevelConfig",
types: ["u8", "u32", "u8"],
customTypes: [],
},
},
);
})(),
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

New component RealmLevelConfig added correctly

The RealmLevelConfig component has been introduced with appropriate properties and matching metadata. However, consider specifying more explicit RecsType types to enhance clarity and ensure type safety.

For instance, since level corresponds to "u8" in the metadata, you could use RecsType.Number8 if available. This approach can help prevent potential type mismatches and improve code readability.

Comment on lines +999 to +1012
RealmMaxLevelConfig: (() => {
return defineComponent(
world,
{ config_id: RecsType.Number, max_level: RecsType.Number },
{
metadata: {
namespace: "eternum",
name: "RealmMaxLevelConfig",
types: ["u32", "u8"],
customTypes: [],
},
},
);
})(),
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

New component RealmMaxLevelConfig added correctly

The RealmMaxLevelConfig component has been added with correct properties and metadata. Similar to the previous comment, consider using explicit RecsType types for clarity.

For example, since max_level corresponds to "u8" in the metadata, using RecsType.Number8 (if available) instead of RecsType.Number would enhance type specificity.

@@ -1230,6 +1285,7 @@
crossbowman_strength: RecsType.Number,
advantage_percent: RecsType.Number,
disadvantage_percent: RecsType.Number,
max_troop_count: RecsType.Number,
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Inconsistent Usage of max_troop_count in TroopConfig

The property max_troop_count is not consistently included in all instances of TroopConfig. Specifically, in client/src/dojo/modelManager/ConfigManager.ts, the property is referenced as maxTroopCount instead of max_troop_count.

  • client/src/dojo/modelManager/ConfigManager.ts uses maxTroopCount instead of max_troop_count.
🔗 Analysis chain

Addition of max_troop_count to TroopConfig

The new property max_troop_count has been added to the TroopConfig component with the appropriate type RecsType.Number. Please ensure that all instances where TroopConfig is used are updated to accommodate this new property to maintain consistency across the codebase.

Run the following script to verify that all usages of TroopConfig have been updated appropriately:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that all usages of `TroopConfig` include `max_troop_count`

# Test: Search for definitions and usages of `TroopConfig` and check for `max_troop_count` property
# Expect: All instances of `TroopConfig` should include `max_troop_count`

rg --type ts 'TroopConfig' -A 15 | rg 'max_troop_count'

Length of output: 406

Comment on lines +109 to +111
const constructionCost = configManager.structureCosts[StructureType.Hyperstructure]
.filter((cost) => cost.resource !== ResourcesIds["AncientFragment"])
.map((cost) => ({ ...cost }));
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Simplify constructionCost by removing unnecessary .map

The .map function is spreading each cost into a new object without modifications. Since the objects remain the same, the .map step can be omitted.

Apply this diff to simplify the code:

 const constructionCost = configManager.structureCosts[StructureType.Hyperstructure]
   .filter((cost) => cost.resource !== ResourcesIds["AncientFragment"])
-  .map((cost) => ({ ...cost }));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const constructionCost = configManager.structureCosts[StructureType.Hyperstructure]
.filter((cost) => cost.resource !== ResourcesIds["AncientFragment"])
.map((cost) => ({ ...cost }));
const constructionCost = configManager.structureCosts[StructureType.Hyperstructure]
.filter((cost) => cost.resource !== ResourcesIds["AncientFragment"]);

Comment on lines +56 to +60
const creationCost = configManager.structureCosts[structureId]
.filter((cost) => cost.resource === ResourcesIds["AncientFragment"])
.map((cost) => ({
...cost,
}));
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Simplify creationCost by removing unnecessary .map

The .map function is spreading each cost into a new object without modifications. Since no properties are being altered, the .map step can be omitted for clarity.

Apply this diff to simplify the code:

 const creationCost = configManager.structureCosts[structureId]
   .filter((cost) => cost.resource === ResourcesIds["AncientFragment"])
-  .map((cost) => ({
-    ...cost,
-  }));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const creationCost = configManager.structureCosts[structureId]
.filter((cost) => cost.resource === ResourcesIds["AncientFragment"])
.map((cost) => ({
...cost,
}));
const creationCost = configManager.structureCosts[structureId]
.filter((cost) => cost.resource === ResourcesIds["AncientFragment"]);

Copy link
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: 2

🧹 Outside diff range and nitpick comments (5)
client/src/dojo/modelManager/ProductionManager.ts (3)

52-55: New timeUntilFinishTick method added

The addition of the timeUntilFinishTick method is a good improvement. It provides a clear way to calculate the remaining time until a production finishes.

Consider using Math.max for improved readability:

- return finishTick > currentTick ? finishTick - currentTick : 0;
+ return Math.max(0, finishTick - currentTick);

97-106: New balanceFromComponents method added

The addition of the balanceFromComponents method is a good improvement. It provides a public interface to calculate balance based on various components without exposing the private _calculateBalance method.

For consistency with other method signatures in the class, consider using resourceId: ResourcesIds instead of resourceId: ResourcesIds, (remove the trailing comma):

public balanceFromComponents(
-   resourceId: ResourcesIds,
+   resourceId: ResourcesIds
    rate: number,
    sign: boolean,
    resourceBalance: bigint | undefined,
    productionDuration: number,
    depletionDuration: number,
  ): number {
  // ...
}

Line range hint 108-149: New private _calculateBalance method added

The addition of the _calculateBalance method is a significant improvement:

  1. It centralizes the balance calculation logic, improving maintainability.
  2. It handles both positive and negative net rates correctly.
  3. It considers store capacity and resource weight in calculations.
  4. The use of multiplyByPrecision ensures consistent precision handling.

Consider adding comments to explain the logic for each case (positive rate, negative rate, and no rate change) to improve readability and maintainability.

client/src/ui/modules/entity-details/BuildingEntityDetails.tsx (2)

200-202: LGTM: Improved flexibility in immunity duration calculation.

The use of configManager methods enhances the configurability of the immunity duration. This change aligns well with the summary's mention of improving flexibility in timing logic.

Consider extracting this calculation into a separate function for improved readability:

const calculateImmunityEndTimestamp = (createdAt: number) => {
  return createdAt + configManager.getBattleGraceTickCount() * configManager.getTick(TickIds.Armies);
};

// Usage
const immunityEndTimestamp = useMemo(() => calculateImmunityEndTimestamp(Number(structure.created_at)), [structure.created_at]);

This would make the code more self-documenting and easier to maintain.


219-223: LGTM: Enhanced resource management with improved precision.

The use of configManager.realmUpgradeCosts and divideByPrecision improves the accuracy and maintainability of balance checks. These changes align well with the summary's mention of enhancing resource management capabilities.

Consider extracting the balance check logic into a separate function for improved readability:

const hasEnoughResources = (cost: Record<number, { resource: number; amount: number }>) => {
  return Object.entries(cost).every(([resourceId, { resource, amount }]) => {
    const balance = getBalance(structureEntityId, resource);
    return divideByPrecision(balance.balance) >= amount;
  });
};

// Usage
const checkBalance = useMemo(() => {
  if (!getNextRealmLevel) return false;
  const cost = configManager.realmUpgradeCosts[getNextRealmLevel];
  return hasEnoughResources(cost);
}, [getBalance, structureEntityId, getNextRealmLevel]);

This would make the code more modular and easier to understand.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 0e25f47 and 51fddb3.

📒 Files selected for processing (6)
  • client/src/dojo/modelManager/BattleManager.ts (10 hunks)
  • client/src/dojo/modelManager/ProductionManager.ts (8 hunks)
  • client/src/dojo/modelManager/tests/BattleManager.test.ts (5 hunks)
  • client/src/ui/components/resources/ResourceChip.tsx (5 hunks)
  • client/src/ui/modules/entity-details/BuildingEntityDetails.tsx (4 hunks)
  • client/src/ui/modules/military/battle-view/BattleActions.tsx (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • client/src/dojo/modelManager/tests/BattleManager.test.ts
  • client/src/ui/components/resources/ResourceChip.tsx
  • client/src/ui/modules/military/battle-view/BattleActions.tsx
🧰 Additional context used
🔇 Additional comments (9)
client/src/dojo/modelManager/ProductionManager.ts (5)

1-1: Improved precision handling with multiplyByPrecision

The addition of multiplyByPrecision to the imports is a good improvement. This utility function can centralize precision-related calculations, making the code more maintainable and less prone to errors when dealing with resource precision.


82-88: Improved getStoreCapacity method

The refactoring of the getStoreCapacity method is a good improvement:

  1. Using multiplyByPrecision centralizes precision handling.
  2. The logic for calculating store capacity has been simplified.
  3. The use of gramToKg improves readability.

These changes make the code more maintainable and less prone to errors when dealing with unit conversions and precision.


142-149: Refactored _balance method

The refactoring of the _balance method is a good improvement:

  1. It simplifies the method by delegating the calculation to _calculateBalance.
  2. This change reduces code duplication and improves maintainability.
  3. All necessary parameters are correctly passed to _calculateBalance.

These changes make the code more organized and easier to understand.


218-218: Updated input source in _inputs_available method

The change from RESOURCE_INPUTS_SCALED to configManager.resourceInputs is a good improvement:

  1. It suggests a more flexible approach to managing resource inputs.
  2. Using configManager allows for easier configuration changes without modifying the code.

Please verify that configManager.resourceInputs is properly initialized and contains the correct data for all resource types. Run the following script to check the structure and content of resourceInputs:

#!/bin/bash
# Search for the initialization of resourceInputs in configManager
rg 'resourceInputs\s*=' --type typescript

32-32: Simplified netRate method signature

The removal of the currentTick parameter from the netRate method simplifies its signature. This is a good change if the current tick is not necessary for the calculation.

Please verify that this change doesn't affect the correctness of calculations or its usage in other parts of the codebase. Run the following script to check for any remaining uses of netRate with a parameter:

✅ Verification successful

Verified Removal of currentTick Parameter from netRate

All existing calls to netRate have been updated to match the new signature without parameters. The change maintains the correctness of calculations and does not impact other parts of the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining calls to netRate with parameters
rg 'netRate\s*\([^)]*\)' --type typescript

Length of output: 78


Script:

#!/bin/bash
# Search for any remaining calls to netRate with parameters in .ts and .tsx files
rg 'netRate\s*\([^)]*\)' --glob '*.ts' --glob '*.tsx'

Length of output: 857

client/src/ui/modules/entity-details/BuildingEntityDetails.tsx (4)

22-22: LGTM: Improved imports for enhanced precision and configurability.

The addition of divideByPrecision and TickIds imports, along with REALM_MAX_LEVEL, suggests improvements in resource management precision and timing logic configurability. These changes align well with the summary's mention of enhancing resource management capabilities.

Also applies to: 31-35


213-213: LGTM: Improved maintainability with REALM_MAX_LEVEL constant.

The use of REALM_MAX_LEVEL instead of a hardcoded value enhances code maintainability and readability. This change aligns with best practices for avoiding magic numbers in the code.


302-302: LGTM: Consistent use of configManager for upgrade costs.

The use of configManager.realmUpgradeCosts in the UI rendering ensures consistency with the balance check logic. This change maintains a single source of truth for upgrade costs, improving maintainability and reducing the risk of inconsistencies.


Line range hint 1-328: Overall assessment: Improved resource management and configurability

The changes in this file significantly enhance the resource management capabilities and configurability of the BuildingEntityDetails component. Key improvements include:

  1. More precise resource calculations using divideByPrecision.
  2. Increased flexibility in timing logic with the use of configManager and TickIds.
  3. Improved maintainability through the use of constants like REALM_MAX_LEVEL.
  4. Consistent use of configManager for upgrade costs across balance checks and UI rendering.

These modifications align well with the pull request's objectives of enhancing claimability logic and improving resource management. The changes also contribute to better code maintainability and flexibility for future updates.

Consider the suggested minor improvements for readability and modularity in the previous comments to further enhance the code quality.

Comment on lines +210 to +232
const remainingKnights =
Number(cloneArmy.troops.knight_count) *
this.getRemainingPercentageOfTroops(battle_army.troops.knight_count, battle_army_lifetime.troops.knight_count);
cloneArmy.troops.knight_count = BigInt(
remainingKnights - (remainingKnights % EternumGlobalConfig.resources.resourcePrecision),
);

const remainingPaladins =
Number(cloneArmy.troops.paladin_count) *
this.getRemainingPercentageOfTroops(battle_army.troops.paladin_count, battle_army_lifetime.troops.paladin_count);
cloneArmy.troops.paladin_count = BigInt(
remainingPaladins - (remainingPaladins % EternumGlobalConfig.resources.resourcePrecision),
);

const remainingCrossbowmen =
Number(cloneArmy.troops.crossbowman_count) *
this.getRemainingPercentageOfTroops(
battle_army.troops.crossbowman_count,
battle_army_lifetime.troops.crossbowman_count,
);
cloneArmy.troops.crossbowman_count = BigInt(
remainingCrossbowmen - (remainingCrossbowmen % EternumGlobalConfig.resources.resourcePrecision),
);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider refactoring troop calculations for improved maintainability

The current implementation calculates remaining troops for each type (knights, paladins, crossbowmen) separately, leading to repetitive code. Consider refactoring this section to use a loop or a helper function to reduce duplication and improve maintainability.

Here's a suggested refactoring:

private calculateRemainingTroops(
  cloneArmy: ArmyInfo,
  battle_army: ComponentValue<ClientComponents["Battle"]["schema"]["defence_army"]>,
  battle_army_lifetime: ComponentValue<ClientComponents["Battle"]["schema"]["defence_army_lifetime"]>
) {
  const troopTypes = ['knight', 'paladin', 'crossbowman'] as const;
  
  troopTypes.forEach(type => {
    const remaining = Number(cloneArmy.troops[`${type}_count`]) *
      this.getRemainingPercentageOfTroops(
        battle_army.troops[`${type}_count`],
        battle_army_lifetime.troops[`${type}_count`]
      );
    cloneArmy.troops[`${type}_count`] = BigInt(
      remaining - (remaining % EternumGlobalConfig.resources.resourcePrecision)
    );
  });
}

// Usage in getUpdatedArmy method:
this.calculateRemainingTroops(cloneArmy, battle_army, battle_army_lifetime);

This refactoring reduces code duplication and makes it easier to add or modify troop types in the future.

Comment on lines +502 to 505
private getRemainingPercentageOfTroops(current_troops: bigint, lifetime_troops: bigint): number {
if (lifetime_troops === 0n) return 0;
return Number(current_troops) / Number(lifetime_troops);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider using BigInt operations for higher precision

The current implementation converts BigInt values to Number for the calculation, which could lead to precision loss for very large numbers. Consider using BigInt operations throughout to maintain precision.

Here's a suggested modification:

private getRemainingPercentageOfTroops(current_troops: bigint, lifetime_troops: bigint): number {
  if (lifetime_troops === 0n) return 0;
  // Use BigInt division and then convert to number at the end
  return Number((current_troops * 10000n) / lifetime_troops) / 10000;
}

This approach performs the division using BigInt and only converts to a number at the end, maintaining higher precision. The multiplication by 10000 and subsequent division is used to simulate a percentage calculation with two decimal places of precision.

Copy link
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: 0

🧹 Outside diff range and nitpick comments (1)
scripts/deploy.sh (1)

Line range hint 1-23: Consider updating related documentation and scripts.

The version updates for both katana and torii are consistent and appropriate. However, it's important to ensure that these changes are reflected in any related documentation or scripts.

Please review and update the following if necessary:

  1. Any documentation that references the katana or torii versions.
  2. CI/CD pipelines that might be using these versions.
  3. README files or setup instructions for developers.
  4. Any other scripts in the project that interact with katana or torii deployments.

This will help maintain consistency across your project and prevent potential issues for other developers or in different environments.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 51fddb3 and 78a9a12.

⛔ Files ignored due to path filters (1)
  • contracts/Scarb.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • .github/workflows/test-contracts.yml (1 hunks)
  • contracts/Scarb.toml (2 hunks)
  • contracts/manifests/dev/deployment/manifest.json (42 hunks)
  • contracts/manifests/dev/deployment/manifest.toml (21 hunks)
  • scripts/deploy.sh (2 hunks)
🧰 Additional context used
🔇 Additional comments (18)
contracts/manifests/dev/deployment/manifest.json (9)

3461-3482: Updated set_mercenaries_config function signature

The set_mercenaries_config function signature has been updated. Instead of accepting a single troops parameter of type Troops, it now accepts six separate parameters for different troop types and bounds.

This change provides more granular control over the mercenaries configuration, allowing for independent setting of lower and upper bounds for each troop type.

Let's verify if this change has been properly implemented in the contract code and if all calls to this function have been updated:

#!/bin/bash
# Search for the old function signature
rg "fn set_mercenaries_config\(troops: Troops\)" --type cairo
# Search for the new function signature
rg "fn set_mercenaries_config\(.*knights_lower_bound.*knights_upper_bound.*paladins_lower_bound.*paladins_upper_bound.*crossbowmen_lower_bound.*crossbowmen_upper_bound.*\)" --type cairo
# Search for function calls to set_mercenaries_config
rg "set_mercenaries_config\(" --type cairo

32314-32335: Updated input parameters for mercenaries configuration

The input parameters for the mercenaries configuration have been updated to include separate fields for lower and upper bounds of each troop type (knights, paladins, crossbowmen) instead of a single troops field.

This change is consistent with the updates made to the MercenariesConfig struct and the set_mercenaries_config function signature.

Let's verify if these new parameters are used consistently across the codebase:

#!/bin/bash
# Search for functions or methods using these new parameters
rg "fn .*\(.*knights_lower_bound.*knights_upper_bound.*paladins_lower_bound.*paladins_upper_bound.*crossbowmen_lower_bound.*crossbowmen_upper_bound.*\)" --type cairo

31890-31916: Updated MercenariesConfig struct

The MercenariesConfig struct has been updated to include separate fields for lower and upper bounds of each troop type (knights, paladins, crossbowmen) instead of a single troops field.

This change aligns with the updated set_mercenaries_config function signature and provides more detailed configuration options for mercenaries.

Let's verify if this struct is consistently used across the codebase:

#!/bin/bash
# Search for the old MercenariesConfig struct
rg "struct MercenariesConfig \{[^}]*troops:" --type cairo
# Search for the new MercenariesConfig struct
rg "struct MercenariesConfig \{[^}]*knights_lower_bound:" --type cairo
# Search for usages of MercenariesConfig
rg "MercenariesConfig" --type cairo

Line range hint 1-32335: Summary of changes to the manifest file

The changes in this manifest file reflect a comprehensive update to the contract system:

  1. New deployments of multiple contracts, including the World contract and various other contracts, as evidenced by updated addresses and class hashes.
  2. Modification of the MercenariesConfig struct and related functions to provide more granular control over troop configurations.
  3. Renaming of the contract_name function to name across multiple contracts for better consistency with standard naming conventions.

These changes appear to be part of a coordinated effort to improve the contract system's functionality and maintainability. The modifications to the mercenaries configuration, in particular, suggest an enhancement in the game's mechanics related to troop management.

To ensure the completeness and consistency of these changes, consider running the following final verifications:

#!/bin/bash
# Verify that all contracts in the manifest have been updated
rg '"kind": "DojoContract"' contracts/manifests/dev/deployment/manifest.json | wc -l

# Check for any remaining references to the old 'Troops' type
rg "Troops" --type cairo

# Verify that all contracts now use the 'name' function instead of 'contract_name'
rg "fn contract_name" --type cairo
rg "fn name" --type cairo

# Check for any inconsistencies in the use of the new mercenaries configuration
rg "MercenariesConfig" --type cairo

These verifications will help ensure that the changes have been applied consistently across the entire codebase.


31925-31926: Updated class hash for MercenariesConfig

The class_hash and original_class_hash for the MercenariesConfig struct have been updated. This change is consistent with the modifications made to the struct's fields.

Let's verify if this new class hash is used consistently across the codebase:

#!/bin/bash
# Search for the new class hash
rg "0x12247bf8d7b37069a7c9b217db67538f14d0bae3b72478b20c3c6011493da57" --type json --type cairo

1237-1239: Updated World contract deployment details

The address, transaction_hash, and block_number for the World contract have been updated. This indicates a new deployment of the contract.

Note that the block_number has decreased from 65 to 50. This might indicate a redeployment on a different network or a reset of the development environment.

Let's verify if this new address is referenced correctly in other parts of the codebase:

✅ Verification successful

World contract address correctly referenced

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the new World contract address in other files
rg "0x320b2713e324fe3125bbc42d85ff69cb3c0908b436fa38a35746dbc45deeb11" --type json --type cairo

Length of output: 430


Script:

#!/bin/bash
# Corrected script to search for the new World contract address in JSON and relevant files
rg "0x320b2713e324fe3125bbc42d85ff69cb3c0908b436fa38a35746dbc45deeb11" --type json --type js --type ts --type py --type go

Length of output: 255


4-5: Updated class hashes for the World contract

The class_hash and original_class_hash for the World contract have been updated. This change likely reflects a new version of the contract being deployed.

To ensure consistency, let's verify if this class hash is used elsewhere in the codebase:

✅ Verification successful

Class hash verification succeeded

The updated class_hash is only present in contracts/manifests/dev/deployment/manifest.json, ensuring that the changes are confined to this configuration file.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the new class hash in other files
rg "0x6f38d5d9507c5d9546290e1a27e309efe5a9af3770b6cc1627db4a1b90a7dce" --type json

Length of output: 430


Script:

#!/bin/bash
# Corrected script to search for the new class hash in JSON files
rg "0x6f38d5d9507c5d9546290e1a27e309efe5a9af3770b6cc1627db4a1b90a7dce" --type json

Length of output: 363


1292-1292: Updated function name from contract_name to name

The function name has been changed from contract_name to name across multiple contracts. This change improves consistency with standard naming conventions for contract interfaces.

Let's verify if this change has been consistently applied across the codebase:

Also applies to: 1615-1615, 2052-2052, 2517-2517, 3877-3877, 4157-4157, 4415-4415, 4634-4634, 4984-4984, 5375-5375, 5691-5691, 5969-5969, 6230-6230, 6546-6546, 6874-6874, 7178-7178, 7464-7464, 7808-7808


1258-1260: Updated contract deployment details for multiple contracts

The address, class_hash, and original_class_hash have been updated for multiple contracts. This indicates a new deployment of these contracts, likely due to code changes or a new deployment environment.

Let's verify if these new addresses and class hashes are consistently used across the codebase:

Also applies to: 1581-1583, 2018-2020, 2483-2485, 3843-3845, 4123-4125, 4381-4383, 4600-4602, 4950-4952, 5341-5343, 5657-5659, 5935-5937, 6196-6198, 6512-6514, 6840-6842, 7144-7146, 7430-7432, 7774-7776

contracts/Scarb.toml (2)

9-9: Dependency version update looks good, but verify compatibility.

The update of the dojo dependency from v1.0.0-alpha.12 to v1.0.0-alpha.16 is noted. This change seems intentional and follows semantic versioning.

To ensure smooth integration:

  1. Review the changelog for dojo between these versions to understand new features or breaking changes.
  2. Verify that your project is compatible with this new version, especially considering it's an alpha release.
  3. Check if any other dependencies in your project rely on dojo and may need updates as well.

Would you like me to search for any potential compatibility issues in the codebase?


19-19: Newline addition is a good practice.

Adding a newline at the end of the file is a good practice. It ensures proper file termination and can prevent issues with certain tools or version control systems.

scripts/deploy.sh (2)

14-14: Approve version update for katana deployment.

The katana deployment version has been updated from v1.0.0-alpha.12 to v1.0.0-alpha.16. This change is likely to include improvements or new features.

Please ensure that this new version is compatible with the rest of your system. Consider running the following commands to verify the compatibility and check for any breaking changes:


23-23: Approve version update for torii deployment.

The torii deployment version has been updated from v1.0.0-alpha.12 to v1.0.0-alpha.16, consistent with the katana update.

Please ensure that this new version of torii is compatible with the updated katana version and the rest of your system. Consider running the following commands to verify the compatibility:

.github/workflows/test-contracts.yml (1)

52-52: Dojo version update: Verify compatibility and test thoroughly

The Dojo release artifact version has been updated from v1.0.0-alpha.12 to v1.0.0-alpha.16. This change may introduce new features, bug fixes, or potential breaking changes.

To ensure this update doesn't negatively impact the project:

  1. Verify that v1.0.0-alpha.16 is the intended version for this update.
  2. Review the changelog or release notes for Dojo v1.0.0-alpha.16 to understand the changes introduced.
  3. Ensure all tests pass with the new version.
  4. Check if any project code needs to be updated to accommodate changes in Dojo v1.0.0-alpha.16.
contracts/manifests/dev/deployment/manifest.toml (4)

Line range hint 26-339: Contract configurations updated

The contract configurations have been updated with new class hashes and addresses. These changes appear to be consistent across all contract entries and likely reflect a new deployment or version of the contracts.

To ensure these changes are consistent and no unintended modifications were made, run the following script:

#!/bin/bash
# Description: Verify the consistency of contract configuration updates

# Test: Check for any remaining old class hashes or addresses
echo "Checking for any remaining old class hashes or addresses in the contracts section:"
sed -n '/\[\[contracts\]\]/,/\[\[models\]\]/p' contracts/manifests/dev/deployment/manifest.toml | grep -E "0x[a-fA-F0-9]{64}" | sort | uniq -c

# Test: Verify that all contract entries have been updated
echo "Verifying that all contract entries have been updated:"
sed -n '/\[\[contracts\]\]/,/\[\[models\]\]/p' contracts/manifests/dev/deployment/manifest.toml | grep -E "class_hash = |original_class_hash = |address = " | wc -l

Line range hint 2074-2113: MercenariesConfig model restructured

The MercenariesConfig model has been significantly restructured:

  1. The 'troops' field has been removed.
  2. New fields for knights, paladins, and crossbowmen have been added, each with lower and upper bounds.

This change provides more granular control over different troop types, which could impact game balance and mechanics. Ensure that all systems interacting with this model have been updated accordingly.

To verify the impact of these changes and ensure all related code has been updated, run the following script:

#!/bin/bash
# Description: Verify the impact of MercenariesConfig changes

# Test: Search for uses of the old 'troops' field
echo "Searching for uses of the old 'troops' field:"
rg --type rust "MercenariesConfig.*troops"

# Test: Search for uses of the new troop-specific fields
echo "Searching for uses of the new troop-specific fields:"
rg --type rust "MercenariesConfig.*(knights|paladins|crossbowmen)_(lower|upper)_bound"

# Test: Check for any remaining references to the old model structure
echo "Checking for any remaining references to the old model structure:"
rg --type rust "MercenariesConfig" -C 5

3-8: World configuration updated

The world configuration has been updated with new class hashes, addresses, and block number. These changes appear to be part of a deployment update.

To ensure these changes are consistent across the codebase, run the following script:

#!/bin/bash
# Description: Verify the consistency of world configuration values across the codebase

# Test: Search for occurrences of the old and new values
echo "Searching for old and new class_hash:"
rg --type toml "0x6f4515274ee23404789c3351a77107d0ec07508530119822046600ca6948d6e"
rg --type toml "0x6f38d5d9507c5d9546290e1a27e309efe5a9af3770b6cc1627db4a1b90a7dce"

echo "Searching for old and new address:"
rg --type toml "0x76ca3dfc3e96843716f882546f0db96b7da0cf988bdba284b469d0defb2f48f"
rg --type toml "0x320b2713e324fe3125bbc42d85ff69cb3c0908b436fa38a35746dbc45deeb11"

echo "Searching for old and new transaction_hash:"
rg --type toml "0x73f424096734f925628f50730e27889506b6b9141efd4aed165165ef8367ce5"
rg --type toml "0x5a4deb5ecebc548f10b969db5496f9605a3b862dc766bb419c42615ff735760"

echo "Searching for old and new block_number:"
rg --type toml "block_number = 65"
rg --type toml "block_number = 50"

Line range hint 1-2853: Comprehensive manifest update

This manifest file has undergone significant changes, including:

  1. Updated world configuration
  2. Updated contract configurations with new class hashes and addresses
  3. Restructured MercenariesConfig model

While these changes appear appropriate for a deployment update, it's crucial to ensure all modifications are intentional and no unintended changes have been introduced.

To perform a comprehensive verification of the changes, run the following script:

Please review the output of this script carefully to ensure all changes are as expected.

✅ Verification successful

✅ Manifest Update Verified Successfully

The manifest.toml file has been thoroughly reviewed and verified. All changes related to class hashes, addresses, and other deployment-specific configurations align with the expected updates. Additionally, the number of model definitions remains consistent, and no new or removed models have been introduced inadvertently.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Comprehensive verification of manifest changes

# Test: Compare the old and new versions of the file
echo "Generating a diff of the manifest file:"
git diff HEAD~1 contracts/manifests/dev/deployment/manifest.toml > manifest_diff.txt

# Test: Check for any unexpected changes
echo "Checking for unexpected changes:"
grep -vE "(class_hash|original_class_hash|address|transaction_hash|block_number)" manifest_diff.txt

# Test: Verify that all model definitions are present
echo "Verifying all model definitions are present:"
grep -c "\[\[models\]\]" contracts/manifests/dev/deployment/manifest.toml

# Test: Check for any removed or added models
echo "Checking for removed or added models:"
diff <(grep "\[\[models\]\]" contracts/manifests/dev/deployment/manifest.toml | sort) <(git show HEAD~1:contracts/manifests/dev/deployment/manifest.toml | grep "\[\[models\]\]" | sort)

# Cleanup
rm manifest_diff.txt

Length of output: 1158


Script:

#!/bin/bash
# Description: Comprehensive verification of manifest.toml changes

# Step 1: Generate a diff of the manifest file
echo "Generating a diff of the manifest file:"
git diff HEAD~1 contracts/manifests/dev/deployment/manifest.toml > manifest_diff.txt

# Step 2: Check for any unexpected changes excluding specific keys
echo "Checking for any unexpected changes (excluding class_hash, original_class_hash, address, transaction_hash, block_number):"
grep -vE "(class_hash|original_class_hash|address|transaction_hash|block_number)" manifest_diff.txt

# Step 3: Verify the number of [[models]] sections matches the previous version
echo "Verifying the number of [[models]] sections:"
current_models_count=$(grep -c "\[\[models\]\]" contracts/manifests/dev/deployment/manifest.toml)
previous_models_count=$(git show HEAD~1:contracts/manifests/dev/deployment/manifest.toml | grep -c "\[\[models\]\]")

echo "Current number of models: $current_models_count"
echo "Previous number of models: $previous_models_count"

if [ "$current_models_count" -eq "$previous_models_count" ]; then
    echo "Model count verification passed."
else
    echo "Model count mismatch detected."
fi

# Step 4: Check for any removed or added models by comparing model tags
echo "Checking for removed or added models based on tags:"
current_model_tags=$(grep -E 'tag = "[^"]+"' contracts/manifests/dev/deployment/manifest.toml | sort)
previous_model_tags=$(git show HEAD~1:contracts/manifests/dev/deployment/manifest.toml | grep -E 'tag = "[^"]+"' | sort)

echo "Differences in model tags:"
diff <(echo "$current_model_tags") <(echo "$previous_model_tags")

Length of output: 21308


Script:

#!/bin/bash
# Description: Comprehensive verification of manifest.toml changes with improved error handling

# Define temporary files
CURRENT_MODELS_TAGS=$(mktemp)
PREVIOUS_MODELS_TAGS=$(mktemp)
DIFF_OUTPUT=$(mktemp)

# Ensure temporary files are removed on exit
trap 'rm -f "$CURRENT_MODELS_TAGS" "$PREVIOUS_MODELS_TAGS" "$DIFF_OUTPUT"' EXIT

# Step 1: Generate a diff of the manifest file
echo "Generating a diff of the manifest file:"
git diff HEAD~1 contracts/manifests/dev/deployment/manifest.toml > manifest_diff.txt

# Step 2: Check for any unexpected changes excluding specific keys
echo "Checking for any unexpected changes (excluding class_hash, original_class_hash, address, transaction_hash, block_number):"
grep -vE "(class_hash|original_class_hash|address|transaction_hash|block_number)" manifest_diff.txt > unexpected_changes.txt

if [ -s unexpected_changes.txt ]; then
    echo "Unexpected changes detected:"
    cat unexpected_changes.txt
else
    echo "No unexpected changes found."
fi

# Step 3: Verify the number of [[models]] sections matches the previous version
echo "Verifying the number of [[models]] sections:"
current_models_count=$(grep -c "\[\[models\]\]" contracts/manifests/dev/deployment/manifest.toml)
previous_models_count=$(git show HEAD~1:contracts/manifests/dev/deployment/manifest.toml | grep -c "\[\[models\]\]")

echo "Current number of models: $current_models_count"
echo "Previous number of models: $previous_models_count"

if [ "$current_models_count" -eq "$previous_models_count" ]; then
    echo "Model count verification passed."
else
    echo "Model count mismatch detected."
fi

# Step 4: Check for any removed or added models by comparing model tags
echo "Checking for removed or added models based on tags:"

# Extract current model tags
grep -E 'tag = "[^"]+"' contracts/manifests/dev/deployment/manifest.toml | sort > "$CURRENT_MODELS_TAGS"

# Extract previous model tags
git show HEAD~1:contracts/manifests/dev/deployment/manifest.toml | grep -E 'tag = "[^"]+"' | sort > "$PREVIOUS_MODELS_TAGS"

# Compare the tags
diff "$CURRENT_MODELS_TAGS" "$PREVIOUS_MODELS_TAGS" > "$DIFF_OUTPUT"

if [ -s "$DIFF_OUTPUT" ]; then
    echo "Differences in model tags detected:"
    cat "$DIFF_OUTPUT"
else
    echo "No differences in model tags. No models were added or removed."
fi

# Cleanup is handled by the trap

Length of output: 7018

Copy link
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: 4

🧹 Outside diff range and nitpick comments (11)
client/src/hooks/helpers/useHyperstructures.tsx (1)

37-39: LGTM: Improved owner determination logic

The changes to the useHyperstructures hook improve the accuracy of owner determination by using ContractAddress for comparison. Adding isOwner to the returned object is a useful addition.

Consider using optional chaining for a more concise null check:

const isOwner = ContractAddress(ownerComponent?.address) === ContractAddress(account.address);

Also applies to: 46-46

sdk/packages/eternum/src/types/common.ts (1)

375-379: Approve new Player interface with a minor suggestion

The new Player interface is a good addition, providing a clear structure for player data. The property names are descriptive and the types are appropriate.

Minor suggestion: Consider using camelCase for all property names to maintain consistency with TypeScript naming conventions. Change entity_id to entityId.

Here's the suggested change:

 export interface Player {
-  entity_id: number;
+  entityId: number;
   address: ContractAddress;
   addressName: string;
 }
client/src/ui/components/hyperstructures/HyperstructurePanel.tsx (3)

37-37: LGTM: Enhanced functionality with guild and access management

The additions of set_access, getGuildFromPlayerAddress, and setTooltip improve the component's capabilities:

  1. Dynamic access level management is now possible.
  2. Guild-related functionality has been integrated.
  3. Tooltip support adds to the UI's interactivity.

These changes align well with the component's evolving requirements.

Consider adding a brief comment explaining the purpose of setTooltip for better code readability.

Also applies to: 42-43, 49-49


111-123: LGTM: Improved contribution permission logic

The new canContribute memoized value centralizes and clarifies the logic for determining if a user can contribute. It considers ownership, guild membership, and access levels, which aligns well with the new guild and access management functionality.

To improve readability, consider extracting the complex condition into a separate function:

const canContribute = useMemo(() => {
  const hyperstructureOwnerGuild = getGuildFromPlayerAddress(BigInt(entity?.owner || 0));
  
  const isGuildMemberWithAccess = () => {
    return hyperstructure?.access === Access[Access.GuildOnly] &&
      playerGuild?.guildEntityId !== undefined &&
      playerGuild.guildEntityId !== 0 &&
      hyperstructureOwnerGuild?.guildEntityId !== undefined &&
      hyperstructureOwnerGuild.guildEntityId !== 0 &&
      hyperstructureOwnerGuild.guildEntityId === playerGuild.guildEntityId;
  };

  return entity.isOwner || isGuildMemberWithAccess() || hyperstructure?.access === Access[Access.Public];
}, [newContributions]);

This separation of concerns makes the logic easier to understand and maintain.


133-139: LGTM: Enhanced access control functionality

The renaming of set_private to setAccess and the updated implementation improve flexibility in access control. The function now supports multiple access levels, which aligns well with the earlier changes related to access management.

To improve type safety, consider using a union type for the access parameter instead of bigint:

const setAccess = async (access: Access) => {
  setIsLoading(Loading.SetPrivate);
  try {
    await set_access({
      signer: account,
      hyperstructure_entity_id: entity.entity_id,
      access: BigInt(access),
    });
  } finally {
    // ... rest of the code
  }
};

This change ensures that only valid Access enum values can be passed to the function.

client/src/dojo/createSystemCalls.ts (1)

238-240: LGTM! Consider adding a return type for consistency.

The set_access function is well-implemented and follows the established pattern for system calls in this file. It's a clean wrapper around the provider method.

For consistency with TypeScript best practices, consider adding an explicit return type:

const set_access = async (props: SystemProps.SetAccessProps): Promise<void> => {
  await provider.set_access(props);
};
sdk/packages/eternum/src/provider/index.ts (3)

1038-1043: LGTM! Consider adding JSDoc for improved clarity.

The renaming of set_private to set_access and the corresponding parameter change improve the method's clarity and flexibility. This change aligns well with the contract's entrypoint name.

Consider adding JSDoc comments to clarify the expected values for the access parameter, especially if it supports more than just boolean values. For example:

/**
 * Sets the access level for a hyperstructure.
 * @param props.hyperstructure_entity_id The ID of the hyperstructure
 * @param props.access The access level to set (e.g., 'public', 'private', or other supported values)
 * @param props.signer The signer for the transaction
 */
public async set_access(props: SystemProps.SetAccessProps) {
  // ... (existing implementation)
}

1084-1105: LGTM! Update related documentation for this breaking change.

The set_mercenaries_config method has been significantly improved, allowing for more granular control over mercenary configurations. The separate bounds for knights, paladins, and crossbowmen provide greater flexibility in balancing the game mechanics.

As this is a breaking change, ensure that:

  1. The version number is updated appropriately (e.g., major version bump).
  2. The change is clearly documented in the changelog or release notes.
  3. Any documentation or guides referencing this method are updated to reflect the new parameter structure.

Consider adding JSDoc comments to clarify the purpose and expected values for each parameter:

/**
 * Sets the configuration for mercenaries.
 * @param props.knights_lower_bound The lower bound for knights
 * @param props.knights_upper_bound The upper bound for knights
 * @param props.paladins_lower_bound The lower bound for paladins
 * @param props.paladins_upper_bound The upper bound for paladins
 * @param props.crossbowmen_lower_bound The lower bound for crossbowmen
 * @param props.crossbowmen_upper_bound The upper bound for crossbowmen
 * @param props.rewards The rewards configuration
 * @param props.signer The signer for the transaction
 */
public async set_mercenaries_config(props: SystemProps.SetMercenariesConfigProps) {
  // ... (existing implementation)
}

Line range hint 1038-1105: Summary: Improved flexibility with breaking changes

The changes to set_access (formerly set_private) and set_mercenaries_config methods enhance the flexibility and granularity of the EternumProvider class. However, the set_mercenaries_config change is not backwards-compatible.

To ensure a smooth transition for users of this SDK:

  1. Update the package version following semantic versioning principles (likely a major version bump).
  2. Clearly document these changes in the changelog, highlighting the breaking change in set_mercenaries_config.
  3. Update any related documentation, examples, or guides that use these methods.
  4. Consider providing migration guidelines for users updating from the previous version.

These changes appear to be part of a larger refactoring effort to improve the game's mechanics and configurability. Ensure that these changes are consistent with updates in other parts of the codebase and game design.

contracts/src/models/hyperstructure.cairo (2)

Line range hint 100-121: Handle cases where contributor or owner may not be guild members

In the assert_access method within HyperstructureCustomImpl, the code assumes that both the contributor and the owner are guild members when self.access is Access::GuildOnly:

let guild_member = get!(world, contributor_address, GuildMember);
let owner_guild_member = get!(world, hyperstructure_owner.address, GuildMember);
assert!(guild_member.guild_entity_id == owner_guild_member.guild_entity_id, "not in the same guild");

If either the contributor or the owner is not a guild member, the get! macro might fail or cause a runtime error. Consider adding error handling to manage scenarios where the contributor or owner does not belong to any guild. This will prevent unexpected crashes and provide clearer feedback to the user.


110-111: Enhance error message for Access::Private case

In the Access::Private branch, the current assertion error message is:

assert!(contributor_address == hyperstructure_owner.address, "Hyperstructure is private");

Consider improving the error message to be more descriptive, aiding in debugging and user understanding. For example:

assert!(contributor_address == hyperstructure_owner.address, "Only the owner can access this Hyperstructure");
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 78a9a12 and 34a4a72.

📒 Files selected for processing (10)
  • client/src/dojo/contractComponents.ts (6 hunks)
  • client/src/dojo/createSystemCalls.ts (2 hunks)
  • client/src/hooks/helpers/useHyperstructures.tsx (4 hunks)
  • client/src/ui/components/hyperstructures/HyperstructurePanel.tsx (9 hunks)
  • client/src/ui/utils/utils.tsx (7 hunks)
  • contracts/src/models/hyperstructure.cairo (3 hunks)
  • contracts/src/systems/hyperstructure/contracts.cairo (6 hunks)
  • sdk/packages/eternum/src/provider/index.ts (2 hunks)
  • sdk/packages/eternum/src/types/common.ts (4 hunks)
  • sdk/packages/eternum/src/types/provider.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • client/src/dojo/contractComponents.ts
🧰 Additional context used
🪛 Biome
client/src/ui/components/hyperstructures/HyperstructurePanel.tsx

[error] 204-204: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

🔇 Additional comments (26)
client/src/hooks/helpers/useHyperstructures.tsx (4)

2-3: LGTM: Improved imports and destructuring

The changes to the imports and destructuring look good. The introduction of configManager and divideByPrecision suggests a move towards more centralized configuration management and improved precision handling, which are positive improvements.

Also applies to: 22-22


Line range hint 137-139: LGTM: Consistent use of ContractAddress for comparison

The update to use ContractAddress for comparison in the useGetPlayerEpochs hook is consistent with the changes made in useHyperstructures. This change improves the accuracy of address comparison across the codebase.


Line range hint 165-170: LGTM: Extracted getContributions function

The addition of the getContributions function is a good refactoring step. It improves code organization by extracting the contribution fetching logic into a separate, reusable function. This change enhances maintainability and potentially allows for easier testing of this functionality.


176-192: ⚠️ Potential issue

Improved calculation logic, but potential null reference issue remains

The changes to getAllProgressesAndTotalPercentage are generally positive:

  • Using configManager.hyperstructureTotalCosts allows for more flexible configuration management.
  • The use of divideByPrecision likely improves the accuracy of calculations.

However, the potential issue with the non-null assertion on progress!.resource_type that was flagged in a previous review still exists. To address this:

let foundProgress = progresses.find((progress) => progress?.resource_type === resource);

This change will safely handle potential undefined values in the progresses array.

sdk/packages/eternum/src/types/common.ts (3)

39-43: LGTM: New Access enum added

The new Access enum is a good addition. It provides a clear way to define different access levels, which can be useful for various game mechanics. The naming is clear and follows common conventions.


Line range hint 1-379: Summary of changes in common.ts

The changes in this file enhance the game's type system and configuration structure. Key improvements include:

  1. Addition of the Access enum for better control over game element accessibility.
  2. Restructuring of the mercenaries configuration in the Config interface for more granular troop management.
  3. Introduction of the Player interface to represent player data consistently.

These changes improve code clarity and flexibility. Minor suggestions have been made for naming consistency and verifying the impact of the mercenaries configuration change on the rest of the codebase.


334-339: Approve changes to mercenaries configuration with a suggestion

The restructuring of the mercenaries configuration in the Config interface is a good improvement. It allows for more granular control over troop numbers and is more flexible for future extensions.

However, this change might impact other parts of the codebase that were using the previous troops object.

Please run the following script to check for any potential impacts:

client/src/ui/components/hyperstructures/HyperstructurePanel.tsx (3)

3-3: LGTM: Improved imports for better configuration management and precision

The new imports enhance the component's capabilities:

  1. configManager allows for centralized configuration management.
  2. useGuilds hook suggests new guild-related functionality.
  3. multiplyByPrecision utility improves calculation precision.
  4. Access type import indicates more granular access control.

These changes should lead to more maintainable and flexible code.

Also applies to: 7-7, 15-15, 17-18


72-72: LGTM: Improved precision in contribution calculations

The use of multiplyByPrecision(amount) instead of the previous hardcoded multiplication enhances precision and maintainability. This change aligns well with the earlier import modifications and centralizes the precision logic.


Line range hint 192-284: LGTM: Improved UI for access control and contribution feedback

The addition of the Select component for access level management and the tooltip for the Contribute button significantly enhance the user interface:

  1. The Select component provides an intuitive way for owners to change access levels.
  2. Dynamic generation of Select options ensures only valid choices are presented.
  3. The tooltip on the Contribute button gives immediate feedback on permission issues.

These changes align well with the earlier modifications to access control logic and improve overall usability.

To enhance accessibility, consider adding an aria-label to the Select component:

<Select
  onValueChange={(access: keyof typeof Access) => {
    setAccess(BigInt(Access[access]));
  }}
  aria-label="Change access level"
>
  {/* ... rest of the Select component ... */}
</Select>

This addition will make the component more screen-reader friendly.

To ensure that the access level changes are correctly reflected in the UI, let's verify the implementation:

🧰 Tools
🪛 Biome

[error] 204-204: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

client/src/dojo/createSystemCalls.ts (2)

353-353: LGTM! Consistent implementation of the new system call.

The addition of set_access to the systemCalls object is well-implemented. It correctly uses the withQueueing and withErrorHandling wrappers, maintaining consistency with other system calls.


238-240: Verify the integration and usage of the new set_access system call.

The introduction of the set_access system call appears to be part of a larger change related to access control. While the implementation is consistent and well-integrated, it's important to ensure that this new functionality is properly utilized throughout the codebase.

To confirm the proper integration and usage of the new set_access system call, please run the following script:

This script will help identify where the new set_access call is being used, if there are any lingering references to the old set_private call (if it existed), and if there are any TODO comments related to access control that might need addressing.

Also applies to: 353-353

✅ Verification successful

set_access System Call Integration Verified Successfully.

The set_access system call is correctly integrated and utilized across the codebase. There are no remaining references to the old set_private call, and no related TODO comments are present.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for usage of the new set_access system call and compare with the old set_private call (if it existed).

echo "Searching for usage of set_access:"
rg --type typescript 'set_access'

echo "\nSearching for any remaining usage of set_private (if it existed before):"
rg --type typescript 'set_private'

echo "\nChecking for any TODO comments related to access control:"
rg --type typescript 'TODO.*access'

Length of output: 578


Script:

#!/bin/bash
# Description: Check for usage of the new set_access system call and compare with the old set_private call (if it existed).
# Also, check for any TODO comments related to access control.

echo "Searching for usage of set_access in TypeScript files:"
rg 'set_access' --glob '*.ts' --glob '*.tsx'

echo -e "\nSearching for any remaining usage of set_private in TypeScript files (if it existed before):"
rg 'set_private' --glob '*.ts' --glob '*.tsx'

echo -e "\nChecking for any TODO comments related to access control in TypeScript files:"
rg 'TODO.*access' --glob '*.ts' --glob '*.tsx'

Length of output: 1307

sdk/packages/eternum/src/types/provider.ts (1)

518-520: LGTM! Verify usage across the codebase.

The renaming of SetPrivateProps to SetAccessProps and the change from to_private: boolean to access: num.BigNumberish suggests a more flexible access control system. This is a good improvement in terms of extensibility.

Please ensure that all usages of the old interface name and property have been updated accordingly throughout the codebase. Run the following script to verify:

✅ Verification successful

Verification Successful

All usages of SetPrivateProps and to_private have been successfully updated to SetAccessProps and access: num.BigNumberish respectively. No remaining references to the old interface name or property were found throughout the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining usage of old interface name and property

# Test 1: Search for old interface name
echo "Searching for old interface name 'SetPrivateProps':"
rg --type typescript "SetPrivateProps"

# Test 2: Search for old property name
echo "Searching for old property name 'to_private':"
rg --type typescript "to_private"

# Test 3: Search for usage of new interface name
echo "Searching for new interface name 'SetAccessProps':"
rg --type typescript "SetAccessProps"

# Test 4: Search for usage of new property name
echo "Searching for new property name 'access':"
rg --type typescript "access:\s*num\.BigNumberish"

Length of output: 745


Script:

#!/bin/bash
# Description: Check for any remaining usage of the old interface name and property in TypeScript files

# Test 1: Search for old interface name 'SetPrivateProps'
echo "Searching for old interface name 'SetPrivateProps' in .ts files:"
rg "SetPrivateProps" --glob "*.ts"

# Test 2: Search for old property name 'to_private'
echo "Searching for old property name 'to_private' in .ts files:"
rg "to_private" --glob "*.ts"

# Test 3: Search for new interface name 'SetAccessProps'"
echo "Searching for new interface name 'SetAccessProps' in .ts files:"
rg "SetAccessProps" --glob "*.ts"

# Test 4: Search for new property name 'access' with type 'num.BigNumberish'
echo "Searching for new property name 'access: num.BigNumberish' in .ts files:"
rg "access:\s*num\.BigNumberish" --glob "*.ts"

Length of output: 1109

contracts/src/models/hyperstructure.cairo (3)

3-16: Imports are appropriately structured

The updated import statements correctly include the necessary modules and constants, improving the organization and maintainability of the code.


37-38: Addition of access field to Hyperstructure struct

The new access: Access field enhances the Hyperstructure struct by introducing flexible access control mechanisms.


40-44: Enum Access is correctly defined

The Access enum with variants Public, Private, and GuildOnly is well-defined and will facilitate nuanced access control within Hyperstructure.

client/src/ui/utils/utils.tsx (5)

1-2: Imports are appropriate for new functionalities.

The addition of ClientComponents and ClientConfigManager imports is necessary for the new code changes.


13-13: Including 'TickIds' in imports is necessary.

The import of TickIds supports retrieving tick intervals from the configuration manager.


15-15: Importing 'ComponentValue' enhances type safety.

Adding ComponentValue improves type annotations for better code reliability.


292-293: Handling undefined tick intervals correctly.

Using configManager.getTick(TickIds.Armies) || 1 ensures a default value, preventing potential undefined behavior.


425-432: 'separateCamelCase' function is well-implemented.

The function effectively splits camelCase strings and capitalizes each word for improved readability.

contracts/src/systems/hyperstructure/contracts.cairo (5)

4-4: Addition of Access import is appropriate

The inclusion of hyperstructure::Access in the imports is necessary for the new access control logic implemented in the code.


26-26: Added set_access method to IHyperstructureSystems interface

The addition of fn set_access(...) to the IHyperstructureSystems trait allows for setting the access level of a hyperstructure. This is a valuable addition to manage access control at the interface level.


42-42: Included CapacityCategory import

Including capacity::{CapacityCategory} is necessary for handling capacity categories in the hyperstructure module.


143-143: Set default access level to Public during hyperstructure creation

Initializing the access field to Access::Public in the create function ensures that new hyperstructures are publicly accessible by default, which aligns with expected behavior.


181-181: Enforced access control in contribute_to_construction

Adding hyperstructure.assert_access(world); effectively enforces the new access control mechanism before allowing contributions, enhancing security and compliance with access levels.

@@ -88,7 +90,7 @@ export const HyperstructurePanel = ({ entity }: any) => {

const resourceElements = useMemo(() => {
if (progresses.percentage === 100) return;
return HYPERSTRUCTURE_TOTAL_COSTS_SCALED.map(({ resource }) => {
return Object.values(configManager.hyperstructureTotalCosts).map(({ resource }) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

LGTM: Improved configuration management for resource elements

The use of configManager.hyperstructureTotalCosts instead of hardcoded values enhances flexibility and maintainability. This change aligns well with the centralized configuration approach introduced earlier.

Consider memoizing the result of Object.values(configManager.hyperstructureTotalCosts) if it's not expected to change frequently, to avoid unnecessary recalculations:

const hyperstructureTotalCosts = useMemo(() => Object.values(configManager.hyperstructureTotalCosts), []);

// Then use hyperstructureTotalCosts in the map function
return hyperstructureTotalCosts.map(({ resource }) => {
  // ... rest of the code
});

This could potentially improve performance, especially if this component re-renders often.

<SelectContent className="bg-black/90 text-gold">
{Object.keys(Access)
.filter((access) => {
if (!isNaN(Number(access))) return false;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Replace isNaN with Number.isNaN for improved type safety

The use of isNaN can lead to unexpected results due to type coercion. It's recommended to use Number.isNaN instead for more predictable behavior.

Replace the current line with:

if (!Number.isNaN(Number(access))) return false;

This change will ensure that only actual NaN values are filtered out, improving the robustness of the access level filtering logic.

🧰 Tools
🪛 Biome

[error] 204-204: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

Comment on lines 545 to 550
knights_lower_bound: num.BigNumberish;
knights_upper_bound: num.BigNumberish;
paladins_lower_bound: num.BigNumberish;
paladins_upper_bound: num.BigNumberish;
crossbowmen_lower_bound: num.BigNumberish;
crossbowmen_upper_bound: num.BigNumberish;
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Troops type is still in use elsewhere in the codebase.

The Troops interface is still utilized in the following files:

  • sdk/packages/eternum/src/types/provider.ts
  • client/src/ui/components/hyperstructures/StructureCard.tsx

Please ensure that removing or modifying the Troops type does not negatively impact these areas.

🔗 Analysis chain

LGTM! Update documentation and verify Troops type usage.

The changes to SetMercenariesConfigProps provide more granular control over troop configurations by introducing separate lower and upper bounds for each troop type. This is a good improvement in terms of flexibility.

Please ensure the following:

  1. Update any documentation related to mercenary configuration to reflect these changes.
  2. Verify that the Troops type is still used elsewhere in the codebase, or remove it if it's no longer needed.

Run the following script to check the usage of the Troops type:

  1. Ensure that the implementation of mercenary configuration logic has been updated to use these new properties correctly.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for usage of Troops type

# Test 1: Search for Troops type definition
echo "Searching for Troops type definition:"
rg --type typescript "interface\s+Troops"

# Test 2: Search for Troops type usage
echo "Searching for Troops type usage:"
rg --type typescript ":\s*Troops"

Length of output: 309


Script:

#!/bin/bash
# Description: Check for usage of Troops type

# Test 1: Search for Troops type definition
echo "Searching for Troops type definition in .ts and .tsx files:"
rg "interface\s+Troops" --glob "*.ts" --glob "*.tsx"

# Test 2: Search for Troops type usage
echo "Searching for Troops type usage in .ts and .tsx files:"
rg ":\s*Troops" --glob "*.ts" --glob "*.tsx"

Length of output: 700

Comment on lines 273 to 285
fn set_access(ref world: IWorldDispatcher, hyperstructure_entity_id: ID, access: Access) {
let owner = get!(world, hyperstructure_entity_id, Owner);
owner.assert_caller_owner();

let mut hyperstructure = get!(world, hyperstructure_entity_id, Hyperstructure);
hyperstructure.private = private;
hyperstructure.access = access;

if (access == Access::GuildOnly) {
let caller_address = starknet::get_caller_address();
let caller_guild_member = get!(world, caller_address, GuildMember);
assert!(caller_guild_member.guild_entity_id != 0, "caller is not in a guild");
}

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Implemented set_access function with appropriate access control checks

The new set_access function correctly updates the hyperstructure's access level and enforces that only guild members can set the access to GuildOnly. This ensures proper validation and maintains the integrity of access control.

Potential runtime error if the caller is not a guild member

If the GuildMember component does not exist for the caller, the get! macro might fail, leading to a runtime error. To prevent this and provide a clearer error message, consider adding a check to verify the existence of the GuildMember component before accessing it.

Apply this diff to improve error handling:

 fn set_access(ref world: IWorldDispatcher, hyperstructure_entity_id: ID, access: Access) {
     let owner = get!(world, hyperstructure_entity_id, Owner);
     owner.assert_caller_owner();

     let mut hyperstructure = get!(world, hyperstructure_entity_id, Hyperstructure);
     hyperstructure.access = access;

     if (access == Access::GuildOnly) {
         let caller_address = starknet::get_caller_address();
+        assert!(world.has::<GuildMember>(caller_address), "caller is not a guild member");
         let caller_guild_member = get!(world, caller_address, GuildMember);
         assert!(caller_guild_member.guild_entity_id != 0, "caller is not in a guild");
     }

     set!(world, (hyperstructure,));
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fn set_access(ref world: IWorldDispatcher, hyperstructure_entity_id: ID, access: Access) {
let owner = get!(world, hyperstructure_entity_id, Owner);
owner.assert_caller_owner();
let mut hyperstructure = get!(world, hyperstructure_entity_id, Hyperstructure);
hyperstructure.private = private;
hyperstructure.access = access;
if (access == Access::GuildOnly) {
let caller_address = starknet::get_caller_address();
let caller_guild_member = get!(world, caller_address, GuildMember);
assert!(caller_guild_member.guild_entity_id != 0, "caller is not in a guild");
}
fn set_access(ref world: IWorldDispatcher, hyperstructure_entity_id: ID, access: Access) {
let owner = get!(world, hyperstructure_entity_id, Owner);
owner.assert_caller_owner();
let mut hyperstructure = get!(world, hyperstructure_entity_id, Hyperstructure);
hyperstructure.access = access;
if (access == Access::GuildOnly) {
let caller_address = starknet::get_caller_address();
assert!(world.has::<GuildMember>(caller_address), "caller is not a guild member");
let caller_guild_member = get!(world, caller_address, GuildMember);
assert!(caller_guild_member.guild_entity_id != 0, "caller is not in a guild");
}
set!(world, (hyperstructure,));
}

Copy link
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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 34a4a72 and e2c3420.

📒 Files selected for processing (1)
  • client/src/three/systems/SystemManager.ts (4 hunks)
🧰 Additional context used
🔇 Additional comments (7)
client/src/three/systems/SystemManager.ts (7)

2-2: LGTM: Import changes improve modularity and precision handling

The changes to the imports are well-considered:

  1. Using configManager centralizes configuration management.
  2. Adding divideByPrecision suggests improved precision in calculations.
  3. Explicit imports of Has and HasValue enhance code clarity.

These modifications should lead to better maintainability and accuracy in the codebase.

Also applies to: 5-6, 13-14


171-171: Ensure consistent number types in Battle getter

This change is consistent with the earlier modification in the Army getter. However, the same potential issue with type mismatch exists here.

Please refer to the previous comment on line 78 regarding the use of BigInt and potential type mismatches in arithmetic operations. The same considerations apply here.


278-303: Improved precision and dynamic configuration in progress calculations

The refactoring of getAllProgressesAndTotalPercentage method brings several improvements:

  1. Using configManager for totalContributableAmount and hyperstructureTotalCosts enhances flexibility.
  2. The introduction of epsilon addresses floating-point precision issues effectively.
  3. The refactored calculation of allProgresses is more concise and easier to understand.

These changes should lead to more accurate and maintainable code.


285-293: LGTM: Improved precision in progress calculations

The creation of the progress object with its various properties provides a clear and structured representation of each progress item. The use of divideByPrecision for calculating amount and percentage enhances the accuracy of these calculations.

These changes contribute to more precise and reliable progress tracking in the system.


294-297: LGTM: Enhanced percentage calculation with resource rarity

The incorporation of configManager.getResourceRarity in the percentage calculation is a valuable improvement. This change:

  1. Provides a more nuanced and potentially more accurate representation of progress by considering resource rarity.
  2. Aligns with the codebase's shift towards centralized configuration management.

This enhancement should lead to more meaningful progress tracking in the system.


299-302: LGTM: Improved handling of floating-point precision for percentages

The addition of this check to adjust the percentage to exactly 1.0 when it's very close to it is a good practice. This change:

  1. Addresses potential floating-point precision issues that could occur when the percentage is near 100%.
  2. Uses the epsilon value appropriately to ensure only truly close values are adjusted.

This improvement enhances the accuracy and reliability of the percentage calculations in the system.


284-284: ⚠️ Potential issue

Potential runtime error due to unsafe non-null assertion

In the find method, there's a non-null assertion on progress within the callback: progress!.resource_type. Since progresses is an array of ComponentValue | undefined, progress could be undefined. Accessing progress!.resource_type when progress is undefined will cause a runtime error.

Apply this diff to fix the issue:

-let foundProgress = progresses.find((progress) => progress!.resource_type === resource);
+let foundProgress = progresses.find((progress) => progress && progress.resource_type === resource);

This ensures that progress is not undefined before accessing its properties.

Likely invalid or redundant comment.

@@ -81,7 +75,7 @@ export class SystemManager {
const protectee = getComponentValue(this.setup.components.Protectee, update.entity);
if (protectee) return;

const healthMultiplier = BigInt(EternumGlobalConfig.resources.resourcePrecision);
const healthMultiplier = BigInt(configManager.getResourcePrecision());
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure consistent number types in arithmetic operations

The change to use configManager.getResourcePrecision() is good for centralized configuration. However, be cautious about potential type mismatches in subsequent operations.

When performing arithmetic operations or comparisons with health.current, ensure that both operands are of the same type (Number or BigInt). Mixing BigInt and Number types without explicit conversion can lead to TypeError.

Consider converting healthMultiplier to Number for consistency:

-const healthMultiplier = BigInt(configManager.getResourcePrecision());
+const healthMultiplier = Number(configManager.getResourcePrecision());

Adjust any related calculations accordingly, ensuring type consistency throughout.

Committable suggestion was skipped due to low confidence.

Copy link
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: 52

🧹 Outside diff range and nitpick comments (70)
contracts/src/systems/dev/contracts.cairo (1)

1-3: New realm module added: Consider architectural implications

The addition of the realm module alongside existing bank and resource modules suggests an expansion of the system's functionality. This change appears to be consistent with the existing structure and naming conventions.

However, it's important to consider the following:

  1. Ensure that the realm module's functionality aligns with the overall system architecture and design principles.
  2. Verify that any necessary imports or dependencies for the realm module are properly handled in other parts of the codebase.
  3. Update relevant documentation to reflect the addition of this new module and its purpose within the system.

Consider documenting the purpose and responsibilities of the realm module in a comment above the module declaration or in a separate documentation file to maintain clear architectural boundaries and facilitate easier onboarding for other developers.

season_pass/contracts/src/lib.cairo (3)

1-1: Consider adding documentation for the contract module.

The contract module is likely the main implementation of the season pass functionality. To improve code readability and maintainability, consider adding a brief documentation comment explaining the purpose and main components of this module.

Example:

/// Main implementation of the Season Pass contract.
/// This module contains the core logic for managing season passes,
/// including creation, validation, and redemption of passes.
pub mod contract;

2-8: Well-structured mock module. Consider adding documentation.

The mock module structure is well-organized, with separate sub-modules for lords and realms. This separation will be helpful for isolating different mock implementations. To further improve clarity, consider adding brief documentation comments for each sub-module.

Example:

pub mod mock {
    /// Mock implementation of the LORDS token contract.
    mod lords;
    mod realms {
        /// Mock implementation of realm metadata.
        mod metadata;
        /// Mock implementation of the Realms contract.
        mod realms;
    }
}

9-11: Consider expanding test coverage.

The presence of a dedicated tests module with a test_season_pass sub-module is a good practice. To ensure comprehensive test coverage, consider adding additional test modules for different components or scenarios of the season pass system.

Example:

pub mod tests {
    mod test_season_pass;
    // Consider adding more test modules:
    // mod test_pass_creation;
    // mod test_pass_validation;
    // mod test_pass_redemption;
}
season_pass/contracts/Scarb.toml (1)

8-10: LGTM: Dependencies are well-defined. Consider using tags for all dependencies.

The dependencies are correctly specified with Git sources and specific versions. Using a commit hash for alexandria_math ensures exact reproducibility, while the tag for openzeppelin provides version stability with easier updates.

Consider using a tag instead of a commit hash for alexandria_math if available, as it would make future updates easier while still maintaining version stability.

.github/workflows/test-season-pass.yml (2)

1-13: LGTM with a minor suggestion.

The workflow name and trigger conditions are well-defined. The path exclusions are appropriate for avoiding unnecessary runs.

Consider removing the .github/** path from the exclusion list to ensure this workflow runs when it's modified:

 on:
   pull_request:
     paths-ignore:
       - "contracts/**"
       - "client/**"
       - "**/manifest.json"
       - "discord-bot/**"
       - "config/**"
-      - ".github/**"
       - "pnpm-lock.yaml"

28-31: LGTM with suggestions for improved error handling and logging.

The build and test steps are correctly defined and use the appropriate tools.

Consider adding error handling and improved logging:

 - run: scarb build
   working-directory: season_pass/contracts
+  continue-on-error: false
+  id: build
 - run: snforge test
   working-directory: season_pass/contracts
+  continue-on-error: false
+  id: test
+- name: Check for failures
+  if: failure()
+  run: |
+    echo "Build step status: ${{ steps.build.outcome }}"
+    echo "Test step status: ${{ steps.test.outcome }}"
+    exit 1

This will provide more detailed information in case of failures and ensure the workflow stops if either step fails.

contracts/src/models/quantity.cairo (1)

29-29: LGTM! Consider adding a brief comment for clarity.

The addition of REALM_COUNT constant is consistent with the existing pattern and likely supports new functionality for tracking realm quantities.

Consider adding a brief comment above the QuantityTrackerType module to explain its purpose, such as:

// Constants for different types of quantity trackers
mod QuantityTrackerType {
    // ... existing code ...
}

This would improve code readability and maintainability.

client/src/ui/utils/packedData.tsx (1)

Line range hint 15-39: Good updates to the packResources function!

The changes in this function maintain consistency with the unpackResources function and improve overall code clarity:

  1. Renaming MAX_NUMBER_SIZE to MAX_BITS_PER_VALUE is consistent and improves readability.
  2. Updating the maxValues calculation and error messages to use the new constant name maintains consistency.
  3. Updating the bitwise operations ensures the function still works as intended.

These changes are well-implemented and maintain the function's logic while improving its clarity.

For even better consistency, consider updating the error message on line 24 to use maxValues instead of recalculating it:

- throw new Error(`Exceeded maximum number of values that can be packed: ${maxValues}`);
+ throw new Error(`Exceeded maximum number of values that can be packed: ${maxValues}`);

This small change would make the error message consistent with the calculated maxValues variable.

config/index.ts (3)

56-61: Good addition of season configuration, consider error handling

The addition of the season property to setupConfig is a good enhancement. However, there are a few points to consider:

  1. Error handling: Add checks for the existence of the environment variables to prevent potential runtime errors.
  2. Refactoring: The comment suggests awareness of potential improvements. Consider creating a separate function or module for season configuration to improve code organization.

Here's a suggested improvement:

function getSeasonConfig() {
  const requiredEnvVars = ['VITE_SEASON_PASS_ADDRESS', 'VITE_REALMS_ADDRESS', 'VITE_LORDS_ADDRESS'];
  const missingVars = requiredEnvVars.filter(varName => !process.env[varName]);
  
  if (missingVars.length > 0) {
    throw new Error(`Missing required environment variables: ${missingVars.join(', ')}`);
  }

  return {
    seasonPassAddress: process.env.VITE_SEASON_PASS_ADDRESS!,
    realmsAddress: process.env.VITE_REALMS_ADDRESS!,
    lordsAddress: process.env.VITE_LORDS_ADDRESS!,
  };
}

// Usage
setupConfig.season = getSeasonConfig();

This approach centralizes the season configuration logic, adds error handling, and improves maintainability.


69-69: Consider a more robust approach for bank setup timing

The increase in delay from 15 to 20 seconds before setting up the bank has been noted. While this may solve immediate timing issues, it's worth considering more robust alternatives:

  1. Event-based readiness: Implement a system where previous operations emit events upon completion, triggering the bank setup.
  2. Polling with timeout: Periodically check if the system is ready for bank setup, with a maximum timeout.
  3. Async/await pattern: If possible, refactor the setup process to use async/await, ensuring operations complete before moving to the next step.

Here's a conceptual example of a polling approach:

async function waitForReadiness(maxAttempts = 20, interval = 1000) {
  for (let i = 0; i < maxAttempts; i++) {
    if (await checkIfReadyForBankSetup()) {
      console.log("System ready for bank setup");
      return true;
    }
    await new Promise(resolve => setTimeout(resolve, interval));
  }
  throw new Error("Timeout waiting for system to be ready for bank setup");
}

// Usage
await waitForReadiness();
console.log("Setting up bank...");
await config.setupBank(account, provider);

This approach provides more flexibility and reliability compared to a fixed delay.


Line range hint 1-69: Consider modularizing the configuration setup

The changes to this file have enhanced its capabilities, but they've also increased its complexity. To improve maintainability and readability, consider the following suggestions:

  1. Modularization: Split the configuration into separate modules (e.g., devConfig.ts, prodConfig.ts, seasonConfig.ts).
  2. Configuration factory: Implement a factory pattern to create the appropriate configuration based on the environment.
  3. Type safety: Enhance type safety by defining interfaces for different parts of the configuration.

Here's a conceptual example of how this could be structured:

// devConfig.ts
export const getDevConfig = (): Partial<Config> => ({
  // Dev-specific configuration
});

// prodConfig.ts
export const getProdConfig = (): Partial<Config> => ({
  // Production-specific configuration
});

// seasonConfig.ts
export const getSeasonConfig = (): SeasonConfig => ({
  // Season-specific configuration
});

// configFactory.ts
export const createConfig = (env: 'dev' | 'prod'): Config => {
  const baseConfig = env === 'dev' ? getDevConfig() : getProdConfig();
  return {
    ...baseConfig,
    season: getSeasonConfig(),
    // Other common configuration
  };
};

// index.ts
const config = createConfig(VITE_PUBLIC_DEV === "true" ? 'dev' : 'prod');

This structure would make the configuration more modular, easier to maintain, and less prone to errors.

contracts/src/models/hyperstructure.cairo (2)

32-36: Well-defined Access enum with room for improvement.

The introduction of the Access enum with Public, Private, and GuildOnly variants is a great addition. It provides clear and distinct access levels, improving the overall design of the access control system.

Consider adding documentation comments to each variant to clarify their intended use cases. For example:

/// Defines the access level for a Hyperstructure
pub enum Access {
    /// Accessible by anyone
    Public,
    /// Accessible only by the owner
    Private,
    /// Accessible by members of the same guild as the owner
    GuildOnly,
}

81-97: Solid implementation of access control logic.

The assert_access method in HyperstructureCustomImpl provides a robust implementation of the new access control system. It correctly handles different access levels and integrates well with other parts of the system.

Consider optimizing the GuildOnly case to reduce potential code duplication:

Access::GuildOnly => {
    let contributor_guild = get!(world, contributor_address, GuildMember).guild_entity_id;
    let owner_guild = get!(world, hyperstructure_owner.address, GuildMember).guild_entity_id;
    assert!(contributor_guild == owner_guild, "not in the same guild");
}

This change reduces the number of get! calls and makes the comparison more straightforward.

contracts/scripts/contracts.sh (1)

27-27: LGTM! Consider addressing the shellcheck warning.

The addition of the RESOURCE_BRIDGE_SYSTEMS export is consistent with the existing pattern in the script. However, there's a minor shellcheck warning (SC2155) about potential masking of return values when declaring and assigning in the same statement.

While this is a common pattern and doesn't pose a significant risk here, you might consider splitting the declaration and assignment for improved robustness:

export RESOURCE_BRIDGE_SYSTEMS
RESOURCE_BRIDGE_SYSTEMS=$(get_contract_address "eternum-resource_bridge_systems")
🧰 Tools
🪛 Shellcheck

[warning] 27-27: Declare and assign separately to avoid masking return values.

(SC2155)

client/src/dojo/modelManager/__tests__/__BattleManagerMock__.ts (1)

Line range hint 1-164: Summary of changes and potential impact

This file has undergone significant changes that appear to be part of a larger refactoring effort:

  1. The realm object in generateMockArmyInfo has been simplified, potentially affecting how realm resources are represented throughout the application.
  2. A new generateMockTroopConfig function has been added, standardizing troop configurations for tests.

These changes, while improving code organization and potentially simplifying the data model, may have wider implications:

  • Other parts of the codebase that depend on the detailed realm structure may need to be updated.
  • The new troop configuration function might need to be integrated into existing tests and may require additional flexibility for comprehensive test coverage.

Consider the following to ensure smooth integration of these changes:

  1. Review and update all components and tests that interact with the realm object to ensure compatibility with the new structure.
  2. Evaluate if the simplification of the realm object aligns with the overall architecture and design goals of the application.
  3. Create or update documentation to reflect these changes, especially regarding the new troop configuration standards.
  4. Consider creating a migration guide if these changes are part of a larger refactoring effort that affects multiple parts of the codebase.
contracts/src/systems/combat/tests/army_buy_test.cairo (1)

Line range hint 71-82: Approved: Simplified realm creation in setup.

The updated setup function now uses spawn_realm to create a realm directly, which simplifies the process and improves readability. The use of get_default_realm_pos() ensures consistent realm positioning across tests.

Consider adding a brief comment explaining the significance of the 1 parameter in the spawn_realm call for better clarity:

// Spawn a realm with ID 1 at the default position
let realm_id = spawn_realm(world, 1, get_default_realm_pos().into());
contracts/src/systems/bank/contracts/liquidity.cairo (1)

100-100: LGTM: Consistent change in season implementation. Consider refactoring.

The change from SeasonCustomImpl to SeasonImpl for the assert_season_is_not_over method is consistent with the import modification and the change in the add method. The functionality remains the same, ensuring that liquidity can only be removed when the season is active.

Consider refactoring the repeated SeasonImpl::assert_season_is_not_over(world); call into a private method within the LiquiditySystemsImpl to reduce code duplication. This would make future changes easier and reduce the risk of inconsistencies. For example:

fn assert_season_active(ref world: IWorldDispatcher) {
    SeasonImpl::assert_season_is_not_over(world);
}

Then use this method in both add and remove:

self.assert_season_active(ref world);

This refactoring would make the code more DRY (Don't Repeat Yourself) and easier to maintain.

contracts/scripts/system_models.json (2)

39-55: Approve addition of DEV_REALM_SYSTEMS array

The introduction of the DEV_REALM_SYSTEMS array with its comprehensive list of realm-related systems is a significant addition that aligns with the enhanced resource management capabilities mentioned in the summary.

Consider adding a comment or documentation explaining the purpose and usage of these development-specific realm systems. This will help other developers understand when and how to use these systems in the development environment.


125-140: Approve addition of RESOURCE_BRIDGE_SYSTEMS array and request documentation

The introduction of the RESOURCE_BRIDGE_SYSTEMS array is a significant addition that appears to be related to, but distinct from, the existing RESOURCE_SYSTEMS.

To improve clarity and maintainability:

  1. Consider adding a comment or documentation explaining the purpose and functionality of the RESOURCE_BRIDGE_SYSTEMS.
  2. Clarify how this new system interacts with or differs from the existing RESOURCE_SYSTEMS.
    This additional context will help other developers understand the role of this new subsystem in the overall architecture.
contracts/src/systems/bank/contracts/bank.cairo (1)

Line range hint 1-168: Summary: Consistent replacement of SeasonCustomImpl with SeasonImpl

The main change in this file is the replacement of SeasonCustomImpl with SeasonImpl for season-related functionality. This change is applied consistently across the file, affecting the import statement and the assert_season_is_not_over calls in the create_bank and change_owner_amm_fee methods.

While the overall structure and functionality of the bank systems remain intact, it's crucial to verify that:

  1. SeasonImpl provides all the necessary methods that were previously available in SeasonCustomImpl.
  2. The behavior of assert_season_is_not_over remains consistent with the previous implementation.
  3. This change has been applied consistently across the entire codebase.

The verification scripts provided in the previous comments will help ensure these points. Additionally, consider updating the documentation to reflect this change in season management implementation.

contracts/src/systems/combat/tests/battle_pillage_test.cairo (2)

56-56: LGTM! Consider using a constant for the realm ID.

The simplification of the spawn_realm function call improves clarity by directly using a realm ID and Coord struct. This change aligns well with the removal of entity_id from the parameters.

For consistency and maintainability, consider defining a constant for the attacker's realm ID, similar to how you've defined other constants in this file. For example:

const ATTACKER_REALM_ID: u32 = 1;

Then use it in the function call:

let attacker_realm_entity_id = spawn_realm(world, ATTACKER_REALM_ID, Coord { x: 1, y: 1 });

72-73: LGTM! Consider improvements for consistency and clarity.

The modification to the spawn_realm function call for the defender's realm is consistent with the changes made for the attacker's realm, improving overall clarity and simplicity.

To enhance consistency and clarity:

  1. Define a constant for the defender's realm ID:

    const DEFENDER_REALM_ID: u32 = 2;
  2. Consider creating a Coord constant for the defender's realm position:

    const DEFENDER_REALM_COORD: Coord = Coord { x: DEFENDER_REALM_COORD_X, y: DEFENDER_REALM_COORD_Y };
  3. Update the function call:

    let defender_realm_entity_id = spawn_realm(world, DEFENDER_REALM_ID, DEFENDER_REALM_COORD);

These changes will improve code readability and maintain consistency with the existing coding style in this file.

contracts/src/systems/bank/contracts/swap.cairo (1)

Line range hint 1-185: Overall LGTM. Suggest thorough testing of season-related functionality.

The changes in this file are minimal and consistent, focusing on the transition from SeasonCustomImpl to SeasonImpl. This appears to be part of a larger refactoring effort to standardize season-related functionality. The compatibility of the new SeasonImpl with the existing code is a positive sign.

To ensure the refactoring hasn't introduced any unintended changes:

  1. Verify that all tests related to season functionality still pass.
  2. Consider adding new tests specifically for the assert_season_is_not_over functionality if they don't already exist.
  3. Perform integration testing to ensure that the swap system still interacts correctly with the season system in various scenarios.
contracts/src/systems/combat/tests/army_create_test.cairo (1)

63-63: LGTM: Simplified realm creation in setup.

The replacement of deploy_realm_systems(world) with spawn_realm(world, 1, get_default_realm_pos().into()) streamlines the realm creation process. This change enhances clarity and potentially improves efficiency in the test setup.

Consider adding a brief comment explaining the significance of the 1 parameter in the spawn_realm function call for better readability:

// Create a realm with ID 1 at the default position
let realm_id = spawn_realm(world, 1, get_default_realm_pos().into());
contracts/src/constants.cairo (2)

121-161: resource_type_name function updated to match new resource types.

The resource_type_name function has been successfully updated to reflect the changes in the ResourceTypes module. The order and values of the conditions now correctly correspond to the new resource type definitions.

While the current implementation is correct, consider refactoring this function to use a match statement or a constant array for better performance and maintainability, especially as the number of resource types grows.

Here's a suggested refactoring using a match statement:

fn resource_type_name(resource_type: u8) -> ByteArray {
    match resource_type {
        1 => "STONE",
        2 => "COAL",
        3 => "WOOD",
        4 => "COPPER",
        5 => "IRONWOOD",
        6 => "OBSIDIAN",
        7 => "GOLD",
        8 => "SILVER",
        9 => "MITHRAL",
        10 => "ALCHEMICAL SILVER",
        11 => "COLD IRON",
        12 => "DEEP CRYSTAL",
        13 => "RUBY",
        14 => "DIAMONDS",
        15 => "HARTWOOD",
        16 => "IGNIUM",
        17 => "TWILIGHT QUARTZ",
        18 => "TRUE ICE",
        19 => "ADAMANTINE",
        20 => "SAPPHIRE",
        21 => "ETHEREAL SILICA",
        22 => "DRAGONHIDE",
        28 => "DEMONHIDE",
        29 => "EARTHEN SHARD",
        249 => "DONKEY",
        250 => "KNIGHT",
        251 => "CROSSBOWMAN",
        252 => "PALADIN",
        253 => "LORDS",
        254 => "WHEAT",
        255 => "FISH",
        _ => format!("{} (unknown resource name)", resource_type),
    }
}

This refactoring improves readability and makes it easier to add or modify resource types in the future.


Line range hint 31-63: Update all_resource_ids() function to reflect new resource type order.

The all_resource_ids() function has not been updated to reflect the new order and values of resource types. This inconsistency could lead to bugs or unexpected behavior in parts of the codebase that rely on this function.

Please update the all_resource_ids() function to match the new resource type order and values. Here's a suggested update:

fn all_resource_ids() -> Array<u8> {
    array![
        1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
        11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
        21, 22,
        28, 29,
        249, 250, 251, 252, 253, 254, 255
    ]
}

Also, consider adding a comment to explain the significance of each number or group of numbers for better maintainability.

contracts/src/systems/realm/tests.cairo (5)

70-77: LGTM with a minor suggestion.

The changes look good. Replacing realm_systems_dispatcher with _realm_systems_dispatcher correctly indicates that this variable is unused in the function. However, consider using a constant for the hardcoded realm ID (1) to improve maintainability and clarity.

Consider defining a constant for the realm ID:

const TEST_REALM_ID: u64 = 1;

Then use it in the spawn_realm call:

let realm_entity_id = spawn_realm(world, TEST_REALM_ID, get_default_realm_pos().into());

This approach would make it easier to change the ID if needed in the future and improve the test's readability.


103-103: LGTM with a suggestion for consistency.

The change to hardcode the realm ID to 1 is consistent with the previous function. The rest of the function's logic remains intact, which is good.

For consistency with the previous suggestion, consider using the same constant for the realm ID:

let realm_entity_id = spawn_realm(world, TEST_REALM_ID, get_default_realm_pos().into());

This would maintain consistency across all test functions and improve maintainability.


123-123: LGTM with a reminder for consistency.

The change to hardcode the realm ID to 1 is consistent with the previous functions. The test's logic for checking the double-minting scenario remains intact.

As suggested earlier, consider using the TEST_REALM_ID constant here as well:

let realm_entity_id = spawn_realm(world, TEST_REALM_ID, get_default_realm_pos().into());

This would ensure consistency across all test functions and improve maintainability.


141-141: LGTM with a final reminder for consistency.

The change to hardcode the realm ID to 1 is consistent with the previous functions. The test's logic for checking the minting scenario with a non-realm entity remains intact.

This is the last reminder to use the TEST_REALM_ID constant for consistency:

let realm_entity_id = spawn_realm(world, TEST_REALM_ID, get_default_realm_pos().into());

Implementing this change across all test functions will ensure consistency and improve maintainability.


Line range hint 1-291: Overall changes look good with a suggestion for improvement.

The modifications in this file are consistent and do not alter the core logic of the tests. The changes include:

  1. Replacing realm_systems_dispatcher with _realm_systems_dispatcher in function signatures, correctly indicating that this parameter is unused.
  2. Hardcoding the realm ID to 1 in all spawn_realm calls.

These changes maintain the existing test coverage and scenarios. However, to improve maintainability and clarity, consider implementing the following suggestion:

Define a constant for the realm ID at the beginning of the file:

const TEST_REALM_ID: u64 = 1;

Then use this constant in all spawn_realm calls throughout the file. This approach would make it easier to change the ID if needed in the future and improve the tests' readability.

contracts/src/systems/combat/tests/battle_start_test.cairo (2)

111-111: LGTM: Simplified realm creation

The use of spawn_realm() simplifies the realm creation process and makes the coordinate specification more explicit. This change improves code readability and consistency.

Consider adding documentation for the spawn_realm function in its implementation file if it doesn't already exist, explaining any additional features or flexibility it provides compared to the previous method.


137-137: LGTM: Consistent realm creation improvements

The changes to realm creation for Players 2 and 3 are consistent with the improvements made for Player 1. The explicit coordinate definitions enhance code clarity and make it easier to understand the spatial relationships between realms.

Consider defining the coordinates as constants at the top of the file, similar to how other constants are defined (e.g., PLAYER_1_REALM_COORD_X, PLAYER_1_REALM_COORD_Y). This would make it easier to modify realm positions across the entire test suite if needed. For example:

const PLAYER_1_REALM_COORD: Coord = Coord { x: 1, y: 1 };
const PLAYER_2_REALM_COORD: Coord = Coord { x: 2, y: 2 };
const PLAYER_3_REALM_COORD: Coord = Coord { x: 4, y: 4 };

// Then in the setup function:
let player_1_realm_id = spawn_realm(world, 1, PLAYER_1_REALM_COORD);
let player_2_realm_id = spawn_realm(world, 2, PLAYER_2_REALM_COORD);
let player_3_realm_id = spawn_realm(world, 3, PLAYER_3_REALM_COORD);

This approach would centralize the coordinate definitions and make future updates easier.

Also applies to: 163-163

sdk/packages/eternum/src/constants/global.ts (4)

99-104: LGTM: Mercenaries bounds added for flexibility

The addition of lower and upper bounds for knights, paladins, and crossbowmen (1,000 to 10,000 each) provides more flexibility in mercenary recruitment compared to the previous fixed counts.

Consider using uppercase for these constant names to maintain consistency with other constants in the file:

export const MERCENARIES_KNIGHTS_LOWER_BOUND = 1_000;
export const MERCENARIES_KNIGHTS_UPPER_BOUND = 10_000;
// ... (apply to all mercenary constants)

118-133: LGTM: Season and bridge fee constants added

The addition of constants for season pass, realms, lords addresses, and various bridge fees is a good step towards implementing a new season system and a more complex fee structure. The fee structure is well-defined with different types of fees for deposits and withdrawals.

Note:

  • The placeholder addresses ("0x0") for SEASON_PASS_ADDRESS, REALMS_ADDRESS, and LORDS_ADDRESS are set to be updated in the indexer.sh script.
  • Consider adding comments to explain the purpose of each fee type for better clarity.

Example:

// Fee collected for veLORDS stakers
export const VELORDS_FEE_ON_DEPOSIT = 500; // 5%
// Fee collected for the current season's reward pool
export const SEASON_POOL_FEE_ON_DEPOSIT = 250; // 2.5%
// ... (add similar comments for other fees)

150-150: LGTM with suggestions: EternumGlobalConfig updated

The EternumGlobalConfig object has been successfully updated to include the new constants for resource rarity, mercenaries bounds, season, and bridge configurations. However, there are some inconsistencies in naming conventions:

  1. The mercenaries configuration uses snake_case, which is inconsistent with the camelCase used elsewhere in the object. Consider updating to camelCase:
mercenaries: {
  knightsLowerBound: MERCENARIES_KNIGHTS_LOWER_BOUND,
  knightsUpperBound: MERCENARIES_KNIGHTS_UPPER_BOUND,
  paladinsLowerBound: MERCENARIES_PALADINS_LOWER_BOUND,
  paladinsUpperBound: MERCENARIES_PALADINS_UPPER_BOUND,
  crossbowmenLowerBound: MERCENARIES_CROSSBOWMEN_LOWER_BOUND,
  crossbowmenUpperBound: MERCENARIES_CROSSBOWMEN_UPPER_BOUND,
  // ... (rest of the mercenaries config)
},
  1. In the bridge configuration, consider using full words instead of abbreviations for better readability:
bridge: {
  velordsFeeOnDepositPercent: VELORDS_FEE_ON_DEPOSIT,
  velordsFeeOnWithdrawalPercent: VELORDS_FEE_ON_WITHDRAWAL,
  seasonPoolFeeOnDepositPercent: SEASON_POOL_FEE_ON_DEPOSIT,
  seasonPoolFeeOnWithdrawalPercent: SEASON_POOL_FEE_ON_WITHDRAWAL,
  clientFeeOnDepositPercent: CLIENT_FEE_ON_DEPOSIT,
  clientFeeOnWithdrawalPercent: CLIENT_FEE_ON_WITHDRAWAL,
  velordsFeeRecipient: BigInt(VELORDS_FEE_RECIPIENT),
  seasonPoolFeeRecipient: BigInt(SEASON_POOL_FEE_RECIPIENT),
  maxBankFeeOnDepositPercent: MAX_BANK_FEE_ON_DEPOSIT,
  maxBankFeeOnWithdrawalPercent: MAX_BANK_FEE_ON_WITHDRAWAL,
},

These changes will improve consistency and readability throughout the configuration object.

Also applies to: 210-215, 247-263


Line range hint 1-266: Overall assessment: Good additions with minor improvements needed

The changes to this file enhance the game's mechanics by:

  1. Providing more flexibility in mercenary recruitment through the use of lower and upper bounds.
  2. Implementing a new season system with associated addresses.
  3. Introducing a more complex bridge fee structure.

These additions are well-structured and provide valuable configuration options for the game. However, there are some minor inconsistencies in naming conventions that should be addressed:

  1. Use uppercase for constant names (e.g., MERCENARIES_KNIGHTS_LOWER_BOUND).
  2. Use camelCase consistently in the EternumGlobalConfig object, especially in the mercenaries and bridge sections.
  3. Consider using full words instead of abbreviations in the bridge configuration for better readability.

Addressing these minor issues will improve code consistency and maintainability. Overall, the changes are a positive addition to the game's configuration.

discord-bot/src/events.rs (2)

284-284: LGTM! Consider updating to_discord_message to utilize the new field.

The change from resource_types_packed and resource_types_count to a single produced_resources field simplifies the struct and potentially improves efficiency. However, the to_discord_message implementation doesn't currently use this information.

Consider updating the to_discord_message implementation to include information about the produced resources in the Discord message. This would provide more valuable information to users. For example:

let resources = decode_resources(self.produced_resources);
embed = embed.field("Produced Resources", format!("{:?}", resources), false);

You'll need to implement a decode_resources function to extract the resource information from the packed u128 value.


Line range hint 301-337: Enhance to_discord_message implementation with additional realm details.

The current implementation of to_discord_message for SettleRealm doesn't utilize many of the struct's fields, including the new produced_resources field. Consider enhancing the Discord message with more details about the settled realm to provide users with richer information.

Here's a suggested improvement to the to_discord_message implementation:

impl ToDiscordMessage for SettleRealm {
    fn to_discord_message(&self, msg_type: DiscordMessageType) -> DiscordMessage {
        let footer = CreateEmbedFooter::new(ETERNUM_URL);
        let normalized_position = self.position.get_normalized();
        let embed = CreateEmbed::new()
            .title(format!(
                "{} has settled realm '{}' at ({}, {})",
                self.owner_name, self.realm_name, normalized_position.0, normalized_position.1
            ))
            .description(format!(
                "Cities: {}\nHarbors: {}\nRivers: {}\nRegions: {}\nWonder: {}\nOrder: {}",
                self.cities, self.harbors, self.rivers, self.regions, self.wonder, self.order
            ))
            .field("Produced Resources", format!("{:#x}", self.produced_resources), false)
            .footer(footer)
            .color(poise::serenity_prelude::Color::BLURPLE)
            .timestamp(Timestamp::now());

        // Rest of the implementation remains the same
        // ...
    }
}

This enhancement provides more detailed information about the settled realm, including its name, geographical features, and produced resources (in hexadecimal format). You may want to implement a function to decode produced_resources into a more human-readable format if needed.

contracts/src/systems/map/tests.cairo (1)

210-210: Clarify the implications of the spawn_realm function call change.

The spawn_realm function call has been modified to use a hardcoded value of 1 instead of realm_systems_dispatcher, and realm_position is now converted using .into(). While this simplifies the function call, it raises a few points:

  1. What does the hardcoded value of 1 represent? Is it a default or specific realm ID?
  2. How does this change affect the initialization of realms in the tests?
  3. Does the removal of realm_systems_dispatcher impact any other parts of the test suite?

Consider adding a comment explaining the reason for this change and its implications. Also, verify that this modification doesn't unintentionally affect other test cases that might rely on specific realm configurations.

contracts/src/systems/combat/tests/battle_leave_test.cairo (3)

112-112: LGTM: Simplified realm creation for player 1.

The use of spawn_realm simplifies the realm creation process and aligns with the new imports. This change improves code consistency and readability.

Consider extracting the coordinate values into constants at the top of the file for better maintainability, especially if these values are used elsewhere in the tests.


139-139: LGTM: Consistent realm creation for players 2 and 3.

The changes for players 2 and 3 are consistent with the modification made for player 1, improving overall code consistency and readability.

For better consistency and maintainability:

  1. Consider extracting the coordinate values into constants at the top of the file.
  2. You might want to create a helper function that takes a player number and returns the appropriate coordinates. This would centralize the logic for assigning coordinates to players and make it easier to modify in the future if needed.

Example:

fn get_player_coordinates(player_number: u8) -> Coord {
    match player_number {
        1 => Coord { x: 1, y: 1 },
        2 => Coord { x: 2, y: 2 },
        3 => Coord { x: 4, y: 4 },
        _ => panic_with_felt252('Invalid player number')
    }
}

// Usage in setup():
let player_1_realm_id = spawn_realm(world, 1, get_player_coordinates(1));
let player_2_realm_id = spawn_realm(world, 2, get_player_coordinates(2));
let player_3_realm_id = spawn_realm(world, 3, get_player_coordinates(3));

Also applies to: 166-166


Line range hint 1-324: Overall assessment: Improved test setup with consistent realm creation.

The changes in this file focus on simplifying and standardizing the realm creation process in the test setup. The use of spawn_realm function across all player realm creations improves code consistency and readability. The core test logic remains unchanged, which maintains the integrity of the test cases.

These modifications should make the tests easier to maintain and understand, particularly for developers working on the realm creation aspects of the system.

Consider the following to further improve the test structure:

  1. Implement the suggested helper function for player coordinates to centralize coordinate assignment logic.
  2. If spawn_realm is a commonly used function in tests, consider creating a dedicated test utility file for realm-related setup functions. This would promote reusability across different test files.
sdk/packages/eternum/src/types/provider.ts (1)

500-511: LGTM: New interface for resource bridge fee configuration.

The SetResourceBridgeFeesConfigProps interface is well-structured and provides a comprehensive way to configure various fees for the resource bridge.

Consider adding comments to explain the purpose of each fee and recipient, especially for terms like "velords" and "season pool". This would enhance the clarity and maintainability of the code.

discord-bot/src/types.rs (2)

393-402: LGTM! Consider adding comments for clarity.

The changes to the parse_settle_realm function align well with the modifications to the SettleRealm struct. The new fields provide more detailed information about the realm, which is a good improvement.

Consider adding comments to explain the meaning of each new field, especially for less self-explanatory ones like order. This would improve code readability and maintainability.


Line range hint 410-419: LGTM! Consider adding documentation for new fields.

The modifications to the SettleRealm struct provide more detailed information about the realm, which is a good improvement. The new fields (produced_resources, cities, harbors, rivers, regions, wonder, order) offer a richer representation of the realm's attributes.

Consider adding documentation comments for each new field in the SettleRealm struct to explain their purpose and any constraints (e.g., valid ranges for numeric fields). This would improve code clarity and help other developers understand the struct's usage.

contracts/src/models/config.cairo (1)

405-410: LGTM: MercenariesConfig changes improve granularity, consider refactoring

The changes to MercenariesConfig provide more granular control over troop limits for each type, which is good. However, consider encapsulating these bounds into a nested structure for better organization:

 pub struct MercenariesConfig {
     #[key]
     config_id: ID,
-    knights_lower_bound: u64,
-    knights_upper_bound: u64,
-    paladins_lower_bound: u64,
-    paladins_upper_bound: u64,
-    crossbowmen_lower_bound: u64,
-    crossbowmen_upper_bound: u64,
+    knights_bounds: TroopBounds,
+    paladins_bounds: TroopBounds,
+    crossbowmen_bounds: TroopBounds,
     rewards: Span<(u8, u128)>
 }

+pub struct TroopBounds {
+    lower_bound: u64,
+    upper_bound: u64,
+}

This refactoring would improve maintainability and scalability, especially if more troop types are added in the future.

sdk/packages/eternum/src/config/index.ts (1)

440-457: LGTM: New setResourceBridgeFeesConfig method added, but remove incorrect comment

The setResourceBridgeFeesConfig method has been implemented correctly, configuring various fee percentages and recipients for the resource bridge. However, there's an incorrect comment that should be removed.

Please remove the following comment as it's not relevant to this method:

- // allow bridging in of lords into the game

This comment seems to be a copy-paste error from the setResourceBridgeWhitlelistConfig method.

sdk/packages/eternum/src/provider/index.ts (3)

Line range hint 171-184: Simplified realm creation, but potential loss of flexibility

The create_realm method has been significantly simplified:

  1. The method now only takes realm_id and signer as parameters, removing other resource-related arguments.
  2. The contractAddress now references ${NAMESPACE}-dev_realm_systems.
  3. The calldata includes a hardcoded value: "0x1a3e37c77be7de91a9177c6b57956faa6da25607e567b10a25cf64fea5e533b".

While this simplification might streamline the realm creation process, it could potentially limit flexibility in creating realms with varying initial parameters. Ensure that this change aligns with the intended game design and doesn't restrict future expandability.

Consider adding a comment explaining the significance of the hardcoded value in the calldata for better code maintainability.


757-789: Complex resource bridge fee configuration system added

A new set_resource_bridge_fees_config method has been introduced with the following features:

  1. It allows setting various fee percentages for different aspects of resource bridging (e.g., deposits, withdrawals).
  2. The method sets fee recipients for different fee types.
  3. It also sets maximum bank fee percentages for deposits and withdrawals.

This addition suggests a sophisticated economic model for resource transfers, potentially allowing for revenue generation and economic balancing within the game ecosystem.

However, there's a potential issue to consider:

The method uses a hardcoded config id of 0. While this might be intentional for simplicity, it could limit flexibility if multiple fee configurations are needed in the future.

Consider either:

  1. Adding a comment explaining why the config id is hardcoded to 0, or
  2. Making the config id a parameter of the method for more flexibility.

Example:

public async set_resource_bridge_fees_config(props: SystemProps.SetResourceBridgeFeesConfigProps & { config_id?: number }) {
  const {
    config_id = 0, // Default to 0 if not provided
    // ... other props ...
  } = props;
  
  // ... rest of the method ...
}

Line range hint 1-1110: Overall assessment: Significant enhancements to game systems and configurations

This update to the EternumProvider class introduces several important changes and additions:

  1. Simplified realm creation process, potentially trading some flexibility for ease of use.
  2. Introduction of a seasonal configuration system, suggesting new time-based gameplay elements.
  3. Addition of resource bridging systems with whitelist and fee configurations, indicating a more complex economy.
  4. Enhanced mercenaries configuration, allowing for more nuanced troop balance.
  5. Improved access control system, providing more flexibility in managing permissions.

These changes collectively suggest a significant expansion and refinement of the game's underlying systems. They provide more tools for game balancing, economy management, and potentially new gameplay features.

Given the scope of these changes, consider the following:

  1. Ensure thorough testing of all new and modified systems, particularly their interactions.
  2. Update any related documentation to reflect these new capabilities.
  3. Consider creating a migration guide if these changes affect existing game data or player interactions.
  4. Review the overall architecture to ensure these additions align with the long-term vision for the game's systems.
client/src/dojo/contractComponents.ts (5)

540-551: New point system introduced in HyperstructureConfig

The addition of points_per_cycle, points_for_win, and points_on_completion introduces what appears to be a new scoring or reward system for Hyperstructures. This enhancement adds depth to the gameplay mechanics.

Consider adding inline comments or documentation to explain the purpose and usage of these new properties, especially how they interact with other game systems.


965-978: New RealmLevelConfig component added

The introduction of the RealmLevelConfig component appears to implement a level progression system for Realms. This addition can enhance gameplay depth and provide goals for players.

Consider using more descriptive names for the properties to improve code readability:

  • 'required_resources_id' could be 'required_resource_type_id'
  • 'required_resource_count' could be 'required_resource_amount'

These changes would make the purpose of each property more immediately clear to other developers.


937-945: Enhanced Realm component with production and progression properties

The changes to the Realm component improve its functionality:

  1. Changing produced_resources to BigInt allows for handling larger resource quantities.
  2. The addition of order and level properties introduces progression and sorting capabilities.

These enhancements provide more depth to the Realm system. However, consider using more specific types for order and level:

  • For level, you could use RecsType.Number8 (if available) to match the u8 type in RealmLevelConfig.
  • For order, the intended range isn't clear. If it's meant to be a small number, RecsType.Number8 or RecsType.Number16 might be more appropriate.

Using more specific types can help prevent potential overflow issues and make the intended use clearer.


1218-1238: New TravelFoodCostConfig component added

The introduction of the TravelFoodCostConfig component adds depth to the game's travel and exploration mechanics by implementing a food cost system. This can create interesting strategic decisions for players.

To improve code organization and readability, consider grouping the food burn amounts into structs or objects:

explore_food_burn: {
  wheat: RecsType.BigInt,
  fish: RecsType.BigInt
},
travel_food_burn: {
  wheat: RecsType.BigInt,
  fish: RecsType.BigInt
}

This structure would make it easier to add new food types in the future and improve the overall organization of the component.


Line range hint 1268-1281: New max_troop_count property added to TroopConfig

The addition of the max_troop_count property to the TroopConfig component is a good way to implement troop limits, which is crucial for game balance.

However, consider using a more specific type for max_troop_count:

  • If the maximum troop count is expected to be a relatively small number (up to 255), RecsType.Number8 would be more appropriate.
  • For larger numbers up to 65535, RecsType.Number16 could be used.
  • If even larger numbers are needed, RecsType.Number32 would be suitable.

Using a more specific type can help prevent potential overflow issues and make the intended range of values clearer to other developers.

contracts/src/models/season.cairo (2)

6-10: Add documentation comments to the Season struct

Consider adding documentation comments to the Season struct and its fields to enhance readability and maintainability.

Example:

+/// Represents the season configuration and its status.
 pub struct Season {
     #[key]
+    /// The configuration ID associated with the season.
     config_id: ID,
+    /// Indicates whether the season has concluded.
     is_over: bool
 }

14-23: Add documentation comments to the methods

Adding documentation comments to end_season and assert_season_is_not_over will improve code clarity and help other developers understand their purpose.

Example:

+/// Ends the current season by setting `is_over` to `true`.
 fn end_season(world: IWorldDispatcher) { ... }

+/// Asserts that the current season has not ended.
 fn assert_season_is_not_over(world: IWorldDispatcher) { ... }
contracts/src/systems/dev/contracts/realm.cairo (2)

32-33: Grammar correction in function documentation

In the function documentation, "A system that simplifies onboarding for test purpose" should be "A system that simplifies onboarding for testing purposes" to improve grammatical correctness.

Apply this diff to fix the grammatical error:

-        /// A system that simplifies onboarding for test purpose
+        /// A system that simplifies onboarding for testing purposes

46-46: Typographical error in comment

There's a typo in the comment on line 46. The word "passs" has an extra 's'. It should be "pass".

Apply this diff to correct the typo:

-                // approve realms systems contract to spend season passs
+                // approve realms systems contract to spend season pass
contracts/src/utils/testing/general.cairo (1)

16-23: Parameterize hardcoded values for better flexibility

The function spawn_realm uses hardcoded values for produced_resources and order. If these values are intended to vary across different test scenarios, consider parameterizing them to enhance the function's reusability and flexibility.

Consider modifying the function signature:

-fn spawn_realm(world: IWorldDispatcher, realm_id: ID, coord: Coord) -> ID {
+fn spawn_realm(world: IWorldDispatcher, realm_id: ID, coord: Coord, produced_resources: Array<Resource>, order: felt) -> ID {

And update the function body accordingly:

     let owner = starknet::get_contract_address();
     let produced_resources = array![];
     let order = 1;

Replace with:

     let owner = starknet::get_contract_address();
client/src/data/orders.ts (3)

7-7: Consistency in Capitalization for "The Order of Reflection"

Ensure consistent capitalization of "Order". Currently, "order" is in lowercase.

Apply this diff for consistency:

-"The order of Reflection thrives off of time spent with their own thoughts, believing that interaction with an everchanging Realm dulls their ability to see the ethereal. They’re most often found searching for insights into the past and the future by isolating themselves in the darkness. There are rumors of disturbing rituals to aid in conjuring the visions they seek, and their trade in the less savoury markets banned in some Realms does nothing to dispel these rumors.",
+"The Order of Reflection thrives off of time spent with their own thoughts, believing that interaction with an ever-changing Realm dulls their ability to see the ethereal. They’re most often found searching for insights into the past and the future by isolating themselves in the darkness. There are rumors of disturbing rituals to aid in conjuring the visions they seek, and their trade in the less savoury markets banned in some Realms does nothing to dispel these rumors.",

Additionally, consider adding a hyphen in "ever-changing".


13-13: Spelling Correction in "The Order of Brilliance" Description

The word "catalog" is acceptable, but in some dialects, "catalogue" might be preferred for consistency. Also, ensure consistency in spelling.

If you prefer British English spelling, consider this change:

-"... they catalog and store the history of the realms and conduct extensive research into mana usage.",
+"... they catalogue and store the history of the realms and conduct extensive research into mana usage.",

15-15: Grammar Improvement in "The Order of Protection" Description

The sentence contains a comma splice. Replace the comma with a semicolon or split into two sentences.

Apply this diff for better clarity:

-"The Order of Protection values stability between the Realms, they wish to build economies to help feed and clothe the destitute.",
+"The Order of Protection values stability between the Realms; they wish to build economies to help feed and clothe the destitute.",
contracts/src/systems/realm/contracts.cairo (2)

139-139: Use proper error messages in assert statements

The assert statement uses a string 'realm is already at max level' for the error message. Ensure that the error messages are informative and provide clear guidance on what went wrong.

Consider standardizing error messages and possibly defining them as constants for reuse and consistency.


285-290: Ensure proper sequencing when bridging lords into the realm

The approval of lords spending (approve) and the actual deposit (deposit_initial) are performed sequentially, but the code does not confirm that the approve has taken effect before calling deposit_initial.

Consider ensuring that the approve operation is confirmed before proceeding. Additionally, verify that deposit_initial handles cases where approval might not have been granted.

contracts/src/models/realm.cairo (1)

223-246: Optimize the pack_resource_types function for efficiency

Currently, the pack_resource_types function shifts and updates the produced_resources value within each iteration. This can be optimized for performance by preallocating the required space or using more efficient bit manipulation techniques.

Suggestion:

Consider accumulating the packed value using a single expression or by minimizing the number of shift operations. This can improve the function's performance, especially when dealing with a large number of resource types.

contracts/src/systems/resources/contracts/resource_bridge_systems.cairo (1)

211-259: Ensure unit tests cover the new deposit_initial function.

While the implementation appears correct, it's important to add unit tests for deposit_initial to verify its functionality, especially given the critical operations involving token transfers and resource allocations.

Would you like assistance in creating unit tests for this function or opening a GitHub issue to track this task?

contracts/src/systems/config/contracts.cairo (1)

22-29: Add documentation comments to the new trait ISeasonConfig

Consider adding documentation comments to the ISeasonConfig trait and the set_season_config method to explain their purpose and usage. This will improve code readability and help other developers understand the configuration process.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between e2c3420 and f6db602.

⛔ Files ignored due to path filters (2)
  • season_pass/contracts/Scarb.lock is excluded by !**/*.lock
  • season_pass/scripts/deployment/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (82)
  • .github/workflows/test-season-pass.yml (1 hunks)
  • .gitignore (1 hunks)
  • .tool-versions (1 hunks)
  • client/.env.preview (1 hunks)
  • client/.env.production (2 hunks)
  • client/src/data/orders.ts (1 hunks)
  • client/src/dojo/contractComponents.ts (8 hunks)
  • client/src/dojo/modelManager/tests/BattleManagerMock.ts (2 hunks)
  • client/src/hooks/helpers/useRealm.tsx (6 hunks)
  • client/src/hooks/helpers/useStructures.tsx (2 hunks)
  • client/src/ui/components/cityview/realm/SettleRealmComponent.tsx (1 hunks)
  • client/src/ui/components/construction/SelectPreviewBuilding.tsx (13 hunks)
  • client/src/ui/components/resources/RealmResourcesIO.tsx (2 hunks)
  • client/src/ui/components/trading/RealmProduction.tsx (2 hunks)
  • client/src/ui/utils/packedData.tsx (2 hunks)
  • config/index.ts (1 hunks)
  • contracts/.tool-versions (1 hunks)
  • contracts/Scarb.toml (1 hunks)
  • contracts/scripts/contracts.sh (3 hunks)
  • contracts/scripts/env_variables.sh (2 hunks)
  • contracts/scripts/system_models.json (2 hunks)
  • contracts/src/constants.cairo (2 hunks)
  • contracts/src/lib.cairo (0 hunks)
  • contracts/src/models.cairo (1 hunks)
  • contracts/src/models/config.cairo (2 hunks)
  • contracts/src/models/event.cairo (1 hunks)
  • contracts/src/models/hyperstructure.cairo (3 hunks)
  • contracts/src/models/metadata.cairo (0 hunks)
  • contracts/src/models/owner.cairo (1 hunks)
  • contracts/src/models/quantity.cairo (1 hunks)
  • contracts/src/models/realm.cairo (2 hunks)
  • contracts/src/models/season.cairo (1 hunks)
  • contracts/src/models/structure.cairo (0 hunks)
  • contracts/src/systems/bank/contracts/bank.cairo (3 hunks)
  • contracts/src/systems/bank/contracts/liquidity.cairo (3 hunks)
  • contracts/src/systems/bank/contracts/swap.cairo (3 hunks)
  • contracts/src/systems/buildings/contracts.cairo (3 hunks)
  • contracts/src/systems/combat/contracts.cairo (11 hunks)
  • contracts/src/systems/combat/tests/army_buy_test.cairo (2 hunks)
  • contracts/src/systems/combat/tests/army_create_test.cairo (2 hunks)
  • contracts/src/systems/combat/tests/battle_leave_test.cairo (4 hunks)
  • contracts/src/systems/combat/tests/battle_pillage_test.cairo (2 hunks)
  • contracts/src/systems/combat/tests/battle_start_test.cairo (4 hunks)
  • contracts/src/systems/config/contracts.cairo (6 hunks)
  • contracts/src/systems/dev/contracts.cairo (1 hunks)
  • contracts/src/systems/dev/contracts/realm.cairo (1 hunks)
  • contracts/src/systems/guild/contracts.cairo (7 hunks)
  • contracts/src/systems/hyperstructure/contracts.cairo (10 hunks)
  • contracts/src/systems/hyperstructure/tests.cairo (1 hunks)
  • contracts/src/systems/map/contracts.cairo (4 hunks)
  • contracts/src/systems/map/tests.cairo (1 hunks)
  • contracts/src/systems/name/contracts.cairo (2 hunks)
  • contracts/src/systems/realm/contracts.cairo (2 hunks)
  • contracts/src/systems/realm/tests.cairo (9 hunks)
  • contracts/src/systems/resources/contracts/resource_bridge_systems.cairo (2 hunks)
  • contracts/src/systems/trade/contracts/trade_systems.cairo (5 hunks)
  • contracts/src/systems/trade/tests/trade_systems_tests/accept_order.cairo (2 hunks)
  • contracts/src/systems/trade/tests/trade_systems_tests/cancel_order.cairo (1 hunks)
  • contracts/src/systems/trade/tests/trade_systems_tests/create_order.cairo (1 hunks)
  • contracts/src/systems/transport/contracts/travel_systems.cairo (3 hunks)
  • contracts/src/utils.cairo (0 hunks)
  • contracts/src/utils/testing/general.cairo (1 hunks)
  • contracts/src/utils/testing/world.cairo (2 hunks)
  • contracts/src/utils/unpack.cairo (0 hunks)
  • discord-bot/Secrets.toml.example (1 hunks)
  • discord-bot/src/events.rs (1 hunks)
  • discord-bot/src/types.rs (1 hunks)
  • scripts/deploy.sh (3 hunks)
  • scripts/indexer.sh (2 hunks)
  • sdk/packages/eternum/src/config/index.ts (4 hunks)
  • sdk/packages/eternum/src/constants/global.ts (7 hunks)
  • sdk/packages/eternum/src/constants/index.ts (1 hunks)
  • sdk/packages/eternum/src/constants/orders.ts (2 hunks)
  • sdk/packages/eternum/src/constants/resources.ts (4 hunks)
  • sdk/packages/eternum/src/provider/index.ts (5 hunks)
  • sdk/packages/eternum/src/types/common.ts (5 hunks)
  • sdk/packages/eternum/src/types/provider.ts (4 hunks)
  • season_pass/contracts/.tool-versions (1 hunks)
  • season_pass/contracts/Scarb.toml (1 hunks)
  • season_pass/contracts/src/contract.cairo (1 hunks)
  • season_pass/contracts/src/lib.cairo (1 hunks)
  • season_pass/contracts/src/mock/lords.cairo (1 hunks)
⛔ Files not processed due to max files limit (13)
  • season_pass/contracts/src/mock/realms/realms.cairo
  • season_pass/contracts/src/tests/test_season_pass.cairo
  • season_pass/scripts/deployment/.env.example
  • season_pass/scripts/deployment/.gitignore
  • season_pass/scripts/deployment/addresses/dev/season_pass.json
  • season_pass/scripts/deployment/addresses/dev/test_lords.json
  • season_pass/scripts/deployment/addresses/dev/test_realms.json
  • season_pass/scripts/deployment/deploy_dev.js
  • season_pass/scripts/deployment/deploy_prod.js
  • season_pass/scripts/deployment/libs/commands.js
  • season_pass/scripts/deployment/libs/common.js
  • season_pass/scripts/deployment/libs/network.js
  • season_pass/scripts/deployment/package.json
💤 Files with no reviewable changes (5)
  • contracts/src/lib.cairo
  • contracts/src/models/metadata.cairo
  • contracts/src/models/structure.cairo
  • contracts/src/utils.cairo
  • contracts/src/utils/unpack.cairo
✅ Files skipped from review due to trivial changes (5)
  • .gitignore
  • .tool-versions
  • client/.env.preview
  • contracts/.tool-versions
  • season_pass/contracts/.tool-versions
🚧 Files skipped from review as they are similar to previous changes (6)
  • client/src/hooks/helpers/useRealm.tsx
  • client/src/ui/components/construction/SelectPreviewBuilding.tsx
  • client/src/ui/components/resources/RealmResourcesIO.tsx
  • client/src/ui/components/trading/RealmProduction.tsx
  • contracts/Scarb.toml
  • scripts/deploy.sh
🧰 Additional context used
🪛 Shellcheck
contracts/scripts/contracts.sh

[warning] 27-27: Declare and assign separately to avoid masking return values.

(SC2155)


[warning] 59-59: Declare and assign separately to avoid masking return values.

(SC2155)

🔇 Additional comments (138)
season_pass/contracts/src/lib.cairo (1)

1-11: Well-structured module organization. LGTM!

The overall structure of the lib.cairo file is well-organized, clearly separating the main contract implementation, mock objects, and tests. This separation of concerns will contribute to better maintainability and testability of the codebase.

contracts/src/models.cairo (1)

21-21: LGTM! Verify the implementation and usage of the new season module.

The addition of the season module is correctly placed in alphabetical order within the list of modules. This suggests new functionality related to seasons in the project.

To ensure the proper implementation and usage of this new module, please run the following script:

This script will help verify:

  1. The existence of the season.cairo file.
  2. The usage of the season module in other parts of the project.

Please review the results to ensure the module is properly implemented and utilized.

✅ Verification successful

Verified the addition of the season module.

The season.cairo file exists and is correctly imported in multiple contracts, ensuring that the new module is properly implemented and utilized throughout the project.

  • season.cairo found at contracts/src/models/season.cairo.
  • Imported in:
    • contracts/src/systems/trade/contracts/trade_systems.cairo
    • contracts/src/systems/name/contracts.cairo
    • contracts/src/systems/realm/contracts.cairo
    • contracts/src/systems/hyperstructure/contracts.cairo
    • contracts/src/systems/map/contracts.cairo
    • contracts/src/systems/guild/contracts.cairo
    • contracts/src/systems/buildings/contracts.cairo
    • contracts/src/systems/combat/contracts.cairo
    • contracts/src/systems/transport/contracts/travel_systems.cairo
    • contracts/src/systems/bank/contracts/bank.cairo
    • contracts/src/systems/bank/contracts/liquidity.cairo
    • contracts/src/systems/bank/contracts/swap.cairo
    • contracts/src/utils/testing/world.cairo
    • contracts/src/systems/config/contracts.cairo

All usages align with expected patterns, confirming the module's correct integration.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the implementation and usage of the new `season` module.

# Test 1: Check if the season.cairo file exists
echo "Checking for the existence of season.cairo file:"
fd --type f "season.cairo$"

# Test 2: Search for imports or uses of the season module
echo "Searching for imports or uses of the season module:"
rg --type cairo "use.*season::" -g '!models.cairo'

Length of output: 366


Script:

#!/bin/bash
# Description: Verify the usage of the new `season` module by searching within .cairo files.

# Test 1: Search for imports or uses of the season module without specifying the file type
echo "Searching for imports or uses of the season module in .cairo files:"
rg "use.*season::" -g '*.cairo' -g '!models.cairo'

Length of output: 1493

season_pass/contracts/Scarb.toml (4)

1-3: LGTM: Package information is well-defined.

The package name "esp" and version "1.0.0" are clearly specified. The version follows semantic versioning, which is a good practice.


5-6: LGTM: Cairo configuration is appropriate.

The sierra-replace-ids = true setting is correctly configured. This option replaces function and struct IDs with their names in the Sierra output, which can improve readability and debugging.


12-17: LGTM: Dev-dependencies and target configurations are appropriate.

The dev-dependency snforge_std is correctly specified with a Git source and a specific tag, ensuring version stability. The target configuration enables both Sierra and CASM outputs for StarkNet contracts, which is standard practice and provides flexibility for different deployment scenarios.


19-21: LGTM: Formatting configuration promotes code consistency.

The formatting settings are well-defined:

  • sort-module-level-items = true helps maintain a consistent order of items within modules.
  • max-line-length = 120 is a reasonable line length limit that balances readability with efficient use of screen space.

These settings will contribute to consistent and readable code across the project.

sdk/packages/eternum/src/constants/index.ts (1)

15-35: ⚠️ Potential issue

Significant changes to ResourcesIds enum require careful consideration and documentation.

The modifications to the ResourcesIds enum are extensive and could have far-reaching implications on the codebase:

  1. The reordering of basic resources (Stone, Coal, Wood) and changes to other resource IDs might affect core game mechanics and existing logic that relies on these specific numeric values.
  2. The addition of new resources (e.g., Mithral) suggests an expansion of game elements, which is positive for game development but requires careful integration.

To ensure a smooth transition and maintain code integrity:

  1. Please provide the rationale behind these changes, especially the reordering of basic resources.
  2. Update all documentation and dependent code to reflect these new resource IDs.
  3. Consider adding a migration guide for any external systems or scripts that might be using the old resource IDs.

For future-proofing:

  1. Consider implementing a more flexible system for resource IDs that doesn't rely on hard-coded enum values. This could involve using string identifiers or a dynamic ID system that allows for easier addition and modification of resources without breaking existing code.
  2. If maintaining backwards compatibility is crucial, consider keeping the old IDs as aliases or implementing a mapping system between old and new IDs.

To assess the impact of these changes, please run the following script:

This script will help identify areas of the codebase that might be affected by the changes to the ResourcesIds enum.

client/src/ui/utils/packedData.tsx (2)

1-13: Excellent improvements to the unpackResources function!

The changes made to this function are well-thought-out and improve its flexibility and robustness:

  1. Removing the valueCount parameter simplifies the function signature and allows it to handle variable-length packed values.
  2. Renaming MAX_NUMBER_SIZE to MAX_BITS_PER_VALUE is more descriptive and aligns better with its usage.
  3. Replacing the for-loop with a while-loop is more appropriate for this use case, as we don't know the number of iterations in advance.
  4. The updated logic correctly unpacks the values until no more bits are left, making it more flexible and less error-prone.

These changes make the function more versatile and easier to use. Great job!


Line range hint 1-39: Overall excellent improvements to the file!

The changes made to both unpackResources and packResources functions are consistent, well-implemented, and improve the overall quality of the code. Key improvements include:

  1. Increased flexibility in handling packed values of variable lengths.
  2. Improved readability with more descriptive constant naming.
  3. Better error handling and reporting.
  4. Consistent use of the new MAX_BITS_PER_VALUE constant throughout the file.

These changes make the code more robust, easier to understand, and simpler to maintain in the future. Great work on refactoring this utility file!

contracts/src/systems/name/contracts.cairo (3)

32-32: Ensure consistent usage of SeasonImpl::assert_season_is_not_over.

The change to use SeasonImpl::assert_season_is_not_over is consistent with the change in the set_address_name method.

This consistency is good and suggests a systematic update across the contract. Ensure that this change is reflected in all relevant parts of the project for maintainability.


19-19: Verify the behavior of assert_season_is_not_over.

The assert_season_is_not_over method is now called from SeasonImpl instead of SeasonCustomImpl.

Please confirm that:

  1. The logic for determining when a season is over remains consistent with the previous implementation.
  2. Any differences in behavior are intentional and documented.
#!/bin/bash
# Search for the implementation of assert_season_is_not_over in SeasonImpl
ast-grep --lang cairo --pattern 'fn assert_season_is_not_over($$$) { $$$ }'

14-14: Confirm the transition from SeasonCustomImpl to SeasonImpl.

The import has been changed from SeasonCustomImpl to SeasonImpl. This suggests a shift from a custom implementation to a standard implementation of the Season model.

Please ensure that:

  1. The SeasonImpl provides all the necessary functionality that was previously available in SeasonCustomImpl.
  2. This change is consistent across the entire project.
  3. The new implementation doesn't introduce any breaking changes in the season logic.
contracts/src/models/owner.cairo (1)

61-61: LGTM! Consider verifying Realm struct consistency.

The simplification of the Realm struct initialization in this test is a good improvement. It reduces complexity while still effectively testing the get_realm_id function.

To ensure this simplified Realm struct is consistent with its actual implementation, please run the following script:

This script will help verify that the simplified Realm struct used here is consistent with its definition and usage across the codebase.

✅ Verification successful

Verified Realm Struct Consistency

The simplified Realm struct initialization in contracts/src/models/owner.cairo is consistent with its definition and usage across the codebase. No discrepancies were found, and the change does not impact existing functionality.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the Realm struct definition and its usage across the codebase.

# Test 1: Check the Realm struct definition
echo "Realm struct definition:"
ast-grep --lang cairo --pattern 'struct Realm { $$$_ }'

# Test 2: Check Realm struct usage in other tests
echo "\nRealm struct usage in tests:"
rg --type cairo -g '*_test.cairo' 'Realm \{(?s).*?\}'

# Test 3: Check Realm struct usage in non-test files
echo "\nRealm struct usage in non-test files:"
rg --type cairo -g '!*_test.cairo' 'Realm \{(?s).*?\}'

Length of output: 560


Script:

#!/bin/bash
# Description: Verify the Realm struct definition and its usage across the codebase without specifying unsupported language types.

# Test 1: Check the Realm struct definition
echo "Realm struct definition:"
rg 'struct\s+Realm\s*\{[^}]*\}'

# Test 2: Check Realm struct usage in other tests
echo -e "\nRealm struct usage in test files:"
rg 'Realm\s*\{' --glob='*_test.cairo'

# Test 3: Check Realm struct usage in non-test files
echo -e "\nRealm struct usage in non-test files:"
rg 'Realm\s*\{' --glob='!*_test.cairo'

Length of output: 1273

sdk/packages/eternum/src/constants/orders.ts (2)

Line range hint 120-122: LGTM! The getOrderName function remains valid.

The getOrderName function's implementation is unchanged and remains valid with the updated orders array. It correctly retrieves the order name based on the orderId.


Line range hint 25-117: LGTM! Verify the impact of the new "Reflection" order.

The changes to the orders array are consistent with the modifications in ORDER_NAME_DICT. The addition of a new order (orderId: 7, "Reflection") is noteworthy.

To ensure that the addition of the new order doesn't cause any issues, please run the following script:

#!/bin/bash
# Description: Verify the impact of the new "Reflection" order

# Test: Search for any hardcoded assumptions about the number of orders
echo "Searching for hardcoded assumptions about the number of orders:"
rg --type typescript --type javascript '(16|sixteen).*orders' -C 3

# Test: Look for any loops or iterations over the orders array
echo "Searching for loops or iterations over the orders array:"
rg --type typescript --type javascript '(for|\.map|\.forEach|\.filter).*orders' -C 3

# Test: Search for any switch statements or if-else chains handling order IDs
echo "Searching for switch statements or if-else chains handling order IDs:"
rg --type typescript --type javascript '(switch|case|if).*orderId' -C 5

This script will help identify any areas in the codebase that might need to be updated to accommodate the new order.

contracts/src/models/hyperstructure.cairo (2)

3-15: LGTM: Import statements are well-organized and comprehensive.

The new import statements are correctly structured and provide access to necessary components from the eternum module. This expansion suggests improved integration with other parts of the system, which is a positive change.


29-30: Excellent improvement to access control.

Replacing the private: bool field with access: Access is a significant enhancement. This change allows for more granular access control and improves type safety. The use of an enum also makes the code more extensible, allowing for easy addition of new access levels in the future if needed.

contracts/scripts/contracts.sh (4)

59-59: LGTM! Consider addressing the shellcheck warning.

The addition of the DEV_REALM_SYSTEMS export is consistent with the existing pattern in the script. The same shellcheck warning (SC2155) applies here as mentioned in the previous comment.

🧰 Tools
🪛 Shellcheck

[warning] 59-59: Declare and assign separately to avoid masking return values.

(SC2155)


67-67: LGTM!

The addition of the echo statement for RESOURCE_BRIDGE_SYSTEMS is consistent with the existing pattern and ensures that the new contract address is displayed when the script is executed.


83-83: LGTM!

The addition of the echo statement for DEV_REALM_SYSTEMS is consistent with the existing pattern and ensures that the new contract address is displayed when the script is executed.


Line range hint 27-83: Overall, the changes look good and enhance the script's functionality.

The additions of RESOURCE_BRIDGE_SYSTEMS and DEV_REALM_SYSTEMS exports, along with their corresponding echo statements, are consistent with the existing pattern in the script. These changes improve the script by adding support for two new contract systems while maintaining the overall structure and readability.

Minor shellcheck warnings were noted for the export statements, but they don't pose significant risks in this context. Consider addressing them if you want to further improve the script's robustness.

🧰 Tools
🪛 Shellcheck

[warning] 57-57: Declare and assign separately to avoid masking return values.

(SC2155)


[warning] 59-59: Declare and assign separately to avoid masking return values.

(SC2155)

contracts/src/models/event.cairo (1)

150-150: Verify the impact of consolidating resource fields in SettleRealmData

The changes to the SettleRealmData struct consolidate resource information into a single field produced_resources: u128, replacing the previous resource_types_packed: u128 and resource_types_count: u8 fields. This modification suggests a more compact representation of resource data.

While this change may improve data efficiency, it's important to ensure that:

  1. The new produced_resources field can adequately represent all necessary resource information without loss of data.
  2. Any code that previously used resource_types_packed and resource_types_count is updated to work with the new produced_resources field.
  3. The logic for packing and unpacking resource data is adjusted accordingly in other parts of the codebase.

To ensure the change is properly implemented across the codebase, please run the following script:

This script will help identify any areas that might need updates due to this change.

✅ Verification successful

Impact of Consolidating Resource Fields in SettleRealmData Verified

The consolidation of resource-related fields into produced_resources: u128 in the SettleRealmData struct has been successfully verified. No references to the removed fields resource_types_packed or resource_types_count exist outside contracts/src/models/event.cairo, and the new field is consistently utilized across the codebase. This change enhances data efficiency without introducing issues.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for usage of old fields and new field across the codebase

echo "Checking for usage of old fields:"
rg --type cairo 'resource_types_packed|resource_types_count' -g '!contracts/src/models/event.cairo'

echo "Checking for usage of new field:"
rg --type cairo 'produced_resources' -g '!contracts/src/models/event.cairo'

echo "Checking for SettleRealmData usage:"
rg --type cairo 'SettleRealmData' -A 10 -B 2

Length of output: 545


Script:

#!/bin/bash
# Description: Check for usage of old fields and new field across the codebase

echo "Checking for usage of old fields:"
rg 'resource_types_packed|resource_types_count' -g '*.cairo' -g '!contracts/src/models/event.cairo'

echo "Checking for usage of new field:"
rg 'produced_resources' -g '*.cairo' -g '!contracts/src/models/event.cairo'

echo "Checking for SettleRealmData usage:"
rg 'SettleRealmData' -g '*.cairo' -A 10 -B 2

Length of output: 6519

contracts/src/systems/buildings/contracts.cairo (6)

58-58: Approve the update to SeasonImpl in the create method.

The change to use SeasonImpl::assert_season_is_not_over(world) is consistent with the earlier import statement modification. This ensures that the season validation logic is centralized under the new SeasonImpl, maintaining consistency across the codebase.


78-78: Approve the update to SeasonImpl in the pause_production method.

The change to use SeasonImpl::assert_season_is_not_over(world) is consistent with the earlier modifications. This ensures that the season validation logic is centralized under the new SeasonImpl, maintaining consistency across the codebase.


84-84: Approve the updates to SeasonImpl in the resume_production and destroy methods.

The changes to use SeasonImpl::assert_season_is_not_over(world) in both methods are consistent with the earlier modifications. This ensures that the season validation logic is centralized under the new SeasonImpl, maintaining consistency across the codebase.

Also applies to: 90-90


Line range hint 20-90: Summary of changes and potential impact

The changes in this file primarily revolve around two main points:

  1. Transition from SeasonCustomImpl to SeasonImpl: This change is consistently applied across all methods that perform season checks. It likely represents a move towards a more standardized or refined implementation of season management.

  2. Refinement of resource check in the create method: The change from has_resource to produces_resource provides a more precise condition for building creation.

These modifications improve code clarity and consistency. However, the transition to SeasonImpl might have broader implications in the codebase, particularly if other components were relying on specific behaviors of SeasonCustomImpl. It's recommended to verify that this change doesn't introduce any unintended side effects in the broader system.

To ensure a smooth transition, it would be beneficial to run a comprehensive test suite that covers season-related functionality across the entire project.


54-54: Approve the refined resource check in the create method.

The change from has_resource to produces_resource is a more precise condition that better aligns with the intent of the method. This refinement ensures that buildings can only be created for resources that the realm actually produces, not just possesses.

To ensure this change doesn't unexpectedly prevent building creation in valid scenarios, let's verify the usage:

✅ Verification successful

Verified: produces_resource usage is consistent and properly implemented.

The produces_resource method is correctly integrated across relevant files and is supported by comprehensive test cases. This ensures that the refined resource check functions as intended without introducing issues.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check the usage of produces_resource method

# Test: Find all occurrences of produces_resource method
echo "Checking usage of produces_resource method:"
rg "produces_resource" --type cairo -A 5 -B 5

Length of output: 172


Script:

#!/bin/bash
# Description: Check the usage of produces_resource method in .cairo files

# Test: Find all occurrences of produces_resource method in .cairo files
echo "Checking usage of produces_resource method in .cairo files:"
rg "produces_resource" --glob "*.cairo" -A 5 -B 5

Length of output: 5377


20-20: Verify the impact of switching from SeasonCustomImpl to SeasonImpl.

The change from SeasonCustomImpl to SeasonImpl suggests a shift to a more standardized implementation. This modification might affect other parts of the codebase that relied on SeasonCustomImpl.

Let's verify the usage of SeasonImpl across the codebase:

✅ Verification successful

Verification Successful: SeasonCustomImpl has been fully replaced by SeasonImpl.

All instances of SeasonCustomImpl have been removed, and SeasonImpl is consistently used across the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check the usage of SeasonImpl across the codebase

# Test 1: Check for any remaining usage of SeasonCustomImpl
echo "Checking for any remaining usage of SeasonCustomImpl:"
rg "SeasonCustomImpl" --type cairo

# Test 2: Verify consistent usage of SeasonImpl
echo "Verifying consistent usage of SeasonImpl:"
rg "SeasonImpl" --type cairo

Length of output: 333


Script:

#!/bin/bash
# Description: Check the usage of SeasonImpl across the codebase

# Test 1: Check for any remaining usage of SeasonCustomImpl
echo "Checking for any remaining usage of SeasonCustomImpl:"
rg "SeasonCustomImpl" --glob "*.cairo"

# Test 2: Verify consistent usage of SeasonImpl
echo "Verifying consistent usage of SeasonImpl:"
rg "SeasonImpl" --glob "*.cairo"

Length of output: 6137

contracts/src/systems/combat/tests/army_buy_test.cairo (2)

20-21: Approved: Updated imports for improved realm creation.

The new imports (get_default_realm_pos and spawn_realm) from the general module indicate a more streamlined approach to realm creation in the test setup. This change aligns with the removal of the realm_system_dispatcher, suggesting a shift towards a more direct method of spawning realms.


Line range hint 86-134: Verify test functionality with updated setup.

While the core logic of the test functions remains unchanged, it's crucial to ensure that they still function correctly with the modified setup process. The tests should continue to accurately verify the army buying functionality and resource management.

Please run the following script to verify that the tests are still passing:

If any tests fail, please review the output and make necessary adjustments to ensure all tests pass with the new setup.

contracts/src/systems/bank/contracts/liquidity.cairo (3)

59-59: LGTM: Consistent change in season implementation.

The change from SeasonCustomImpl to SeasonImpl for the assert_season_is_not_over method is consistent with the import modification. The functionality remains the same, ensuring that liquidity can only be added when the season is active.


Line range hint 1-165: Summary: Consistent implementation change with room for minor improvement.

The changes in this file consistently replace SeasonCustomImpl with SeasonImpl, which is a positive step towards standardization. The functionality remains unchanged, ensuring that liquidity operations are only performed when the season is active.

Key points:

  1. Import change is appropriate and consistent.
  2. Both add and remove methods have been updated consistently.
  3. A suggestion for refactoring the repeated season check has been made to improve code quality.

Overall, these changes improve the codebase's consistency and maintainability. The suggested refactoring, if implemented, would further enhance these benefits.


29-29: Approve import change and verify consistency.

The change from SeasonCustomImpl to SeasonImpl suggests a move towards a more standardized season implementation. This is generally a good practice for maintainability and consistency.

To ensure this change is applied consistently across the codebase, please run the following script:

This will help identify any inconsistencies in the implementation change across the project.

✅ Verification successful

Revise shell scripts to correctly target .cairo files.

The previous script failed because ripgrep does not recognize cairo as a file type. Let's target .cairo files explicitly.


Import change verified and consistent across the codebase.

All instances of SeasonCustomImpl have been successfully removed, and SeasonImpl is consistently used throughout the contracts.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining uses of SeasonCustomImpl and new uses of SeasonImpl

# Test 1: Check for any remaining uses of SeasonCustomImpl
echo "Checking for remaining uses of SeasonCustomImpl:"
rg --type cairo "SeasonCustomImpl"

# Test 2: Check for new uses of SeasonImpl
echo "Checking for new uses of SeasonImpl:"
rg --type cairo "SeasonImpl"

Length of output: 313


Script:

#!/bin/bash
# Description: Check for any remaining uses of SeasonCustomImpl and new uses of SeasonImpl in .cairo files

# Test 1: Check for any remaining uses of SeasonCustomImpl
echo "Checking for remaining uses of SeasonCustomImpl:"
rg "SeasonCustomImpl" --glob "*.cairo"

# Test 2: Check for new uses of SeasonImpl
echo "Checking for new uses of SeasonImpl:"
rg "SeasonImpl" --glob "*.cairo"

Length of output: 6117

contracts/scripts/system_models.json (1)

35-36: Approve addition of SeasonConfig

The addition of "SeasonConfig" to the CONFIG_SYSTEMS array is appropriate and aligns with the introduction of season-related functionality mentioned in the summary.

Please ensure that the corresponding SeasonConfig implementation exists and is properly integrated into the system. Run the following script to verify:

✅ Verification successful

SeasonConfig Integration Verified

The "SeasonConfig" has been successfully integrated and is utilized in the following files:

  • sdk/packages/eternum/src/types/provider.ts
  • sdk/packages/eternum/src/config/index.ts
  • sdk/packages/eternum/src/provider/index.ts
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify the existence and usage of SeasonConfig
rg --type typescript --type javascript -i "seasonconfig"

Length of output: 91


Script:

#!/bin/bash
# Verify the existence and usage of SeasonConfig
rg --type ts --type js -i "SeasonConfig"

Length of output: 439

contracts/src/systems/bank/contracts/bank.cairo (3)

54-54: LGTM. Verify season check behavior.

The change to use SeasonImpl::assert_season_is_not_over(world) is consistent with the updated import. The overall logic of the create_bank method remains intact.

To ensure the season check behaves as expected, please run the following test:

#!/bin/bash
# Description: Verify the behavior of SeasonImpl::assert_season_is_not_over

# Test: Check the implementation of assert_season_is_not_over in SeasonImpl
echo "Checking assert_season_is_not_over implementation:"
rg --type cairo -A 10 "fn assert_season_is_not_over" | grep -A 10 "impl SeasonImpl"

101-101: LGTM. Ensure consistent season check usage.

The change to use SeasonImpl::assert_season_is_not_over(world) in the change_owner_amm_fee method is consistent with the previous modifications. The overall logic of the method remains intact.

To ensure consistent usage of the new season check across the codebase, please run the following test:

✅ Verification successful

Please run the following updated verification scripts to ensure consistent usage of SeasonImpl::assert_season_is_not_over:


Consistent season check usage verified.

The usage of SeasonImpl::assert_season_is_not_over(world) has been consistently applied across the codebase. No remaining instances of SeasonCustomImpl::assert_season_is_not_over were found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify consistent usage of SeasonImpl::assert_season_is_not_over

# Test: Check for any remaining uses of SeasonCustomImpl::assert_season_is_not_over
echo "Checking for remaining uses of SeasonCustomImpl::assert_season_is_not_over:"
rg --type cairo "SeasonCustomImpl::assert_season_is_not_over"

# Test: Check for consistent usage of SeasonImpl::assert_season_is_not_over
echo "Checking for consistent usage of SeasonImpl::assert_season_is_not_over:"
rg --type cairo "SeasonImpl::assert_season_is_not_over"

Length of output: 321


Script:

#!/bin/bash
# Description: Verify consistent usage of SeasonImpl::assert_season_is_not_over

# Test: Check for any remaining uses of SeasonCustomImpl::assert_season_is_not_over
echo "Checking for remaining uses of SeasonCustomImpl::assert_season_is_not_over:"
fd --extension cairo --type f | xargs rg "SeasonCustomImpl::assert_season_is_not_over"

# Test: Check for consistent usage of SeasonImpl::assert_season_is_not_over
echo "Checking for consistent usage of SeasonImpl::assert_season_is_not_over:"
fd --extension cairo --type f | xargs rg "SeasonImpl::assert_season_is_not_over"

Length of output: 4951


37-37: Verify the impact of switching from SeasonCustomImpl to SeasonImpl.

The change from SeasonCustomImpl to SeasonImpl suggests a refactoring of the season-related functionality. Ensure that SeasonImpl provides all the necessary methods and behaves consistently with the previous implementation.

To verify the impact of this change, please run the following script:

✅ Verification successful

SeasonCustomImpl has been successfully replaced with SeasonImpl, and no remaining usages of SeasonCustomImpl were found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Compare the implementations of SeasonCustomImpl and SeasonImpl

# Test 1: Check for the existence of both implementations
echo "Checking for SeasonCustomImpl:"
rg --type cairo "impl SeasonCustomImpl"
echo "Checking for SeasonImpl:"
rg --type cairo "impl SeasonImpl"

# Test 2: Compare method signatures
echo "Comparing method signatures:"
rg --type cairo -A 10 "impl SeasonCustomImpl" | grep "fn"
echo "---"
rg --type cairo -A 10 "impl SeasonImpl" | grep "fn"

# Test 3: Check for usages of SeasonCustomImpl that might have been missed
echo "Checking for remaining usages of SeasonCustomImpl:"
rg --type cairo "SeasonCustomImpl"

Length of output: 695


Script:

#!/bin/bash
# Description: Compare the implementations of SeasonCustomImpl and SeasonImpl

# Test 1: Check for the existence of both implementations
echo "Checking for SeasonCustomImpl:"
rg "impl SeasonCustomImpl" --glob "*.cairo"
echo "Checking for SeasonImpl:"
rg "impl SeasonImpl" --glob "*.cairo"

# Test 2: Compare method signatures
echo "Comparing method signatures of SeasonCustomImpl:"
rg "impl SeasonCustomImpl" --glob "*.cairo" -A 10 | grep "fn"
echo "---"
echo "Comparing method signatures of SeasonImpl:"
rg "impl SeasonImpl" --glob "*.cairo" -A 10 | grep "fn"

# Test 3: Check for usages of SeasonCustomImpl that might have been missed
echo "Checking for remaining usages of SeasonCustomImpl:"
rg "SeasonCustomImpl" --glob "*.cairo"

Length of output: 944

contracts/src/systems/combat/tests/battle_pillage_test.cairo (1)

56-56: Verify the impact of the spawn_realm function signature change.

The modifications to the spawn_realm function calls in the setup function improve clarity and simplify the setup process. However, it's important to ensure that these changes don't negatively impact other parts of the codebase.

Please run the following script to check for any other occurrences of spawn_realm that might need updating:

This will help identify any other places where the spawn_realm function is used or defined, allowing us to ensure consistent updates across the codebase.

Also applies to: 72-73

✅ Verification successful

Re-run the search with explicit file extensions to verify the impact of the spawn_realm function signature change.

Please execute the following script to check for any other occurrences of spawn_realm that might need updating:


Verification Successful: spawn_realm Function Signature Change is Consistently Applied.

All occurrences of the spawn_realm function across the codebase have been reviewed and align with the updated function signature. No further action is required.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for other occurrences of spawn_realm that might need updating

# Search for spawn_realm function calls
echo "Searching for spawn_realm function calls:"
rg --type cairo -A 5 'spawn_realm\s*\(' --glob '!**/battle_pillage_test.cairo'

# Search for spawn_realm function definition
echo "Searching for spawn_realm function definition:"
rg --type cairo -A 5 'fn\s+spawn_realm\s*\('

Length of output: 383


Script:

# 
#!/bin/bash
# Description: Check for other occurrences of spawn_realm that might need updating

# Search for spawn_realm function calls excluding battle_pillage_test.cairo
echo "Searching for spawn_realm function calls in .cairo files:"
rg 'spawn_realm\s*\(' -A 5 -g "*.cairo" --glob "!**/battle_pillage_test.cairo"

# Search for spawn_realm function definition
echo "Searching for spawn_realm function definition in .cairo files:"
rg 'fn\s+spawn_realm\s*\(' -A 5 -g "*.cairo"

Length of output: 13739

contracts/src/systems/bank/contracts/swap.cairo (3)

52-52: LGTM. Consistent with import change.

The update to use SeasonImpl::assert_season_is_not_over is consistent with the earlier import change. The functionality remains the same, indicating that the SeasonImpl interface is compatible with the previous SeasonCustomImpl.


104-104: LGTM. Consistent implementation across functions.

The update to use SeasonImpl::assert_season_is_not_over in the sell function mirrors the change in the buy function. This consistency is good and confirms that the SeasonImpl interface is compatible across different use cases.


22-22: LGTM. Verify consistent usage across the codebase.

The change from SeasonCustomImpl to SeasonImpl looks good. This likely reflects a refactoring of the season-related functionality.

To ensure consistency, let's verify that this change has been applied throughout the codebase:

✅ Verification successful

Verified: No remaining usages of SeasonCustomImpl found in the codebase.

The import change from SeasonCustomImpl to SeasonImpl has been consistently applied throughout the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining usage of SeasonCustomImpl
# Expected result: No occurrences of SeasonCustomImpl

rg --type cairo 'SeasonCustomImpl'

Length of output: 64


Script:

#!/bin/bash
# Description: Check for any remaining usage of SeasonCustomImpl in .cairo files
# Expected result: No occurrences of SeasonCustomImpl

rg --glob '*.cairo' 'SeasonCustomImpl'

Length of output: 38

contracts/src/systems/trade/tests/trade_systems_tests/create_order.cairo (2)

Line range hint 71-228: Verify test coverage after setup change.

The modification in the setup function doesn't appear to directly impact the logic or assertions in the existing test cases. These tests focus on trade order creation, permissions, resource checks, and input validation, which are not directly related to the realm spawning process.

However, to ensure the change doesn't have any unforeseen consequences:

  1. Verify that there are no implicit dependencies on the realm system dispatcher in these tests that might be affected by the change.
  2. Consider running the entire test suite to confirm that no regressions have been introduced.

To help verify the test coverage, you can run the following command to check for any failing tests after this change:

If any tests fail, please review them carefully to understand if the failure is related to this change.


43-43: Verify the impact of hardcoding the realm system value.

The change simplifies the spawn_realm call by using a hardcoded value of 1 instead of realm_systems_dispatcher. While this simplification might be intentional, it's worth considering the following points:

  1. This change may reduce the flexibility of the test setup, as it no longer uses a potentially configurable dispatcher.
  2. There's a potential for reduced test coverage if the dispatcher was providing different values in different test scenarios.

Please confirm if this change is intentional and doesn't negatively impact other tests or test scenarios. If it's a deliberate simplification, consider adding a comment explaining the reasoning behind using a constant value.

✅ Verification successful

Verification Successful: No Other spawn_realm Usage with realm_systems_dispatcher.

The search confirmed that there are no other instances of spawn_realm calls using realm_systems_dispatcher in the codebase. Therefore, the change to hardcode the realm system value is isolated and does not impact other tests or modules.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for other occurrences of spawn_realm with realm_systems_dispatcher

# Test: Search for other spawn_realm calls with realm_systems_dispatcher
rg --type cairo "spawn_realm.*realm_systems_dispatcher" -C 3

Length of output: 92


Script:

#!/bin/bash
# Description: Check for other occurrences of spawn_realm with realm_systems_dispatcher

# Test: Search for other spawn_realm calls with realm_systems_dispatcher in .cairo files
rg "spawn_realm.*realm_systems_dispatcher" --glob "*.cairo" -C 3

Length of output: 66

contracts/src/systems/guild/contracts.cairo (8)

32-32: LGTM: Consistent update to season assertion.

The change from SeasonCustomImpl to SeasonImpl for asserting that the season is not over is correctly implemented here.


58-58: LGTM: Consistent update to season assertion.

The change from SeasonCustomImpl to SeasonImpl for asserting that the season is not over is correctly implemented here.


78-78: LGTM: Consistent update to season assertion.

The change from SeasonCustomImpl to SeasonImpl for asserting that the season is not over is correctly implemented here.


93-93: LGTM: Consistent update to season assertion.

The change from SeasonCustomImpl to SeasonImpl for asserting that the season is not over is correctly implemented here.


123-123: LGTM: Consistent update to season assertion.

The change from SeasonCustomImpl to SeasonImpl for asserting that the season is not over is correctly implemented here.


138-138: LGTM: Consistent update to season assertion.

The change from SeasonCustomImpl to SeasonImpl for asserting that the season is not over is correctly implemented here.


157-157: LGTM: Consistent update to season assertion.

The change from SeasonCustomImpl to SeasonImpl for asserting that the season is not over is correctly implemented here.


24-25: Overall changes look good, consider verifying broader context.

The transition from SeasonCustomImpl to SeasonImpl for asserting that the season is not over has been consistently applied across all relevant functions in this file. This change appears to be part of a larger refactoring effort.

To ensure this change is part of a broader, consistent update across the codebase, please run the following script:

This will help verify that the change has been applied consistently across the entire project and identify any places that might have been missed.

✅ Verification successful

SeasonCustomImpl has been fully replaced by SeasonImpl across the codebase.

All instances of SeasonCustomImpl are no longer present, and SeasonImpl is used consistently in all relevant contracts.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining uses of SeasonCustomImpl and compare with SeasonImpl usage

echo "Checking for remaining SeasonCustomImpl usage:"
rg "SeasonCustomImpl" --type cairo

echo "\nChecking for SeasonImpl usage:"
rg "SeasonImpl" --type cairo

echo "\nComparing import statements:"
rg "use.*Season.*Impl" --type cairo

Length of output: 440


Script:

#!/bin/bash
# Description: Check for any remaining uses of SeasonCustomImpl and compare with SeasonImpl usage in .cairo files

echo "Checking for remaining SeasonCustomImpl usage in .cairo files:"
fd -e cairo | xargs grep "SeasonCustomImpl"

echo -e "\nChecking for SeasonImpl usage in .cairo files:"
fd -e cairo | xargs grep "SeasonImpl"

echo -e "\nComparing import statements for SeasonImpl and SeasonCustomImpl in .cairo files:"
fd -e cairo | xargs grep "use.*Season.*Impl"

Length of output: 7624

contracts/src/systems/trade/tests/trade_systems_tests/cancel_order.cairo (2)

Line range hint 1-71: LGTM: Test cases remain intact and consistent.

The changes in the setup function don't appear to affect the behavior of the test cases. The test logic for canceling orders and asserting conditions remains unchanged and consistent with the previous implementation. This suggests that the modification to the spawn_realm function call doesn't impact the core functionality being tested.

Also applies to: 74-189


72-73: Verify the impact of spawn_realm function signature change.

The spawn_realm function call has been modified, changing from using realm_systems_dispatcher to hardcoded values (1 for maker, 2 for taker). This change might affect how realms are initialized in the test setup. Please ensure that:

  1. The new signature of spawn_realm is correct and consistent with its implementation.
  2. The hardcoded values (1 and 2) are appropriate and won't cause issues in different test scenarios.
  3. The use of .into() on the position is necessary and correct for the new function signature.

To confirm the changes are consistent across the codebase, run the following script:

This will help ensure that the changes are applied consistently and that the new function signature is used correctly throughout the codebase.

✅ Verification successful

Verification Successful: spawn_realm function signature is consistent across the codebase.

All instances of spawn_realm correctly pass the required parameters:

  • world: Maintains the IWorldDispatcher type.
  • realm_id: Uses appropriate numeric IDs (e.g., 1, 2) consistent with the ID type.
  • coord: Utilizes .into() to convert positions to the expected Coord type.

No discrepancies or issues were found regarding the changes to the spawn_realm function calls.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for other occurrences of spawn_realm and verify consistency

# Search for spawn_realm usage
echo "Searching for spawn_realm usage:"
rg --type cairo "spawn_realm\(" -A 2

# Search for the spawn_realm function definition
echo "\nSearching for spawn_realm function definition:"
rg --type cairo "fn spawn_realm"

Length of output: 315


Script:

#!/bin/bash
# Description: Check for other occurrences of spawn_realm and verify consistency by searching .cairo files explicitly

# Search for spawn_realm usage
echo "Searching for spawn_realm usage in .cairo files:"
rg "spawn_realm\(" --glob "*.cairo" -A 2

# Search for the spawn_realm function definition
echo "\nSearching for spawn_realm function definition in .cairo files:"
rg "fn spawn_realm" --glob "*.cairo"

Length of output: 7919

contracts/src/systems/combat/tests/army_create_test.cairo (2)

20-20: LGTM: New imports added for realm setup.

The addition of get_default_realm_pos and spawn_realm imports from the testing utilities is appropriate for the changes made in the setup function. These imports enhance the test setup process by providing more specific realm creation and positioning functionality.


63-63: Existing tests remain intact and valid.

The changes made to the setup function do not negatively impact the existing tests. All test cases continue to function as intended, using the realm_id returned from the modified setup function. The test coverage and scenarios remain unchanged, ensuring the continued validity of the test suite.

contracts/src/utils/testing/world.cairo (3)

Line range hint 1-146: Summary: Refactoring changes look good, verify consistency.

The changes in this file appear to be part of a larger refactoring effort to improve code organization. The main modifications include:

  1. Updating import statements for the season model.
  2. Removing the unused entity_metadata model.

These changes seem to enhance code clarity and remove unnecessary components. However, it's crucial to ensure that these refactoring changes are consistent across the entire codebase.

Please run the verification scripts provided in the previous comments to ensure the refactoring has been applied consistently and doesn't have any unintended consequences in other parts of the project.


Line range hint 57-146: LGTM! Verify the impact of removing entity_metadata.

The removal of entity_metadata::TEST_CLASS_HASH from the models array is consistent with the import changes. This suggests that the entity_metadata model is no longer needed for testing purposes in this context.

To ensure that the removal of entity_metadata doesn't have unintended consequences, please run the following script:

#!/bin/bash
# Description: Verify the impact of removing entity_metadata

# Test 1: Check for any remaining uses of entity_metadata in test files
echo "Checking for remaining uses of entity_metadata in test files:"
rg --type cairo "entity_metadata" $(fd -e cairo -e cairo$ -g "*test*")

# Test 2: Verify that entity_metadata is not used in any world spawning functions
echo "Checking for entity_metadata in world spawning functions:"
rg --type cairo -C 5 "fn spawn_.*world" | rg "entity_metadata"

# Test 3: Check if entity_metadata is still used elsewhere in the project
echo "Checking for any remaining uses of entity_metadata in the project:"
rg --type cairo "entity_metadata"

This script will help ensure that the removal of entity_metadata is consistent across the project and doesn't affect any other parts of the codebase.


25-25: LGTM! Verify refactoring consistency across the codebase.

The changes in the import statements, including the removal of Season and season from hyperstructure and the addition of season from a separate module, appear to be part of a refactoring effort. This change improves code organization by separating concerns.

To ensure consistency across the codebase, please run the following script:

This script will help ensure that the refactoring has been applied consistently across the entire project.

Also applies to: 46-46

✅ Verification successful

Refactoring verified successfully.

All import changes have been consistently applied across the codebase. No remaining imports of Season or season from hyperstructure, and no uses of entity_metadata were found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the refactoring of Season and season imports across the codebase

# Test 1: Check for any remaining imports of Season or season from hyperstructure
echo "Checking for remaining imports from hyperstructure:"
rg --type cairo "use eternum::models::hyperstructure::(Season|season)" || echo "No remaining imports found."

# Test 2: Verify the new import pattern for season
echo "Verifying new import pattern for season:"
rg --type cairo "use eternum::models::season::season"

# Test 3: Check for any remaining uses of entity_metadata
echo "Checking for remaining uses of entity_metadata:"
rg --type cairo "entity_metadata::"

Length of output: 1983


Script:

#!/bin/bash
# Description: Verify the refactoring of Season and season imports across the codebase

# Test 1: Check for any remaining imports of Season or season from hyperstructure
echo "Checking for remaining imports of Season or season from hyperstructure:"
fd --extension cairo --search-path contracts | xargs rg "use eternum::models::hyperstructure::(Season|season)" || echo "No remaining imports found."

# Test 2: Verify the new import pattern for season
echo "Verifying new import pattern for season:"
fd --extension cairo --search-path contracts | xargs rg "use eternum::models::season::season"

# Test 3: Check for any remaining uses of entity_metadata
echo "Checking for any remaining uses of entity_metadata:"
fd --extension cairo --search-path contracts | xargs rg "entity_metadata::" || echo "No remaining uses of entity_metadata found."

Length of output: 880

sdk/packages/eternum/src/types/common.ts (5)

39-43: LGTM: New Access enum added

The new Access enum is a good addition, providing clear definitions for different access levels (Public, Private, GuildOnly). This can be useful for controlling access to various game features or resources.


265-265: LGTM: resourceRarity property added to Config interface

The addition of the resourceRarity property to the resources section of the Config interface is a good enhancement. It allows for the definition of rarity values for different resource types, which can be useful for game mechanics or UI display purposes.


334-339: LGTM: Troop bounds added to mercenaries configuration

The addition of lower and upper bounds for knights, paladins, and crossbowmen in the mercenaries section of the Config interface is a good improvement. This change allows for more precise control over mercenary troop numbers, which can be beneficial for game balancing and mechanics.


352-368: LGTM: New season and bridge sections added to Config interface

The addition of season and bridge sections to the Config interface is a significant enhancement:

  1. The season section includes addresses for season pass, realms, and lords, which suggests integration with smart contracts.
  2. The bridge section introduces a detailed fee structure for bridge operations, including various percentages and recipient addresses.

These additions provide a robust configuration for season-related features and bridge operations. The fee structure in the bridge section is quite detailed, which allows for fine-grained control but also introduces complexity. Ensure that the logic handling these fees is well-documented and tested to prevent potential issues.


391-395: LGTM: New Player interface added

The addition of the Player interface is a good enhancement to the type system. It provides a clear structure for representing player information, including an entity ID, blockchain address, and a human-readable address name. This interface will be useful for maintaining consistency in player data throughout the application.

contracts/src/constants.cairo (2)

Line range hint 1-355: Summary of changes and recommendations

The changes in this file primarily involve reordering and adding new resource types. These modifications have been consistently applied throughout most of the file, including the ResourceTypes module, resource_type_name function, and various utility functions.

Key points:

  1. The reordering and addition of resource types appear intentional and well-structured.
  2. Most functions have been correctly updated to use the new resource type values.
  3. The resource_type_name function could benefit from refactoring for better maintainability.
  4. The all_resource_ids() function needs to be updated to reflect the new resource type order.

Please address the inconsistency in the all_resource_ids() function and consider the suggested refactoring for the resource_type_name function. Also, ensure that all other parts of the codebase that rely on these resource type values have been updated accordingly.


78-100: Resource types have been reordered and new types added.

The ResourceTypes module has undergone significant changes:

  1. The order of basic resources (STONE, COAL, WOOD) has been modified.
  2. New resource types have been added (e.g., MITHRAL, ALCHEMICAL_SILVER, DEEP_CRYSTAL).
  3. The values for existing resources have been updated to accommodate the new order.

These changes appear intentional and well-structured. However, please ensure that all other parts of the codebase that rely on these resource type values have been updated accordingly to prevent any inconsistencies or bugs.

To verify the impact of these changes, please run the following script:

✅ Verification successful

Verification Successful: No usages of old resource type values found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for usages of old resource type values in the codebase

# Search for hardcoded old resource type values
echo "Searching for old resource type values:"
rg --type cairo '(WOOD: u8 = 1|STONE: u8 = 2|COAL: u8 = 3)' --glob '!contracts/src/constants.cairo'

# Search for potential usages of resource types that might need updating
echo "Searching for potential usages of resource types:"
rg --type cairo 'ResourceTypes::(WOOD|STONE|COAL|IRONWOOD|OBSIDIAN|GOLD|SILVER|DIAMONDS|HARTWOOD|IGNIUM|ETHEREAL_SILICA|TRUE_ICE|ADAMANTINE)' --glob '!contracts/src/constants.cairo'

Length of output: 543


Script:

#!/bin/bash
# Description: Check for usages of old resource type values in the codebase

# Search for hardcoded old resource type values
echo "Searching for old resource type values:"
rg '(WOOD: u8 = 1|STONE: u8 = 2|COAL: u8 = 3)' -g '*.cairo' --glob '!contracts/src/constants.cairo'

# Search for potential usages of resource types
echo "Searching for potential usages of resource types:"
rg 'ResourceTypes::(WOOD|STONE|COAL|IRONWOOD|OBSIDIAN|GOLD|SILVER|DIAMONDS|HARTWOOD|IGNIUM|ETHEREAL_SILICA|TRUE_ICE|ADAMANTINE)' -g '*.cairo' --glob '!contracts/src/constants.cairo'

Length of output: 37344

client/src/hooks/helpers/useStructures.tsx (3)

Line range hint 1-280: Summary of changes and potential impact.

The changes in this file are part of a larger refactoring effort to improve configuration management and resource representation. Key changes include:

  1. Moving from EternumGlobalConfig to more specific entity-based configurations using DONKEY_ENTITY_TYPE and configManager.getSpeedConfig().
  2. Updating realm resource representation from resource_types_packed to produced_resources.

These changes generally improve the flexibility and maintainability of the code. However, it's crucial to ensure that these changes have been consistently applied across the entire codebase to prevent any inconsistencies or errors.

To ensure a smooth transition, please verify that:

  1. All usages of EternumGlobalConfig have been updated appropriately.
  2. The Realm component structure has been updated to reflect the new produced_resources field.
  3. Any other files that interact with realm resources or entity speeds have been updated to use the new patterns established in this file.

Consider running a full suite of tests and performing a thorough QA process to catch any potential issues arising from these changes.


234-236: Approve time to travel calculation update and verify consistency.

The time to travel calculation has been updated to use configManager.getSpeedConfig(DONKEY_ENTITY_TYPE) instead of EternumGlobalConfig.speed.donkey. This change aligns with the move towards more specific entity-based configurations and provides a more flexible approach.

To ensure consistency across the codebase, please run the following script to check for any remaining usages of EternumGlobalConfig.speed:

#!/bin/bash
# Description: Check for remaining usages of EternumGlobalConfig.speed

# Test: Search for EternumGlobalConfig.speed usage
rg --type typescript --type tsx 'EternumGlobalConfig\.speed'

If the script returns any results, consider updating those occurrences to use the configManager.getSpeedConfig() approach for consistency and maintainability.


230-230: Verify consistency of realm resource representation.

The resource unpacking has been updated to use realm.produced_resources instead of realm.resource_types_packed. This change suggests a shift in how resources are represented for a realm.

Please run the following script to check for any remaining usages of resource_types_packed that might need to be updated:

#!/bin/bash
# Description: Check for remaining usages of resource_types_packed

# Test: Search for resource_types_packed usage
rg --type typescript --type tsx 'resource_types_packed'

If the script returns any results, those occurrences may need to be updated to use produced_resources for consistency. Additionally, verify that the Realm component structure has been updated accordingly in the relevant model or component definition file.

contracts/src/systems/trade/tests/trade_systems_tests/accept_order.cairo (3)

76-77: Simplified realm spawning process: Approved

The changes to the realm spawning process in the setup function are a good improvement:

  1. It simplifies the setup by removing the intermediate realm_systems_dispatcher.
  2. Using specific entity IDs (1 for maker, 2 for taker) makes the test more deterministic.
  3. This change enhances readability and maintainability of the test setup.

Line range hint 1-253: Overall Assessment: Improvements to Test Setup and Error Handling

The changes in this file enhance the test suite in two main areas:

  1. Simplified realm spawning in the setup function, improving readability and maintainability.
  2. Updated error message in the trade_test_transport_not_enough_donkey_capacity test, potentially reflecting changes in the resource management system.

These modifications align with the goal of streamlining the setup process and adjusting error handling to accurately reflect the current state of the system. The changes appear to be positive improvements to the test suite.


230-230: Updated error message: Verify consistency

The change in the error message, specifically the entity ID from 4 to 3, appears to reflect an update in how resources are tracked or referenced within the system. This aligns with the goal of ensuring tests accurately reflect the current state of the resource management system.

To ensure this change is consistent across the codebase, please run the following script:

This will help verify that:

  1. There are no remaining references to entity ID 4 in similar error messages.
  2. The use of entity ID 3 is consistent in other parts of the codebase.

Please review the results to ensure this change is applied consistently throughout the project.

✅ Verification successful

Revised Verification Scripts Needed

The previous scripts failed because the file type cairo is not recognized by ripgrep. To proceed, please run the following updated scripts that correctly target .cairo files:

This adjustment ensures that the searches are confined to .cairo files by using the --glob "*.cairo" parameter, bypassing the need for a predefined file type.


Change Verified: Entity ID Updated Consistently

The change from entity ID 4 to 3 in the error message has been successfully verified. No remaining references to entity ID 4 were found, and entity ID 3 is used consistently across the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining references to entity ID 4 in error messages related to resource management

# Search for error messages containing 'not enough resources' and 'entity id: 4'
rg --type cairo "not enough resources.*entity id: 4" -C 3

# Search for other occurrences of 'entity id: 3' in error messages
rg --type cairo "entity id: 3" -C 3

Length of output: 157


Script:

# 
#!/bin/bash
# Description: Check for any remaining references to entity ID 4 in error messages related to resource management within .cairo files

# Search for error messages containing 'not enough resources' and 'entity id: 4' in .cairo files
rg "not enough resources.*entity id: 4" --glob "*.cairo" -C 3

# Search for other occurrences of 'entity id: 3' in .cairo files
rg "entity id: 3" --glob "*.cairo" -C 3

Length of output: 826

contracts/src/systems/realm/tests.cairo (5)

156-156: LGTM.

The change to hardcode the realm ID to 1 is consistent with the previous functions. The test's logic for upgrading a realm's level and checking resource consumption remains intact.


189-189: LGTM.

The change to hardcode the realm ID to 1 is consistent with the previous functions. The test's logic for checking the upgrade attempt by a non-owner remains intact.


218-218: LGTM.

The change to hardcode the realm ID to 1 is consistent with the previous functions. The test's logic for checking the upgrade attempt on a realm at max level remains intact.


241-241: LGTM.

The change to hardcode the realm ID to 1 is consistent with the previous functions. The test's logic for checking the upgrade attempt with insufficient resources remains intact.


253-253: LGTM.

The change to hardcode the realm ID to 1 is consistent with the previous functions. The test's logic for checking multiple level upgrades and resource consumption remains intact.

contracts/src/systems/combat/tests/battle_start_test.cairo (2)

27-27: LGTM: Improved import organization

The addition of general::{mint, teleport, spawn_realm} to the imports suggests a move towards more generalized testing utilities. This change likely improves code organization and reusability across tests.


Line range hint 1-265: Overall assessment: Improved test setup with consistent realm creation

The changes in this file focus on improving the realm creation process in the setup function. The use of spawn_realm() and explicit coordinate definitions enhances code clarity and consistency. These modifications do not alter the test logic in combat_test_battle_start(), maintaining the integrity of the test.

To ensure these changes don't have unintended consequences, please run the following verification script:

This script will help verify that the spawn_realm() function is used consistently across all test files and that all tests still pass with the new realm creation method.

sdk/packages/eternum/src/constants/global.ts (1)

11-11: LGTM: New imports and constants added

The addition of RESOURCE_RARITY to the imports and the new population-related configuration constants (BUILDING_CATEGORY_POPULATION_CONFIG_ID and POPULATION_CONFIG_ID) are appropriate additions to the game mechanics.

Also applies to: 20-21

contracts/src/systems/map/tests.cairo (1)

Line range hint 1-247: Overall assessment of the change in the test file.

The modification in the setup function is the only change in this file. While it doesn't directly alter the logic of the existing tests, it's crucial to ensure that this change in realm spawning doesn't indirectly affect the test outcomes. The tests for map exploration, mine creation, and production deadlines remain unchanged, which is good for maintaining existing functionality.

To ensure the change doesn't introduce any regressions, please run the entire test suite and confirm that all tests pass with this modification.

contracts/src/systems/combat/tests/battle_leave_test.cairo (1)

22-22: LGTM: New imports added for test setup.

The addition of mint and spawn_realm imports from the testing utilities is appropriate for the changes made in the realm creation process.

contracts/src/systems/hyperstructure/tests.cairo (2)

Line range hint 1-424: Overall assessment: Minor change with potential impact on test setup

The modification in this file is limited to a single line change in the setup function. While this change simplifies the spawn_realm function call, it's crucial to ensure that it doesn't alter the test environment in unexpected ways.

Given that this file contains numerous test cases for the hyperstructure system, I recommend:

  1. Running the entire test suite to verify that all tests still pass with this change.
  2. Reviewing the spawn_realm function implementation to confirm that the new parameter value (1) is handled correctly.
  3. Updating any documentation related to the test setup process to reflect this change.

To ensure the integrity of the test suite, please run the following command:

#!/bin/bash
# Run the test suite for the hyperstructure system
# Replace 'your_test_command' with the actual command used to run these tests
your_test_command contracts/src/systems/hyperstructure/tests.cairo

This will help verify that the change hasn't introduced any regressions in the test cases.


46-46: Clarification needed: Simplification of spawn_realm parameters

The change from deploy_realm_systems(world) to 1 simplifies the spawn_realm function call. However, it's not immediately clear why 1 is an appropriate replacement.

Could you please provide some context on this change? Additionally, consider adding a comment to explain the significance of the value 1 in this context. This would improve code readability and make it easier for other developers to understand the test setup.

To ensure this change doesn't introduce any regressions, please run the following command to check for any other occurrences of deploy_realm_systems:

✅ Verification successful

Change Verified: Replacement of deploy_realm_systems with 1 is isolated and does not impact other parts of the codebase.

However, to maintain code readability, please consider adding a comment explaining the rationale behind using the value 1 in this context.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other occurrences of deploy_realm_systems
rg "deploy_realm_systems" --type cairo

Length of output: 153


Script:

#!/bin/bash
# Search for other occurrences of deploy_realm_systems
rg "deploy_realm_systems" --type cairo

Length of output: 68


Script:

#!/bin/bash
# Search for other occurrences of deploy_realm_systems in .cairo files
rg "deploy_realm_systems" --glob "*.cairo"

Length of output: 2022

sdk/packages/eternum/src/types/provider.ts (4)

489-493: LGTM: New interface for season configuration.

The SetSeasonConfigProps interface is well-structured and consistent with the existing codebase. It provides a clear way to configure season-related addresses.


495-498: LGTM: New interface for resource bridge whitelist configuration.

The SetResourceBridgeWhitelistConfigProps interface is well-defined and consistent with the existing codebase. It provides a clear way to configure whitelisting for resource bridging.


559-564: LGTM: Enhanced granularity in mercenary configuration.

The changes to SetMercenariesConfigProps provide more precise control over troop configurations by introducing separate lower and upper bounds for each troop type. This is a good improvement in terms of flexibility.

Please ensure the following:

  1. Verify that the implementation of mercenary configuration logic has been updated to use these new properties correctly.
  2. Check if the Troops interface (defined around line 450) is still used elsewhere in the codebase. If not, consider removing it.

Run the following script to check the usage of the Troops interface:

#!/bin/bash
# Description: Check for usage of Troops interface

echo "Searching for Troops interface definition:"
rg "interface\s+Troops" --type typescript

echo "Searching for Troops type usage:"
rg ":\s*Troops" --type typescript
  1. Update any documentation related to mercenary configuration to reflect these changes.

532-534: LGTM: Improved flexibility in access control.

The renaming of SetPrivateProps to SetAccessProps and the replacement of the to_private boolean with an access number provides more flexibility in access control.

Please ensure that all usages of the old SetPrivateProps interface and to_private property have been updated throughout the codebase. Run the following script to check for any remaining occurrences:

✅ Verification successful

Verified: No remaining usages of SetPrivateProps and to_private found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for usage of old SetPrivateProps interface and to_private property

echo "Searching for SetPrivateProps usage:"
rg "SetPrivateProps" --type typescript

echo "Searching for to_private property usage:"
rg "to_private" --type typescript

Length of output: 414


Script:

#!/bin/bash
# Description: Check for usage of old SetPrivateProps interface and to_private property

echo "Searching for SetPrivateProps usage:"
rg "SetPrivateProps" --glob "*.ts" --glob "*.tsx"

echo "Searching for to_private property usage:"
rg "to_private" --glob "*.ts" --glob "*.tsx"

Length of output: 268

discord-bot/src/types.rs (1)

Line range hint 393-419: Summary: Improved realm data representation

The changes to the parse_settle_realm function and the SettleRealm struct enhance the representation of realm data by adding more detailed attributes. These modifications provide a richer set of information about each realm, which could be beneficial for game logic, user interface, or analytics.

The removal of resource_types_packed and resource_types_count in favor of produced_resources suggests a simplification of the resource representation, which could lead to easier data handling.

Overall, these changes appear to be a positive improvement to the codebase, offering more detailed and potentially more useful realm information.

contracts/src/systems/hyperstructure/contracts.cairo (5)

4-4: LGTM: Improved access control mechanism

The addition of the Access enum and its integration into the Hyperstructure struct enhances the access control mechanism, providing more granular control over hyperstructure accessibility.

Also applies to: 43-43


143-143: LGTM: Appropriate default access setting

Initializing the access field to Access::Public is a sensible default, assuming most hyperstructures should be publicly accessible upon creation.


309-309: LGTM: Proper season ending on game completion

The addition of SeasonImpl::end_season(world); ensures that the season is correctly concluded when the game ends, maintaining the integrity of the game state.


273-285: ⚠️ Potential issue

Implemented set_access function with appropriate access control checks

The new set_access function correctly updates the hyperstructure's access level and enforces that only guild members can set the access to GuildOnly. This ensures proper validation and maintains the integrity of access control.

Potential runtime error if the caller is not a guild member

If the GuildMember component does not exist for the caller, the get! macro might fail, leading to a runtime error. To prevent this and provide a clearer error message, consider adding a check to verify the existence of the GuildMember component before accessing it.

Apply this diff to improve error handling:

 fn set_access(ref world: IWorldDispatcher, hyperstructure_entity_id: ID, access: Access) {
     let owner = get!(world, hyperstructure_entity_id, Owner);
     owner.assert_caller_owner();

     let mut hyperstructure = get!(world, hyperstructure_entity_id, Hyperstructure);
     hyperstructure.access = access;

     if (access == Access::GuildOnly) {
         let caller_address = starknet::get_caller_address();
+        assert!(world.has::<GuildMember>(caller_address), "caller is not a guild member");
         let caller_guild_member = get!(world, caller_address, GuildMember);
         assert!(caller_guild_member.guild_entity_id != 0, "caller is not in a guild");
     }

     set!(world, (hyperstructure,));
 }

Likely invalid or redundant comment.


173-173: LGTM: Improved robustness in contribution logic

The addition of the season check and the use of assert_access method enhance the function's robustness and access control.

Please confirm the implementation of the assert_access method in the Hyperstructure struct. Run the following script to verify:

Also applies to: 181-181

contracts/src/systems/trade/contracts/trade_systems.cairo (6)

49-49: Import change looks good.

The addition of the SeasonImpl import is consistent with the changes made throughout the file, replacing SeasonCustomImpl with SeasonImpl.


119-119: Season check update in create_order is correct.

The SeasonImpl::assert_season_is_not_over(world) call replaces the previous SeasonCustomImpl implementation, maintaining the same functionality while using the newly imported SeasonImpl.


245-245: Season check update in accept_order is correct.

The SeasonImpl::assert_season_is_not_over(world) call replaces the previous SeasonCustomImpl implementation, maintaining consistency with the changes made throughout the file.


266-266: Season check update in accept_partial_order is correct.

The SeasonImpl::assert_season_is_not_over(world) call replaces the previous SeasonCustomImpl implementation, maintaining consistency with the changes made throughout the file.


440-440: Season check update in cancel_order is correct.

The SeasonImpl::assert_season_is_not_over(world) call replaces the previous SeasonCustomImpl implementation, maintaining consistency with the changes made throughout the file.


Line range hint 1-524: Overall changes look good and improve consistency.

The modifications in this file are limited to replacing SeasonCustomImpl with SeasonImpl across multiple functions. These changes:

  1. Maintain the existing logic and functionality.
  2. Improve code consistency by using the new SeasonImpl.
  3. Align with the updated season implementation.

No logical changes or potential issues were introduced. The refactoring appears to be clean and well-executed.

contracts/src/models/config.cairo (1)

40-49: LGTM: New SeasonConfig struct looks good

The new SeasonConfig struct is well-defined and appears to provide necessary configuration for the season system. The use of ContractAddress for address fields is appropriate.

sdk/packages/eternum/src/config/index.ts (3)

26-28: LGTM: New configuration methods integrated into setup

The new configuration methods for season, resource bridge whitelist, and resource bridge fees have been appropriately integrated into the setup method. This ensures that all necessary configurations are set up during initialization.


418-427: LGTM: New setSeasonConfig method added

The setSeasonConfig method has been implemented correctly. It properly configures the season-related addresses using the provider's set_season_config method. The console log provides useful feedback about the configuration process.


526-533: LGTM: Improved flexibility in mercenary configuration

The changes to setMercenariesConfig method improve the flexibility of mercenary configuration by using lower and upper bounds for troop counts instead of fixed counts. This implementation is correct and consistent with the rest of the codebase.

Regarding the previous review comment about code duplication, while the suggestion to use a loop for setting troop bounds is valid, the current implementation is still readable and maintainable. If you decide to refactor in the future, consider using an object to store the troop types and their corresponding bounds, which could then be iterated over to set the configuration.

sdk/packages/eternum/src/provider/index.ts (3)

1042-1049: Improved flexibility in access control

The set_private method has been renamed to set_access, with the following improvements:

  1. The method name is now more generic, suggesting it can handle various access levels beyond just public/private.
  2. The parameter to_private has been changed to access, which is more descriptive and flexible.

This change enhances the clarity and potential functionality of the access control system. It allows for more nuanced access settings, which could be beneficial for future expansions of the game's permission system.


1088-1110: Enhanced mercenaries configuration with troop-specific bounds

The set_mercenaries_config method has been significantly improved:

  1. The method now accepts specific upper and lower bounds for each troop type (knights, paladins, crossbowmen).
  2. This granular control allows for more nuanced balancing of mercenary troops.
  3. The calldata has been updated to include all these new parameters.

These changes provide several benefits:

  • More precise control over the composition of mercenary forces.
  • Ability to create diverse gameplay scenarios by adjusting troop ratios.
  • Potential for dynamic balancing of the game economy and combat system.

This improvement adds depth to the mercenary system and provides tools for fine-tuning gameplay balance. It's a positive change that enhances the game's strategic elements.


737-745: New seasonal configuration system added

A new set_season_config method has been introduced with the following features:

  1. It allows setting addresses for season pass, realms, and lords.
  2. This suggests the implementation of a seasonal system in the game.

The addition of this method indicates a potential expansion of the game's mechanics to include time-limited events, seasonal progression, or other time-based features. This could enhance player engagement and provide a framework for regular content updates.

To ensure this new feature is properly integrated, let's check for any related components or systems:

✅ Verification successful

Seasonal Configuration System Properly Integrated

The set_season_config method has been successfully integrated across the codebase. Searches confirmed its usage in the following areas:

  • sdk/packages/eternum/src/constants/global.ts
  • sdk/packages/eternum/src/types/provider.ts
  • sdk/packages/eternum/src/types/common.ts
  • sdk/packages/eternum/src/config/index.ts

This indicates that the seasonal configuration system is consistently implemented, supporting time-limited events and seasonal progression as intended.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other season-related components
rg --type typescript "season" -g "!**/provider/index.ts"

Length of output: 91


Script:

#!/bin/bash
# Search for other season-related components in TypeScript files, excluding provider/index.ts
rg "season" -g "*.ts" -g "!provider/index.ts"

Length of output: 3418

client/src/dojo/contractComponents.ts (2)

505-512: Improved access control for Hyperstructure component

The replacement of the 'private' boolean with an 'access' enum provides more flexible and granular access control. This change enhances the component's ability to handle different levels of access, which is a good practice for complex systems.


979-992: New RealmMaxLevelConfig component added

The addition of the RealmMaxLevelConfig component complements the RealmLevelConfig by defining a maximum level for Realms. This is a good practice for setting upper bounds on progression systems.

The use of u8 for max_level allows for up to 255 levels, which should be sufficient for most game designs. If there's a possibility that more levels might be needed in the future, consider using u16 instead for additional flexibility.

contracts/src/systems/combat/contracts.cairo (4)

421-422: Approved: Consistent import change for season validation

The addition of use eternum::models::season::SeasonImpl; aligns with the transition from SeasonCustomImpl to SeasonImpl for season validation, as mentioned in the summary. This change appears to be part of a broader refactoring effort to improve season-related functionality.


Line range hint 448-469: Approved: Consistent season validation update

The replacement of SeasonCustomImpl::assert_season_is_not_over(world) with SeasonImpl::assert_season_is_not_over(world) in the army_create function is part of the broader refactoring mentioned in the summary. This change is consistent and appears throughout the file, updating the season validation mechanism without altering the core logic of army creation.


Line range hint 496-984: Approved: Comprehensive season validation refactoring

The consistent replacement of SeasonCustomImpl::assert_season_is_not_over(world) with SeasonImpl::assert_season_is_not_over(world) across multiple functions (army_buy_troops, army_merge_troops, battle_start, battle_force_start, battle_join, battle_leave, battle_claim, and battle_pillage) demonstrates a thorough and systematic refactoring effort. This uniformity in season validation across various combat-related operations enhances code consistency and maintainability.

Benefits of this refactoring include:

  1. Improved code consistency across the combat system.
  2. Easier maintenance and updates to season-related functionality in the future.
  3. Reduced risk of inconsistencies in season validation between different combat operations.

The core logic of these functions remains unchanged, preserving the existing behavior while updating the implementation details.


Line range hint 421-984: Summary: Successful season validation refactoring

This pull request successfully implements a consistent refactoring of the season validation mechanism across the combat system. The changes include:

  1. Updating the import statement to use SeasonImpl instead of SeasonCustomImpl.
  2. Replacing all instances of SeasonCustomImpl::assert_season_is_not_over(world) with SeasonImpl::assert_season_is_not_over(world) in relevant functions.

These changes enhance code consistency and maintainability without altering the core logic of the combat system. The refactoring appears to be thorough and well-executed, with no apparent issues or inconsistencies.

Recommendation: Approve these changes, as they contribute to improved code quality and easier future maintenance of season-related functionality.

contracts/src/systems/dev/contracts/realm.cairo (1)

58-59: Verify caller's authorization and address correctness

The function retrieves the caller's address and uses it to mint the realm:

let caller = starknet::get_caller_address();
IRealmSystemsDispatcher { contract_address: realm_systems_address }.create(caller, realm_id, frontend);

Ensure that the caller is authorized to perform this action and that the address retrieved is correct, especially in the context of testing versus production environments.

You can run the following script to check if the create function is correctly secured:

client/src/data/orders.ts (4)

16-16: Spelling Correction in "The Order of Titans" Description

The word "attuned" is used; verify if "tuned" is more appropriate.

Please confirm whether "attuned" is the intended word.


4-4: ⚠️ Potential issue

Grammar Correction in "The Order of Perfection" Description

There is a duplicated conjunction "and" in the description.

Apply this diff to fix the sentence:

-"The Order of Perfection loves to both appreciate and create beautiful things. They disregard confrontation in favor of creation, appreciation, and protection of art and and refinement of culture. Although often dismissed as just artists and bards, those with intelligence know that the most dangerous creations originate from the Order of Perfection, and hope to never see those creations come to light.",
+"The Order of Perfection loves to both appreciate and create beautiful things. They disregard confrontation in favor of creation, appreciation, and protection of art and refinement of culture. Although often dismissed as just artists and bards, those with intelligence know that the most dangerous creations originate from the Order of Perfection, and hope to never see those creations come to light.",

Likely invalid or redundant comment.


7-7: ⚠️ Potential issue

Spelling Correction in "The Order of Fury" Description

The word "assasinations" is misspelled. The correct spelling is "assassinations".

Apply this diff to correct the spelling:

-"... destroys its own power structures constantly due to infighting and assasinations.",
+"... destroys its own power structures constantly due to infighting and assassinations.",

Likely invalid or redundant comment.


2-2: ⚠️ Potential issue

Typographical Error: Replace "order_statments" with "order_statements"

The variable name order_statments seems to be misspelled. It should be order_statements.

Apply this diff to correct the typo:

-export const order_statments = [
+export const order_statements = [

Likely invalid or redundant comment.

contracts/src/systems/transport/contracts/travel_systems.cairo (3)

30-30: Approved: Imports for Season and Stamina Implementations

The addition of SeasonImpl and StaminaCustomImpl imports is appropriate, as they are utilized in the travel and travel_hex functions to handle season checks and stamina costs.


68-68: Approved: Season Check in travel Function

Including SeasonImpl::assert_season_is_not_over(world); in the travel function ensures that travel actions cannot be initiated when the season is over, aligning with the game's rules and preventing unintended behavior.


92-92: Approved: Season Check in travel_hex Function

Adding SeasonImpl::assert_season_is_not_over(world); to the travel_hex function correctly prohibits hex-based travel when the season has concluded, maintaining consistency in game mechanics.

contracts/src/systems/map/contracts.cairo (6)

35-35: Importing SeasonImpl

The addition of use eternum::models::season::SeasonImpl; is appropriate, enabling seasonal checks within the system.


82-82: Ensure Season Is Active Before Exploration

Including SeasonImpl::assert_season_is_not_over(world); in the explore function ensures that exploration actions are only permitted during an active season. This prevents unintended behavior after the season ends.


173-176: Transfer Rewards to Shard Mine Structure

Transferring rewards to the newly created shard mine structure using InternalResourceSystemsImpl::transfer correctly initializes the structure with resources from mercenaries_config. This ensures the structure starts with the intended assets.


281-285: Initialize Troops with Randomized Counts

Creating a Troops instance with the randomized counts for knights, paladins, and crossbowmen adds variability to the mercenaries defending the shard mine. This dynamic setup enhances gameplay unpredictability.


287-287: Normalize Troop Counts

Calling troops.normalize_counts(); ensures that the troop counts conform to predefined limits, maintaining balance within the game mechanics.


289-289: Add Troops to Defensive Army

Adding the initialized troops to the defensive army with InternalCombatImpl::add_troops_to_army completes the setup for the shard mine's defenses.

contracts/src/systems/realm/contracts.cairo (1)

132-132: Ensure assert_caller_owner handles unauthorized access appropriately

The method get!(world, realm_id, EntityOwner).assert_caller_owner(world); assumes that the caller is the owner of the realm. If the caller is not the owner, it should revert or handle the unauthorized access properly.

Confirm that assert_caller_owner properly handles unauthorized access by reverting the transaction with an appropriate error message.

✅ Verification successful

Verified: assert_caller_owner properly handles unauthorized access by reverting as expected.

  • Located in contracts/src/models/owner.cairo
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that 'assert_caller_owner' reverts when the caller is not the owner.

# Test: Attempt to call 'upgrade_level' as a non-owner and expect a revert.
# Note: This is a high-level test description; actual testing requires a testing framework.

# Since we cannot execute the code, ensure that 'assert_caller_owner' includes a revert statement.
rg --type cairo --context 5 "fn assert_caller_owner" contracts/

Length of output: 95


Script:

#!/bin/bash
# Description: Verify that 'assert_caller_owner' includes a revert statement when unauthorized access occurs.

# Search for 'fn assert_caller_owner' in .cairo files and check for 'revert' statements within the function.
rg -g "*.cairo" --context 5 "fn assert_caller_owner" contracts/

Length of output: 1234

contracts/src/models/realm.cairo (2)

263-278: Efficient implementation of produces_resource function

The produces_resource function correctly checks whether a realm produces a specific resource by iterating over the packed resources. The use of bitwise operations and a loop efficiently searches through the resources.


281-426: Comprehensive unit tests enhance code reliability

The unit tests provided in test_realm_name_and_attrs_decode_impl and test_realm_resources_impl cover a wide range of scenarios and edge cases. This thorough testing increases confidence in the correctness of the implementation.

sdk/packages/eternum/src/constants/resources.ts (4)

43-52: Addition of new resource "Ironwood" is well-implemented

The new resource "Ironwood" has been added correctly with all necessary properties, including trait, value, colour, id, description, img, and ticker.


91-99: Addition of new resource "Alchemical Silver" is well-implemented

The new resource "Alchemical Silver" has been added correctly with all necessary properties. The detailed description and image are appropriate.


201-209: Addition of new resource "Ethereal Silica" is well-implemented

The new resource "Ethereal Silica" has been added correctly with all necessary properties. Its inclusion in the unique tier within RESOURCE_TIERS is appropriate.


9-9: Verify consistency of updated resource IDs across the codebase

Multiple resource IDs have been changed. Please ensure that all references to these resource IDs in other parts of the codebase are updated accordingly to prevent inconsistencies or bugs.

Run the following script to find references to the old resource IDs:

#!/bin/bash
# Description: Find references to old resource IDs in the codebase

# Old IDs and their new mappings
declare -A id_mappings=(
  [1]="3"   # Wood: 1 -> 3
  [2]="1"   # Stone: 2 -> 1
  [3]="2"   # Coal: 3 -> 2
  [5]="6"   # Obsidian: 5 -> 6
  [6]="8"   # Silver: 6 -> 8
  [7]="9"   # Mithral: 7 -> 9
  [8]="11"  # Cold Iron: 8 -> 11
  [17]="18" # True Ice: 17 -> 18
)

# Search for old IDs in the codebase
for old_id in "${!id_mappings[@]}"; do
  echo "Searching for references to old ID: $old_id"
  rg "ResourcesIds\.\w+\s*=\s*$old_id"
done

This script helps identify any lingering references to the old resource IDs.

Also applies to: 18-18, 28-28, 47-47, 57-57, 67-67, 76-76, 85-85, 95-95, 105-105, 113-113, 133-133, 175-175

contracts/src/systems/resources/contracts/resource_bridge_systems.cairo (2)

6-44: Documentation and function signature are well-written.

The documentation for the deposit_initial function is comprehensive and clearly explains the purpose, arguments, configuration requirements, fees, and additional notes. The function signature matches the documentation, and all parameters are appropriately described.


256-258: Verify the use of 0 as the from_entity_id in resource transfer.

In the call to InternalResourceSystemsImpl::transfer, the from_entity_id is set to 0. Ensure that 0 is an acceptable identifier representing the system or a null entity in this context. Using 0 should not inadvertently reference an unintended entity or cause security issues.

Run the following script to confirm that from_entity_id = 0 is a standard practice:

contracts/src/systems/config/contracts.cairo (1)

686-722: Previous refactoring suggestions are still applicable

The past review comments about encapsulating troop bounds into a struct and refactoring repetitive assertions remain valid. Implementing these suggestions will enhance code maintainability and readability.

scripts/indexer.sh (2)

25-27: ⚠️ Potential issue

Review directory navigation for accurate path resolution

The cd commands in lines 25-26 may not navigate to the intended directories due to potential path issues. From the current directory, cd season_pass/contracts moves into season_pass/contracts. However, cd ../scripts/deployment from there attempts to navigate to season_pass/scripts/deployment, which may not exist if scripts is not within season_pass.

To verify the existence and correctness of the paths, consider running:

#!/bin/bash
# Description: Verify directory paths for deployment scripts.

# Check if 'season_pass/contracts' exists
if [ -d "season_pass/contracts" ]; then
  echo "Directory 'season_pass/contracts' exists."
else
  echo "Directory 'season_pass/contracts' does not exist."
fi

# Navigate to 'season_pass/contracts'
cd season_pass/contracts

# Check if '../scripts/deployment' exists from current location
if [ -d "../scripts/deployment" ]; then
  echo "Directory '../scripts/deployment' exists from 'season_pass/contracts'."
else
  echo "Directory '../scripts/deployment' does not exist from 'season_pass/contracts'."
fi

Consider adjusting the paths based on the actual directory structure or using absolute paths to ensure the script functions correctly.


70-70: Verify the updated world address in the torii command

The --world parameter in the torii command on line 70 has been updated to 0x320b2713e324fe3125bbc42d85ff69cb3c0908b436fa38a35746dbc45deeb11. It's important to confirm that this new address is correct and intended, as an incorrect world address could lead to issues with the indexing service.

You can verify the change by comparing it with previous commits:

This script displays the previous and current world addresses to help confirm the change.

WORLD_ADDRESS = "0x320b2713e324fe3125bbc42d85ff69cb3c0908b436fa38a35746dbc45deeb11"
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Old WORLD_ADDRESS occurrences found. Please update all instances to the new address.

The old WORLD_ADDRESS is still present in the following files:

  • contracts/manifests/prod/deployment/manifest.toml
  • contracts/manifests/prod/deployment/manifest.json

Ensure these files are updated to use the new WORLD_ADDRESS to maintain consistency across environments.

🔗 Analysis chain

Verify the new WORLD_ADDRESS and update documentation accordingly.

The WORLD_ADDRESS has been updated to a new value. While this change in the example file is straightforward, it has important implications:

  1. Ensure that the new address 0x320b2713e324fe3125bbc42d85ff69cb3c0908b436fa38a35746dbc45deeb11 is correct and corresponds to the intended world contract in the target environment.
  2. Update any relevant documentation that references the world address to reflect this change.
  3. Remind team members to update their actual Secrets.toml file with this new address if they're using the discord bot.

To verify the correctness of this address, you can run the following script:

This script will help ensure that the address has been updated consistently across the codebase and identify any potential conflicts or outdated references.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the WORLD_ADDRESS usage across the codebase

# Test: Search for occurrences of the old and new WORLD_ADDRESS
echo "Occurrences of the old WORLD_ADDRESS:"
rg "0x76ca3dfc3e96843716f882546f0db96b7da0cf988bdba284b469d0defb2f48f"

echo "Occurrences of the new WORLD_ADDRESS:"
rg "0x320b2713e324fe3125bbc42d85ff69cb3c0908b436fa38a35746dbc45deeb11"

# Test: Check for any other WORLD_ADDRESS definitions
echo "Other potential WORLD_ADDRESS definitions:"
rg "WORLD_ADDRESS\s*=\s*\"0x[a-fA-F0-9]+\""

Length of output: 1839

Comment on lines +14 to +15
env:
SCARB_VERSION: v2.8.2
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider using the SCARB_VERSION environment variable.

The SCARB_VERSION environment variable is defined but not explicitly used in the workflow steps. To ensure consistency and make version updates easier, consider using this variable in the setup steps.

Update the Scarb setup step to use the environment variable:

 - uses: software-mansion/setup-scarb@v1
   with:
+    scarb-version: ${{ env.SCARB_VERSION }}
     tool-versions: season_pass/contracts/.tool-versions
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
env:
SCARB_VERSION: v2.8.2
env:
SCARB_VERSION: v2.8.2
- uses: software-mansion/setup-scarb@v1
with:
scarb-version: ${{ env.SCARB_VERSION }}
tool-versions: season_pass/contracts/.tool-versions

Comment on lines +17 to +27
jobs:
test-season-pass:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: software-mansion/setup-scarb@v1
with:
tool-versions: season_pass/contracts/.tool-versions
- uses: foundry-rs/setup-snfoundry@v3
with:
tool-versions: season_pass/contracts/.tool-versions
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

🛠️ Refactor suggestion

Update actions and pin the Ubuntu version.

The current workflow uses actions/checkout@v3 and runs on ubuntu-latest. To ensure compatibility and consistency, consider the following improvements:

  1. Update actions/checkout to the latest version:

    - uses: actions/checkout@v3
    + uses: actions/checkout@v4
  2. Pin the Ubuntu version to ensure build consistency:

    - runs-on: ubuntu-latest
    + runs-on: ubuntu-22.04
🔗 Analysis chain

Consider updating actions and pinning the Ubuntu version.

The job setup looks good overall, but there are a few suggestions for improvement:

  1. Update the checkout action to the latest version:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
  1. Consider pinning the Ubuntu version to ensure consistency:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-22.04
  1. Verify that the .tool-versions file exists and contains the correct versions:
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the existence and content of the .tool-versions file

# Test: Check if the file exists and display its content
if [ -f "season_pass/contracts/.tool-versions" ]; then
    echo "Content of .tool-versions file:"
    cat "season_pass/contracts/.tool-versions"
else
    echo "Error: .tool-versions file not found"
    exit 1
fi

Length of output: 201


Script:

#!/bin/bash
# Description: Check the version of actions/checkout in the workflow file

# Use grep to find the actions/checkout version
echo "Checking actions/checkout version:"
grep 'uses: actions/checkout@' .github/workflows/test-season-pass.yml || { echo "actions/checkout not found"; exit 1; }

Length of output: 184


Script:

#!/bin/bash
# Description: Verify if the Ubuntu version is pinned in the workflow file

# Check if runs-on is set to ubuntu-latest
echo "Checking runs-on configuration:"
if grep -q 'runs-on: ubuntu-latest' .github/workflows/test-season-pass.yml; then
    echo "runs-on is set to ubuntu-latest. Consider pinning to a specific version like ubuntu-22.04."
    exit 1
else
    echo "runs-on is pinned to a specific Ubuntu version."
fi

Length of output: 346

Comment on lines 14 to 16
VITE_SEASON_PASS_ADDRESS="0x0"
VITE_REALMS_ADDRESS="0x0"
VITE_LORDS_ADDRESS="0x0"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Reconsider using placeholder addresses in production

The newly added variables VITE_SEASON_PASS_ADDRESS, VITE_REALMS_ADDRESS, and VITE_LORDS_ADDRESS are all set to "0x0". This is unusual for a production environment and could potentially lead to issues or security risks.

Consider the following actions:

  1. If these addresses are not yet available, it might be better to leave them undefined or use a more descriptive placeholder (e.g., "NOT_YET_DEPLOYED").
  2. If these addresses should be defined, ensure that the correct production addresses are used instead of "0x0".
  3. Add comments explaining the purpose of these addresses and when they are expected to be populated with real values.

Example:

-VITE_SEASON_PASS_ADDRESS="0x0"
-VITE_REALMS_ADDRESS="0x0"
-VITE_LORDS_ADDRESS="0x0"
+# TODO: Update with actual addresses before deployment
+VITE_SEASON_PASS_ADDRESS="NOT_YET_DEPLOYED"
+VITE_REALMS_ADDRESS="NOT_YET_DEPLOYED"
+VITE_LORDS_ADDRESS="NOT_YET_DEPLOYED"

Additionally, consider adding checks in the application code to ensure these addresses are properly set before using them.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
VITE_SEASON_PASS_ADDRESS="0x0"
VITE_REALMS_ADDRESS="0x0"
VITE_LORDS_ADDRESS="0x0"
# TODO: Update with actual addresses before deployment
VITE_SEASON_PASS_ADDRESS="NOT_YET_DEPLOYED"
VITE_REALMS_ADDRESS="NOT_YET_DEPLOYED"
VITE_LORDS_ADDRESS="NOT_YET_DEPLOYED"

@@ -1,6 +1,6 @@
VITE_PUBLIC_MASTER_ADDRESS="0x779c2c098f066ddde5850ec8426511e46e6499adf0b5c77e8961917413b57db"
VITE_PUBLIC_MASTER_PRIVATE_KEY="0x189765c7b9daa2efdd3025d3236a929ce5e510834b8cba4f002a0d5c1accb5a"
VITE_PUBLIC_WORLD_ADDRESS="0x76ca3dfc3e96843716f882546f0db96b7da0cf988bdba284b469d0defb2f48f"
VITE_PUBLIC_WORLD_ADDRESS="0x320b2713e324fe3125bbc42d85ff69cb3c0908b436fa38a35746dbc45deeb11"
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Old VITE_PUBLIC_WORLD_ADDRESS still present in deployment manifests

The old VITE_PUBLIC_WORLD_ADDRESS is still found in the following files:

  • contracts/manifests/prod/deployment/manifest.toml
  • contracts/manifests/prod/deployment/manifest.json

Please verify if these instances need to be updated to the new address to ensure consistency across your deployment configurations.

🔗 Analysis chain

Verify the new VITE_PUBLIC_WORLD_ADDRESS value

The VITE_PUBLIC_WORLD_ADDRESS has been updated to a new value. This change could have significant implications for the entire system in the production environment.

Please confirm that this new address is correct and has been thoroughly tested. Run the following script to check for any other occurrences of the old address in the codebase:

If any occurrences are found, they may need to be updated as well.


Please run the following script to search for any remaining instances of the old VITE_PUBLIC_WORLD_ADDRESS:


Please run the following script to search for any remaining instances of the old VITE_PUBLIC_WORLD_ADDRESS:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for any remaining instances of the old VITE_PUBLIC_WORLD_ADDRESS

OLD_ADDRESS="0x76ca3dfc3e96843716f882546f0db96b7da0cf988bdba284b469d0defb2f48f"

echo "Searching for occurrences of the old address:"
rg "$OLD_ADDRESS" --type-not env

Length of output: 294


Script:

#!/bin/bash
# Description: Search for any remaining instances of the old VITE_PUBLIC_WORLD_ADDRESS

OLD_ADDRESS="0x76ca3dfc3e96843716f882546f0db96b7da0cf988bdba284b469d0defb2f48f"

echo "Searching for occurrences of the old address:"
rg "$OLD_ADDRESS" --type-not dotenv

Length of output: 300


Script:

#!/bin/bash
# Description: Search for any remaining instances of the old VITE_PUBLIC_WORLD_ADDRESS

OLD_ADDRESS="0x76ca3dfc3e96843716f882546f0db96b7da0cf988bdba284b469d0defb2f48f"

echo "Searching for occurrences of the old address:"
rg "$OLD_ADDRESS" --glob '!*.env*'

Length of output: 530

Comment on lines 241 to 243
ERC20ABIDispatcher { contract_address: token }.transfer_from(realm_systems_address, this, amount),
"Bridge: transfer failed"
);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Handle potential failure of transfer_from method appropriately.

The transfer_from function may return false if the transfer fails due to insufficient allowance or balance issues. While the current assert! checks for a successful transfer, it might be more robust to provide a detailed error message or handle exceptions that could aid in debugging.

Consider enhancing the error message to include specifics:

-                assert!(
-                    ERC20ABIDispatcher { contract_address: token }.transfer_from(realm_systems_address, this, amount),
-                    "Bridge: transfer failed"
-                );
+                let transfer_success = ERC20ABIDispatcher { contract_address: token }
+                    .transfer_from(realm_systems_address, this, amount);
+                assert!(
+                    transfer_success,
+                    "Bridge: transfer_from failed: insufficient allowance or balance"
+                );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ERC20ABIDispatcher { contract_address: token }.transfer_from(realm_systems_address, this, amount),
"Bridge: transfer failed"
);
let transfer_success = ERC20ABIDispatcher { contract_address: token }
.transfer_from(realm_systems_address, this, amount);
assert!(
transfer_success,
"Bridge: transfer_from failed: insufficient allowance or balance"
);

Comment on lines 218 to 225
// ensure this system can only be called by realms systems contract
let caller = get_caller_address();
let (_realm_systems_class_hash, realm_systems_address) =
match world.resource(selector_from_tag!("eternum-realm_systems")) {
dojo::world::Resource::Contract((class_hash, contract_address)) => (class_hash, contract_address),
_ => (Zeroable::zero(), Zeroable::zero())
};
assert!(caller == realm_systems_address, "only realm systems can call this system");
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure realm_systems_address is valid before assertion.

If the eternum-realm_systems resource is not found in the world, realm_systems_address will be zero. This could lead to unintended behavior if get_caller_address() also returns zero, potentially allowing unauthorized access. It's recommended to add a check to ensure realm_systems_address is not zero before asserting that the caller is equal to it.

Apply this diff to add the check:

+                assert!(realm_systems_address.is_non_zero(), "Realm systems address not found");
                 assert!(caller == realm_systems_address, "only realm systems can call this system");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// ensure this system can only be called by realms systems contract
let caller = get_caller_address();
let (_realm_systems_class_hash, realm_systems_address) =
match world.resource(selector_from_tag!("eternum-realm_systems")) {
dojo::world::Resource::Contract((class_hash, contract_address)) => (class_hash, contract_address),
_ => (Zeroable::zero(), Zeroable::zero())
};
assert!(caller == realm_systems_address, "only realm systems can call this system");
// ensure this system can only be called by realms systems contract
let caller = get_caller_address();
let (_realm_systems_class_hash, realm_systems_address) =
match world.resource(selector_from_tag!("eternum-realm_systems")) {
dojo::world::Resource::Contract((class_hash, contract_address)) => (class_hash, contract_address),
_ => (Zeroable::zero(), Zeroable::zero())
};
assert!(realm_systems_address.is_non_zero(), "Realm systems address not found");
assert!(caller == realm_systems_address, "only realm systems can call this system");

Comment on lines 252 to 265
impl SeasonConfigCustomImpl of super::ISeasonConfig<ContractState> {
fn set_season_config(
ref world: IWorldDispatcher,
season_pass_address: starknet::ContractAddress,
realms_address: starknet::ContractAddress,
lords_address: starknet::ContractAddress
) {
assert_caller_is_admin(world);

set!(
world, (SeasonConfig { config_id: WORLD_CONFIG_ID, season_pass_address, realms_address, lords_address })
)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Validate contract addresses before setting the SeasonConfig

Currently, the set_season_config function sets the SeasonConfig with the provided contract addresses without validation. To enhance robustness, consider adding checks to ensure that season_pass_address, realms_address, and lords_address are valid and not zero addresses.

Apply this diff to add validation:

 fn set_season_config(
     ref world: IWorldDispatcher,
     season_pass_address: starknet::ContractAddress,
     realms_address: starknet::ContractAddress,
     lords_address: starknet::ContractAddress
 ) {
     assert_caller_is_admin(world);

+    assert!(season_pass_address != 0, "season_pass_address must be a valid contract address");
+    assert!(realms_address != 0, "realms_address must be a valid contract address");
+    assert!(lords_address != 0, "lords_address must be a valid contract address");

     set!(
         world, (SeasonConfig { config_id: WORLD_CONFIG_ID, season_pass_address, realms_address, lords_address })
     )
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
impl SeasonConfigCustomImpl of super::ISeasonConfig<ContractState> {
fn set_season_config(
ref world: IWorldDispatcher,
season_pass_address: starknet::ContractAddress,
realms_address: starknet::ContractAddress,
lords_address: starknet::ContractAddress
) {
assert_caller_is_admin(world);
set!(
world, (SeasonConfig { config_id: WORLD_CONFIG_ID, season_pass_address, realms_address, lords_address })
)
}
}
impl SeasonConfigCustomImpl of super::ISeasonConfig<ContractState> {
fn set_season_config(
ref world: IWorldDispatcher,
season_pass_address: starknet::ContractAddress,
realms_address: starknet::ContractAddress,
lords_address: starknet::ContractAddress
) {
assert_caller_is_admin(world);
assert!(season_pass_address != 0, "season_pass_address must be a valid contract address");
assert!(realms_address != 0, "realms_address must be a valid contract address");
assert!(lords_address != 0, "lords_address must be a valid contract address");
set!(
world, (SeasonConfig { config_id: WORLD_CONFIG_ID, season_pass_address, realms_address, lords_address })
)
}
}

Comment on lines 35 to 37
sed -i '' '/VITE_SEASON_PASS_ADDRESS=/d' $ENV_FILE
sed -i '' '/VITE_REALMS_ADDRESS=/d' $ENV_FILE
sed -i '' '/VITE_LORDS_ADDRESS=/d' $ENV_FILE
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure cross-platform compatibility of sed -i commands

The sed -i '' syntax used in lines 35-37 is specific to BSD sed (commonly found on macOS). On GNU sed (commonly found on Linux), this syntax will cause an error due to the differing requirements for the -i (in-place edit) option.

To make the script portable across different environments, consider modifying the sed commands as follows:

# Detect the operating system
if [[ "$OSTYPE" == "darwin"* ]]; then
  # macOS/BSD sed
  sed -i '' '/VITE_SEASON_PASS_ADDRESS=/d' "$ENV_FILE"
  sed -i '' '/VITE_REALMS_ADDRESS=/d' "$ENV_FILE"
  sed -i '' '/VITE_LORDS_ADDRESS=/d' "$ENV_FILE"
else
  # GNU sed (Linux)
  sed -i '/VITE_SEASON_PASS_ADDRESS=/d' "$ENV_FILE"
  sed -i '/VITE_REALMS_ADDRESS=/d' "$ENV_FILE"
  sed -i '/VITE_LORDS_ADDRESS=/d' "$ENV_FILE"
fi

Alternatively, you can use a backup extension that works on both versions:

sed -i.bak '/VITE_SEASON_PASS_ADDRESS=/d' "$ENV_FILE"
sed -i.bak '/VITE_REALMS_ADDRESS=/d' "$ENV_FILE"
sed -i.bak '/VITE_LORDS_ADDRESS=/d' "$ENV_FILE"
# Remove backup files after editing
rm "${ENV_FILE}.bak"

echo "VITE_REALMS_ADDRESS=$VITE_REALMS_ADDRESS" >> $ENV_FILE
echo "VITE_LORDS_ADDRESS=$VITE_LORDS_ADDRESS" >> $ENV_FILE

cd ../../../
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Re-evaluate directory changes for script consistency

After executing the deployment scripts, the command cd ../../../ on line 45 may not return to the expected directory, depending on the nested depths of previous cd commands. Similarly, on line 50, the script executes cd contracts, which relies on the current working directory being correct.

To ensure consistent navigation, consider saving the initial directory at the start of the script and returning to it when needed:

# At the beginning of the script
INITIAL_DIR=$(pwd)

# ... your script logic ...

# Return to the initial directory
cd "$INITIAL_DIR"

This approach prevents potential errors caused by incorrect directory paths and makes the script more robust.

Also applies to: 50-50

Enable social before finishing quests
Copy link
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: 13

🧹 Outside diff range and nitpick comments (23)
client/src/ui/components/resources/EntityResourceTable.tsx (2)

26-27: Improve variable naming for clarity.

The capacity calculation could be more readable with explicit variable names that reflect the base capacity concept.

-    const storehouseCapacityKg = gramToKg(configManager.getCapacityConfig(CapacityConfigCategory.Storehouse));
-    return multiplyByPrecision(quantity * storehouseCapacityKg + storehouseCapacityKg);
+    const baseCapacityKg = gramToKg(configManager.getCapacityConfig(CapacityConfigCategory.Storehouse));
+    const totalCapacityKg = baseCapacityKg * (quantity + 1); // Base capacity plus additional capacity per quantity
+    return multiplyByPrecision(totalCapacityKg);

44-47: Consider responsive grid layout.

The current grid layout uses a single column which might not utilize space efficiently on larger screens.

-      <div key={tier}>
-        <div className="grid grid-cols-1 flex-wrap">{resources}</div>
-      </div>
+      <div key={tier}>
+        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">{resources}</div>
+      </div>
client/src/three/components/BattleManager.ts (2)

119-121: Add JSDoc documentation for the public method.

The implementation looks good, but as this is a public method, it would benefit from documentation describing its purpose and return value.

Add JSDoc documentation:

+/**
+ * Returns all active battles in the scene.
+ * @returns Array of battle entries containing their indices and positions
+ */
 getAll() {
   return this.battles.getAll();
 }

160-162: Consider adding type safety to the return value.

The implementation is correct, but explicitly typing the return value would improve type safety and documentation.

Consider adding an interface and return type:

+interface BattleEntry {
+  index: number;
+  position: Position;
+}

 class Battles {
   private battles: Map<ID, { index: number; position: Position }> = new Map();
   
-  getAll() {
+  getAll(): BattleEntry[] {
     return Array.from(this.battles.values());
   }
 }
client/src/ui/components/resources/ResourceChip.tsx (2)

62-104: Consider optimizing the balance update effect.

The current implementation recalculates several values within the interval that could be memoized or moved outside. Also, the dependencies array includes production which might cause unnecessary effect reruns.

Consider these optimizations:

  useEffect(() => {
    const tickTime = configManager.getTick(TickIds.Default) * 1000;
+   const [sign, rate] = productionManager.netRate();
    
    let realTick = useUIStore.getState().currentDefaultTick;
-   const resource = productionManager.getResource();
-   const [sign, rate] = productionManager.netRate();

    const productionDuration = productionManager.productionDuration(realTick);
    const depletionDuration = productionManager.depletionDuration(realTick);

+   const calculateNewBalance = (currentTick: number) => {
+     const resource = productionManager.getResource();
+     const productionDuration = productionManager.productionDuration(currentTick);
+     const depletionDuration = productionManager.depletionDuration(currentTick);
+     
+     return productionManager.balanceFromComponents(
+       resourceId,
+       rate,
+       sign,
+       resource?.balance,
+       productionDuration,
+       depletionDuration,
+     );
+   };

-   const newBalance = productionManager.balanceFromComponents(/*...*/);
+   const newBalance = calculateNewBalance(realTick);
    setBalance(newBalance);

    if (Math.abs(netRate) > 0) {
      const interval = setInterval(() => {
        realTick += 1;
-       const localResource = productionManager.getResource();
-       const localProductionDuration = productionManager.productionDuration(realTick);
-       const localDepletionDuration = productionManager.depletionDuration(realTick);
-
-       const newBalance = productionManager.balanceFromComponents(/*...*/);
+       const newBalance = calculateNewBalance(realTick);
        setBalance(newBalance);
      }, tickTime);
      return () => clearInterval(interval);
    }
-  }, [setBalance, productionManager, netRate, resourceId, production]);
+  }, [setBalance, productionManager, netRate, resourceId]);

Line range hint 136-191: LGTM: UI implementation is well-structured.

The render logic effectively handles all display cases with proper error states and formatting. Consider extracting the tooltip content into a separate component for better maintainability.

Consider extracting tooltip content:

const ResourceTooltip = ({ isConsumingInputsWithoutOutput }: { isConsumingInputsWithoutOutput: boolean }) => (
  <>
    {isConsumingInputsWithoutOutput
      ? "Production has stopped because inputs have been depleted"
      : "Production has stopped because the max balance has been reached"}
  </>
);
client/src/ui/components/worldmap/guilds/Guilds.tsx (3)

34-44: Optimize guild filtering performance

The current filtering implementation can be optimized by moving the toLowerCase() operation outside the filter loop and simplifying the condition.

 const filteredGuilds = useMemo(
   () => {
+    const searchTerm = guildSearchTerm.toLowerCase();
     return guilds.filter((guild) => {
-      const nameMatch = guild.name.toLowerCase().startsWith(guildSearchTerm.toLowerCase());
+      const nameMatch = guild.name.toLowerCase().startsWith(searchTerm);
       if (viewGuildInvites) {
         return nameMatch && guildInvites.some((invite) => invite.guildEntityId === guild.entityId);
       }
       return nameMatch;
     });
   },
   [guilds, guildSearchTerm, guildInvites, viewGuildInvites],
 );

243-243: Add visual feedback for maximum name length

The TextInput has a maxLength constraint but doesn't provide visual feedback to users about the remaining characters.

-      <TextInput placeholder="Tribe Name . . ." onChange={setGuildName} maxLength={MAX_NAME_LENGTH} />
+      <div className="flex flex-col w-full">
+        <TextInput placeholder="Tribe Name . . ." onChange={setGuildName} maxLength={MAX_NAME_LENGTH} />
+        <div className="text-xs text-right text-gray-400">
+          {guildName.length}/{MAX_NAME_LENGTH}
+        </div>
+      </div>

182-182: Handle empty state for search results

The component only shows an empty state message for guild invites but not for search results with no matches.

-      {!guilds.length && viewGuildInvites && <p className="text-center italic">No Tribe Invites Received</p>}
+      {!guilds.length && (
+        <p className="text-center italic">
+          {viewGuildInvites ? "No Tribe Invites Received" : "No Tribes Found"}
+        </p>
+      )}
client/src/hooks/context/DojoContext.tsx (1)

173-232: Simplify loading state management.

The loading state logic is scattered across multiple conditions and could be simplified into a single function for better maintainability.

+const useLoadingState = (isDev: boolean, burnerAccount: any, isConnecting: boolean, isConnected: boolean, controllerAccount: AccountInterface | null) => {
+  if (!accountsInitialized) return true;
+  if (isDev) return !burnerAccount;
+  if (isConnecting) return true;
+  if (!isConnected && !isConnecting && !controllerAccount) return false; // Show login
+  return !controllerAccount && isConnected;
+};

-if (!accountsInitialized) {
-  return <LoadingScreen />;
-}
-
-// Handle Loading Screen
-if (isDev) {
-  if (!burnerAccount) {
-    return <LoadingScreen />;
-  }
-} else {
-  if (isConnecting) {
-    return <LoadingScreen />;
-  }
-  if (!isConnected && !isConnecting && !controllerAccount) {
-    return <LoginScreen connectWallet={connectWallet} />;
-  }
-
-  if (!controllerAccount && isConnected) {
-    // Connected but controllerAccount is not set yet
-    return <LoadingScreen />;
-  }
-}
+const isLoading = useLoadingState(isDev, burnerAccount, isConnecting, isConnected, controllerAccount);
+if (isLoading) return <LoadingScreen />;
+if (!isConnected && !isConnecting && !controllerAccount) return <LoginScreen connectWallet={connectWallet} />;
client/src/ui/components/worldmap/players/PlayersPanel.tsx (2)

103-106: Improve type safety in structure filtering

The structure filtering could be made more type-safe by using optional chaining.

- player.structures.some(
-   (structure) => structure && structure.toLowerCase().includes(searchInput.toLowerCase()),
- )
+ player.structures.some(
+   (structure) => structure?.toLowerCase()?.includes(searchInput.toLowerCase()) ?? false,
+ )
🧰 Tools
🪛 Biome

[error] 104-104: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


234-264: Optimize tooltip handling to reduce code duplication

The tooltip reset logic (setTooltip(null)) is duplicated across click and mouse leave handlers.

Consider extracting tooltip handling into a custom hook or utility function:

const useTooltip = (content: React.ReactNode, position: string = "top") => {
  const setTooltip = useUIStore((state) => state.setTooltip);
  
  return {
    onMouseEnter: () => setTooltip({ content, position }),
    onMouseLeave: () => setTooltip(null),
    clearTooltip: () => setTooltip(null)
  };
};

// Usage in component:
const { onMouseEnter, onMouseLeave, clearTooltip } = useTooltip(<div>Invite to tribe</div>);

// Then in JSX:
<Invite
  onClick={() => {
    whitelistPlayer(player.address);
    clearTooltip();
  }}
  className="fill-gold/70 hover:scale-125 hover:animate-pulse duration-300 transition-all"
  onMouseEnter={onMouseEnter}
  onMouseLeave={onMouseLeave}
/>
client/src/hooks/helpers/useGuilds.tsx (2)

15-70: Consider improving rank sorting robustness

The rank sorting logic could be improved to handle edge cases more gracefully.

Apply this diff to make the sorting more robust:

    .sort((a, b) => {
-     const rankA = parseInt(a!.rank.substring(1)) || Infinity;
-     const rankB = parseInt(b!.rank.substring(1)) || Infinity;
+     const parseRank = (rank: string) => {
+       const num = parseInt(rank.substring(1));
+       return isNaN(num) ? Infinity : num;
+     };
+     return parseRank(a!.rank) - parseRank(b!.rank);
    })

73-156: Consider extracting common ranking logic

The ranking and sorting logic is duplicated across formatGuilds and formatGuildMembers. Consider extracting this into a shared utility function.

Example implementation:

const formatRank = (index: number, rankList: any[]): { rank: string; points: number } => {
  const hasRank = index !== -1;
  return {
    rank: "#" + (hasRank ? String(index + 1) : "NA"),
    points: hasRank ? rankList[index][1] : 0
  };
};
client/src/ui/components/worldmap/guilds/GuildMembers.tsx (1)

14-18: Consider making isOwner and ownerAddress required props

The optional props isOwner and ownerAddress are used in the component logic but their undefined states aren't explicitly handled. This could lead to unexpected behavior.

Consider making these props required or providing default values:

interface GuildMembersProps {
  selectedGuildEntityId: number;
  viewPlayerInfo: (playerAddress: ContractAddress) => void;
  setIsExpanded: (isExpanded: boolean) => void;
-  isOwner?: boolean;
-  ownerAddress?: string;
+  isOwner: boolean;
+  ownerAddress: string;
}
client/src/three/components/Minimap.ts (3)

13-25: Consider using asset management for image paths.

The hardcoded image paths in the LABELS constant could be fragile during refactoring or deployment. Consider:

  1. Moving these paths to a centralized asset configuration
  2. Using a build-time asset management system to handle paths

Line range hint 279-295: Reduce code duplication in drawing methods.

The drawBattles method shares similar logic with drawArmies. Consider extracting the common drawing logic into a reusable method.

+ private drawMapIcon(position: { x: number, y: number }, iconKey: string, size: { width: number, height: number }) {
+   const { x: col, y: row } = position;
+   const cacheKey = `${col},${row}`;
+   if (this.scaledCoords.has(cacheKey)) {
+     const { scaledCol, scaledRow } = this.scaledCoords.get(cacheKey)!;
+     const labelImg = this.labelImages.get(iconKey);
+     if (!labelImg) return;
+
+     this.context.drawImage(
+       labelImg,
+       scaledCol - size.width * (row % 2 !== 0 ? 1 : 0.5),
+       scaledRow - size.height / 2,
+       size.width,
+       size.height,
+     );
+   }
+ }

Line range hint 392-426: Extract magic numbers into named constants.

The zoom implementation uses magic numbers (0.15) for shift calculations. Consider extracting these into named constants for better maintainability.

+ private static readonly ZOOM_SHIFT_FACTOR = 0.15;
+
  private zoom(zoomOut: boolean, event?: MouseEvent) {
    // ...
-     this.mapCenter.col += Math.round(colShift * 0.15);
-     this.mapCenter.row += Math.round(rowShift * 0.15);
+     this.mapCenter.col += Math.round(colShift * Minimap.ZOOM_SHIFT_FACTOR);
+     this.mapCenter.row += Math.round(rowShift * Minimap.ZOOM_SHIFT_FACTOR);
    }
client/src/three/scenes/Worldmap.ts (4)

170-173: Consider debouncing the URL change handler.

The event listener for URL changes clears both entity and hex selections. Consider debouncing this handler to prevent multiple rapid clearings if URL changes happen in quick succession.

-    window.addEventListener("urlChanged", () => {
+    window.addEventListener("urlChanged", debounce(() => {
       this.clearEntitySelection();
       this.clearHexSelection();
-    });
+    }, 250));

203-206: Add volume control for sound effects.

The sound effect playback should respect user preferences. Consider implementing a volume control system.

-        new Audio(dir + soundSelector.hoverClick).play();
+        const audio = new Audio(dir + soundSelector.hoverClick);
+        audio.volume = this.state.soundVolume ?? 1.0;
+        audio.play();

303-311: Consider memoizing army selection logic.

The army selection handler creates new instances and performs path calculations on every selection. Consider memoizing the results to prevent unnecessary recalculations.

+  private armyPathCache = new Map<ID, { paths: Map<string, any>, hexes: any[] }>();
+
   private onArmySelection(selectedEntityId: ID | null) {
     if (!selectedEntityId) {
       this.clearEntitySelection();
       return;
     }

     const audio = new Audio(dir + soundSelector.snap);
+    audio.volume = this.state.soundVolume ?? 1.0;
     audio.play();

+    const cached = this.armyPathCache.get(selectedEntityId);
+    if (cached) {
+      this.state.updateTravelPaths(cached.paths);
+      this.highlightHexManager.highlightHexes(cached.hexes);
+      return;
+    }
+
     const armyMovementManager = new ArmyMovementManager(this.dojo, selectedEntityId);
     const travelPaths = armyMovementManager.findPaths(
       this.exploredTiles,
       this.state.currentDefaultTick,
       this.state.currentArmiesTick,
     );
     this.state.updateTravelPaths(travelPaths.getPaths());
     this.highlightHexManager.highlightHexes(travelPaths.getHighlightedHexes());
+    
+    this.armyPathCache.set(selectedEntityId, {
+      paths: travelPaths.getPaths(),
+      hexes: travelPaths.getHighlightedHexes()
+    });
   }

323-328: Remove commented-out code.

There's a commented-out line that sets the selected hex to null. Either remove it or document why it's kept for future reference.

   private clearEntitySelection() {
-    // this.state.setSelectedHex(null);
     this.highlightHexManager.highlightHexes([]);
     this.state.updateTravelPaths(new Map());
     this.structurePreview?.clearPreviewStructure();
   }
client/src/three/scenes/Hexception.tsx (1)

271-278: Add a comment explaining the purpose of center hex selection.

Consider adding a comment to explain why the center hex is selected after camera movement. This would help other developers understand the interaction flow.

+    // Select center hex after camera movement to ensure proper UI state initialization
     this.state.setSelectedBuildingHex({
       outerCol: col,
       outerRow: row,
       innerCol: BUILDINGS_CENTER[0],
       innerRow: BUILDINGS_CENTER[1],
     });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between d005dc2 and 4f92f84.

⛔ Files ignored due to path filters (5)
  • client/public/images/squire.png is excluded by !**/*.png
  • client/public/textures/battle_label.png is excluded by !**/*.png
  • client/public/textures/my_army_label.png is excluded by !**/*.png
  • client/public/textures/my_realm_label.png is excluded by !**/*.png
  • client/src/assets/icons/common/envelope.svg is excluded by !**/*.svg
📒 Files selected for processing (16)
  • .tool-versions (1 hunks)
  • client/hex/index.html (1 hunks)
  • client/index.html (2 hunks)
  • client/map/index.html (1 hunks)
  • client/src/hooks/context/DojoContext.tsx (4 hunks)
  • client/src/hooks/helpers/useGuilds.tsx (1 hunks)
  • client/src/hooks/store/useBlockchainStore.tsx (2 hunks)
  • client/src/three/components/BattleManager.ts (2 hunks)
  • client/src/three/components/Minimap.ts (14 hunks)
  • client/src/three/scenes/Hexception.tsx (11 hunks)
  • client/src/three/scenes/Worldmap.ts (10 hunks)
  • client/src/ui/components/resources/EntityResourceTable.tsx (1 hunks)
  • client/src/ui/components/resources/ResourceChip.tsx (3 hunks)
  • client/src/ui/components/worldmap/guilds/GuildMembers.tsx (2 hunks)
  • client/src/ui/components/worldmap/guilds/Guilds.tsx (1 hunks)
  • client/src/ui/components/worldmap/players/PlayersPanel.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • .tool-versions
  • client/src/hooks/store/useBlockchainStore.tsx
🧰 Additional context used
🪛 Biome
client/src/three/scenes/Hexception.tsx

[error] 355-355: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

client/src/ui/components/worldmap/players/PlayersPanel.tsx

[error] 104-104: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (25)
client/src/ui/components/resources/EntityResourceTable.tsx (1)

1-5: LGTM: Clean import organization and proper hook usage.

The addition of useUIStore and multiplyByPrecision aligns well with the component's enhanced functionality for tick-based updates and precise calculations.

Also applies to: 13-13

client/hex/index.html (1)

43-52: LGTM! Improved naming consistency for avatar assets.

The standardization to zero-padded numbers (01-10) improves consistency in asset naming.

Let's verify the existence of the avatar files and their usage:

✅ Verification successful

The previous script failed because we assumed the wrong path. Let's first find where these avatar files are actually stored in the repository and then check for any code references to them.


Avatar files and references are properly aligned with the new zero-padded format

The verification shows:

  • All 10 zero-padded avatar files (01.png through 10.png) exist in client/public/images/avatars/
  • The prefetch links are consistently updated across all HTML files
  • Code references in TypeScript files use dynamic indexing that's compatible with both formats:
    • randomAvatarIndex variable usage
    • addressToNumber function usage
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify avatar files exist and check for potential breaking changes

# Test 1: Check if all new avatar files exist
echo "Checking for avatar files..."
for i in {01..10}; do
  fd "^${i}.png$" --type f --base-directory images/avatars
done

# Test 2: Search for potential references to old single-digit format
echo "Checking for references to old format..."
rg -g '*.{ts,tsx,js,jsx}' '[^0-9]/avatars/[1-9]\.png'

Length of output: 1753


Script:

#!/bin/bash
# Let's try a different approach to locate the avatar files
echo "Searching for avatar files in the repository..."
fd "\.png$" | grep -i "avatar"

echo -e "\nSearching for any avatar-related code..."
rg -g '*.{ts,tsx,js,jsx,html}' -i "avatar.*\.png"

Length of output: 3505

client/index.html (3)

86-91: LGTM! Well-structured meta tags for SEO and social sharing.

The meta tags follow best practices with appropriate Open Graph properties for social media sharing and a game-specific description.


92-95: Verify the existence of icon files.

New icon files have been referenced. Let's ensure they exist to prevent broken links.

#!/bin/bash
# Description: Verify that all referenced icon files exist
# Expected: All files should exist to prevent broken links

echo "Checking for icon files..."
FILES=(
  "images/favicon.ico"
  "images/apple-touch-icon-180x180.png"
  "images/maskable-icon-512x512.png"
)

for file in "${FILES[@]}"; do
  if ! fd "^$(basename "$file")$" "$(dirname "$file")/"; then
    echo "Missing icon file: $file"
  fi
done

43-52: Verify the existence of avatar image files.

The avatar image paths have been updated to use zero-padded numbers and new avatars (07-10) have been added.

✅ Verification successful

Let me try a different search strategy to verify the avatar images.


All avatar images are present in the correct location

The verification shows that all referenced avatar images (01.png through 10.png) exist at client/public/images/avatars/, which matches the prefetch paths in the HTML file. The zero-padded naming convention is correctly implemented and all files are present.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that all referenced avatar images exist
# Expected: All files should exist, otherwise the prefetch links would be broken

echo "Checking for avatar images..."
for i in {01..10}; do
  if ! fd "^${i}.png$" "images/avatars/"; then
    echo "Missing avatar image: ${i}.png"
  fi
done

Length of output: 1215


Script:

#!/bin/bash
# Search for all PNG files in the repository to find avatar images
echo "Searching for all PNG files..."
fd -e png

# Also check if there's a different location for assets
echo -e "\nChecking for possible asset directories..."
fd -t d -i 'assets|public|static|resources'

Length of output: 4927

client/src/ui/components/resources/ResourceChip.tsx (4)

1-22: LGTM: Props and imports are well-structured.

The addition of the tick prop and configManager import aligns with the component's enhanced functionality for real-time resource management.


42-46: LGTM: Resource capacity calculation is well-implemented.

The use of configManager.getResourceWeight provides a more maintainable approach to resource weight management.


132-135: LGTM: Production status logic is comprehensive.

The isProducingOrConsuming calculation effectively handles all relevant edge cases and is properly memoized.


47-61: Verify rate calculation edge cases.

The net rate calculation looks correct, but let's verify the handling of edge cases.

✅ Verification successful

Net rate calculation implementation is correct and well-handled

The implementation in ResourceChip.tsx correctly handles all edge cases for net rate calculations:

  • The ProductionManager._netRate() method properly calculates the difference between production and consumption rates
  • The UI component handles negative rates by checking against current balance
  • The code prevents showing negative rates when there's insufficient balance
  • Rate display includes proper formatting for both per-second and per-hour views
  • The implementation correctly integrates with the balance tracking system
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for test coverage of net rate calculations
rg -A 5 "netRate" --type ts --type tsx

Length of output: 66


Script:

#!/bin/bash
# Search for test coverage of net rate calculations with proper file extensions
rg -A 5 "netRate" -t ts -t typescript

# Also search for related production rate tests
rg -A 5 "production.*rate" -t ts -t typescript

# Look for the ProductionManager class implementation
ast-grep --pattern 'class ProductionManager {
  $$$
  netRate() {
    $$$
  }
  $$$
}'

Length of output: 245


Script:

#!/bin/bash
# Search for files containing netRate without file type filters
rg -A 5 "netRate"

# Search for ProductionManager class
rg -A 20 "class ProductionManager"

# Find all TypeScript files that might contain tests
fd "\.test\.(ts|tsx)$" --exec grep -l "production.*rate" {} \;

Length of output: 10434

client/src/hooks/context/DojoContext.tsx (1)

68-72: 🛠️ Refactor suggestion

Add cleanup to prevent memory leaks.

The effect should clean up the account state when the component unmounts to prevent memory leaks and stale state.

 useEffect(() => {
   if (controllerAccount) {
     useAccountStore.getState().setAccount(controllerAccount);
   }
+  return () => {
+    useAccountStore.getState().setAccount(null);
+  };
 }, [controllerAccount, isConnected]);

Likely invalid or redundant comment.

client/src/ui/components/worldmap/players/PlayersPanel.tsx (2)

17-25: LGTM! Well-structured Player interface

The Player interface is well-defined with clear and typed properties, making the code more maintainable and type-safe.


148-185: LGTM! Well-structured component with proper type safety

The PlayerList component is well-organized with proper prop types and clean component composition.

client/src/hooks/helpers/useGuilds.tsx (1)

1-11: LGTM! New imports align with the leaderboard functionality.

The addition of LeaderboardManager and useUIStore imports properly supports the new ranking and timestamp features.

client/src/ui/components/worldmap/guilds/GuildMembers.tsx (2)

88-91: ⚠️ Potential issue

Add missing dependencies to useCallback

The joinGuild function depends on account and join_guild, but they're not included in the dependency array.

Apply this diff:

 const joinGuild = useCallback((guildEntityId: ID) => {
   setIsLoading(true);
   join_guild({ guild_entity_id: guildEntityId, signer: account }).finally(() => setIsLoading(false));
- }, []);
+ }, [account, join_guild]);

Likely invalid or redundant comment.


93-100: ⚠️ Potential issue

Add missing dependencies to useCallback

The removePlayerFromWhitelist function depends on account, selectedGuildEntityId, and remove_player_from_whitelist.

Apply this diff:

 const removePlayerFromWhitelist = useCallback((address: string) => {
   setIsLoading(true);
   remove_player_from_whitelist({
     player_address_to_remove: address,
     guild_entity_id: selectedGuildEntityId,
     signer: account,
   }).finally(() => setIsLoading(false));
- }, []);
+ }, [account, selectedGuildEntityId, remove_player_from_whitelist]);

Likely invalid or redundant comment.

client/src/three/components/Minimap.ts (3)

37-41: LGTM! Type-safe structure colors mapping.

The use of computed property names with StructureType ensures type safety and maintainability.


Line range hint 64-84: LGTM! Well-structured property additions.

The new properties are well-typed and the Map structure for labelImages provides efficient caching of image resources.


Line range hint 232-275: LGTM! Robust image-based rendering implementation.

The transition to image-based rendering is well-implemented with proper null checks and accurate scaling calculations.

client/src/three/scenes/Worldmap.ts (4)

8-8: LGTM: Import changes are well-organized.

The new imports for sound effects, mobile support, and navigation components are logically grouped and properly scoped.

Also applies to: 11-11, 13-13


146-156: Good mobile-first approach with conditional minimap initialization.

The minimap is only initialized for non-mobile devices, which helps reduce unnecessary resource usage on mobile devices.


625-628: LGTM: Efficient update cycle with mobile optimization.

The update cycle properly handles animations and includes mobile-specific optimizations by conditionally updating the minimap.


265-272: ⚠️ Potential issue

Add error handling for structure placement.

The structure placement operation could fail. Consider adding try-catch block to handle potential errors.

   protected handleStructurePlacement(hexCoords: HexPosition) {
     const buildingType = this.structurePreview?.getPreviewStructure();
     if (!buildingType) return;

     const contractHexPosition = new Position({ x: hexCoords.col, y: hexCoords.row }).getContract();
-    this.tileManager.placeStructure(this.structureEntityId, buildingType.type, contractHexPosition);
-    this.clearEntitySelection();
+    try {
+      this.tileManager.placeStructure(this.structureEntityId, buildingType.type, contractHexPosition);
+      this.clearEntitySelection();
+    } catch (error) {
+      this.state.setError(`Failed to place structure: ${error.message}`);
+    }
   }

Likely invalid or redundant comment.

client/src/three/scenes/Hexception.tsx (3)

688-712: Skip comment as it's covered by past review.

The implementation of sound effects has already been addressed in a previous review comment that suggested preloading sounds and adding error handling.


447-469: Skip comment as it's covered by past review.

The implementation of mine materials handling has already been addressed in a previous review comment that suggested using safer mesh selection methods.


631-634: Consider using a more robust random number generator.

The current implementation uses hashCoordinates for generating rotation seeds. Consider using a deterministic PRNG for more uniform distribution.

Comment on lines +15 to +17
if (!entityId) {
return <div>No Entity Selected</div>; // Early return for undefined entityId
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove redundant null check.

The second null check at lines 30-32 is unreachable due to the early return at lines 15-17. Both checks return the same message.

  if (!entityId) {
    return <div>No Entity Selected</div>; // Early return for undefined entityId
  }

  const quantity =
    useComponentValue(
      dojo.setup.components.BuildingQuantityv2,
      getEntityIdFromKeys([BigInt(entityId || 0), BigInt(BuildingType.Storehouse)]),
    )?.value || 0;

  const maxStorehouseCapacityKg = useMemo(() => {
    const storehouseCapacityKg = gramToKg(configManager.getCapacityConfig(CapacityConfigCategory.Storehouse));
    return multiplyByPrecision(quantity * storehouseCapacityKg + storehouseCapacityKg);
  }, [quantity, entityId]);

-  if (entityId === undefined || entityId === null) {
-    return <div>No Entity Selected</div>;
-  }

Also applies to: 30-32

Comment on lines +43 to +52
<link rel="prefetch" href="/images/avatars/01.png" />
<link rel="prefetch" href="/images/avatars/02.png" />
<link rel="prefetch" href="/images/avatars/03.png" />
<link rel="prefetch" href="/images/avatars/04.png" />
<link rel="prefetch" href="/images/avatars/05.png" />
<link rel="prefetch" href="/images/avatars/06.png" />
<link rel="prefetch" href="/images/avatars/07.png" />
<link rel="prefetch" href="/images/avatars/08.png" />
<link rel="prefetch" href="/images/avatars/09.png" />
<link rel="prefetch" href="/images/avatars/10.png" />
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

⚠️ Missing avatar images and potential reference issues

The prefetch links reference avatar images that don't exist in the expected location. Additionally, there are dynamic avatar references in the codebase that might need adjustment:

  • client/src/ui/modules/settings/Settings.tsx uses dynamic avatar path based on address
  • client/src/ui/modules/social/PlayerId.tsx and EntityAvatar.tsx use random avatar indices
  • A special case avatar "mercenary.png" is referenced in EntityAvatar.tsx

Please ensure:

  1. All referenced avatar images (01.png through 10.png) are added to the public images directory
  2. Update the avatar index generation logic in the components to match the new range (1-10)
  3. Verify if "mercenary.png" should also follow the new naming convention
🔗 Analysis chain

LGTM! Improved avatar naming convention.

The update to a two-digit format (01-10) provides better consistency and sorting. The expansion from 6 to 10 avatars suggests enhanced customization options.

Let's verify the existence of the new avatar images and check for any remaining old-format references:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify avatar images and references
# Test 1: Check if all new avatar images exist
for i in {01..10}; do
  fd "^${i}.png$" "images/avatars"
done

# Test 2: Look for any remaining single-digit avatar references that might need updating
rg -g '!*.html' '[^0-9][1-6]\.png' 

# Test 3: Check for any hardcoded avatar paths that might need updating
ast-grep --pattern 'avatars/[1-6].png'

Length of output: 3281


Script:

#!/bin/bash
# Let's verify if the images directory exists and its structure
fd -t d "images"

# Check for any avatar-related files in the repository
fd -t f "avatar"

# Look for any references to avatar images in the codebase
rg -g '!*.html' "avatar.*\.png"

Length of output: 641

Comment on lines +38 to +41
const production = useMemo(() => {
setBalance(getBalance());
return getProduction();
}, [getBalance, getProduction]);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid setState in useMemo.

Setting state within a useMemo hook is an anti-pattern as it can lead to unnecessary re-renders and potential race conditions. The state update should be moved to an effect.

Consider refactoring to:

  const production = useMemo(() => {
-   setBalance(getBalance());
    return getProduction();
-  }, [getBalance, getProduction]);
+  }, [getProduction]);
+
+useEffect(() => {
+  setBalance(getBalance());
+}, [getBalance]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const production = useMemo(() => {
setBalance(getBalance());
return getProduction();
}, [getBalance, getProduction]);
const production = useMemo(() => {
return getProduction();
}, [getProduction]);
useEffect(() => {
setBalance(getBalance());
}, [getBalance]);

Comment on lines +76 to +82
export const DojoProvider = ({ children, value }: DojoProviderProps) => {
const currentValue = useContext(DojoContext);
if (currentValue) throw new Error("DojoProvider can only be used once");

const rpcProvider = useRpcProvider();
const masterAccount = useMasterAccount(rpcProvider);
const controllerAccount = useControllerAccount();
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error boundary for RPC initialization failures.

The RPC provider and account initialization could fail, but there's no error handling mechanism in place. Consider wrapping the provider with an error boundary to gracefully handle initialization failures.

+class DojoErrorBoundary extends React.Component<{children: ReactNode}, {hasError: boolean}> {
+  constructor(props) {
+    super(props);
+    this.state = { hasError: false };
+  }
+
+  static getDerivedStateFromError(error) {
+    return { hasError: true };
+  }
+
+  render() {
+    if (this.state.hasError) {
+      return <div>Something went wrong initializing Dojo. Please refresh the page.</div>;
+    }
+    return this.props.children;
+  }
+}

 export const DojoProvider = ({ children, value }: DojoProviderProps) => {
   // ... existing code ...
   return (
+    <DojoErrorBoundary>
       <BurnerProvider
         initOptions={{
           masterAccount,
           accountClassHash: import.meta.env.VITE_PUBLIC_ACCOUNT_CLASS_HASH,
           rpcProvider,
           feeTokenAddress: import.meta.env.VITE_NETWORK_FEE_TOKEN,
         }}
       >
         <DojoContextProvider value={value} masterAccount={masterAccount} controllerAccount={controllerAccount!}>
           {children}
         </DojoContextProvider>
       </BurnerProvider>
+    </DojoErrorBoundary>
   );
 };

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +188 to +224
<div className="relative h-screen w-screen pointer-events-auto">
<img className="absolute h-screen w-screen object-cover" src="/images/cover.png" alt="Cover" />
<div className="absolute z-10 w-screen h-screen flex justify-center flex-wrap self-center ">
<div className="self-center bg-brown rounded-lg border p-8 text-gold min-w-[600px] max-w-[800px] overflow-hidden relative z-50 shadow-2xl border-white/40 border-gradient">
<div className="w-full text-center pt-6">
<div className="mx-auto flex mb-8">
<img src="/images/eternum_with_snake.png" className="w-96 mx-auto" alt="Eternum Logo" />
</div>
</div>
<div className="flex space-x-2 mt-8 justify-center">
{!isConnected && (
<button
className="px-4 py-2 bg-[#ffc52a] border-2 border-[#ffc52a] text-black flex font-bold rounded text-lg fill-black uppercase leading-6 shadow-md hover:shadow-lg active:shadow-inner hover:scale-105 transition-all duration-300 hover:-translate-y-1"
onClick={connectWallet}
>
<CartridgeSmall className="w-6 mr-2 fill-current self-center" /> Login
</button>
)}
</div>
<div className="text-center text-sm text-white/50 mt-4">
Eternum uses a next generation smart contract wallet -{" "}
<a href="https://cartridge.gg/" target="_blank" className="underline">
Cartridge Controller
</a>{" "}
<br />
No download, no seed or passphrase - only a Passkey. <br />
No transaction signatures needed. <br /> We recommend using a phone however you can also use{" "}
<a href="https://www.bitwarden.com/" target="_blank" className="underline">
{" "}
bitwarden
</a>{" "}
<br />
to manage your passkeys
</div>
</div>
</div>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve login screen accessibility.

The login screen has several accessibility issues that should be addressed:

  1. Missing ARIA labels
  2. Poor color contrast
  3. Missing keyboard navigation support
-<div className="relative h-screen w-screen pointer-events-auto">
+<div className="relative h-screen w-screen pointer-events-auto" role="main" aria-label="Login screen">
   <img 
     className="absolute h-screen w-screen object-cover" 
     src="/images/cover.png" 
-    alt="Cover" 
+    alt="Eternum game cover background" 
   />
   <div className="absolute z-10 w-screen h-screen flex justify-center flex-wrap self-center ">
-    <div className="self-center bg-brown rounded-lg border p-8 text-gold min-w-[600px] max-w-[800px] overflow-hidden relative z-50 shadow-2xl border-white/40 border-gradient">
+    <div 
+      className="self-center bg-brown rounded-lg border p-8 text-gold min-w-[600px] max-w-[800px] overflow-hidden relative z-50 shadow-2xl border-white/40 border-gradient"
+      role="dialog"
+      aria-labelledby="login-title"
+    >
       <div className="w-full text-center pt-6">
-        <div className="mx-auto flex mb-8">
+        <div className="mx-auto flex mb-8" id="login-title">
           <img src="/images/eternum_with_snake.png" className="w-96 mx-auto" alt="Eternum Logo" />
         </div>
       </div>
       <div className="flex space-x-2 mt-8 justify-center">
         {!isConnected && (
           <button
-            className="px-4 py-2 bg-[#ffc52a] border-2 border-[#ffc52a] text-black flex font-bold rounded text-lg fill-black uppercase leading-6 shadow-md hover:shadow-lg active:shadow-inner hover:scale-105 transition-all duration-300 hover:-translate-y-1"
+            className="px-4 py-2 bg-[#ffc52a] border-2 border-[#ffc52a] text-black flex font-bold rounded text-lg fill-black uppercase leading-6 shadow-md hover:shadow-lg active:shadow-inner hover:scale-105 transition-all duration-300 hover:-translate-y-1 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[#ffc52a]"
             onClick={connectWallet}
+            aria-label="Connect wallet using Cartridge Controller"
          >
            <CartridgeSmall className="w-6 mr-2 fill-current self-center" /> Login
          </button>
        )}
      </div>
-      <div className="text-center text-sm text-white/50 mt-4">
+      <div className="text-center text-sm text-white/60 mt-4">
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className="relative h-screen w-screen pointer-events-auto">
<img className="absolute h-screen w-screen object-cover" src="/images/cover.png" alt="Cover" />
<div className="absolute z-10 w-screen h-screen flex justify-center flex-wrap self-center ">
<div className="self-center bg-brown rounded-lg border p-8 text-gold min-w-[600px] max-w-[800px] overflow-hidden relative z-50 shadow-2xl border-white/40 border-gradient">
<div className="w-full text-center pt-6">
<div className="mx-auto flex mb-8">
<img src="/images/eternum_with_snake.png" className="w-96 mx-auto" alt="Eternum Logo" />
</div>
</div>
<div className="flex space-x-2 mt-8 justify-center">
{!isConnected && (
<button
className="px-4 py-2 bg-[#ffc52a] border-2 border-[#ffc52a] text-black flex font-bold rounded text-lg fill-black uppercase leading-6 shadow-md hover:shadow-lg active:shadow-inner hover:scale-105 transition-all duration-300 hover:-translate-y-1"
onClick={connectWallet}
>
<CartridgeSmall className="w-6 mr-2 fill-current self-center" /> Login
</button>
)}
</div>
<div className="text-center text-sm text-white/50 mt-4">
Eternum uses a next generation smart contract wallet -{" "}
<a href="https://cartridge.gg/" target="_blank" className="underline">
Cartridge Controller
</a>{" "}
<br />
No download, no seed or passphrase - only a Passkey. <br />
No transaction signatures needed. <br /> We recommend using a phone however you can also use{" "}
<a href="https://www.bitwarden.com/" target="_blank" className="underline">
{" "}
bitwarden
</a>{" "}
<br />
to manage your passkeys
</div>
</div>
</div>
</div>
<div className="relative h-screen w-screen pointer-events-auto" role="main" aria-label="Login screen">
<img
className="absolute h-screen w-screen object-cover"
src="/images/cover.png"
alt="Eternum game cover background"
/>
<div className="absolute z-10 w-screen h-screen flex justify-center flex-wrap self-center ">
<div
className="self-center bg-brown rounded-lg border p-8 text-gold min-w-[600px] max-w-[800px] overflow-hidden relative z-50 shadow-2xl border-white/40 border-gradient"
role="dialog"
aria-labelledby="login-title"
>
<div className="w-full text-center pt-6">
<div className="mx-auto flex mb-8" id="login-title">
<img src="/images/eternum_with_snake.png" className="w-96 mx-auto" alt="Eternum Logo" />
</div>
</div>
<div className="flex space-x-2 mt-8 justify-center">
{!isConnected && (
<button
className="px-4 py-2 bg-[#ffc52a] border-2 border-[#ffc52a] text-black flex font-bold rounded text-lg fill-black uppercase leading-6 shadow-md hover:shadow-lg active:shadow-inner hover:scale-105 transition-all duration-300 hover:-translate-y-1 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[#ffc52a]"
onClick={connectWallet}
aria-label="Connect wallet using Cartridge Controller"
>
<CartridgeSmall className="w-6 mr-2 fill-current self-center" /> Login
</button>
)}
</div>
<div className="text-center text-sm text-white/60 mt-4">
Eternum uses a next generation smart contract wallet -{" "}
<a href="https://cartridge.gg/" target="_blank" className="underline">
Cartridge Controller
</a>{" "}
<br />
No download, no seed or passphrase - only a Passkey. <br />
No transaction signatures needed. <br /> We recommend using a phone however you can also use{" "}
<a href="https://www.bitwarden.com/" target="_blank" className="underline">
{" "}
bitwarden
</a>{" "}
<br />
to manage your passkeys
</div>
</div>
</div>
</div>

Comment on lines +248 to +252
<div
className="col-span-5 grid grid-cols-5 gap-1 text-md hover:opacity-70 p-1"
onClick={() => {
viewPlayerInfo(ContractAddress(guildMember.address));
}}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve accessibility for clickable elements

Using a div as a clickable element is not accessible. Use semantic elements like button instead.

Apply this diff:

-<div
+<button
+  type="button"
   className="col-span-5 grid grid-cols-5 gap-1 text-md hover:opacity-70 p-1"
   onClick={() => {
     viewPlayerInfo(ContractAddress(guildMember.address));
   }}
+  onKeyPress={(e) => {
+    if (e.key === 'Enter' || e.key === ' ') {
+      viewPlayerInfo(ContractAddress(guildMember.address));
+    }
+  }}
>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div
className="col-span-5 grid grid-cols-5 gap-1 text-md hover:opacity-70 p-1"
onClick={() => {
viewPlayerInfo(ContractAddress(guildMember.address));
}}
<button
type="button"
className="col-span-5 grid grid-cols-5 gap-1 text-md hover:opacity-70 p-1"
onClick={() => {
viewPlayerInfo(ContractAddress(guildMember.address));
}}
onKeyPress={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
viewPlayerInfo(ContractAddress(guildMember.address));
}
}}

Comment on lines +72 to +86
const disbandGuild = (guildEntityId: ID) => {
let calldata = [
...guildMembers.filter((member) => !member.isGuildMaster).map((member) => ({ address: member.address })),
{ address: account.address },
];

setIsLoading(true);
disband_guild({
calls: calldata,
signer: account,
}).finally(() => {
setIsLoading(false);
setIsExpanded(false);
});
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Prevent duplicate addresses in disbandGuild calldata

The function might include duplicate addresses if the current user is also a non-master member.

Apply this diff to ensure unique addresses:

 const disbandGuild = (guildEntityId: ID) => {
-  let calldata = [
-    ...guildMembers.filter((member) => !member.isGuildMaster).map((member) => ({ address: member.address })),
-    { address: account.address },
-  ];
+  const uniqueAddresses = new Set(
+    guildMembers
+      .filter((member) => !member.isGuildMaster)
+      .map((member) => member.address)
+  );
+  uniqueAddresses.add(account.address);
+  
+  let calldata = Array.from(uniqueAddresses).map(address => ({ address }));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const disbandGuild = (guildEntityId: ID) => {
let calldata = [
...guildMembers.filter((member) => !member.isGuildMaster).map((member) => ({ address: member.address })),
{ address: account.address },
];
setIsLoading(true);
disband_guild({
calls: calldata,
signer: account,
}).finally(() => {
setIsLoading(false);
setIsExpanded(false);
});
};
const disbandGuild = (guildEntityId: ID) => {
const uniqueAddresses = new Set(
guildMembers
.filter((member) => !member.isGuildMaster)
.map((member) => member.address)
);
uniqueAddresses.add(account.address);
let calldata = Array.from(uniqueAddresses).map(address => ({ address }));
setIsLoading(true);
disband_guild({
calls: calldata,
signer: account,
}).finally(() => {
setIsLoading(false);
setIsExpanded(false);
});
};

Comment on lines 86 to +100
constructor(
worldmapScene: WorldmapScene,
exploredTiles: Map<number, Set<number>>,
camera: THREE.PerspectiveCamera,
structureManager: StructureManager,
armyManager: ArmyManager,
battleManager: BattleManager,
biome: Biome,
) {
this.worldmapScene = worldmapScene;
this.waitForMinimapElement().then((canvas) => {
this.canvas = canvas;
this.initializeCanvas(structureManager, exploredTiles, armyManager, biome, camera);
this.loadLabelImages();
this.initializeCanvas(structureManager, exploredTiles, armyManager, biome, camera, battleManager);
this.canvas.addEventListener("canvasResized", this.handleResize);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add event listener cleanup.

The resize event listener is added but never removed. Consider adding a cleanup method to remove the event listener when the component is destroyed to prevent memory leaks.

 class Minimap {
+  private cleanup() {
+    this.canvas.removeEventListener("canvasResized", this.handleResize);
+  }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +452 to +469
private loadLabelImages() {
// Load army labels
this.loadImage("ARMY", LABELS.ARMY);
this.loadImage("MY_ARMY", LABELS.MY_ARMY);
this.loadImage("BATTLE", LABELS.BATTLE);
this.loadImage("MY_REALM", LABELS.MY_REALM);

// Load structure labels
Object.entries(LABELS.STRUCTURES).forEach(([type, path]) => {
this.loadImage(`STRUCTURE_${type}`, path);
});
}

private loadImage(key: string, path: string) {
const img = new Image();
img.src = path;
this.labelImages.set(key, img);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add error handling for image loading.

The image loading implementation should handle loading failures to prevent rendering issues when images fail to load.

  private loadImage(key: string, path: string) {
    const img = new Image();
+   img.onerror = () => {
+     console.error(`Failed to load image: ${path}`);
+     this.labelImages.delete(key);
+   };
    img.src = path;
    this.labelImages.set(key, img);
  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private loadLabelImages() {
// Load army labels
this.loadImage("ARMY", LABELS.ARMY);
this.loadImage("MY_ARMY", LABELS.MY_ARMY);
this.loadImage("BATTLE", LABELS.BATTLE);
this.loadImage("MY_REALM", LABELS.MY_REALM);
// Load structure labels
Object.entries(LABELS.STRUCTURES).forEach(([type, path]) => {
this.loadImage(`STRUCTURE_${type}`, path);
});
}
private loadImage(key: string, path: string) {
const img = new Image();
img.src = path;
this.labelImages.set(key, img);
}
private loadLabelImages() {
// Load army labels
this.loadImage("ARMY", LABELS.ARMY);
this.loadImage("MY_ARMY", LABELS.MY_ARMY);
this.loadImage("BATTLE", LABELS.BATTLE);
this.loadImage("MY_REALM", LABELS.MY_REALM);
// Load structure labels
Object.entries(LABELS.STRUCTURES).forEach(([type, path]) => {
this.loadImage(`STRUCTURE_${type}`, path);
});
}
private loadImage(key: string, path: string) {
const img = new Image();
img.onerror = () => {
console.error(`Failed to load image: ${path}`);
this.labelImages.delete(key);
};
img.src = path;
this.labelImages.set(key, img);
}

@@ -323,13 +352,13 @@ export default class HexceptionScene extends HexagonScene {
this.buildingPreview?.resetBuildingColor();
}
const building = this.tileManager.getBuilding(normalizedCoords);
if (building) {
if (building && building.produced_resource_type) {
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use optional chaining for safer property access.

To prevent potential runtime errors, use optional chaining when accessing the produced_resource_type property.

-if (building && building.produced_resource_type) {
+if (building?.produced_resource_type) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (building && building.produced_resource_type) {
if (building?.produced_resource_type) {
🧰 Tools
🪛 Biome

[error] 355-355: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

Copy link
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

🧹 Outside diff range and nitpick comments (1)
client/src/hooks/helpers/useQuests.tsx (1)

Line range hint 268-271: Reconsider conditional dependencies in useMemo

The dependency array uses conditional expressions:

[
  structureEntityId,
  questClaimStatus,
  unclaimedQuestsCount > 0 ? entityUpdate : null,
  unclaimedQuestsCount > 0 ? orders : null,
]

This pattern might not trigger updates as expected when unclaimedQuestsCount changes from 0 to positive. Consider always including these dependencies:

[
  structureEntityId,
  questClaimStatus,
- unclaimedQuestsCount > 0 ? entityUpdate : null,
- unclaimedQuestsCount > 0 ? orders : null,
+ entityUpdate,
+ orders,
+ unclaimedQuestsCount
]
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7212a73 and 6f6c17a.

📒 Files selected for processing (1)
  • client/src/hooks/helpers/useQuests.tsx (6 hunks)
🔇 Additional comments (3)
client/src/hooks/helpers/useQuests.tsx (3)

75-75: LGTM! Parameter types are well-defined

The function signature has been improved with proper typing for both setup and account parameters.


314-317: Verify BuildingQuantityv2 migration strategy

The switch from BuildingQuantity to BuildingQuantityv2 suggests a schema change. Ensure there's a migration strategy in place for existing data and that both versions can coexist during the transition if needed.

#!/bin/bash
# Search for BuildingQuantity usage to ensure complete migration
rg --type typescript "BuildingQuantity[^v2]"

18-18: Document the purpose of the new view property

The newly added view property in the Quest interface lacks documentation explaining its purpose. Additionally, since it's a required property, verify that all existing quest definitions include this property to prevent TypeScript errors.

✅ Verification successful

Let's search for actual usage of quests to understand the context better:

And let's look at the specific file content:


The view property is correctly implemented and used

The view property in the Quest interface is used to control quest visibility based on the current view (WORLD/REALM). It's properly initialized in questDetails.tsx and correctly utilized in QuestInfo.tsx for conditional rendering. The property can be empty string (as seen in Settle quest) or contain view-specific values that determine where the quest should be displayed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for quest definitions to verify they include the 'view' property
rg -A 5 "questDetails.set|questDetails.get" 

Length of output: 175


Script:

#!/bin/bash
# Search for quest definitions and related code
rg -l "Quest.*{" --type ts

# After finding the files, let's examine their content
rg "Quest.*{[\s\S]*?view\s*:" --type ts -A 5

Length of output: 270


Script:

#!/bin/bash
# Search for quest-related code and implementations
rg "createQuest|useQuest" --type ts -A 5

Length of output: 23622


Script:

#!/bin/bash
cat client/src/hooks/helpers/useQuests.tsx

Length of output: 12004


Script:

#!/bin/bash
# Let's check the questDetails to understand how the view property is used
rg -g "questDetails.ts*" "questDetails" -A 10

# Also check for any UI components that might use the view property
rg "quest\.view" --type ts

Length of output: 1192

Comment on lines +81 to +83
const playerPillages = useEntityQuery([
HasValue(setup.components.events.BattlePillageData, { pillager: BigInt(account.address) }),
]);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add null check before BigInt conversion

The BigInt(account.address) conversion could throw if account.address is undefined. Consider adding a null check:

-    HasValue(setup.components.events.BattlePillageData, { pillager: BigInt(account.address) }),
+    HasValue(setup.components.events.BattlePillageData, { 
+      pillager: account.address ? BigInt(account.address) : 0n 
+    }),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const playerPillages = useEntityQuery([
HasValue(setup.components.events.BattlePillageData, { pillager: BigInt(account.address) }),
]);
const playerPillages = useEntityQuery([
HasValue(setup.components.events.BattlePillageData, {
pillager: account.address ? BigInt(account.address) : 0n
}),
]);

@ponderingdemocritus ponderingdemocritus merged commit e58e2d3 into main Nov 4, 2024
26 of 27 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.

8 participants