protected Batch <Ghost> visibleFor(Rendering rendering, Base base) {
    final Batch <Ghost> results = new Batch <Ghost> () ;
    final Viewport port = rendering.port ;
    
    for (Section section : world.visibleSections(rendering)) {
      final List <Ghost> SG = ghosts.get(section) ;
      if (SG != null) for (Ghost ghost : SG) {
        
        final float duration = ghost.duration ;
        float timeGone = world.currentTime() - ghost.inceptTime ;
        timeGone += PlayLoop.frameTime() / PlayLoop.UPDATES_PER_SECOND ;
        
        if (timeGone >= duration) {
          SG.remove(ghost) ;
          continue ;
        }
        else {
          final Sprite s = ghost.sprite ;
          if (! port.intersects(s.position, ghost.size)) continue ;
          s.colour = Colour.transparency((duration - timeGone) / duration) ;
          
          if (ghost.tracked != null) {
            if (! ghost.tracked.visibleTo(base)) continue ;
            s.fog = ghost.tracked.fogFor(base) ;
            trackElement(ghost, section, SG) ;
          }
          s.update() ;
          results.add(ghost) ;
        }
      }
    }
    return results ;
  }