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

client: make client biome impl equivalent to contracts #2660

Merged
merged 2 commits into from
Jan 24, 2025

Conversation

credence0x
Copy link
Collaborator

@credence0x credence0x commented Jan 23, 2025

  • make client biome implementation equivalent to contracts by using fixed point math in client. it was previously not equivalent because of precision issues in many places

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced advanced fixed-point arithmetic system for precise mathematical calculations.
    • Enhanced biome generation with improved noise generation algorithms.
    • Added new classes for three-dimensional (Vec3) and four-dimensional (Vec4) vector operations.
  • Technical Improvements

    • Implemented comprehensive vector and mathematical utility classes.
    • Upgraded computational precision for terrain and biome generation.
    • Added support for fixed-point arithmetic operations and enhanced type safety in biome calculations.
  • Performance

    • Optimized noise generation and vector computation methods.
    • Improved mathematical precision in terrain generation algorithms.

Copy link
Contributor

mentatbot bot commented Jan 23, 2025

Hi @credence0x! You need to be added as a user to interact with me. Please ask @ponderingdemocritus to add you on the settings page.

You are receiving this comment because I am set to review all PRs. That is configurable here.

Copy link

vercel bot commented Jan 23, 2025

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 Jan 24, 2025 2:50am
eternum-docs ❌ Failed (Inspect) Jan 24, 2025 2:50am
1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
eternum-landing ⬜️ Ignored (Inspect) Visit Preview Jan 24, 2025 2:50am

Copy link
Contributor

coderabbitai bot commented Jan 23, 2025

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 eslint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

client/apps/game/src/three/managers/biome.ts

Oops! Something went wrong! :(

ESLint: 9.18.0

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.

Walkthrough

The pull request introduces a comprehensive implementation of fixed-point arithmetic for biome generation in a game environment. The changes involve creating utility classes for fixed-point numbers (Fixed), vector operations (Vec3 and Vec4), and a new simplex noise generation algorithm. The primary focus is on transitioning from standard floating-point calculations to a more precise fixed-point arithmetic system, specifically targeting the biome generation process in the game's terrain creation mechanism.

Changes

File Change Summary
client/apps/game/src/three/managers/biome.ts Migrated biome calculation methods to use fixed-point arithmetic, updated method signatures, and internal logic for elevation and moisture calculations. Changed BiomeType from union type to enum.
client/apps/game/src/utils/biome/fixed-point.ts Added Fixed and FixedTrait classes implementing robust fixed-point arithmetic operations, including methods for basic arithmetic and conversion between integer and fixed-point types.
client/apps/game/src/utils/biome/simplex-noise.ts Implemented noise generation using fixed-point arithmetic, including functions for generating noise and octave-based noise calculations.
client/apps/game/src/utils/biome/vec3.ts Created a 3D vector class (Vec3) with fixed-point arithmetic operations and various vector manipulation methods.
client/apps/game/src/utils/biome/vec4.ts Created a 4D vector class (Vec4) with fixed-point arithmetic operations and various vector manipulation methods.

Sequence Diagram

sequenceDiagram
    participant Biome as Biome Manager
    participant Noise as Simplex Noise Generator
    participant Fixed as Fixed-Point Arithmetic
    participant Vec3 as Vector Operations

    Biome->>Fixed: Convert input parameters
    Biome->>Noise: Generate elevation noise
    Noise->>Vec3: Create vector representation
    Noise->>Fixed: Perform noise calculations
    Noise-->>Biome: Return fixed-point elevation
    Biome->>Noise: Generate moisture noise
    Noise-->>Biome: Return fixed-point moisture
    Biome->>Biome: Determine biome type
Loading

Possibly related PRs

  • Add pillage simulation tool #2131: The main PR introduces fixed-point arithmetic for biome calculations, while this PR adds a pillage simulation tool that includes new components and functionalities. Both PRs involve significant changes to the codebase, but they focus on different aspects of the application (biome calculations vs. simulation tools) and do not share direct code changes or modifications to the same functions or classes.

Poem

🐰 Fixed-point magic, precise and bright,
Rabbit's numbers dance with mathematical might!
Vectors twirl, noise softly sings,
Biomes bloom from computational springs 🌍
Precision leaps with every byte! 🧮

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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: 3

🧹 Nitpick comments (8)
client/apps/game/src/utils/biome/simplex-noise.ts (2)

144-157: Consider removing the unused export 'noise_octaves'.

The function noise_octaves is exported but not used anywhere in the codebase, as indicated by the pipeline failure [warning] 144-144: Unused export 'noise_octaves'. If this function is not needed, consider removing it to clean up the codebase. If it's intended for future use, you might suppress the warning or ensure it's properly utilized.

🧰 Tools
🪛 GitHub Actions: knip

[warning] 144-144: Unused export 'noise_octaves'

🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.


1-157: Run Prettier to fix code formatting issues.

The code formatting does not match Prettier standards, as indicated by the pipeline failure. Please run Prettier with the --write option to automatically fix formatting issues.

🧰 Tools
🪛 GitHub Actions: knip

[warning] 144-144: Unused export 'noise_octaves'

🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

client/apps/game/src/three/managers/biome.ts (2)

Line range hint 1-139: Run Prettier to fix code formatting issues.

The code formatting does not match Prettier standards, as indicated by the pipeline failure. Please run Prettier with the --write option to automatically fix formatting issues.

🧰 Tools
🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.


129-139: Remove commented-out code or relocate it to appropriate test files.

The commented-out test code at the end of the file may clutter the production code. Consider removing it if it's no longer needed, or moving it to a dedicated test file to keep the codebase clean and maintainable.

🧰 Tools
🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

client/apps/game/src/utils/biome/fixed-point.ts (2)

67-356: Refactor FixedTrait to use a module or standalone functions instead of a class with only static members.

The FixedTrait class contains only static methods and no instance members, which is not recommended. According to the static analysis hint (lint/complexity/noStaticOnlyClass), it's preferable to use simple functions or a module. Refactoring FixedTrait into a module or exporting the functions directly can improve code clarity and adhere to best practices.

🧰 Tools
🪛 Biome (1.9.4)

[error] 67-356: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)

🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.


1-356: Run Prettier to fix code formatting issues.

The code formatting does not match Prettier standards, as indicated by the pipeline failure. Please run Prettier with the --write option to automatically fix formatting issues.

🧰 Tools
🪛 Biome (1.9.4)

[error] 67-356: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)

🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

client/apps/game/src/utils/biome/vec3.ts (1)

9-15: Consider renaming methods and removing redundant factory method.

The new static method is redundant as it provides the same functionality as the constructor. Consider:

  1. Removing the new method as it doesn't add value
  2. Renaming splat to something more descriptive like uniform or fill
-    static new(x: Fixed, y: Fixed, z: Fixed): Vec3 {
-        return new Vec3(x, y, z);
-    }

-    static splat(v: Fixed): Vec3 {
+    static uniform(v: Fixed): Vec3 {
         return new Vec3(v, v, v);
     }
🧰 Tools
🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

client/apps/game/src/utils/biome/vec4.ts (1)

1-71: Fix formatting issues.

The pipeline indicates formatting issues. Run Prettier to fix the formatting:

prettier --write "client/apps/game/src/utils/biome/vec*.ts"
🧰 Tools
🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5a4783a and 0567a9c.

📒 Files selected for processing (5)
  • client/apps/game/src/three/managers/biome.ts (3 hunks)
  • client/apps/game/src/utils/biome/fixed-point.ts (1 hunks)
  • client/apps/game/src/utils/biome/simplex-noise.ts (1 hunks)
  • client/apps/game/src/utils/biome/vec3.ts (1 hunks)
  • client/apps/game/src/utils/biome/vec4.ts (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: knip
client/apps/game/src/utils/biome/simplex-noise.ts

[warning] 144-144: Unused export 'noise_octaves'

🪛 GitHub Actions: lint
client/apps/game/src/utils/biome/simplex-noise.ts

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

client/apps/game/src/three/managers/biome.ts

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

client/apps/game/src/utils/biome/vec4.ts

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

client/apps/game/src/utils/biome/vec3.ts

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

client/apps/game/src/utils/biome/fixed-point.ts

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

🪛 Biome (1.9.4)
client/apps/game/src/utils/biome/fixed-point.ts

[error] 67-356: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)

🔇 Additional comments (1)
client/apps/game/src/utils/biome/vec3.ts (1)

1-7: LGTM! Clean and idiomatic TypeScript implementation.

The class structure and constructor implementation follow TypeScript best practices by using public constructor parameters for automatic property creation and initialization.

🧰 Tools
🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

Comment on lines +17 to +46
dot(other: Vec3): Fixed {
let x = this.x.mul(other.x);
let y = this.y.mul(other.y);
let z = this.z.mul(other.z);
return x.add(y).add(z);
}

minus(other: Vec3): Vec3 {
return new Vec3(this.x.sub(other.x), this.y.sub(other.y), this.z.sub(other.z));
}

add(other: Vec3): Vec3 {
return new Vec3(this.x.add(other.x), this.y.add(other.y), this.z.add(other.z));
}

mul(other: Vec3): Vec3 {
return new Vec3(this.x.mul(other.x), this.y.mul(other.y), this.z.mul(other.z));
}

mod(other: Vec3): Vec3 {
return new Vec3(this.x.mod(other.x), this.y.mod(other.y), this.z.mod(other.z));
}

div(other: Vec3): Vec3 {
return new Vec3(this.x.div(other.x), this.y.div(other.y), this.z.div(other.z));
}

floor(): Vec3 {
return new Vec3(this.x.floor(), this.y.floor(), this.z.floor());
}
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 essential vector operations and error handling.

The current implementation is missing several common vector operations and safety checks:

  1. Add length/magnitude calculation
  2. Add normalization
  3. Add error handling for division by zero

Consider adding these methods:

length(): Fixed {
    return this.dot(this).sqrt();
}

normalize(): Vec3 {
    const len = this.length();
    if (len.isZero()) {
        throw new Error("Cannot normalize zero vector");
    }
    return this.divScalar(len);
}

Also, add division by zero checks in div and divScalar methods:

 div(other: Vec3): Vec3 {
+    if (other.x.isZero() || other.y.isZero() || other.z.isZero()) {
+        throw new Error("Division by zero");
+    }
     return new Vec3(this.x.div(other.x), this.y.div(other.y), this.z.div(other.z));
 }
🧰 Tools
🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

Comment on lines +48 to +67
remScaler(scalar: Fixed): Vec3 {
return new Vec3(this.x.mod(scalar), this.y.mod(scalar), this.z.mod(scalar));
}

divScalar(scalar: Fixed): Vec3 {
return new Vec3(this.x.div(scalar), this.y.div(scalar), this.z.div(scalar));
}

mulScalar(scalar: Fixed): Vec3 {
return new Vec3(this.x.mul(scalar), this.y.mul(scalar), this.z.mul(scalar));
}

addScalar(scalar: Fixed): Vec3 {
return new Vec3(this.x.add(scalar), this.y.add(scalar), this.z.add(scalar));
}

abs(): Vec3 {
return new Vec3(this.x.abs(), this.y.abs(), this.z.abs());
}
}
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

