New map! "Amazon River" 🏞️ (#2798)

## Description:

We didn't have a river map and we didn't have a map with a crazy size.
So I made a "Amazon River" map with a crazy size.
280 x 5536!
21 nations based on real locations.
Should be interesting gameplay because you don't have many attack
options, your only escape is the river.
The land tiles size is similar to the achiran and iceland map.

<img width="2442" height="147" alt="Screenshot 2026-01-06 150831"
src="https://github.com/user-attachments/assets/91c4142d-c1e3-4aee-ac49-529b8d9f60c4"
/>

<img width="2324" height="139" alt="Screenshot 2026-01-06 150957"
src="https://github.com/user-attachments/assets/5e049ae5-f32a-495f-afde-9e20257b3676"
/>

Because the map is so wide, it looked really ugly stretched in the
thumbnails. So I added some CSS which removes the thumbnail stretching
of the Amazon River map. We can also use this logic for other thumbnails
which shouldn't get stretched.

In `Maps.ts`, `PublicLobby.ts` and `GameInfoModal.ts`.

## 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
- [X] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

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

FloPinguin
This commit is contained in:
FloPinguin
2026-01-07 04:34:02 +01:00
committed by GitHub
parent ae5c111282
commit 387190b916
15 changed files with 278 additions and 6 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 799 KiB

@@ -0,0 +1,110 @@
{
"name": "Amazon River",
"nations": [
{
"coordinates": [524, 60],
"name": "Boa Esperança",
"flag": "br"
},
{
"coordinates": [298, 242],
"name": "Santa Rosa",
"flag": "br"
},
{
"coordinates": [1056, 8],
"name": "Paraíso",
"flag": "br"
},
{
"coordinates": [1161, 8],
"name": "Bom Futuro",
"flag": "br"
},
{
"coordinates": [1662, 254],
"name": "São Paulo de Olivença",
"flag": "br"
},
{
"coordinates": [1807, 8],
"name": "São João",
"flag": "br"
},
{
"coordinates": [1977, 7],
"name": "Castro Alves",
"flag": "br"
},
{
"coordinates": [2487, 70],
"name": "Flora",
"flag": "br"
},
{
"coordinates": [2458, 217],
"name": "Esperito Santo",
"flag": "br"
},
{
"coordinates": [2590, 149],
"name": "Recreio",
"flag": "br"
},
{
"coordinates": [2937, 199],
"name": "Caturiá",
"flag": "br"
},
{
"coordinates": [3101, 222],
"name": "Correnteza",
"flag": "br"
},
{
"coordinates": [3354, 75],
"name": "Botafogo",
"flag": "br"
},
{
"coordinates": [3405, 237],
"name": "São João",
"flag": "br"
},
{
"coordinates": [3744, 228],
"name": "Cajual",
"flag": "br"
},
{
"coordinates": [3861, 244],
"name": "União",
"flag": "br"
},
{
"coordinates": [4409, 211],
"name": "Amaturá",
"flag": "br"
},
{
"coordinates": [4361, 55],
"name": "Monte Cristo",
"flag": "br"
},
{
"coordinates": [4649, 54],
"name": "Floresta",
"flag": "br"
},
{
"coordinates": [5399, 128],
"name": "Vargem Grande",
"flag": "br"
},
{
"coordinates": [5373, 7],
"name": "Baia",
"flag": "br"
}
]
}
+1
View File
@@ -63,6 +63,7 @@ var maps = []struct {
{Name: "lemnos"},
{Name: "twolakes"},
{Name: "didier"},
{Name: "amazonriver"},
{Name: "big_plains", IsTest: true},
{Name: "half_land_half_ocean", IsTest: true},
{Name: "ocean_and_land", IsTest: true},
+2 -1
View File
@@ -254,7 +254,8 @@
"twolakes": "Two Lakes",
"straitofhormuz": "Strait of Hormuz",
"surrounded": "Surrounded",
"didier": "Didier"
"didier": "Didier",
"amazonriver": "Amazon River"
},
"map_categories": {
"continental": "Continental",
+125
View File
@@ -0,0 +1,125 @@
{
"map": {
"height": 280,
"num_land_tiles": 1172808,
"width": 5536
},
"map16x": {
"height": 70,
"num_land_tiles": 71047,
"width": 1384
},
"map4x": {
"height": 140,
"num_land_tiles": 290101,
"width": 2768
},
"name": "Amazon River",
"nations": [
{
"coordinates": [524, 60],
"flag": "br",
"name": "Boa Esperança"
},
{
"coordinates": [298, 242],
"flag": "br",
"name": "Santa Rosa"
},
{
"coordinates": [1056, 8],
"flag": "br",
"name": "Paraíso"
},
{
"coordinates": [1161, 8],
"flag": "br",
"name": "Bom Futuro"
},
{
"coordinates": [1662, 254],
"flag": "br",
"name": "São Paulo de Olivença"
},
{
"coordinates": [1807, 8],
"flag": "br",
"name": "São João"
},
{
"coordinates": [1977, 7],
"flag": "br",
"name": "Castro Alves"
},
{
"coordinates": [2487, 70],
"flag": "br",
"name": "Flora"
},
{
"coordinates": [2458, 217],
"flag": "br",
"name": "Esperito Santo"
},
{
"coordinates": [2590, 149],
"flag": "br",
"name": "Recreio"
},
{
"coordinates": [2937, 199],
"flag": "br",
"name": "Caturiá"
},
{
"coordinates": [3101, 222],
"flag": "br",
"name": "Correnteza"
},
{
"coordinates": [3354, 75],
"flag": "br",
"name": "Botafogo"
},
{
"coordinates": [3405, 237],
"flag": "br",
"name": "São João"
},
{
"coordinates": [3744, 228],
"flag": "br",
"name": "Cajual"
},
{
"coordinates": [3861, 244],
"flag": "br",
"name": "União"
},
{
"coordinates": [4409, 211],
"flag": "br",
"name": "Amaturá"
},
{
"coordinates": [4361, 55],
"flag": "br",
"name": "Monte Cristo"
},
{
"coordinates": [4649, 54],
"flag": "br",
"name": "Floresta"
},
{
"coordinates": [5399, 128],
"flag": "br",
"name": "Vargem Grande"
},
{
"coordinates": [5373, 7],
"flag": "br",
"name": "Baia"
}
]
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

+5 -2
View File
@@ -1,7 +1,7 @@
import { html, LitElement } from "lit";
import { customElement, property, query, state } from "lit/decorators.js";
import { GameEndInfo } from "../core/Schemas";
import { GameMapType } from "../core/game/Game";
import { GameMapType, hasUnusualThumbnailSize } from "../core/game/Game";
import { fetchGameById } from "./Api";
import { terrainMapFileLoader } from "./TerrainMapFileLoader";
import { UsernameInput } from "./UsernameInput";
@@ -105,6 +105,7 @@ export class GameInfoModal extends LitElement {
if (!info) {
return html``;
}
const isUnusualThumbnailSize = hasUnusualThumbnailSize(info.config.gameMap);
return html`
<div
class="h-37.5 flex relative justify-between rounded-xl bg-blue-600 items-center"
@@ -112,7 +113,9 @@ export class GameInfoModal extends LitElement {
${this.mapImage
? html`<img
src="${this.mapImage}"
class="absolute place-self-start col-span-full row-span-full h-full rounded-xl mask-[linear-gradient(to_left,transparent,#fff)]"
class="absolute place-self-start col-span-full row-span-full h-full rounded-xl mask-[linear-gradient(to_left,transparent,#fff)] ${isUnusualThumbnailSize
? "object-cover object-center"
: ""}"
/>`
: html`<div
class="place-self-start col-span-full row-span-full h-full rounded-xl bg-gray-300"
+8 -2
View File
@@ -1,10 +1,11 @@
import { LitElement, html } from "lit";
import { html, LitElement } from "lit";
import { customElement, state } from "lit/decorators.js";
import { renderDuration, translateText } from "../client/Utils";
import {
Duos,
GameMapType,
GameMode,
hasUnusualThumbnailSize,
HumansVsNations,
Quads,
Trios,
@@ -114,6 +115,9 @@ export class PublicLobby extends LitElement {
}
const mapImageSrc = this.mapImages.get(lobby.gameID);
const isUnusualThumbnailSize = hasUnusualThumbnailSize(
lobby.gameConfig.gameMap,
);
return html`
<button
@@ -131,7 +135,9 @@ export class PublicLobby extends LitElement {
? html`<img
src="${mapImageSrc}"
alt="${lobby.gameConfig.gameMap}"
class="place-self-start col-span-full row-span-full h-full -z-10 mask-[linear-gradient(to_left,transparent,#fff)]"
class="place-self-start col-span-full row-span-full h-full -z-10 mask-[linear-gradient(to_left,transparent,#fff)] ${isUnusualThumbnailSize
? "object-cover object-center"
: ""}"
/>`
: html`<div
class="place-self-start col-span-full row-span-full h-full -z-10 bg-gray-300"
+15 -1
View File
@@ -1,6 +1,10 @@
import { LitElement, css, html } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { Difficulty, GameMapType } from "../../core/game/Game";
import {
Difficulty,
GameMapType,
hasUnusualThumbnailSize,
} from "../../core/game/Game";
import { terrainMapFileLoader } from "../TerrainMapFileLoader";
import { translateText } from "../Utils";
@@ -48,6 +52,7 @@ export const MapDescription: Record<keyof typeof GameMapType, string> = {
StraitOfHormuz: "Strait of Hormuz",
Surrounded: "Surrounded",
Didier: "Didier",
AmazonRiver: "Amazon River",
};
@customElement("map-display")
@@ -153,6 +158,14 @@ export class MapDisplay extends LitElement {
}
render() {
const mapType = GameMapType[this.mapKey as keyof typeof GameMapType];
const isUnusualThumbnailSize = mapType
? hasUnusualThumbnailSize(mapType)
: false;
const objectFitStyle = isUnusualThumbnailSize
? "object-fit: cover; object-position: center;"
: "";
return html`
<div class="option-card ${this.selected ? "selected" : ""}">
${this.isLoading
@@ -164,6 +177,7 @@ export class MapDisplay extends LitElement {
src="${this.mapWebpPath}"
alt="${this.mapKey}"
class="option-image"
style="${objectFitStyle}"
/>`
: html`<div class="option-image">Error</div>`}
${this.showMedals
+1
View File
@@ -89,6 +89,7 @@ const numPlayersConfig = {
[GameMapType.StraitOfHormuz]: [40, 36, 30],
[GameMapType.Surrounded]: [42, 28, 14], // 3, 2, 1 player(s) per island
[GameMapType.Didier]: [100, 70, 50],
[GameMapType.AmazonRiver]: [50, 40, 30],
} as const satisfies Record<GameMapType, [number, number, number]>;
export abstract class DefaultServerConfig implements ServerConfig {
+7
View File
@@ -111,10 +111,16 @@ export enum GameMapType {
StraitOfHormuz = "Strait of Hormuz",
Surrounded = "Surrounded",
Didier = "Didier",
AmazonRiver = "Amazon River",
}
export type GameMapName = keyof typeof GameMapType;
/** Maps that have unusual thumbnail dimensions requiring object-fit: cover */
export function hasUnusualThumbnailSize(map: GameMapType): boolean {
return map === GameMapType.AmazonRiver;
}
export const mapCategories: Record<string, GameMapType[]> = {
continental: [
GameMapType.World,
@@ -151,6 +157,7 @@ export const mapCategories: Record<string, GameMapType[]> = {
GameMapType.Lemnos,
GameMapType.TwoLakes,
GameMapType.StraitOfHormuz,
GameMapType.AmazonRiver,
],
fantasy: [
GameMapType.Pangaea,
+1
View File
@@ -61,6 +61,7 @@ const frequency: Partial<Record<GameMapName, number>> = {
StraitOfHormuz: 4,
Surrounded: 4,
Didier: 2,
AmazonRiver: 3,
};
interface MapWithMode {