Skip to content

Allow Mappers to specify custom tribe spawn coordinates in info.json 🗺️ - #4697

Merged
evanpelle merged 6 commits into
mainfrom
custom-tribe-coordinates
Jul 23, 2026
Merged

Allow Mappers to specify custom tribe spawn coordinates in info.json 🗺️#4697
evanpelle merged 6 commits into
mainfrom
custom-tribe-coordinates

Conversation

@FloPinguin

Copy link
Copy Markdown
Contributor

Description:

Allow custom_tribes entries in info.json to optionally include coordinates, so map authors can pin specific tribes to fixed positions on the map.

Supported formats (all can be mixed in the same array for backwards compatibility and ease of use):

"custom_tribes": [
    "Plain string tribe",
    { "name": "Object without coords" },
    { "name": "Positioned tribe", "coordinates": [123, 456] }
]

Spawn priority:

  1. Nations spawn first (existing behavior)
  2. Custom tribes with coordinates spawn next (at exact tile, validated for land/ownership/impassable)
  3. Random-spawn custom tribes (strings or objects without coordinates)
  4. Themed tribes fill remaining slots (With fallback to the default theme)

Technical changes:

  • map-generator/codegen.go: Changed CustomTribes from []string to []json.RawMessage to support mixed format. Added customTribe struct and parseCustomTribes parser. Updated validation and TS code generation to emit CustomTribe objects.
  • TribeSpawner.ts: Added spawnPositionedTribe method that spawns at exact coordinates (compact map scaling handled). Positioned tribes are spawned first; remaining slots are filled via randomTribeName.
  • TribeNames.ts: Updated TribeNameData.customTribes type from string[] to CustomTribe[].
  • Game.ts: Re-exports CustomTribe from Maps.gen.
  • MapConsistency.test.ts: Added normalizeCustomTribes helper to compare the mixed info.json format against the normalized Maps.gen.ts format.

Please complete the following:

  • I have added screenshots for all UI updates
  • I process any text displayed to the user through translateText() and I've added it to the en.json file
  • I have added relevant tests to the test directory

Please put your Discord username so you can be contacted if a bug or regression is found:

FloPinguin

@FloPinguin FloPinguin added this to the v33 milestone Jul 23, 2026
@FloPinguin FloPinguin self-assigned this Jul 23, 2026
@FloPinguin
FloPinguin requested a review from a team as a code owner July 23, 2026 21:34
@FloPinguin FloPinguin added Maps A new map, or adjustments to an existing map itself, its json, etc, Feature labels Jul 23, 2026
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

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

Use the following commands to manage reviews:

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

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Custom tribes now support string or object entries with optional coordinates. The generator validates and emits structured data, while TribeSpawner places positioned tribes before selecting unused names for remaining spawn slots.

Changes

Structured custom tribe pipeline

Layer / File(s) Summary
Map parsing and code generation
map-generator/codegen.go, tests/MapConsistency.test.ts
Mixed entries are parsed and validated, generated as {name, coordinates?} objects, and checked against map metadata.
Custom tribe type wiring
src/core/game/Maps.gen.ts, src/core/game/Game.ts, src/core/execution/utils/TribeNames.ts
CustomTribe is exported and used by map data and tribe-name resolution.
Positioned tribe spawning
src/core/execution/ExecutionManager.ts, src/core/execution/TribeSpawner.ts, tests/core/execution/TribeSpawner.test.ts
Nation cells are passed to spawning; positioned tribes are validated and spawned first, followed by unused custom or generated names.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant MapMetadata
  participant Codegen
  participant ExecutionManager
  participant TribeSpawner
  participant MapTiles
  MapMetadata->>Codegen: Read custom_tribes entries
  Codegen->>ExecutionManager: Provide CustomTribe objects
  ExecutionManager->>TribeSpawner: Pass nation cells and spawn count
  TribeSpawner->>MapTiles: Validate positioned coordinates
  MapTiles-->>TribeSpawner: Return tile availability
  TribeSpawner->>TribeSpawner: Spawn positioned tribes
  TribeSpawner->>TribeSpawner: Select unused names for remaining slots
Loading

Suggested reviewers: evanpelle

Poem

Names take shape, coordinates shine,
Tribes find homes on every line.
Tiles are checked, duplicates flee,
Maps grow structured as can be.
Spawn the brave—then fill the land!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states the main change: adding custom tribe spawn coordinates in info.json.
Description check ✅ Passed The description matches the pull request changes and explains the new custom tribe coordinate support.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/core/execution/TribeSpawner.ts (1)

24-109: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Add direct spawning tests.

The changed MapConsistency test only verifies generated metadata; it does not exercise TribeSpawner. Add setup()-based tests for positioned order, compact scaling, invalid tiles, collisions, and fallback behavior.

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

