protected void performMeltdown() {
    final int safety = 1 + structure.upgradeLevel(FUSION_CONFINEMENT) ;
    //
    //  Pollute the surroundings but cut back the meltdown somewhat-
    float radiationVal = (125 / safety) - 25 ;
    radiationVal *= meltdown * Rand.avgNums(3) * 2 ;
    //
    //  TODO:  You need some method to represent temporary contamination...
    //world.ecology().impingeSqualor(radiationVal, this, false) ;
    meltdown /= 1 + (Rand.num() * safety) ;
    //
    //  Determine the range and severity of the explosion-
    final int maxRange = 1 + (int) (radiationVal * 2 / 25f) ;
    final float maxDamage = (5 - safety) * (5 - safety) * 20 ;
    final Box2D area = this.area(null).expandBy(maxRange) ;
    final Batch <Element> inRange = new Batch <Element> () ;
    //
    //  Then, deal with all the surrounding terrain-
    for (Tile t : world.tilesIn(area, true)) {
      final float dist = (Spacing.distance(t, this) - 2) / (maxRange - 2) ;
      if (dist > 1) continue ;
      //
      //  Change the underlying terrain type-
      if (Rand.num() < 1 - dist) {
        if (Rand.index(10) != 0 && Rand.num() < (0.5f - dist)) {
          world.terrain().setHabitat(t, Habitat.CURSED_EARTH) ;
        }
        else world.terrain().setHabitat(t, Habitat.BARRENS) ;
      }
      //
      //  And deal damage to nearby objects-
      markForDamage(t.owner(), inRange) ;
      for (Mobile m : t.inside()) markForDamage(m, inRange) ;
    }
    markForDamage(this, inRange) ;
    for (Element e : inRange) {
      e.flagWith(null) ;
      doDamageTo(e, maxDamage, radiationVal, maxRange) ;
    }
    //
    //  Add explosion FX-
    int multFX = 3 ; while (multFX -- > 0) {
      final MoteFX blastFX = new MoteFX(
        BuildingSprite.BLAST_MODEL.makeSprite()
      ) ;
      blastFX.scale = this.size * (multFX + 1) / 3f ;
      blastFX.animTime = 2.0f ;
      blastFX.update() ;
      this.viewPosition(blastFX.position) ;
      world.ephemera.addGhost(null, blastFX.scale, blastFX, 2.0f) ;
    }
  }