Fix typo in method name and add missing scalar operation.

  1. The method name remScaler has a typo (should be remScalar)
  2. Missing subScalar operation for consistency
-    remScaler(scalar: Fixed): Vec3 {
+    remScalar(scalar: Fixed): Vec3 {
         return new Vec3(this.x.mod(scalar), this.y.mod(scalar), this.z.mod(scalar));
     }

+    subScalar(scalar: Fixed): Vec3 {
+        return new Vec3(this.x.sub(scalar), this.y.sub(scalar), this.z.sub(scalar));
+    }
📝 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
remScaler(scalar: Fixed): Vec3 {
return new Vec3(this.x.mod(scalar), this.y.mod(scalar), this.z.mod(scalar));
}
divScalar(scalar: Fixed): Vec3 {
return new Vec3(this.x.div(scalar), this.y.div(scalar), this.z.div(scalar));
}
mulScalar(scalar: Fixed): Vec3 {
return new Vec3(this.x.mul(scalar), this.y.mul(scalar), this.z.mul(scalar));
}
addScalar(scalar: Fixed): Vec3 {
return new Vec3(this.x.add(scalar), this.y.add(scalar), this.z.add(scalar));
}
abs(): Vec3 {
return new Vec3(this.x.abs(), this.y.abs(), this.z.abs());
}
}
remScalar(scalar: Fixed): Vec3 {
return new Vec3(this.x.mod(scalar), this.y.mod(scalar), this.z.mod(scalar));
}
divScalar(scalar: Fixed): Vec3 {
return new Vec3(this.x.div(scalar), this.y.div(scalar), this.z.div(scalar));
}
mulScalar(scalar: Fixed): Vec3 {
return new Vec3(this.x.mul(scalar), this.y.mul(scalar), this.z.mul(scalar));
}
addScalar(scalar: Fixed): Vec3 {
return new Vec3(this.x.add(scalar), this.y.add(scalar), this.z.add(scalar));
}
subScalar(scalar: Fixed): Vec3 {
return new Vec3(this.x.sub(scalar), this.y.sub(scalar), this.z.sub(scalar));
}
abs(): Vec3 {
return new Vec3(this.x.abs(), this.y.abs(), this.z.abs());
}
}
🧰 Tools
🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