In `@src/core/execution/TribeSpawner.ts` around lines 24 - 109, Add setup()-based
tests that exercise TribeSpawner.spawnTribes and spawnPositionedTribe behavior
directly, covering positioned custom tribes’ ordering, compact-map coordinate
scaling, invalid or impassable/water coordinates, occupied-tile collisions, and
filling remaining slots via randomTribeName fallback. Assert spawned names,
coordinates, counts, and fallback behavior while preserving the existing test
setup conventions.

Source: Coding guidelines

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

Inline comments:
In `@map-generator/codegen.go`:
- Around line 90-118: Update parseCustomTribes to reject empty plain-string
names and validate object entries consistently. Use a presence-aware
json.RawMessage field for coordinates so omitted coordinates remain allowed,
while supplied null, empty, or non-two-element values are rejected; require
exactly two integers before assigning customTribe.Coordinates.

In `@src/core/execution/TribeSpawner.ts`:
- Around line 61-64: Update the coordinate scaling in TribeSpawner’s spawning
logic to use the project’s integer coordinate-scaling helper instead of
Math.floor(coords[n] / 2). Apply it to both x and y when the map is compact,
preserving unchanged coordinates otherwise, and ensure odd and negative values
follow the helper’s deterministic behavior.
- Around line 93-102: Update the custom tribe selection in the TribeSpawner flow
to filter out entries with defined coordinates, so random selection only
considers tribes where coordinates === undefined. Preserve fixed-location tribes
for spawning at their declared tile or skipping, and keep the existing
usedCustomTribes duplicate tracking for eligible random tribes.
- Around line 28-38: Update the positioned custom-tribe spawning flow in
TribeSpawner so fixed spawn tiles are reserved or validated against all
already-scheduled nation positions before enqueueing SpawnExecution objects.
Ensure duplicate coordinates, compact-map collisions, and pending nation spawns
cannot pass hasOwner() and create conflicting fixed spawns; apply the same
handling to the additional spawning block around lines 66-87.

---

Outside diff comments:
In `@src/core/execution/TribeSpawner.ts`:
- Around line 24-109: Add setup()-based tests that exercise
TribeSpawner.spawnTribes and spawnPositionedTribe behavior directly, covering
positioned custom tribes’ ordering, compact-map coordinate scaling, invalid or
impassable/water coordinates, occupied-tile collisions, and filling remaining
slots via randomTribeName fallback. Assert spawned names, coordinates, counts,
and fallback behavior while preserving the existing test setup conventions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 949d7645-ee46-4b61-8f4a-7739f5d2a5c9

📥 Commits

Reviewing files that changed from the base of the PR and between 741ab0f and 6fda576.

📒 Files selected for processing (6)
  • map-generator/codegen.go
  • src/core/execution/TribeSpawner.ts
  • src/core/execution/utils/TribeNames.ts
  • src/core/game/Game.ts
  • src/core/game/Maps.gen.ts
  • tests/MapConsistency.test.ts

Comment thread map-generator/codegen.go
Comment thread src/core/execution/TribeSpawner.ts
Comment thread src/core/execution/TribeSpawner.ts
Comment thread src/core/execution/TribeSpawner.ts
@github-project-automation github-project-automation Bot moved this from Triage to Development in OpenFront Release Management Jul 23, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/core/execution/TribeSpawner.test.ts (1)

123-147: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Tests do not assert tribe names, so they miss the respawn bug.

These cases only check tile values. Add name assertions so the "failed positioned" case proves the failed entry (OOB) does not reappear as a random spawn, and the "avoids duplicates" case proves distinct names. As-is, both pass even while the open randomTribeName respawn issue exists.

Also applies to: 149-169

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

In `@tests/core/execution/TribeSpawner.test.ts` around lines 123 - 147, Add
assertions to the relevant TribeSpawner tests, including the “falls back to
random names when positioned spawn fails” and “avoids duplicates” cases. Verify
the failed positioned name “OOB” is not returned as a random spawn, and assert
the duplicate-avoidance case produces distinct tribe names while preserving the
existing tile assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/core/execution/ExecutionManager.ts`:
- Around line 130-136: Update the nationCells construction in the execution
method to use a TypeScript type guard when filtering undefined spawnCell values,
so the result is inferred as Cell[] before passing it to TribeSpawner. Preserve
the existing nation mapping and spawning flow.

---

Nitpick comments:
In `@tests/core/execution/TribeSpawner.test.ts`:
- Around line 123-147: Add assertions to the relevant TribeSpawner tests,
including the “falls back to random names when positioned spawn fails” and
“avoids duplicates” cases. Verify the failed positioned name “OOB” is not
returned as a random spawn, and assert the duplicate-avoidance case produces
distinct tribe names while preserving the existing tile assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bd5ff5bf-0c5d-4d2a-9b15-a1cb66d5566d

📥 Commits

Reviewing files that changed from the base of the PR and between 6fda576 and a7081f4.

📒 Files selected for processing (4)
  • map-generator/codegen.go
  • src/core/execution/ExecutionManager.ts
  • src/core/execution/TribeSpawner.ts
  • tests/core/execution/TribeSpawner.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • map-generator/codegen.go

Comment thread src/core/execution/ExecutionManager.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/core/execution/TribeSpawner.test.ts (1)

167-169: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove the duplicate map argument.

Array.map accepts one callback and an optional thisArg; the second arrow function is not applied as another callback. Keep only the first function to make the test intent clear. (tc39.es)

 const names = execs.map(
   (e) => (e as { playerInfo: { name: string } }).playerInfo.name,
-  (e) => (e as { playerInfo: { name: string } }).playerInfo.name,
 );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/core/execution/TribeSpawner.test.ts` around lines 167 - 169, Remove the
