Skip to content

feat: add vanillajs + phaser example #249

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

Merged

Conversation

MartianGreed
Copy link
Collaborator

@MartianGreed MartianGreed commented Aug 1, 2024

Closes #242

Introduced changes

Adds a new example using vanilla js and phaser

Checklist

  • Linked relevant issue
  • Add a dedicated CI job for new examples
  • Performed self-review of the code

Summary by CodeRabbit

  • New Features
    • Introduced configuration files and scripts to support a new Phaser example project.
    • Added foundational files for managing game entities, scenes, and world creation in the Phaser-based application.
  • Documentation
    • Added TypeScript and Vite configuration files for project setup.
  • Bug Fixes
    • Enhanced script handling for building the vanilla Phaser application.

Copy link

coderabbitai bot commented Aug 1, 2024

Warning

Rate limit exceeded

@MartianGreed has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 11 minutes and 4 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

Files that changed from the base of the PR and between 95e373c and 7c6d94e.

## Walkthrough

This update introduces a vanilla Phaser.js example, featuring a character navigating an infinite map. It includes essential configuration files and scripts, enhancing modularity and maintainability while integrating the Dojo engine effectively. This setup streamlines the development process and lays the groundwork for an engaging interactive experience.

## Changes

| Files | Change Summary |
|-------|----------------|
| `examples/vanilla/phaser/.gitignore` | New file to exclude unnecessary files from version control. |
| `examples/vanilla/phaser/dojoConfig.ts`, `examples/vanilla/phaser/src/dojo/*.ts`, `examples/vanilla/phaser/src/models.ts`, `examples/vanilla/phaser/src/utils.ts` | New files defining Dojo configuration, components, models, and utility functions for game logic. |
| `examples/vanilla/phaser/index.html` | New foundational HTML file linking Dojo and Phaser. |
| `examples/vanilla/phaser/package.json`, `examples/vanilla/phaser/tsconfig.json`, `examples/vanilla/phaser/vite.config.ts` | New configuration files for project metadata, TypeScript options, and build setup. |
| `examples/vanilla/phaser/src/entities.ts`, `examples/vanilla/phaser/src/scenes/scene-main.ts`, `examples/vanilla/phaser/src/main.ts` | New files introducing classes for managing game entities, scene management, and game initialization. |
| `package.json` | Addition of a new build script for the vanilla Phaser example. |
| `pnpm-workspace.yaml` | Updated to include new paths for workspace packages. |
| `scripts/build-examples.sh` | Modified script to include building the vanilla Phaser application. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant SceneMain as Scene
    participant GameConfig as Game
    participant DojoConfig as Config
    participant Models as Model

    User->>Scene: Start Game
    Scene->>Config: Load Configuration
    Config->>Scene: Return Config
    Scene->>Game: Initialize Game with Config
    Game->>Model: Setup Models
    Model->>Scene: Return Models
    Scene-->>User: Game Ready

Assessment against linked issues