Comment on lines +1 to +71
import { Fixed } from "./fixed-point";

export class Vec4 {
constructor(
public x: Fixed,
public y: Fixed,
public z: Fixed,
public w: Fixed
) {}

static new(x: Fixed, y: Fixed, z: Fixed, w: Fixed): Vec4 {
return new Vec4(x, y, z, w);
}

static splat(v: Fixed): Vec4 {
return new Vec4(v, v, v, v);
}

dot(other: Vec4): Fixed {
let x = this.x.mul(other.x);
let y = this.y.mul(other.y);
let z = this.z.mul(other.z);
let w = this.w.mul(other.w);
return x.add(y).add(z).add(w);
}

minus(other: Vec4): Vec4 {
return new Vec4(this.x.sub(other.x), this.y.sub(other.y), this.z.sub(other.z), this.w.sub(other.w));
}

add(other: Vec4): Vec4 {
return new Vec4(this.x.add(other.x), this.y.add(other.y), this.z.add(other.z), this.w.add(other.w));
}

mul(other: Vec4): Vec4 {
return new Vec4(this.x.mul(other.x), this.y.mul(other.y), this.z.mul(other.z), this.w.mul(other.w));
}

mod(other: Vec4): Vec4 {
return new Vec4(this.x.mod(other.x), this.y.mod(other.y), this.z.mod(other.z), this.w.mod(other.w));
}

div(other: Vec4): Vec4 {
return new Vec4(this.x.div(other.x), this.y.div(other.y), this.z.div(other.z), this.w.div(other.w));
}

floor(): Vec4 {
return new Vec4(this.x.floor(), this.y.floor(), this.z.floor(), this.w.floor());
}


remScaler(scalar: Fixed): Vec4 {
return new Vec4(this.x.mod(scalar), this.y.mod(scalar), this.z.mod(scalar), this.w.mod(scalar));
}

divScalar(scalar: Fixed): Vec4 {
return new Vec4(this.x.div(scalar), this.y.div(scalar), this.z.div(scalar), this.w.div(scalar));
}

mulScalar(scalar: Fixed): Vec4 {
return new Vec4(this.x.mul(scalar), this.y.mul(scalar), this.z.mul(scalar), this.w.mul(scalar));
}

addScalar(scalar: Fixed): Vec4 {
return new Vec4(this.x.add(scalar), this.y.add(scalar), this.z.add(scalar), this.w.add(scalar));
}

abs(): Vec4 {
return new Vec4(this.x.abs(), this.y.abs(), this.z.abs(), this.w.abs());
}
}
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 a generic base class to reduce code duplication.

The Vec4 implementation largely duplicates code from Vec3. Consider creating a generic base class to share common functionality:

abstract class VecBase<T extends VecBase<T>> {
    protected abstract create(...components: Fixed[]): T;
    
    abstract dot(other: T): Fixed;
    
    mul(other: T): T {
        // Implement common logic
    }
    // ... other common methods
}

class Vec3 extends VecBase<Vec3> {
    constructor(public x: Fixed, public y: Fixed, public z: Fixed) {
        super();
    }
    
    protected create(x: Fixed, y: Fixed, z: Fixed): Vec3 {
        return new Vec3(x, y, z);
    }
    // ... Vec3 specific methods
}

class Vec4 extends VecBase<Vec4> {
    constructor(public x: Fixed, public y: Fixed, public z: Fixed, public w: Fixed) {
        super();
    }
    
    protected create(x: Fixed, y: Fixed, z: Fixed, w: Fixed): Vec4 {
        return new Vec4(x, y, z, w);
    }
    // ... Vec4 specific methods
}