redundant second arrow-function argument from the execs.map call when
constructing names, keeping the existing callback that reads playerInfo.name.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/core/execution/TribeSpawner.test.ts`:
- Around line 162-171: Update the test containing the warnSpy created around
spawnTribes so console.warn is restored on every execution path. Prefer
registering an afterEach cleanup with vi.restoreAllMocks for the test suite, or
wrap the test body in try/finally with warnSpy.mockRestore, while preserving the
existing assertions.

---

Nitpick comments:
In `@tests/core/execution/TribeSpawner.test.ts`:
- Around line 167-169: Remove the redundant second arrow-function argument from
the execs.map call when constructing names, keeping the existing callback that
reads playerInfo.name.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 885676ac-7927-4356-beb2-e21a42d7a5da

📥 Commits

Reviewing files that changed from the base of the PR and between a7081f4 and 99da98c.

📒 Files selected for processing (2)
  • src/core/execution/TribeSpawner.ts
  • tests/core/execution/TribeSpawner.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/core/execution/TribeSpawner.ts

Comment thread tests/core/execution/TribeSpawner.test.ts Outdated
evanpelle
evanpelle previously approved these changes Jul 23, 2026
@evanpelle

Copy link
Copy Markdown
Collaborator

looks like ci is failing

@FloPinguin

Copy link
Copy Markdown
Contributor Author

looks like ci is failing

Now it works, I was in a fight with the rabbit

@evanpelle
evanpelle merged commit 3fc5837 into main Jul 23, 2026
13 checks passed
@evanpelle
evanpelle deleted the custom-tribe-coordinates branch July 23, 2026 23:42
@github-project-automation github-project-automation Bot moved this from Development to Complete in OpenFront Release Management Jul 23, 2026
FloPinguin added a commit to RickD004/OpenFrontIO that referenced this pull request Jul 31, 2026
…coords on LA (openfrontio#4806)

> **Before opening a PR:** discuss new features on
[Discord](https://discord.gg/K9zernJB5z) first, and file bugs or small
improvements as
[issues](https://github.com/openfrontio/OpenFrontIO/issues/new/choose).
You must be assigned to an `approved` issue — unsolicited PRs will be
auto-closed.

**Add approved & assigned issue number here:**

Resolves openfrontio#4805 (issue number)

## Description:

Tribe themes were created by @FloPinguin: openfrontio#4647;
However, they were not implemented, this PR will implement them.
Also I want to sneak the Custom Tribes w/ Coordinates (by @FloPinguin
openfrontio#4697) into the Los Angeles map so it isn't a "feature that isn't
implemented" (we should have one map using it for testing and feedback
purposes)

This is for v33 (Last minute feature release lol)

- Adds tribe themes to all maps containing a continental category like
`"categories": ["europe"]`
- In the format of: `"themes": ["europe"]`
- Adds around 130 custom tribes with coordinates to the LA map in the
form of suburbs, cities and districts
- For testing purpose i added western theme to Las Vegas Strip and scary
theme to Achiran

<img width="1087" height="668" alt="Image"
src="https://github.com/user-attachments/assets/2918022b-52fc-4ce3-884d-91807c3ef9ca"
/>
^China using the custom Asian theme

<img width="1196" height="702" alt="Image"
src="https://github.com/user-attachments/assets/829ac70f-c266-4425-8926-ebd6ec5f1c13"
/>
^The Los Angeles suburbs and district tribes are highlighted yellow

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory

## Please put your Discord username so you can be contacted if a bug or
regression is found:

DISCORD_USERNAME crunchybbbbb

---------

Co-authored-by: FloPinguin <25036848+FloPinguin@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature Maps A new map, or adjustments to an existing map itself, its json, etc,

Projects

Status: Complete

Development

Successfully merging this pull request may close these issues.

2 participants