Objective Addressed Explanation
Create a pure Phaser.js example (#[242])
Show a character moving around on an infinite map (#[242]) Implementation details on character movement are not explicitly confirmed.

Poem

🐰 In a world of maps, so vast and wide,
A character hops with joy and pride.
With Phaser's magic, they leap and bound,
Through endless terrains, adventure found.
Hooray for code, a new tale to tell,
In this rabbit's paradise, all is swell! 🌟


<!-- walkthrough_end --><!-- This is an auto-generated comment: raw summary by coderabbit.ai -->

<!--

```markdown
examples/vanilla/phaser/.gitignore: ## AI-generated summary of changes

The newly added `.gitignore` file specifies which files and directories should be ignored by Git in the `examples/vanilla/phaser` project. This includes log files, build artifacts, and configuration files that are typically not necessary to track in version control. The entries encompass patterns for various log files generated by npm, yarn, and pnpm, as well as directories like `node_modules` and `dist`, which contain dependencies and build outputs. Additionally, it explicitly excludes certain editor configuration files, such as `.vscode/extensions.json`, from being ignored, ensuring that essential settings are preserved in the repository. This addition enhances the project's cleanliness and maintainability by preventing unnecessary files from cluttering the version control history.

## Alterations to the declarations of exported or public entities

- New `.gitignore` file created in `examples/vanilla/phaser/`

---

examples/vanilla/phaser/dojoConfig.ts: ## AI-generated summary of changes

This diff introduces a new file `dojoConfig.ts` that establishes a configuration object for a Dojo application. It imports a manifest from a specified JSON file and leverages the `createDojoConfig` function from the `@dojoengine/core` package to construct the configuration object. The resulting `dojoConfig` is exported for use throughout the application, ensuring that the configuration can be accessed consistently. Additionally, the type of `dojoConfig` is exported as `Config`, which facilitates type safety in other modules that utilize this configuration. This design enhances the modularity and clarity of the application's configuration management.

## Alterations to the declarations of exported or public entities

- `export const dojoConfig` in `examples/vanilla/phaser/dojoConfig.ts` → `export const dojoConfig = createDojoConfig({...})` in `examples/vanilla/phaser/dojoConfig.ts`
- `export type Config` in `examples/vanilla/phaser/dojoConfig.ts` → `export type Config = typeof dojoConfig` in `examples/vanilla/phaser/dojoConfig.ts`

---

examples/vanilla/phaser/index.html: ## AI-generated summary of changes

This new HTML file serves as the foundational structure for a web application that integrates Dojo.js, Vanilla JavaScript, and the Phaser game framework. It establishes a basic HTML document with essential elements such as the `doctype`, `html`, `head`, and `body` tags. The `head` section includes metadata like character set, viewport settings for responsive design, and a title that indicates the purpose of the page. Additionally, it links to a favicon for branding purposes. The `body` contains a `div` element with the ID `app`, which is intended as a mounting point for the JavaScript application. A script tag is included to load the main TypeScript file (`main.ts`) as a module, indicating that the application will utilize modern JavaScript features. Overall, this file lays the groundwork for a web application that will leverage both Dojo.js and Phaser to create interactive experiences.

## Alterations to the declarations of exported or public entities

- No alterations to the declarations of exported or public entities were made.

---

examples/vanilla/phaser/package.json: ## AI-generated summary of changes

This diff introduces a new `package.json` file for the Phaser project, establishing the foundational configuration for a JavaScript module. The `package.json` specifies essential metadata such as the package name ("phaser"), its privacy status (set to true), and the initial version (0.0.0). It also defines the module type as "module", indicating the use of ES module syntax.

The scripts section includes three key commands: 
- `dev` for starting the development server using Vite,
- `build` for compiling TypeScript code and building the project with Vite, 
- `preview` for previewing the built project.

In the `devDependencies`, the file lists necessary development tools, including TypeScript (version 5.5.4), Vite (version 5.3.5), and a Vite plugin for WebAssembly support (version 3.3.0). 

The `dependencies` section outlines the runtime dependencies required for the project, featuring several packages from the Dojo Engine ecosystem, such as `@dojoengine/core`, `@dojoengine/create-burner`, and others, with some marked as workspace dependencies. Additionally, it includes other libraries like `@latticexyz/utils`, `noise`, and a specific version of Phaser (3.60.0-beta.14), as well as StarkNet (version 6.11.0).

Overall, this `package.json` file sets up a structured environment for developing the Phaser project, facilitating builds and dependency management.

## Alterations to the declarations of exported or public entities

- New `package.json` file created in `examples/vanilla/phaser/` with the following contents:
  - Name: `"phaser"`
  - Version: `"0.0.0"`
  - Type: `"module"`
  - Scripts: 
    - `"dev": "vite"`
    - `"build": "tsc && vite build"`
    - `"preview": "vite preview"`
  - DevDependencies:
    - `"typescript": "^5.5.4"`
    - `"vite": "^5.3.5"`
    - `"vite-plugin-wasm": "^3.3.0"`
  - Dependencies:
    - `"@dojoengine/core": "workspace:*"`
    - `"@dojoengine/create-burner": "workspace:*"`
    - `"@dojoengine/recs": "2.0.13"`
    - `"@dojoengine/state": "workspace:*"`
    - `"@dojoengine/torii-client": "workspace:*"`
    - `"@dojoengine/utils": "workspace:*"`
    - `"@latticexyz/utils": "^2.0.12"`
    - `"noise": "^0.0.0"`
    - `"phaser": "3.60.0-beta.14"`
    - `"starknet": "6.11.0"`

---

examples/vanilla/phaser/src/dojo/createClientComponent.ts: ## AI-generated summary of changes

The newly introduced file `createClientComponent.ts` defines a function `createClientComponents` that takes an object with a property `contractComponents` of type `ContractComponents`. This function enhances the `contractComponents` by wrapping the `Position` and `Moves` components with an `overridableComponent` function, allowing for dynamic customization of these components. The return value is an object that includes all original properties from `contractComponents`, along with the modified `Position` and `Moves` components. This structure supports extensibility in component behavior, making it easier to adapt or override specific functionalities in the client component architecture.

The use of TypeScript's `ReturnType` utility type to define `ClientComponents` ensures that the type is automatically inferred based on the return type of the `createClientComponents` function, promoting type safety and reducing potential errors in component usage. Overall, this file introduces a modular approach to component creation, facilitating better management of component behavior in the application.

## Alterations to the declarations of exported or public entities

- `export type ClientComponents` in `createClientComponent.ts` → `export type ClientComponents = ReturnType<typeof createClientComponents>;`
- `export function createClientComponents` in `createClientComponent.ts` → `export function createClientComponents({ contractComponents }: { contractComponents: ContractComponents; })`

---

examples/vanilla/phaser/src/dojo/defineContractComponents.ts: ## AI-generated summary of changes

This newly introduced file, `defineContractComponents.ts`, defines a set of components for a game or simulation environment using the Dojo Engine's component system. The primary function, `defineContractComponents`, accepts a `World` object as an argument and returns an object containing several defined components, each encapsulated within an immediately invoked function expression (IIFE) for modularity.

The components defined include `DirectionsAvailable`, `Moved`, `Moves`, and `Position`. Each component is created using the `defineComponent` function, which takes the `world` context, a set of properties with their respective types, and metadata that describes the component. The properties for each component are defined using types from the `@dojoengine/recs` library, such as `RecsType.BigInt`, `RecsType.StringArray`, and others, ensuring type safety and clarity in the structure of the data.

Overall, the file establishes a structured approach to defining game components, facilitating the management of player states and interactions within the defined world.

## Alterations to the declarations of exported or public entities

- `export type ContractComponents` in `examples/vanilla/phaser/src/dojo/defineContractComponents.ts` → `export type ContractComponents = Awaited<ReturnType<typeof defineContractComponents>>` in `examples/vanilla/phaser/src/dojo/defineContractComponents.ts`
- `export function defineContractComponents(world: World)` in `examples/vanilla/phaser/src/dojo/defineContractComponents.ts` → `export function defineContractComponents(world: World)` in `examples/vanilla/phaser/src/dojo/defineContractComponents.ts` (no change in signature, but function is newly introduced)

---

examples/vanilla/phaser/src/dojo/defineContractSystems.ts: ## AI-generated summary of changes

This diff introduces a new TypeScript file that defines a contract for managing actions within a Dojo environment, specifically for a blockchain application using StarkNet. It begins by importing essential types and modules, including `Account`, `AccountInterface`, and `DojoProvider`, which are crucial for blockchain interactions. A constant `NAMESPACE` is established to group related operations under a common identifier.

The new interface, `MoveProps`, encapsulates the properties required for movement actions, specifically an account and a direction, enhancing type safety and clarity when passing parameters to functions.

The core functionality is encapsulated in the asynchronous `setupWorld` function, which takes a `DojoProvider` and a configuration object as parameters. Inside this function, a closure named `actions` is created, defining two key asynchronous methods: `spawn` and `move`.

Overall, the new file establishes a robust framework for executing actions in a blockchain context, enhancing the functionality of the Dojo application.

## Alterations to the declarations of exported or public entities

- `export interface MoveProps` in `examples/vanilla/phaser/src/dojo/defineContractSystems.ts` → `export interface MoveProps` in `examples/vanilla/phaser/src/dojo/defineContractSystems.ts`
- `export async function setupWorld(provider: DojoProvider, _config: Config)` in `examples/vanilla/phaser/src/dojo/defineContractSystems.ts` → `export async function setupWorld(provider: DojoProvider, _config: Config)` in `examples/vanilla/phaser/src/dojo/defineContractSystems.ts`
- `export type IWorld = Awaited<ReturnType<typeof setupWorld>>` in `examples/vanilla/phaser/src/dojo/defineContractSystems.ts` → `export type IWorld = Awaited<ReturnType<typeof setupWorld>>` in `examples/vanilla/phaser/src/dojo/defineContractSystems.ts`

---

examples/vanilla/phaser/src/dojo/models.ts: ## AI-generated summary of changes

The new file `models.ts` introduces functionality for managing client models in a structured manner. It exports a type alias `ClientModels`, which is derived from the return type of the `models` function. The `models` function accepts an object parameter containing `contractModels`, which is of type `ContractComponents`. This function returns an object that encapsulates the `contractModels` within a `models` property, facilitating the aggregation of various contract-related models into a single structure. This design enhances modularity and simplifies access to the models, promoting a cleaner architecture for handling contract data within the application.

## Alterations to the declarations of exported or public entities

- `export type ClientModels` in `examples/vanilla/phaser/src/dojo/models.ts` → `export type ClientModels = ReturnType<typeof models>` in `examples/vanilla/phaser/src/dojo/models.ts`
- `export function models` in `examples/vanilla/phaser/src/dojo/models.ts` → `export function models({ contractModels }: { contractModels: ContractComponents; })` in `examples/vanilla/phaser/src/dojo/models.ts`

---

examples/vanilla/phaser/src/dojo/setup.ts: ## AI-generated summary of changes

The newly introduced file `setup.ts` provides a comprehensive asynchronous function `setup` that initializes various components required for a Dojo-based application. The function accepts a configuration object and utilizes the `torii` client to establish connections to a remote server using the provided RPC and Torii URLs. It creates contract components by invoking `defineContractComponents` and integrates them with client models through the `createClientComponents` function.

The setup process includes fetching existing entities from the Torii client via `getSyncEntities`, which retrieves data necessary for the application’s state management. The function also initializes a `DojoProvider` and a `RpcProvider`, which are essential for interacting with the Dojo environment and StarkNet, respectively.

Overall, this setup function serves as a critical entry point for initializing the application, encapsulating the logic required to prepare the environment for further interactions.

## Alterations to the declarations of exported or public entities

- `export async function setup({ ...config }: Config)` in `examples/vanilla/phaser/src/dojo/setup.ts` → `export async function setup({ ...config }: Config)` in `examples/vanilla/phaser/src/dojo/setup.ts`
- `export type SetupResult = Awaited<ReturnType<typeof setup>>` in `examples/vanilla/phaser/src/dojo/setup.ts` → `export type SetupResult = Awaited<ReturnType<typeof setup>>` in `examples/vanilla/phaser/src/dojo/setup.ts`
- `export type IDojo = Awaited<ReturnType<typeof setup>>` in `examples/vanilla/phaser/src/dojo/setup.ts` → `export type IDojo = Awaited<ReturnType<typeof setup>>` in `examples/vanilla/phaser/src/dojo/setup.ts`

---

examples/vanilla/phaser/src/dojo/systems.ts: ## AI-generated summary of changes

The newly introduced file `systems.ts` defines a set of systems for managing game entities in a client-server architecture, specifically for a game utilizing the Dojo Engine and StarkNet. It exports a `systems` function that accepts a client instance, client models, and contract components, returning an object containing action functions for spawning and moving entities.

Overall, this file introduces essential game logic for entity management, providing a structured approach to handle actions related to spawning and moving entities, while ensuring proper cleanup and error handling.

## Alterations to the declarations of exported or public entities

- `export function systems({ client, clientModels, contractComponents })` in `examples/vanilla/phaser/src/dojo/systems.ts` → `export function systems({ client, clientModels: { Position, Moves }, contractComponents })` in `examples/vanilla/phaser/src/dojo/systems.ts`
- `type SystemCalls` in `examples/vanilla/phaser/src/dojo/systems.ts` → `export type SystemCalls = ReturnType<typeof systems>;` in `examples/vanilla/phaser/src/dojo/systems.ts`

---

examples/vanilla/phaser/src/dojo/utils.ts: ## AI-generated summary of changes

The new file introduces an enumeration `Direction` and a function `updatePositionWithDirection`. The `Direction` enum defines four cardinal directions: Left, Right, Up, and Down, each associated with a unique integer value. The `updatePositionWithDirection` function takes a direction from the `Direction` enum and an object containing a vector with `x` and `y` properties. 

Inside the function, a switch statement modifies the vector based on the specified direction. The function ultimately returns the updated vector object, providing a clear mechanism for adjusting position based on directional input.

## Alterations to the declarations of exported or public entities

- `enum Direction` in `examples/vanilla/phaser/src/dojo/utils.ts` → New declaration
- `function updatePositionWithDirection(direction: Direction, value: { vec: { x: number; y: number } })` in `examples/vanilla/phaser/src/dojo/utils.ts` → New declaration

---

examples/vanilla/phaser/src/dojo/world.ts: ## AI-generated summary of changes

This diff introduces a new file that implements a basic world creation functionality using the `createWorld` function from the `@dojoengine/recs` package. The primary feature is the export of a constant named `world`, which is initialized by invoking `createWorld()`. This setup allows other modules to import and utilize the `world` instance, facilitating the management of game state or environment within the broader application context.

## Alterations to the declarations of exported or public entities

- `export const world` in `examples/vanilla/phaser/src/dojo/world.ts` → `export const world = createWorld();` in `examples/vanilla/phaser/src/dojo/world.ts`

---

examples/vanilla/phaser/src/entities.ts: ## AI-generated summary of changes

This diff introduces two new classes, `Chunk` and `Tile`, to manage game entities in a Phaser-based scene. The `Chunk` class is responsible for loading and unloading a group of tiles based on Perlin noise values, which are generated using the `snoise` function from the `@dojoengine/utils` package. Each `Chunk` instance holds its position (`x`, `y`), a reference to the `SceneMain`, and a collection of tiles represented by a Phaser group.

The `load` method in the `Chunk` class populates the chunk with tiles by iterating over a defined grid size, calculating the position of each tile, and determining its type (water, sand, or grass) based on the Perlin noise value. 

Overall, this new functionality enhances the game's visual landscape by dynamically generating terrain tiles based on procedural noise, allowing for varied and rich environments.

## Alterations to the declarations of exported or public entities

- `class Chunk` in `examples/vanilla/phaser/src/entities.ts` → New class
- `class Tile` in `examples/vanilla/phaser/src/entities.ts` → New class

---

examples/vanilla/phaser/src/main.ts: ## AI-generated summary of changes

The new file `main.ts` introduces a Phaser-based game configuration and initialization logic. It imports necessary modules, including the Phaser library, a main scene (`SceneMain`), and a Dojo configuration. The game configuration is defined using a `GameConfig` object that specifies parameters such as game type, dimensions, background color, scaling options, and physics settings. 

The file exports a default function that sets up the game using the `setup` function with the provided `dojoConfig`. Upon successful setup, it creates a new instance of `Phaser.Game` with the defined configuration. 

## Alterations to the declarations of exported or public entities

- `export default setup(dojoConfig)` in `examples/vanilla/phaser/src/main.ts` → `export default setup(dojoConfig).then(...)` in `examples/vanilla/phaser/src/main.ts`

---

examples/vanilla/phaser/src/scenes/scene-main.ts: ## AI-generated summary of changes

The newly introduced `SceneMain` class in the `scene-main.ts` file extends the Phaser `Scene` class, providing a structured environment for managing game scenes. It initializes key properties such as `dojo`, `chunkSize`, `tileSize`, and `cameraSpeed`, and sets up keyboard controls for player movement using the W, A, S, and D keys. 

## Alterations to the declarations of exported or public entities

- `export default class SceneMain extends Scene` in `examples/vanilla/phaser/src/scenes/scene-main.ts` → `export default class SceneMain extends Scene` in `examples/vanilla/phaser/src/scenes/scene-main.ts` (new class added)

---

examples/vanilla/phaser/tsconfig.json: ## AI-generated summary of changes

This diff introduces a new TypeScript configuration file (`tsconfig.json`) that establishes the compiler options for a project. It sets the ECMAScript target to ES2020, enabling the use of modern JavaScript features. The module resolution strategy is configured to "bundler," making it compatible with build tools like Webpack or Rollup. 

## Alterations to the declarations of exported or public entities

- New `tsconfig.json` file added with compiler options for TypeScript configuration.

---

examples/vanilla/phaser/vite.config.ts: ## AI-generated summary of changes

The new file `vite.config.ts` introduces a configuration setup for Vite, a modern build tool for JavaScript applications. This configuration utilizes the `defineConfig` function from Vite, which enhances type inference and provides a structured way to define the configuration settings. 

## Alterations to the declarations of exported or public entities

- `export default defineConfig({...})` in `examples/vanilla/phaser/vite.config.ts` → `export default defineConfig({...})` in `examples/vanilla/phaser/vite.config.ts` (new file)

---

package.json: ## AI-generated summary of changes

The diff introduces a new build script for a project that utilizes the Phaser framework, specifically for a vanilla implementation. The addition of the line `"build-vanilla-phaser": "pnpm --dir examples/vanilla/vanilla-phaser build"` in the `scripts` section of `package.json` indicates that a new command has been created to facilitate the building process for this specific example.

## Alterations to the declarations of exported or public entities

- `"build-vanilla-phaser": "pnpm --dir examples/vanilla/vanilla-phaser build"` in `package.json` → New entry added to the `scripts` section in `package.json`

---

pnpm-workspace.yaml: ## AI-generated summary of changes

The diff introduces a new entry to the `packages` section of the `pnpm-workspace.yaml` configuration file. Specifically, it adds the path `"examples/vanilla/*"` to the list of packages, indicating that the workspace will now include a new set of example projects under the "vanilla" category.

## Alterations to the declarations of exported or public entities

- `packages:` in `pnpm-workspace.yaml` → `packages:` in `pnpm-workspace.yaml` (with the addition of `"examples/vanilla/*"`).

---

scripts/build-examples.sh: ## AI-generated summary of changes

The diff modifies the build script in `scripts/build-examples.sh` by adding a command to build a "vanilla-phaser" application. This addition expands the build capabilities of the script. Additionally, the "build-vue-app" command has been repositioned to follow the new "build-vanilla-phaser" command.

## Alterations to the declarations of exported or public entities

- `pnpm run build-vue-app` in `scripts/build-examples.sh` → `pnpm run build-vanilla-phaser` in `scripts/build-examples.sh`
- `pnpm run build-vue-app` in `scripts/build-examples.sh` (moved to follow the new command)

-->


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>.
    • 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 generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @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 as 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.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

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.

@ponderingdemocritus ponderingdemocritus marked this pull request as ready for review August 2, 2024 11:09
Copy link

@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, codebase verification and nitpick comments (1)
examples/vanilla/phaser/src/dojo/setup.ts (1)

16-17: Unused Type Exports

The types SetupResult and IDojo are defined but not used anywhere else in the codebase. Consider removing these unused types or ensure they are utilized appropriately.

  • SetupResult defined at examples/vanilla/phaser/src/dojo/setup.ts
  • IDojo defined at examples/vanilla/phaser/src/dojo/setup.ts
Analysis chain

Ensure type exports are correctly defined and used.

Verify that the exported types SetupResult and IDojo are correctly defined and used in the file.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the exported types are correctly defined and used in the file.

# Test: Search for the usage of each exported type. Expect: Each type should be used at least once.
rg --type typescript -A 5 'export type' examples/vanilla/phaser/src/dojo/setup.ts

Length of output: 118


Script:

#!/bin/bash
# Locate the file and search for type exports

# Find the file
file_path=$(fd setup.ts | grep 'examples/vanilla/phaser/src/dojo/setup.ts')

# Search for type exports in the located file
if [ -n "$file_path" ]; then
  rg 'export type' "$file_path"
else
  echo "File not found"
fi

Length of output: 350


Script:

#!/bin/bash
# Search for the usage of the exported types `SetupResult` and `IDojo` within the codebase

# Search for `SetupResult` usage
rg 'SetupResult' examples/vanilla/phaser/src/dojo/

# Search for `IDojo` usage
rg 'IDojo' examples/vanilla/phaser/src/dojo/

Length of output: 295

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 988730c and d7873b2.

Files ignored due to path filters (5)
  • examples/vanilla/phaser/assets/sprGrass.png is excluded by !**/*.png
  • examples/vanilla/phaser/assets/sprSand.png is excluded by !**/*.png
  • examples/vanilla/phaser/assets/sprWater.png is excluded by !**/*.png
  • examples/vanilla/phaser/public/favicon.ico is excluded by !**/*.ico
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
Files selected for processing (20)
  • examples/vanilla/phaser/.gitignore (1 hunks)
  • examples/vanilla/phaser/dojoConfig.ts (1 hunks)
  • examples/vanilla/phaser/index.html (1 hunks)
  • examples/vanilla/phaser/package.json (1 hunks)
  • examples/vanilla/phaser/src/dojo/createClientComponent.ts (1 hunks)
  • examples/vanilla/phaser/src/dojo/defineContractComponents.ts (1 hunks)
  • examples/vanilla/phaser/src/dojo/defineContractSystems.ts (1 hunks)
  • examples/vanilla/phaser/src/dojo/models.ts (1 hunks)
  • examples/vanilla/phaser/src/dojo/setup.ts (1 hunks)
  • examples/vanilla/phaser/src/dojo/systems.ts (1 hunks)
  • examples/vanilla/phaser/src/dojo/utils.ts (1 hunks)
  • examples/vanilla/phaser/src/dojo/world.ts (1 hunks)
  • examples/vanilla/phaser/src/entities.ts (1 hunks)
  • examples/vanilla/phaser/src/main.ts (1 hunks)
  • examples/vanilla/phaser/src/scenes/scene-main.ts (1 hunks)
  • examples/vanilla/phaser/tsconfig.json (1 hunks)
  • examples/vanilla/phaser/vite.config.ts (1 hunks)
  • package.json (1 hunks)
  • pnpm-workspace.yaml (1 hunks)
  • scripts/build-examples.sh (1 hunks)
Files skipped from review due to trivial changes (8)
  • examples/vanilla/phaser/.gitignore
  • examples/vanilla/phaser/index.html
  • examples/vanilla/phaser/package.json
  • examples/vanilla/phaser/src/dojo/world.ts
  • examples/vanilla/phaser/tsconfig.json
  • examples/vanilla/phaser/vite.config.ts
  • package.json
  • pnpm-workspace.yaml
Additional context used
Biome
examples/vanilla/phaser/src/dojo/utils.ts

[error] 13-13: This is an unexpected use of the debugger statement.

Unsafe fix: Remove debugger statement

(lint/suspicious/noDebugger)

Additional comments not posted (29)
examples/vanilla/phaser/dojoConfig.ts (3)

1-2: Imports are appropriate and necessary.

The imported manifest and createDojoConfig function are required for creating the configuration.


4-6: Configuration creation is correct.

The createDojoConfig function is used correctly to create the configuration with the provided manifest.


7-7: Export statements are correct.

The configuration and its type are correctly exported.

scripts/build-examples.sh (1)

11-13: Build commands are correctly added and reorganized.

The build command for the vanilla Phaser example is correctly added, and the Vue app build command is appropriately moved to follow the new command.

examples/vanilla/phaser/src/dojo/models.ts (3)

1-1: Import statement is appropriate and necessary.

The imported ContractComponents is required for the function's parameter.


5-9: Function definition is correct.

The function models is correctly defined to take contractModels as a parameter.


10-15: Return statement is correct.

The function correctly returns an object with the models, spreading the contractModels.

examples/vanilla/phaser/src/dojo/createClientComponent.ts (3)

1-2: Imports look good.

The import statements are necessary and correctly specified.


4-5: Type definition looks good.

The type definition for ClientComponents is clear and correctly specified.


6-16: Function definition looks good.

The function createClientComponents is well-defined and correctly uses the overridableComponent function to override components.

examples/vanilla/phaser/src/dojo/utils.ts (1)

1-6: Enum definition looks good.

The enum Direction is clear and correctly specified.

examples/vanilla/phaser/src/main.ts (3)

1-4: Imports look good.

The import statements are necessary and correctly specified.


6-25: Phaser game configuration looks good.

The configuration object is well-defined and correctly specifies the necessary settings for the Phaser game.


27-36: Game setup and initialization looks good.

The setup and initialization process is well-defined and correctly handles the game initialization and error handling.

examples/vanilla/phaser/src/dojo/defineContractSystems.ts (4)

1-4: LGTM! Imports are correct and necessary.

The imported modules are used appropriately in the file.


5-10: LGTM! NAMESPACE constant and MoveProps interface are correct.

The NAMESPACE constant and MoveProps interface are defined appropriately.


12-15: LGTM! handleError function handles errors correctly.

The handleError function logs the error and rethrows it, which is appropriate for error handling.


17-55: LGTM! IWorld type definition and setupWorld function are correct.

The IWorld type definition and setupWorld function are implemented correctly and securely.

However, ensure that all function calls to setupWorld match the expected usage.

examples/vanilla/phaser/src/entities.ts (3)

1-3: LGTM! Imports are correct and necessary.

The imported modules are used appropriately in the file.


5-64: LGTM! Chunk class is implemented correctly and efficiently.

The Chunk class includes necessary properties and methods for loading and unloading tiles, and it is implemented efficiently.


67-74: LGTM! Tile class is implemented correctly and efficiently.

The Tile class extends GameObjects.Sprite and includes necessary properties for the scene and coordinates.

examples/vanilla/phaser/src/dojo/defineContractComponents.ts (2)

1-3: LGTM! Imports are correct and necessary.

The imported modules are used appropriately in the file.


5-71: LGTM! ContractComponents type definition and defineContractComponents function are correct.

The ContractComponents type definition and defineContractComponents function are implemented correctly and securely.

However, ensure that all function calls to defineContractComponents match the expected usage.

examples/vanilla/phaser/src/dojo/setup.ts (2)

83-94: Ensure the return statement includes all necessary components.

Verify that the return statement includes all necessary components and configurations.

Verification successful

The return statement includes all necessary components.

The return statement in the setup.ts file includes all the required components and configurations, as verified by their usage in the codebase.

  • client
  • clientModels
  • contractComponents
  • systemCalls
  • config
  • world
  • burnerManager
  • rpcProvider
  • sync
  • account
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the return statement includes all necessary components and configurations.

# Test: Search for the usage of the return values. Expect: Each return value should be used at least once.
rg --type typescript -A 5 'return {' examples/vanilla/phaser/src/dojo/setup.ts

Length of output: 160


Script:

#!/bin/bash
# Description: Verify that the return statement includes all necessary components and configurations.

# Test: Search for the usage of the return values. Expect: Each return value should be used at least once.
rg 'return {' -A 10 examples/vanilla/phaser/src/dojo/setup.ts

Length of output: 143


Script:

#!/bin/bash
# Description: Verify that the return statement includes all necessary components and configurations.

# Test: Search for the return statement and include context lines to verify the return values.
grep -A 10 'return {' examples/vanilla/phaser/src/dojo/setup.ts

Length of output: 302


Script:

#!/bin/bash
# Description: Verify that each return value is used in the codebase.

# List of return values to verify
values=("client" "clientModels" "contractComponents" "systemCalls" "config" "world" "burnerManager" "rpcProvider" "sync" "account")

# Loop through each value and search for its usage in the codebase
for value in "${values[@]}"; do
    echo "Searching for usage of: $value"
    rg "$value" examples/vanilla/phaser/src/dojo/
done

Length of output: 9904


1-15: Ensure all imports are necessary and correctly used.

Verify that all imported modules are necessary and correctly utilized in the file to avoid any unused imports.

Verification successful

Let's modify the script to search for the usage of each imported module in the file without specifying the file type.


All imports are necessary and correctly used.

The verification confirms that each imported module in examples/vanilla/phaser/src/dojo/setup.ts is utilized in the file.

  • getSyncEntities is used in the sync constant.
  • torii is used to create the toriiClient.
  • models is used to get clientModels.
  • systems is used to get actions.
  • defineContractComponents is used to define contractModels.
  • world is used in defineContractComponents.
  • Config is used as a parameter in the setup function.
  • setupWorld is used to set up the client.
  • DojoProvider is used to create a new provider.
  • BurnerManager is used to create a new manager.
  • Account, RpcProvider, and wallet are used in the rpcProvider and burnerManager.
  • createClientComponents is used to create contractModels.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that all imported modules are necessary and correctly utilized in the file.

# Test: Search for the usage of each imported module. Expect: Each module should be used at least once.
rg --type typescript -A 5 'import' examples/vanilla/phaser/src/dojo/setup.ts

Length of output: 111


Script:

#!/bin/bash
# Description: Verify that all imported modules are necessary and correctly utilized in the file.

# Test: Search for the usage of each imported module. Expect: Each module should be used at least once.
rg 'getSyncEntities|torii|models|systems|defineContractComponents|world|Config|setupWorld|DojoProvider|BurnerManager|Account|RpcProvider|wallet|createClientComponents' examples/vanilla/phaser/src/dojo/setup.ts

Length of output: 1661

examples/vanilla/phaser/src/dojo/systems.ts (1)

16-24: Ensure proper typing for function parameters.

The systems function parameters have complex types that should be clearly defined. Ensure that the types ClientComponents, ContractComponents, and IWorld are correctly defined and imported.

Verification successful

Ensure proper typing for function parameters.

The systems function parameters have complex types that are correctly defined and imported in the codebase. The types ClientComponents, ContractComponents, and IWorld are properly defined and utilized.

  • IWorld: Defined in packages/core/src/types/index.ts and examples/react/react-pwa-app/src/dojo/generated/generated.ts.
  • ContractComponents: Defined in examples/react/react-pwa-app/src/dojo/generated/contractComponents.ts.
  • ClientComponents: Defined in examples/react/react-pwa-app/src/dojo/createClientComponents.ts.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the definitions of ClientComponents, ContractComponents, and IWorld.

# Test: Search for the type definitions. Expect: Definitions of the types.
rg --type typescript 'ClientComponents|ContractComponents|IWorld'

Length of output: 102


Script:

#!/bin/bash
# Description: Verify the definitions of ClientComponents, ContractComponents, and IWorld.

# Test: Search for the type definitions. Expect: Definitions of the types.
rg 'ClientComponents|ContractComponents|IWorld'

Length of output: 14186

examples/vanilla/phaser/src/scenes/scene-main.ts (3)

30-37: LGTM!

The asset loading logic in the preload method looks good.


169-176: LGTM!

The input checking logic in the checkInputs method looks good.


77-85: Optimize chunk retrieval logic.

The getChunk method can be optimized by using a Map for this.chunks to improve lookup performance.

Comment on lines 8 to 29
export function updatePositionWithDirection(
direction: Direction,
value: { vec: { x: number; y: number } }
) {
console.log(value);
debugger;
switch (direction) {
case Direction.Left:
value.vec.x--;
break;
case Direction.Right:
value.vec.x++;
break;
case Direction.Up:
value.vec.y--;
break;
case Direction.Down:
value.vec.y++;
break;
default:
throw new Error("Invalid direction provided");
}
return value;
}
Copy link

Choose a reason for hiding this comment

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

Remove console log and debugger statement.

The console log and debugger statement should be removed for production code.

-    console.log(value);
-    debugger;

The rest of the function is well-defined and correctly handles all possible directions.

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
export function updatePositionWithDirection(
direction: Direction,
value: { vec: { x: number; y: number } }
) {
console.log(value);
debugger;
switch (direction) {
case Direction.Left:
value.vec.x--;
break;
case Direction.Right:
value.vec.x++;
break;
case Direction.Up:
value.vec.y--;
break;
case Direction.Down:
value.vec.y++;
break;
default:
throw new Error("Invalid direction provided");
}
return value;
}
export function updatePositionWithDirection(
direction: Direction,
value: { vec: { x: number; y: number } }
) {
switch (direction) {
case Direction.Left:
value.vec.x--;
break;
case Direction.Right:
value.vec.x++;
break;
case Direction.Up:
value.vec.y--;
break;
case Direction.Down:
value.vec.y++;
break;
default:
throw new Error("Invalid direction provided");
}
return value;
}
Tools
Biome

[error] 13-13: This is an unexpected use of the debugger statement.

Unsafe fix: Remove debugger statement

(lint/suspicious/noDebugger)

Comment on lines 44 to 47
const client = await setupWorld(
new DojoProvider(config.manifest, config.rpcUrl),
config
);
Copy link

Choose a reason for hiding this comment

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

Ensure proper error handling for setupWorld.

The setupWorld call should have error handling to manage potential failures.

-    const client = await setupWorld(
-        new DojoProvider(config.manifest, config.rpcUrl),
-        config
-    );
+    let client;
+    try {
+        client = await setupWorld(
+            new DojoProvider(config.manifest, config.rpcUrl),
+            config
+        );
+    } catch (e) {
+        console.error('Failed to setup world:', e);
+        throw e;
+    }
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 client = await setupWorld(
new DojoProvider(config.manifest, config.rpcUrl),
config
);
let client;
try {
client = await setupWorld(
new DojoProvider(config.manifest, config.rpcUrl),
config
);
} catch (e) {
console.error('Failed to setup world:', e);
throw e;
}

Comment on lines 36 to 42
// fetch all existing entities from torii
const sync = await getSyncEntities(
toriiClient,
contractModels as any,
[],
1000
);
Copy link

Choose a reason for hiding this comment

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

Ensure proper error handling for getSyncEntities.

The getSyncEntities call should have error handling to manage potential failures.

-    const sync = await getSyncEntities(
-        toriiClient,
-        contractModels as any,
-        [],
-        1000
-    );
+    let sync;
+    try {
+        sync = await getSyncEntities(
+            toriiClient,
+            contractModels as any,
+            [],
+            1000
+        );
+    } catch (e) {
+        console.error('Failed to sync entities:', e);
+        throw e;
+    }
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
// fetch all existing entities from torii
const sync = await getSyncEntities(
toriiClient,
contractModels as any,
[],
1000
);
// fetch all existing entities from torii
let sync;
try {
sync = await getSyncEntities(
toriiClient,
contractModels as any,
[],
1000
);
} catch (e) {
console.error('Failed to sync entities:', e);
throw e;
}

Comment on lines 28 to 31
// create contract components
const contractModels = createClientComponents({
contractComponents: defineContractComponents(world),
});
Copy link

Choose a reason for hiding this comment

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

Ensure proper error handling for createClientComponents.

The createClientComponents call should have error handling to manage potential failures.

-    const contractModels = createClientComponents({
+    let contractModels;
+    try {
+        contractModels = createClientComponents({
+            contractComponents: defineContractComponents(world),
+        });
+    } catch (e) {
+        console.error('Failed to create client components:', e);
+        throw e;
+    }
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
// create contract components
const contractModels = createClientComponents({
contractComponents: defineContractComponents(world),
});
let contractModels;
try {
contractModels = createClientComponents({
contractComponents: defineContractComponents(world),
});
} catch (e) {
console.error('Failed to create client components:', e);
throw e;
}

Comment on lines 19 to 26
export async function setup({ ...config }: Config) {
// torii client
const toriiClient = await torii.createClient({
rpcUrl: config.rpcUrl,
toriiUrl: config.toriiUrl,
relayUrl: "",
worldAddress: config.manifest.world.address || "",
});
Copy link

Choose a reason for hiding this comment

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

Ensure proper error handling for torii.createClient.

The torii.createClient call should have error handling to manage potential failures.

-    const toriiClient = await torii.createClient({
+    let toriiClient;
+    try {
+        toriiClient = await torii.createClient({
+            rpcUrl: config.rpcUrl,
+            toriiUrl: config.toriiUrl,
+            relayUrl: "",
+            worldAddress: config.manifest.world.address || "",
+        });
+    } catch (e) {
+        console.error('Failed to create torii client:', e);
+        throw e;
+    }
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
export async function setup({ ...config }: Config) {
// torii client
const toriiClient = await torii.createClient({
rpcUrl: config.rpcUrl,
toriiUrl: config.toriiUrl,
relayUrl: "",
worldAddress: config.manifest.world.address || "",
});
export async function setup({ ...config }: Config) {
// torii client
let toriiClient;
try {
toriiClient = await torii.createClient({
rpcUrl: config.rpcUrl,
toriiUrl: config.toriiUrl,
relayUrl: "",
worldAddress: config.manifest.world.address || "",
});
} catch (e) {
console.error('Failed to create torii client:', e);
throw e;
}

Comment on lines 26 to 63
const spawn = async (account: AccountInterface) => {
const entityId = getEntityIdFromKeys([
BigInt(account.address),
]) as Entity;

const positionId = uuid();
Position.addOverride(positionId, {
entity: entityId,
value: { player: BigInt(entityId), vec: { x: 10, y: 10 } },
});

const movesId = uuid();
Moves.addOverride(movesId, {
entity: entityId,
value: {
player: BigInt(entityId),
remaining: 100,
last_direction: 0,
},
});

try {
const { transaction_hash } = await client.actions.spawn({
account,
});
// setComponentsFromEvents(
// contractComponents,
// getEvents(
// await account.waitForTransaction(transaction_hash, {
// retryInterval: 100,
// })
// )
// );
} catch (e) {
console.log(e);
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
} finally {
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
}
Copy link

Choose a reason for hiding this comment

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

Ensure proper cleanup in the finally block.

The finally block in the spawn function removes position and moves overrides regardless of the outcome. This might lead to issues if the transaction is successful. Consider removing these lines from the finally block and handling them only in the catch block.

- finally {
-     Position.removeOverride(positionId);
-     Moves.removeOverride(movesId);
- }
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 spawn = async (account: AccountInterface) => {
const entityId = getEntityIdFromKeys([
BigInt(account.address),
]) as Entity;
const positionId = uuid();
Position.addOverride(positionId, {
entity: entityId,
value: { player: BigInt(entityId), vec: { x: 10, y: 10 } },
});
const movesId = uuid();
Moves.addOverride(movesId, {
entity: entityId,
value: {
player: BigInt(entityId),
remaining: 100,
last_direction: 0,
},
});
try {
const { transaction_hash } = await client.actions.spawn({
account,
});
// setComponentsFromEvents(
// contractComponents,
// getEvents(
// await account.waitForTransaction(transaction_hash, {
// retryInterval: 100,
// })
// )
// );
} catch (e) {
console.log(e);
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
} finally {
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
}
const spawn = async (account: AccountInterface) => {
const entityId = getEntityIdFromKeys([
BigInt(account.address),
]) as Entity;
const positionId = uuid();
Position.addOverride(positionId, {
entity: entityId,
value: { player: BigInt(entityId), vec: { x: 10, y: 10 } },
});
const movesId = uuid();
Moves.addOverride(movesId, {
entity: entityId,
value: {
player: BigInt(entityId),
remaining: 100,
last_direction: 0,
},
});
try {
const { transaction_hash } = await client.actions.spawn({
account,
});
// setComponentsFromEvents(
// contractComponents,
// getEvents(
// await account.waitForTransaction(transaction_hash, {
// retryInterval: 100,
// })
// )
// );
} catch (e) {
console.log(e);
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
}

Comment on lines 25 to 118
const spawn = async (account: AccountInterface) => {
const entityId = getEntityIdFromKeys([
BigInt(account.address),
]) as Entity;

const positionId = uuid();
Position.addOverride(positionId, {
entity: entityId,
value: { player: BigInt(entityId), vec: { x: 10, y: 10 } },
});

const movesId = uuid();
Moves.addOverride(movesId, {
entity: entityId,
value: {
player: BigInt(entityId),
remaining: 100,
last_direction: 0,
},
});

try {
const { transaction_hash } = await client.actions.spawn({
account,
});
// setComponentsFromEvents(
// contractComponents,
// getEvents(
// await account.waitForTransaction(transaction_hash, {
// retryInterval: 100,
// })
// )
// );
} catch (e) {
console.log(e);
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
} finally {
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
}
};

const move = async (
account: AccountInterface,
direction: Direction
) => {
const entityId = getEntityIdFromKeys([
BigInt(account.address),
]) as Entity;

console.log(direction, getComponentValue(Position, entityId));
const positionId = uuid();
Position.addOverride(positionId, {
entity: entityId,
value: {
player: BigInt(entityId),
vec: updatePositionWithDirection(
direction,
getComponentValue(Position, entityId) as any
).vec,
},
});

const movesId = uuid();
Moves.addOverride(movesId, {
entity: entityId,
value: {
player: BigInt(entityId),
remaining:
(getComponentValue(Moves, entityId)?.remaining || 0) -
1,
},
});

try {
const { transaction_hash } = await client.actions.move({
account,
direction,
});

setComponentsFromEvents(
contractComponents,
getEvents(
await account.waitForTransaction(transaction_hash, {
retryInterval: 100,
})
)
);
} catch (e) {
console.error(e);
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
} finally {
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
}
};
return { spawn, move };
}
Copy link

Choose a reason for hiding this comment

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

Ensure error handling and logging consistency.

The actions function contains two asynchronous functions: spawn and move. Both functions have try-catch blocks for error handling, but the error logging is inconsistent. Use console.error for both to maintain consistency.

- console.log(e);
+ console.error(e);
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
function actions() {
const spawn = async (account: AccountInterface) => {
const entityId = getEntityIdFromKeys([
BigInt(account.address),
]) as Entity;
const positionId = uuid();
Position.addOverride(positionId, {
entity: entityId,
value: { player: BigInt(entityId), vec: { x: 10, y: 10 } },
});
const movesId = uuid();
Moves.addOverride(movesId, {
entity: entityId,
value: {
player: BigInt(entityId),
remaining: 100,
last_direction: 0,
},
});
try {
const { transaction_hash } = await client.actions.spawn({
account,
});
// setComponentsFromEvents(
// contractComponents,
// getEvents(
// await account.waitForTransaction(transaction_hash, {
// retryInterval: 100,
// })
// )
// );
} catch (e) {
console.log(e);
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
} finally {
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
}
};
const move = async (
account: AccountInterface,
direction: Direction
) => {
const entityId = getEntityIdFromKeys([
BigInt(account.address),
]) as Entity;
console.log(direction, getComponentValue(Position, entityId));
const positionId = uuid();
Position.addOverride(positionId, {
entity: entityId,
value: {
player: BigInt(entityId),
vec: updatePositionWithDirection(
direction,
getComponentValue(Position, entityId) as any
).vec,
},
});
const movesId = uuid();
Moves.addOverride(movesId, {
entity: entityId,
value: {
player: BigInt(entityId),
remaining:
(getComponentValue(Moves, entityId)?.remaining || 0) -
1,
},
});
try {
const { transaction_hash } = await client.actions.move({
account,
direction,
});
setComponentsFromEvents(
contractComponents,
getEvents(
await account.waitForTransaction(transaction_hash, {
retryInterval: 100,
})
)
);
} catch (e) {
console.error(e);
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
} finally {
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
}
};
return { spawn, move };
}
function actions() {
const spawn = async (account: AccountInterface) => {
const entityId = getEntityIdFromKeys([
BigInt(account.address),
]) as Entity;
const positionId = uuid();
Position.addOverride(positionId, {
entity: entityId,
value: { player: BigInt(entityId), vec: { x: 10, y: 10 } },
});
const movesId = uuid();
Moves.addOverride(movesId, {
entity: entityId,
value: {
player: BigInt(entityId),
remaining: 100,
last_direction: 0,
},
});
try {
const { transaction_hash } = await client.actions.spawn({
account,
});
// setComponentsFromEvents(
// contractComponents,
// getEvents(
// await account.waitForTransaction(transaction_hash, {
// retryInterval: 100,
// })
// )
// );
} catch (e) {
console.error(e);
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
} finally {
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
}
};
const move = async (
account: AccountInterface,
direction: Direction
) => {
const entityId = getEntityIdFromKeys([
BigInt(account.address),
]) as Entity;
console.log(direction, getComponentValue(Position, entityId));
const positionId = uuid();
Position.addOverride(positionId, {
entity: entityId,
value: {
player: BigInt(entityId),
vec: updatePositionWithDirection(
direction,
getComponentValue(Position, entityId) as any
).vec,
},
});
const movesId = uuid();
Moves.addOverride(movesId, {
entity: entityId,
value: {
player: BigInt(entityId),
remaining:
(getComponentValue(Moves, entityId)?.remaining || 0) -
1,
},
});
try {
const { transaction_hash } = await client.actions.move({
account,
direction,
});
setComponentsFromEvents(
contractComponents,
getEvents(
await account.waitForTransaction(transaction_hash, {
retryInterval: 100,
})
)
);
} catch (e) {
console.error(e);
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
} finally {
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
}
};
return { spawn, move };
}

Comment on lines 17 to 30
constructor(dojo: IDojo) {
super({ key: "MainScene" });
this.dojo = dojo;

this.chunkSize = 16;
this.tileSize = 16;
this.cameraSpeed = 2;
this.chunks = [];
this.keyW = null;
this.keyS = null;
this.keyA = null;
this.keyD = null;
}
Copy link

Choose a reason for hiding this comment

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

Ensure proper initialization of properties.

The constructor initializes several properties, but followPoint is not initialized. Consider initializing followPoint to avoid potential undefined errors.

+ this.followPoint = new Phaser.Math.Vector2(0, 0);
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
constructor(dojo: IDojo) {
super({ key: "MainScene" });
this.dojo = dojo;
this.chunkSize = 16;
this.tileSize = 16;
this.cameraSpeed = 2;
this.chunks = [];
this.keyW = null;
this.keyS = null;
this.keyA = null;
this.keyD = null;
}
constructor(dojo: IDojo) {
super({ key: "MainScene" });
this.dojo = dojo;
this.chunkSize = 16;
this.tileSize = 16;
this.cameraSpeed = 2;
this.chunks = [];
this.keyW = null;
this.keyS = null;
this.keyA = null;
this.keyD = null;
this.followPoint = new Phaser.Math.Vector2(0, 0);
}

Comment on lines +38 to +75
create() {
this.anims.create({
key: "sprWater",
frames: this.anims.generateFrameNumbers("sprWater", {
start: 0,
end: 1,
}),
frameRate: 5,
repeat: -1,
});

this.cameras.main.setZoom(2);
this.followPoint = new Phaser.Math.Vector2(
this.cameras.main.worldView.x +
this.cameras.main.worldView.width * 2,
this.cameras.main.worldView.y +
this.cameras.main.worldView.height * 2
);

if (this.input.keyboard === null) {
throw new Error("plugin input.keyboard is not loaded");
}

this.keyW = this.input.keyboard.addKey(
Phaser.Input.Keyboard.KeyCodes.W
);
this.keyS = this.input.keyboard.addKey(
Phaser.Input.Keyboard.KeyCodes.S
);
this.keyA = this.input.keyboard.addKey(
Phaser.Input.Keyboard.KeyCodes.A
);
this.keyD = this.input.keyboard.addKey(
Phaser.Input.Keyboard.KeyCodes.D
);

this.dojo.systemCalls.spawn(this.dojo.account);
Copy link

Choose a reason for hiding this comment

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

Ensure proper error handling for keyboard input.

The create method throws an error if the keyboard input plugin is not loaded. Consider providing a more descriptive error message or handling the error gracefully.

- throw new Error("plugin input.keyboard is not loaded");
+ throw new Error("Keyboard input plugin is not loaded. Ensure the plugin is included in the Phaser configuration.");
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
create() {
this.anims.create({
key: "sprWater",
frames: this.anims.generateFrameNumbers("sprWater", {
start: 0,
end: 1,
}),
frameRate: 5,
repeat: -1,
});
this.cameras.main.setZoom(2);
this.followPoint = new Phaser.Math.Vector2(
this.cameras.main.worldView.x +
this.cameras.main.worldView.width * 2,
this.cameras.main.worldView.y +
this.cameras.main.worldView.height * 2
);
if (this.input.keyboard === null) {
throw new Error("plugin input.keyboard is not loaded");
}
this.keyW = this.input.keyboard.addKey(
Phaser.Input.Keyboard.KeyCodes.W
);
this.keyS = this.input.keyboard.addKey(
Phaser.Input.Keyboard.KeyCodes.S
);
this.keyA = this.input.keyboard.addKey(
Phaser.Input.Keyboard.KeyCodes.A
);
this.keyD = this.input.keyboard.addKey(
Phaser.Input.Keyboard.KeyCodes.D
);
this.dojo.systemCalls.spawn(this.dojo.account);
create() {
this.anims.create({
key: "sprWater",
frames: this.anims.generateFrameNumbers("sprWater", {
start: 0,
end: 1,
}),
frameRate: 5,
repeat: -1,
});
this.cameras.main.setZoom(2);
this.followPoint = new Phaser.Math.Vector2(
this.cameras.main.worldView.x +
this.cameras.main.worldView.width * 2,
this.cameras.main.worldView.y +
this.cameras.main.worldView.height * 2
);
if (this.input.keyboard === null) {
throw new Error("Keyboard input plugin is not loaded. Ensure the plugin is included in the Phaser configuration.");
}
this.keyW = this.input.keyboard.addKey(
Phaser.Input.Keyboard.KeyCodes.W
);
this.keyS = this.input.keyboard.addKey(
Phaser.Input.Keyboard.KeyCodes.S
);
this.keyA = this.input.keyboard.addKey(
Phaser.Input.Keyboard.KeyCodes.A
);
this.keyD = this.input.keyboard.addKey(
Phaser.Input.Keyboard.KeyCodes.D
);
this.dojo.systemCalls.spawn(this.dojo.account);

Comment on lines 87 to 159
update() {
if (this.followPoint === null || this.followPoint === undefined) {
throw new Error("failed to initialize followPoint");
}
if (
this.checkInputs([this.keyA, this.keyD, this.keyW, this.keyS]) ===
false
) {
throw new Error("failed to initialize inputs");
}
var snappedChunkX =
this.chunkSize *
this.tileSize *
Math.round(this.followPoint.x / (this.chunkSize * this.tileSize));
var snappedChunkY =
this.chunkSize *
this.tileSize *
Math.round(this.followPoint.y / (this.chunkSize * this.tileSize));

snappedChunkX = snappedChunkX / this.chunkSize / this.tileSize;
snappedChunkY = snappedChunkY / this.chunkSize / this.tileSize;

for (var x = snappedChunkX - 2; x < snappedChunkX + 2; x++) {
for (var y = snappedChunkY - 2; y < snappedChunkY + 2; y++) {
var existingChunk = this.getChunk(x, y);

if (existingChunk == null) {
var newChunk = new Chunk(this, x, y);
this.chunks.push(newChunk);
}
}
}

for (var i = 0; i < this.chunks.length; i++) {
var chunk = this.chunks[i];

if (
Phaser.Math.Distance.Between(
snappedChunkX,
snappedChunkY,
chunk.x,
chunk.y
) < 3
) {
if (chunk !== null) {
chunk.load();
}
} else {
if (chunk !== null) {
chunk.unload();
}
}
}

if (null !== this.keyW && this.keyW.isDown) {
this.followPoint.y -= this.cameraSpeed;
this.cameras.main.centerOn(this.followPoint.x, this.followPoint.y);
this.dojo.systemCalls.move(this.dojo.account, Direction.Up);
return;
}
if (null !== this.keyS && this.keyS.isDown) {
this.followPoint.y += this.cameraSpeed;
this.cameras.main.centerOn(this.followPoint.x, this.followPoint.y);
this.dojo.systemCalls.move(this.dojo.account, Direction.Down);
return;
}
if (null !== this.keyA && this.keyA.isDown) {
this.followPoint.x -= this.cameraSpeed;
this.cameras.main.centerOn(this.followPoint.x, this.followPoint.y);
this.dojo.systemCalls.move(this.dojo.account, Direction.Left);
return;
}
if (null !== this.keyD && this.keyD.isDown) {
this.followPoint.x += this.cameraSpeed;
this.cameras.main.centerOn(this.followPoint.x, this.followPoint.y);
this.dojo.systemCalls.move(this.dojo.account, Direction.Right);
return;
}

this.cameras.main.centerOn(this.followPoint.x, this.followPoint.y);
}
Copy link

Choose a reason for hiding this comment

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

Optimize chunk management logic.

The update method's chunk management logic can be optimized by using a Map for this.chunks to improve lookup performance.

- this.chunks = [];
+ this.chunks = new Map();

- var chunk = null;
- for (var i = 0; i < this.chunks.length; i++) {
-     if (this.chunks[i].x == x && this.chunks[i].y == y) {
-         chunk = this.chunks[i];
-     }
- }
- return chunk;
+ return this.chunks.get(`${x},${y}`);

- var newChunk = new Chunk(this, x, y);
- this.chunks.push(newChunk);
+ var newChunk = new Chunk(this, x, y);
+ this.chunks.set(`${x},${y}`, newChunk);
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
update() {
if (this.followPoint === null || this.followPoint === undefined) {
throw new Error("failed to initialize followPoint");
}
if (
this.checkInputs([this.keyA, this.keyD, this.keyW, this.keyS]) ===
false
) {
throw new Error("failed to initialize inputs");
}
var snappedChunkX =
this.chunkSize *
this.tileSize *
Math.round(this.followPoint.x / (this.chunkSize * this.tileSize));
var snappedChunkY =
this.chunkSize *
this.tileSize *
Math.round(this.followPoint.y / (this.chunkSize * this.tileSize));
snappedChunkX = snappedChunkX / this.chunkSize / this.tileSize;
snappedChunkY = snappedChunkY / this.chunkSize / this.tileSize;
for (var x = snappedChunkX - 2; x < snappedChunkX + 2; x++) {
for (var y = snappedChunkY - 2; y < snappedChunkY + 2; y++) {
var existingChunk = this.getChunk(x, y);
if (existingChunk == null) {
var newChunk = new Chunk(this, x, y);
this.chunks.push(newChunk);
}
}
}
for (var i = 0; i < this.chunks.length; i++) {
var chunk = this.chunks[i];
if (
Phaser.Math.Distance.Between(
snappedChunkX,
snappedChunkY,
chunk.x,
chunk.y
) < 3
) {
if (chunk !== null) {
chunk.load();
}
} else {
if (chunk !== null) {
chunk.unload();
}
}
}
if (null !== this.keyW && this.keyW.isDown) {
this.followPoint.y -= this.cameraSpeed;
this.cameras.main.centerOn(this.followPoint.x, this.followPoint.y);
this.dojo.systemCalls.move(this.dojo.account, Direction.Up);
return;
}
if (null !== this.keyS && this.keyS.isDown) {
this.followPoint.y += this.cameraSpeed;
this.cameras.main.centerOn(this.followPoint.x, this.followPoint.y);
this.dojo.systemCalls.move(this.dojo.account, Direction.Down);
return;
}
if (null !== this.keyA && this.keyA.isDown) {
this.followPoint.x -= this.cameraSpeed;
this.cameras.main.centerOn(this.followPoint.x, this.followPoint.y);
this.dojo.systemCalls.move(this.dojo.account, Direction.Left);
return;
}
if (null !== this.keyD && this.keyD.isDown) {
this.followPoint.x += this.cameraSpeed;
this.cameras.main.centerOn(this.followPoint.x, this.followPoint.y);
this.dojo.systemCalls.move(this.dojo.account, Direction.Right);
return;
}
this.cameras.main.centerOn(this.followPoint.x, this.followPoint.y);
}
update() {
if (this.followPoint === null || this.followPoint === undefined) {
throw new Error("failed to initialize followPoint");
}
if (
this.checkInputs([this.keyA, this.keyD, this.keyW, this.keyS]) ===
false
) {
throw new Error("failed to initialize inputs");
}
var snappedChunkX =
this.chunkSize *
this.tileSize *
Math.round(this.followPoint.x / (this.chunkSize * this.tileSize));
var snappedChunkY =
this.chunkSize *
this.tileSize *
Math.round(this.followPoint.y / (this.chunkSize * this.tileSize));
snappedChunkX = snappedChunkX / this.chunkSize / this.tileSize;
snappedChunkY = snappedChunkY / this.chunkSize / this.tileSize;
for (var x = snappedChunkX - 2; x < snappedChunkX + 2; x++) {
for (var y = snappedChunkY - 2; y < snappedChunkY + 2; y++) {
var existingChunk = this.getChunk(x, y);
if (existingChunk == null) {
var newChunk = new Chunk(this, x, y);
this.chunks.set(`${x},${y}`, newChunk);
}
}
}
for (var i = 0; i < this.chunks.length; i++) {
var chunk = this.chunks[i];
if (
Phaser.Math.Distance.Between(
snappedChunkX,
snappedChunkY,
chunk.x,
chunk.y
) < 3
) {
if (chunk !== null) {
chunk.load();
}
} else {
if (chunk !== null) {
chunk.unload();
}
}
}
if (null !== this.keyW && this.keyW.isDown) {
this.followPoint.y -= this.cameraSpeed;
this.cameras.main.centerOn(this.followPoint.x, this.followPoint.y);
this.dojo.systemCalls.move(this.dojo.account, Direction.Up);
return;
}
if (null !== this.keyS && this.keyS.isDown) {
this.followPoint.y += this.cameraSpeed;
this.cameras.main.centerOn(this.followPoint.x, this.followPoint.y);
this.dojo.systemCalls.move(this.dojo.account, Direction.Down);
return;
}
if (null !== this.keyA && this.keyA.isDown) {
this.followPoint.x -= this.cameraSpeed;
this.cameras.main.centerOn(this.followPoint.x, this.followPoint.y);
this.dojo.systemCalls.move(this.dojo.account, Direction.Left);
return;
}
if (null !== this.keyD && this.keyD.isDown) {
this.followPoint.x += this.cameraSpeed;
this.cameras.main.centerOn(this.followPoint.x, this.followPoint.y);
this.dojo.systemCalls.move(this.dojo.account, Direction.Right);
return;
}
this.cameras.main.centerOn(this.followPoint.x, this.followPoint.y);
}

Copy link

@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 d7873b2 and 95e373c.

Files ignored due to path filters (5)
  • examples/vanilla/phaser/assets/sprGrass.png is excluded by !**/*.png
  • examples/vanilla/phaser/assets/sprSand.png is excluded by !**/*.png
  • examples/vanilla/phaser/assets/sprWater.png is excluded by !**/*.png
  • examples/vanilla/phaser/public/favicon.ico is excluded by !**/*.ico
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
Files selected for processing (20)
  • examples/vanilla/phaser/.gitignore (1 hunks)
  • examples/vanilla/phaser/dojoConfig.ts (1 hunks)
  • examples/vanilla/phaser/index.html (1 hunks)
  • examples/vanilla/phaser/package.json (1 hunks)
  • examples/vanilla/phaser/src/dojo/createClientComponent.ts (1 hunks)
  • examples/vanilla/phaser/src/dojo/defineContractComponents.ts (1 hunks)
  • examples/vanilla/phaser/src/dojo/defineContractSystems.ts (1 hunks)
  • examples/vanilla/phaser/src/dojo/models.ts (1 hunks)
  • examples/vanilla/phaser/src/dojo/setup.ts (1 hunks)
  • examples/vanilla/phaser/src/dojo/systems.ts (1 hunks)
  • examples/vanilla/phaser/src/dojo/utils.ts (1 hunks)
  • examples/vanilla/phaser/src/dojo/world.ts (1 hunks)
  • examples/vanilla/phaser/src/entities.ts (1 hunks)
  • examples/vanilla/phaser/src/main.ts (1 hunks)
  • examples/vanilla/phaser/src/scenes/scene-main.ts (1 hunks)
  • examples/vanilla/phaser/tsconfig.json (1 hunks)
  • examples/vanilla/phaser/vite.config.ts (1 hunks)
  • package.json (1 hunks)
  • pnpm-workspace.yaml (1 hunks)
  • scripts/build-examples.sh (1 hunks)
Files skipped from review due to trivial changes (6)
  • examples/vanilla/phaser/index.html
  • examples/vanilla/phaser/package.json
  • examples/vanilla/phaser/src/dojo/world.ts
  • examples/vanilla/phaser/src/entities.ts
  • examples/vanilla/phaser/tsconfig.json
  • examples/vanilla/phaser/vite.config.ts
Files skipped from review as they are similar to previous changes (13)
  • examples/vanilla/phaser/.gitignore
  • examples/vanilla/phaser/dojoConfig.ts
  • examples/vanilla/phaser/src/dojo/createClientComponent.ts
  • examples/vanilla/phaser/src/dojo/defineContractComponents.ts
  • examples/vanilla/phaser/src/dojo/defineContractSystems.ts
  • examples/vanilla/phaser/src/dojo/models.ts
  • examples/vanilla/phaser/src/dojo/setup.ts
  • examples/vanilla/phaser/src/dojo/systems.ts
  • examples/vanilla/phaser/src/dojo/utils.ts
  • examples/vanilla/phaser/src/main.ts
  • package.json
  • pnpm-workspace.yaml
  • scripts/build-examples.sh
Additional context used
Biome
examples/vanilla/phaser/src/scenes/scene-main.ts

[error] 11-11: Don't use 'String' as a type.

Use lowercase primitives for consistency.
Safe fix: Use 'string' instead

(lint/complexity/noBannedTypes)

Additional comments not posted (6)
examples/vanilla/phaser/src/scenes/scene-main.ts (6)

31-38: LGTM!

The preload method correctly loads the assets.


58-59: Ensure proper error handling for keyboard input.

The create method throws an error if the keyboard input plugin is not loaded. Consider providing a more descriptive error message.

- throw new Error("plugin input.keyboard is not loaded");
+ throw new Error("Keyboard input plugin is not loaded. Ensure the plugin is included in the Phaser configuration.");

78-83: LGTM!

The getChunk method correctly retrieves the chunk from the chunks map.


105-113: Optimize chunk management logic.

The chunk management logic can be optimized by using a Map for this.chunks to improve lookup performance.

- var chunk = null;
- for (var i = 0; i < this.chunks.length; i++) {
-     if (this.chunks[i].x == x && this.chunks[i].y == y) {
-         chunk = this.chunks[i];
-     }
- }
- return chunk;
+ return this.chunks.get(`${x},${y}`);

- var newChunk = new Chunk(this, x, y);
- this.chunks.push(newChunk);
+ var newChunk = new Chunk(this, x, y);
+ this.chunks.set(`${x},${y}`, newChunk);

133-155: LGTM!

The character movement logic correctly updates the followPoint and camera position based on key presses.


161-167: LGTM!

The checkInputs method correctly verifies that all input keys are initialized.

tileSize: number;
cameraSpeed: number;
followPoint?: Phaser.Math.Vector2;
chunks: Map<String, Chunk>;
Copy link

Choose a reason for hiding this comment

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

Use lowercase primitive for type consistency.

Change the type of chunks map key from 'String' to 'string' for consistency.

- chunks: Map<String, Chunk>;
+ chunks: Map<string, Chunk>;
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
chunks: Map<String, Chunk>;
chunks: Map<string, Chunk>;
Tools
Biome

[error] 11-11: Don't use 'String' as a type.

Use lowercase primitives for consistency.
Safe fix: Use 'string' instead

(lint/complexity/noBannedTypes)

@ponderingdemocritus ponderingdemocritus merged commit d220635 into dojoengine:main Aug 7, 2024
3 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Sep 24, 2024
4 tasks
@coderabbitai coderabbitai bot mentioned this pull request Oct 1, 2024
5 tasks
@coderabbitai coderabbitai bot mentioned this pull request Oct 31, 2024
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.

Vanilla Phaser.js eample
2 participants