Also:

  1. Fix the extra blank line at line 51
  2. Apply the same improvements suggested for Vec3 (method naming, error handling, additional operations)
🧰 Tools
🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

FixedTrait.divi(FixedTrait.fromInt(1n), FixedTrait.fromInt(10n)) // 0.1
];
const ELEVATION_OCTAVES_SUM = ELEVATION_OCTAVES.reduce((a, b) => a.add(b), FixedTrait.ZERO);


export type BiomeType =
Copy link
Collaborator

Choose a reason for hiding this comment

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

should we use an enum instead ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

updated

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

🧹 Nitpick comments (6)
client/apps/game/src/three/managers/biome.ts (3)

74-91: Extract magic numbers into named constants.

Consider extracting magic numbers like 100 and 2 into named constants for better maintainability and clarity.

+const HUNDRED = FixedTrait.fromInt(100n);
+const TWO = FixedTrait.fromInt(2n);

 private calculateElevation(
   col: number,
   row: number,
   mapAmplitude: Fixed,
   octaves: Fixed[],
   octavesSum: Fixed,
 ): Fixed {
   let elevation = FixedTrait.ZERO;
-  let _100 = FixedTrait.fromInt(100n);
-  let _2 = FixedTrait.fromInt(2n);
   for (const octave of octaves) {
     let x = FixedTrait.fromInt(BigInt(col)).div(octave).div(mapAmplitude);
     let z = FixedTrait.fromInt(BigInt(row)).div(octave).div(mapAmplitude);

     let sn = snoise(Vec3.new(x, FixedTrait.ZERO, z));
-    const noise = sn.add(FixedTrait.ONE).mul(_100).div(_2);
+    const noise = sn.add(FixedTrait.ONE).mul(HUNDRED).div(TWO);
     elevation = elevation.add(octave.mul(noise.floor()));
   }

-  return elevation.div(octavesSum).div(FixedTrait.fromInt(100n));
+  return elevation.div(octavesSum).div(HUNDRED);
🧰 Tools
🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.


95-99: Reuse the same constants from calculateElevation.

For consistency, use the same constants (HUNDRED and TWO) suggested for calculateElevation.

 private calculateMoisture(col: number, row: number, mapAmplitude: Fixed, moistureOctave: Fixed): Fixed {
   const moistureX = moistureOctave.mul(FixedTrait.fromInt(BigInt(col))).div(mapAmplitude);
   const moistureZ = moistureOctave.mul(FixedTrait.fromInt(BigInt(row))).div(mapAmplitude);
-  const noise = snoise(Vec3.new(moistureX, FixedTrait.ZERO, moistureZ)).add(FixedTrait.ONE).mul(FixedTrait.fromInt(100n)).div(FixedTrait.fromInt(2n));
+  const noise = snoise(Vec3.new(moistureX, FixedTrait.ZERO, moistureZ)).add(FixedTrait.ONE).mul(HUNDRED).div(TWO);
   return FixedTrait.floor(noise).div(FixedTrait.fromInt(100n));
🧰 Tools
🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.


102-127: Extract moisture thresholds into named constants.

Consider extracting moisture threshold ratios into named constants for better maintainability and readability.

+const MOISTURE_THRESHOLDS = {
+  VERY_DRY: FixedTrait.fromRatio(10n, 100n),
+  DRY: FixedTrait.fromRatio(16n, 100n),
+  MODERATE: FixedTrait.fromRatio(33n, 100n),
+  MOIST: FixedTrait.fromRatio(40n, 100n),
+  HUMID: FixedTrait.fromRatio(50n, 100n),
+  VERY_HUMID: FixedTrait.fromRatio(66n, 100n),
+  WET: FixedTrait.fromRatio(83n, 100n),
+};

 private determineBiome(elevation: Fixed, moisture: Fixed, level: typeof LEVEL): BiomeType {
   if (elevation.value < level.DEEP_OCEAN.value) return BiomeType.DeepOcean;
   if (elevation.value < level.OCEAN.value) return BiomeType.Ocean;
   if (elevation.value < level.SAND.value) return BiomeType.Beach;

   if (elevation.value > level.MOUNTAIN.value) {
-    if (moisture.value < FixedTrait.fromRatio(10n, 100n).value) return BiomeType.Scorched;
-    if (moisture.value < FixedTrait.fromRatio(40n, 100n).value) return BiomeType.Bare;
-    if (moisture.value < FixedTrait.fromRatio(50n, 100n).value) return BiomeType.Tundra;
+    if (moisture.value < MOISTURE_THRESHOLDS.VERY_DRY.value) return BiomeType.Scorched;
+    if (moisture.value < MOISTURE_THRESHOLDS.MOIST.value) return BiomeType.Bare;
+    if (moisture.value < MOISTURE_THRESHOLDS.HUMID.value) return BiomeType.Tundra;
     return BiomeType.Snow;
   }
🧰 Tools
🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

client/apps/game/src/utils/biome/fixed-point.ts (3)

18-65: Add readonly modifier to prevent accidental value mutations.

Consider adding the readonly modifier to the value property to prevent accidental mutations.

 export class Fixed {
-  public value: bigint;
+  public readonly value: bigint;

   constructor(value: bigint) {
     this.value = value;
   }
🧰 Tools
🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.


67-352: Convert FixedTrait class to namespace for better TypeScript idioms.

The static analysis tool correctly flags that this class contains only static members. Consider converting it to a namespace, which is more idiomatic in TypeScript for this use case.

-export class FixedTrait {
+export namespace FixedTrait {
   static ONE_64x64 = ONE_64x64;
   // ... rest of the implementation
🧰 Tools
🪛 Biome (1.9.4)

[error] 67-352: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)

🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.


303-334: Make Newton's method iterations configurable.

Consider making the number of Newton's method iterations configurable to allow trade-offs between precision and performance.

+const DEFAULT_NEWTON_ITERATIONS = 7;

-static sqrt(x: Fixed): Fixed {
+static sqrt(x: Fixed, iterations: number = DEFAULT_NEWTON_ITERATIONS): Fixed {
   // ... initial code ...

   // Newton's method iterations
   r = (r + x.value / r) >> 1n;
-  r = (r + x.value / r) >> 1n;
-  r = (r + x.value / r) >> 1n;
-  r = (r + x.value / r) >> 1n;
-  r = (r + x.value / r) >> 1n;
-  r = (r + x.value / r) >> 1n;
-  r = (r + x.value / r) >> 1n;
+  for (let i = 1; i < iterations; i++) {
+    r = (r + x.value / r) >> 1n;
+  }
🧰 Tools
🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0567a9c and 9eff604.

📒 Files selected for processing (2)
  • client/apps/game/src/three/managers/biome.ts (3 hunks)
  • client/apps/game/src/utils/biome/fixed-point.ts (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: lint
client/apps/game/src/three/managers/biome.ts

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

client/apps/game/src/utils/biome/fixed-point.ts

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

🪛 Biome (1.9.4)
client/apps/game/src/utils/biome/fixed-point.ts

[error] 67-352: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)

🔇 Additional comments (4)
client/apps/game/src/three/managers/biome.ts (3)

1-13: LGTM! Constants correctly converted to fixed-point.

The conversion of constants to fixed-point using FixedTrait is well-implemented and aligns with the PR objective.

🧰 Tools
🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.


16-33: LGTM! BiomeType successfully converted to enum.

The conversion from union type to enum improves type safety and maintainability, as previously suggested.

🧰 Tools
🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.


55-60: LGTM! Level thresholds correctly converted to fixed-point.

The conversion of level thresholds using FixedTrait.fromRatio maintains precision while aligning with the fixed-point implementation.

🧰 Tools
🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

client/apps/game/src/utils/biome/fixed-point.ts (1)

150-204: Add test cases for multiplication and division edge cases.

The custom implementation of mul and div differs from ABDK Math and handles signs separately. Consider adding comprehensive test cases to verify behavior, especially for edge cases like:

  • Numbers close to MIN_64x64/MAX_64x64
  • Numbers with different signs
  • Numbers with extreme differences in magnitude

Would you like me to help create these test cases?

🧰 Tools
🪛 GitHub Actions: lint

[warning] Code formatting does not match Prettier standards. Run Prettier with --write to fix.

@credence0x credence0x merged commit 4222dfd into next Jan 24, 2025
5 of 9 checks passed
@credence0x credence0x deleted the fix/biome-equivalence branch January 24, 2025 02:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants