v0.4: Acid system rework + Iron material + heat conductivity
- Acid now uses acid_resist + health-based damage (not instant delete) - Acid dissolve speeds: Wood ~2s, Dirt ~2.8s, Stone ~4.3s, Iron immune - New material: Iron (ID 16) - silver, static, acid-proof, heat-conductive - Iron texture: bright highlights for metallic shine - Iron reflects light (light_block: 150) - Iron heat_conduct: 200 - conducts heat quickly through entire block - Improved heat transfer formula (divisor 255→200) - Updated AGENTS.md status - No player code (rolled back for fresh start)
This commit is contained in:
@@ -169,6 +169,10 @@ Jedes Material bekommt deterministische Pixel-Variation basierend auf Grid-Koord
|
|||||||
- **Material-Palette**: Leiste am unteren Bildschirmrand, Farb-Swatch + Name + Taste
|
- **Material-Palette**: Leiste am unteren Bildschirmrand, Farb-Swatch + Name + Taste
|
||||||
- **FPS-Anzeige**: Oben rechts, grün, alle 500ms aktualisiert
|
- **FPS-Anzeige**: Oben rechts, grün, alle 500ms aktualisiert
|
||||||
|
|
||||||
|
### Player-System (Phase 4 — in Arbeit)
|
||||||
|
|
||||||
|
Player-Material (7) existiert als grüner Pixel-Cluster. `move_player(dx, dy)`-API in `physics.rs` via WASM exportiert (`engine.movePlayer`). Aktueller Ansatz: Clear+Place (alle Player-Zellen löschen, an Zielposition neu setzen), all-or-nothing bei Kollision mit Solids. Gravitation: `dy=1` jede Frame. Horizontal-Input: Pfeiltasten separat. Kamera: folgt Player-Zentrum (Scan 200×200 Region um letzte Position, cached). Offen: Cluster-Form stabil halten (kreisrund), Sprung-Mechanik, Schadenssystem.
|
||||||
|
|
||||||
## Build & Entwicklung
|
## Build & Entwicklung
|
||||||
|
|
||||||
**WICHTIG**: Native Debug-Binary und WASM/Web-Build müssen immer identisch laufen.
|
**WICHTIG**: Native Debug-Binary und WASM/Web-Build müssen immer identisch laufen.
|
||||||
@@ -217,7 +221,7 @@ cd web && npm run build
|
|||||||
- [x] Phase 1: Sand-Physik (Pixel fällt nach unten) ← **fertig** (Sand + Flüssigkeiten)
|
- [x] Phase 1: Sand-Physik (Pixel fällt nach unten) ← **fertig** (Sand + Flüssigkeiten)
|
||||||
- [x] Phase 2: Mehrere Materialien + Kräfte-Tabelle ← **fertig**
|
- [x] Phase 2: Mehrere Materialien + Kräfte-Tabelle ← **fertig**
|
||||||
- [x] Phase 3: Chunk-System + große Welt + Kamera ← **fertig**
|
- [x] Phase 3: Chunk-System + große Welt + Kamera ← **fertig**
|
||||||
- [ ] Phase 4: Spieler als Atom-Cluster + Input
|
- [ ] Phase 4: Spieler als Atom-Cluster + Input ← **angefangen** — Player-Material (7) existiert, `move_player(dx,dy)` API da, aber Cluster-Zusammenhalt + Steuerung noch instabil. Ansatz: Player-Zellen als Gruppe bewegen (clear+place, nicht swap), Gravitation separat von Horizontalbewegung, Kamera folgt Player-Zentrum.
|
||||||
- [ ] Phase 5: Erweiterungen (Items, Player-Interaktion, Editor, ...)
|
- [ ] Phase 5: Erweiterungen (Items, Player-Interaktion, Editor, ...)
|
||||||
|
|
||||||
## Namenskonventionen
|
## Namenskonventionen
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ pub enum Material {
|
|||||||
Acid = 13,
|
Acid = 13,
|
||||||
Spark = 14,
|
Spark = 14,
|
||||||
Smoke = 15,
|
Smoke = 15,
|
||||||
|
Iron = 16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Material {
|
impl Material {
|
||||||
@@ -38,6 +39,7 @@ impl Material {
|
|||||||
13 => Material::Acid,
|
13 => Material::Acid,
|
||||||
14 => Material::Spark,
|
14 => Material::Spark,
|
||||||
15 => Material::Smoke,
|
15 => Material::Smoke,
|
||||||
|
16 => Material::Iron,
|
||||||
_ => Material::Air,
|
_ => Material::Air,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,14 +63,14 @@ pub struct MaterialProps {
|
|||||||
pub light_block: u8,
|
pub light_block: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const M: usize = 16;
|
pub const M: usize = 17;
|
||||||
pub static PROPS: [MaterialProps; M] = [
|
pub static PROPS: [MaterialProps; M] = [
|
||||||
MaterialProps { color: [0, 0, 0, 0], density: 0, is_powder: false, is_liquid: false, is_gas: false, is_solid: false, is_static: false, flammability: 0, melt_temp: 255, boil_temp: 255, heat_conduct: 0, acid_resist: 255, light_emit: 0, light_block: 0 },
|
MaterialProps { color: [0, 0, 0, 0], density: 0, is_powder: false, is_liquid: false, is_gas: false, is_solid: false, is_static: false, flammability: 0, melt_temp: 255, boil_temp: 255, heat_conduct: 0, acid_resist: 255, light_emit: 0, light_block: 0 },
|
||||||
MaterialProps { color: [120, 120, 130, 255], density: 100, is_powder: false, is_liquid: false, is_gas: false, is_solid: true, is_static: true, flammability: 0, melt_temp: 220, boil_temp: 255, heat_conduct: 3, acid_resist: 200, light_emit: 0, light_block: 255 },
|
MaterialProps { color: [120, 120, 130, 255], density: 100, is_powder: false, is_liquid: false, is_gas: false, is_solid: true, is_static: true, flammability: 0, melt_temp: 220, boil_temp: 255, heat_conduct: 3, acid_resist: 180, light_emit: 0, light_block: 255 },
|
||||||
MaterialProps { color: [101, 67, 33, 255], density: 60, is_powder: true, is_liquid: false, is_gas: false, is_solid: false, is_static: false, flammability: 0, melt_temp: 200, boil_temp: 255, heat_conduct: 2, acid_resist: 100, light_emit: 0, light_block: 255 },
|
MaterialProps { color: [101, 67, 33, 255], density: 60, is_powder: true, is_liquid: false, is_gas: false, is_solid: false, is_static: false, flammability: 0, melt_temp: 200, boil_temp: 255, heat_conduct: 2, acid_resist: 70, light_emit: 0, light_block: 255 },
|
||||||
MaterialProps { color: [194, 178, 128, 255], density: 40, is_powder: true, is_liquid: false, is_gas: false, is_solid: false, is_static: false, flammability: 0, melt_temp: 200, boil_temp: 255, heat_conduct: 5, acid_resist: 150, light_emit: 0, light_block: 200 },
|
MaterialProps { color: [194, 178, 128, 255], density: 40, is_powder: true, is_liquid: false, is_gas: false, is_solid: false, is_static: false, flammability: 0, melt_temp: 200, boil_temp: 255, heat_conduct: 5, acid_resist: 150, light_emit: 0, light_block: 200 },
|
||||||
MaterialProps { color: [30, 60, 200, 180], density: 10, is_powder: false, is_liquid: true, is_gas: false, is_solid: false, is_static: false, flammability: 0, melt_temp: 0, boil_temp: 100, heat_conduct: 10, acid_resist: 200, light_emit: 0, light_block: 80 },
|
MaterialProps { color: [30, 60, 200, 180], density: 10, is_powder: false, is_liquid: true, is_gas: false, is_solid: false, is_static: false, flammability: 0, melt_temp: 0, boil_temp: 100, heat_conduct: 10, acid_resist: 255, light_emit: 0, light_block: 80 },
|
||||||
MaterialProps { color: [90, 60, 30, 255], density: 80, is_powder: false, is_liquid: false, is_gas: false, is_solid: true, is_static: false, flammability: 30, melt_temp: 240, boil_temp: 255, heat_conduct: 1, acid_resist: 80, light_emit: 0, light_block: 255 },
|
MaterialProps { color: [90, 60, 30, 255], density: 80, is_powder: false, is_liquid: false, is_gas: false, is_solid: true, is_static: false, flammability: 30, melt_temp: 240, boil_temp: 255, heat_conduct: 1, acid_resist: 50, light_emit: 0, light_block: 255 },
|
||||||
MaterialProps { color: [255, 100, 0, 255], density: 50, is_powder: false, is_liquid: true, is_gas: false, is_solid: false, is_static: false, flammability: 0, melt_temp: 200, boil_temp: 255, heat_conduct: 20, acid_resist: 255, light_emit: 200, light_block: 60 },
|
MaterialProps { color: [255, 100, 0, 255], density: 50, is_powder: false, is_liquid: true, is_gas: false, is_solid: false, is_static: false, flammability: 0, melt_temp: 200, boil_temp: 255, heat_conduct: 20, acid_resist: 255, light_emit: 200, light_block: 60 },
|
||||||
MaterialProps { color: [50, 200, 50, 255], density: 90, is_powder: false, is_liquid: false, is_gas: false, is_solid: false, is_static: false, flammability: 0, melt_temp: 255, boil_temp: 255, heat_conduct: 5, acid_resist: 255, light_emit: 0, light_block: 100 },
|
MaterialProps { color: [50, 200, 50, 255], density: 90, is_powder: false, is_liquid: false, is_gas: false, is_solid: false, is_static: false, flammability: 0, melt_temp: 255, boil_temp: 255, heat_conduct: 5, acid_resist: 255, light_emit: 0, light_block: 100 },
|
||||||
MaterialProps { color: [200, 200, 220, 140], density: 1, is_powder: false, is_liquid: false, is_gas: true, is_solid: false, is_static: false, flammability: 0, melt_temp: 0, boil_temp: 0, heat_conduct: 5, acid_resist: 255, light_emit: 0, light_block: 20 },
|
MaterialProps { color: [200, 200, 220, 140], density: 1, is_powder: false, is_liquid: false, is_gas: true, is_solid: false, is_static: false, flammability: 0, melt_temp: 0, boil_temp: 0, heat_conduct: 5, acid_resist: 255, light_emit: 0, light_block: 20 },
|
||||||
@@ -79,6 +81,7 @@ pub static PROPS: [MaterialProps; M] = [
|
|||||||
MaterialProps { color: [100, 255, 60, 200], density: 30, is_powder: false, is_liquid: true, is_gas: false, is_solid: false, is_static: false, flammability: 0, melt_temp: 0, boil_temp: 150, heat_conduct: 15, acid_resist: 255, light_emit: 0, light_block: 80 },
|
MaterialProps { color: [100, 255, 60, 200], density: 30, is_powder: false, is_liquid: true, is_gas: false, is_solid: false, is_static: false, flammability: 0, melt_temp: 0, boil_temp: 150, heat_conduct: 15, acid_resist: 255, light_emit: 0, light_block: 80 },
|
||||||
MaterialProps { color: [255, 180, 40, 255], density: 1, is_powder: false, is_liquid: false, is_gas: true, is_solid: false, is_static: false, flammability: 0, melt_temp: 255, boil_temp: 255, heat_conduct: 30, acid_resist: 255, light_emit: 180, light_block: 30 },
|
MaterialProps { color: [255, 180, 40, 255], density: 1, is_powder: false, is_liquid: false, is_gas: true, is_solid: false, is_static: false, flammability: 0, melt_temp: 255, boil_temp: 255, heat_conduct: 30, acid_resist: 255, light_emit: 180, light_block: 30 },
|
||||||
MaterialProps { color: [160, 155, 150, 200], density: 1, is_powder: false, is_liquid: false, is_gas: true, is_solid: false, is_static: false, flammability: 0, melt_temp: 255, boil_temp: 255, heat_conduct: 5, acid_resist: 255, light_emit: 0, light_block: 80 },
|
MaterialProps { color: [160, 155, 150, 200], density: 1, is_powder: false, is_liquid: false, is_gas: true, is_solid: false, is_static: false, flammability: 0, melt_temp: 255, boil_temp: 255, heat_conduct: 5, acid_resist: 255, light_emit: 0, light_block: 80 },
|
||||||
|
MaterialProps { color: [200, 200, 210, 255], density: 110, is_powder: false, is_liquid: false, is_gas: false, is_solid: true, is_static: true, flammability: 0, melt_temp: 200, boil_temp: 255, heat_conduct: 200, acid_resist: 255, light_emit: 0, light_block: 150 },
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
@@ -114,7 +117,7 @@ pub fn interact(a: u8, b: u8) -> Interaction {
|
|||||||
Interaction { attraction: 20, can_merge: true, bond_strength: 1 }
|
Interaction { attraction: 20, can_merge: true, bond_strength: 1 }
|
||||||
} else if a == 3 || a == 2 {
|
} else if a == 3 || a == 2 {
|
||||||
Interaction { attraction: 5, can_merge: false, bond_strength: 0 }
|
Interaction { attraction: 5, can_merge: false, bond_strength: 0 }
|
||||||
} else if a == 1 || a == 10 || a == 11 {
|
} else if a == 1 || a == 10 || a == 11 || a == 16 {
|
||||||
Interaction { attraction: 30, can_merge: false, bond_strength: 10 }
|
Interaction { attraction: 30, can_merge: false, bond_strength: 10 }
|
||||||
} else if a == 5 {
|
} else if a == 5 {
|
||||||
Interaction { attraction: 15, can_merge: false, bond_strength: 8 }
|
Interaction { attraction: 15, can_merge: false, bond_strength: 8 }
|
||||||
|
|||||||
+26
-15
@@ -104,12 +104,12 @@ impl Physics {
|
|||||||
|
|
||||||
let diff = if temp > ntemp {
|
let diff = if temp > ntemp {
|
||||||
let d = temp - ntemp;
|
let d = temp - ntemp;
|
||||||
let rate = (props.heat_conduct as u32 * d as u32) / 255;
|
let rate = (props.heat_conduct as u32 * d as u32) / 200;
|
||||||
((rate + 1) / 2) as u8
|
((rate + 1) / 2) as u8
|
||||||
} else {
|
} else {
|
||||||
let d = ntemp - temp;
|
let d = ntemp - temp;
|
||||||
let nprops = &PROPS[nmat as usize];
|
let nprops = &PROPS[nmat as usize];
|
||||||
let rate = (nprops.heat_conduct as u32 * d as u32) / 255;
|
let rate = (nprops.heat_conduct as u32 * d as u32) / 200;
|
||||||
((rate + 1) / 2) as u8
|
((rate + 1) / 2) as u8
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -185,21 +185,32 @@ impl Physics {
|
|||||||
grid.flags[ni] |= crate::grid::FLAG_UPDATED;
|
grid.flags[ni] |= crate::grid::FLAG_UPDATED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(13, 5) | (13, 3) => {
|
_ => {
|
||||||
if self.rand() % 4 == 0 {
|
if mat == 13 && nmat != 0 && nmat != 13 {
|
||||||
grid.materials[ni] = 0;
|
let resist = PROPS[nmat as usize].acid_resist;
|
||||||
grid.healths[idx] = grid.healths[idx].saturating_sub(5);
|
if resist < 255 {
|
||||||
grid.flags[ni] |= crate::grid::FLAG_UPDATED;
|
let (chance, damage) = if resist < 60 {
|
||||||
|
(2u32, 4u8)
|
||||||
|
} else if resist < 100 {
|
||||||
|
(2u32, 3u8)
|
||||||
|
} else if resist < 200 {
|
||||||
|
(2u32, 2u8)
|
||||||
|
} else {
|
||||||
|
(3u32, 1u8)
|
||||||
|
};
|
||||||
|
if self.rand() % chance == 0 {
|
||||||
|
let h = grid.healths[ni];
|
||||||
|
if h <= damage {
|
||||||
|
grid.materials[ni] = 0;
|
||||||
|
grid.flags[ni] |= crate::grid::FLAG_UPDATED;
|
||||||
|
} else {
|
||||||
|
grid.healths[ni] = h - damage;
|
||||||
|
}
|
||||||
|
grid.healths[idx] = grid.healths[idx].saturating_sub(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(13, 1) | (13, 2) => {
|
|
||||||
if self.rand() % 8 == 0 {
|
|
||||||
grid.materials[ni] = 0;
|
|
||||||
grid.healths[idx] = grid.healths[idx].saturating_sub(2);
|
|
||||||
grid.flags[ni] |= crate::grid::FLAG_UPDATED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -229,6 +229,17 @@ fn texture_offset(x: u32, y: u32, mat: u8) -> i32 {
|
|||||||
let n = hash(x, y.wrapping_mul(y));
|
let n = hash(x, y.wrapping_mul(y));
|
||||||
((n as i32 - 128) * 5) >> 7
|
((n as i32 - 128) * 5) >> 7
|
||||||
}
|
}
|
||||||
|
16 => {
|
||||||
|
let n = hash(x ^ (y >> 2), y ^ (x >> 2));
|
||||||
|
let highlight = ((x.wrapping_mul(13) ^ y.wrapping_mul(7)) & 31) as i32;
|
||||||
|
if highlight < 3 {
|
||||||
|
25 + (highlight * 6)
|
||||||
|
} else if highlight < 6 {
|
||||||
|
14
|
||||||
|
} else {
|
||||||
|
((n as i32 - 128) * 10) >> 7
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => 0,
|
_ => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export const M = {
|
|||||||
ACID: 13,
|
ACID: 13,
|
||||||
SPARK: 14,
|
SPARK: 14,
|
||||||
SMOKE: 15,
|
SMOKE: 15,
|
||||||
|
IRON: 16,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const MATERIAL_NAMES: Record<number, string> = {
|
export const MATERIAL_NAMES: Record<number, string> = {
|
||||||
@@ -46,6 +47,7 @@ export const MATERIAL_NAMES: Record<number, string> = {
|
|||||||
13: "Acid",
|
13: "Acid",
|
||||||
14: "Spark",
|
14: "Spark",
|
||||||
15: "Smoke",
|
15: "Smoke",
|
||||||
|
16: "Iron",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MATERIAL_COLORS: Record<number, string> = {
|
export const MATERIAL_COLORS: Record<number, string> = {
|
||||||
@@ -65,6 +67,7 @@ export const MATERIAL_COLORS: Record<number, string> = {
|
|||||||
13: "#64ff3c",
|
13: "#64ff3c",
|
||||||
14: "#ffb428",
|
14: "#ffb428",
|
||||||
15: "#a09b96",
|
15: "#a09b96",
|
||||||
|
16: "#a0a0aa",
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface Engine {
|
export interface Engine {
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import { Camera } from "./camera";
|
|||||||
const GRID_WIDTH = 4096;
|
const GRID_WIDTH = 4096;
|
||||||
const GRID_HEIGHT = 3072;
|
const GRID_HEIGHT = 3072;
|
||||||
|
|
||||||
const PAINT_MATERIALS = [M.SAND, M.WATER, M.LAVA, M.WOOD, M.FIRE, M.ICE, M.OIL, M.ACID, M.STONE, M.DIRT, M.GLASS];
|
const PAINT_MATERIALS = [M.SAND, M.WATER, M.LAVA, M.WOOD, M.FIRE, M.ICE, M.OIL, M.ACID, M.IRON, M.STONE, M.DIRT, M.GLASS];
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const canvas = document.getElementById("canvas") as HTMLCanvasElement;
|
const canvas = document.getElementById("canvas") as HTMLCanvasElement;
|
||||||
|
|||||||
Reference in New Issue
Block a user