[Question]
  [
# Challenge Description
You have to show a simulation of rain in terminal. 
In the example given below its adding 100 raindrops at random (use the default random function which your language offers) coordinates, waiting for 0.2 seconds and then redrawing again until the given time expires. Any character can be used for representing the raindrop.
### Parameters
* Wait time between redrawing in seconds.
* Time for which the rain will be visible. This is just an integer representing the number of iterations. [So, the net time for which the rain will be visible is this integer multiplied by the wait time]
* Message to be displayed when the rain ends. (This has to be centered)
* Number of raindrops to be displayed on the screen.
### Rules
* A single byte should be used for representing a rain drop, and it can be anything, even cats and dogs.
* It doesn't have to be responsive to terminal size which means you don't have to handle the bug for varied terminal sizes. You can specify the terminal width and height on your own.
* Standard rules of golfing apply.
# Code Sample and Output
This is an ungolfed version written in python 2.7 using ncurses.
```
import curses
import random
import time
myscreen = curses.initscr()
curses.curs_set(0) # no cursor please 
HEIGHT, WIDTH = myscreen.getmaxyx() 
RAIN = '/' # this is what my rain drop looks like 
TIME = 10 
def make_it_rain(window, tot_time, msg, wait_time, num_drops):
    """
    window    :: curses window 
    time      :: Total time for which it rains
    msg       :: Message displayed when it stops raining
    wait_time :: Time between redrawing scene 
    num_drops :: Number of rain drops in the scene 
    """
    for _ in range(tot_time):
        for i in range(num_drops):
            x,y=random.randint(1, HEIGHT-2),random.randint(1,WIDTH-2)       
            window.addstr(x,y,RAIN)
        window.refresh()
        time.sleep(wait_time)
        window.erase()
    window.refresh()
    window.addstr(HEIGHT/2, int(WIDTH/2.7), msg)
if __name__ == '__main__':
    make_it_rain(myscreen, TIME, 'IT HAS STOPPED RAINING!', 0.2, 100)
    myscreen.getch()
    curses.endwin()
```
Output - 
[![enter image description here](https://i.stack.imgur.com/7Nn4x.gif)](https://i.stack.imgur.com/7Nn4x.gif)
  
[Answer]
# [MATL](https://github.com/lmendo/MATL), 52 bytes
```
xxx:"1GY.Xx2e3Z@25eHG>~47*cD]Xx12:~c!3G80yn-H/kZ"why
```
Inputs are, in this order: pause between updates, number of drops, message, number of repetitions. The monitor has size 80×25 characters (hard-coded).
GIF or it didn't happen! (Example with inputs `0.2`, `100`, `'THE END'`, `30`)
[![enter image description here](https://i.stack.imgur.com/QyNGl.gif)](https://i.stack.imgur.com/QyNGl.gif)
Or try it at [**MATL Online**](https://matl.io/?code=xxx%3A%221GY.Xx2e3Z%4025eHG%3E%7E47%2acD%5DXx12%3A%7Ec%213G80yn-H%2FkZ%22why&inputs=0.2%0A100%0A%27THE+END%27%0A30%0A&version=19.7.2).
### Explanation
```
xxx      % Take first three inputs implicitly and delete them (but they get
         % copied into clipboard G)
:"       % Take fourth input implicitly. Repeat that many times
  1G     %   Push first input (pause time)
  Y.     %   Pause that many seconds
  Xx     %   Clear screen
  2e3    %   Push 2000 (number of chars in the monitor, 80*25)
  Z@     %   Push random permutation of the integers from 1 to 2000
  25e    %   Reshape as a 25×80 matrix, which contains the numbers from 1 to 2000
         %   in random positions
  HG     %   Push second input (number of drops)
  >~     %   Set numbers that are <= second input to 1, and the rest to 0
  47*c   %   Multiply by 47 (ASCII for '/') and convert to char. Char 0 will
         %   be displayed as a space
  D      %   Display
]        % End
Xx       % Clear screen
12:~     % Push row vector of twelve zeros
c!       % Convert to char and transpose. This will produce 12 lines containing
         % a space, to vertically center the message in the 25-row monitor
3G       % Push third input (message string)
80       % Push 80
yn       % Duplicate message string and push its length
-        % Subtract
H/k      % Divide by 2 and round down
Z"       % Push string of that many spaces, to horizontally center the message 
         % in the 80-column monitor
w        % Swap
h        % Concatenate horizontally
y        % Duplicate the column vector of 12 spaces to fill the monitor
         % Implicitly display
```
[Answer]
## JavaScript (ES6), ~~268~~ 261 bytes
```
t=
(o,f,d,r,m,g=(r,_,x=Math.random()*78|0,y=Math.random()*9|0)=>r?g(r-(d[y][x]<`/`),d[y][x]=`/`):d.map(a=>a.join``).join`
`)=>i=setInterval(_=>o.data=f--?g(r,d=[...Array(9)].map(_=>[...` `.repeat(78)])):`
`+` `.repeat(40-m.length/2,clearInterval(i))+m,d*1e3)
```
```
<input id=f size=10 placeholder="# of frames"><input id=d placeholder="Interval between frames"><input id=r size=10 placeholder="# of raindrops"><input id=m placeholder="End message"><input type=button value=Go onclick=t(o.firstChild,+f.value,+d.value,+r.value,m.value)><pre id=o>&nbsp;
```
At least on my browser, the output is designed to fit into the Stack Snippet area without having to go "Full page", so if you ask for more than 702 raindrops it will crash.
Edit: Saved 7 bytes by using a text node as my output area.
[Answer]
## R, 196 192 185 bytes
Just a mock version I wrote based on the description. Hopefully it's somewhat what OP was looking for.
Saved some bytes thanks to @plannapus.
```
f=function(w,t,m,n){for(i in 1:t){x=matrix(" ",100,23);x[sample(2300,n)]="/";cat("\f",rbind(x,"\n"),sep="");Sys.sleep(w)};cat("\f",g<-rep("\n",11),rep(" ",(100-nchar(m))/2),m,g,sep="")}
```
The arguments:
* `w`: Wait time between frames
* `t`: Total number of frames
* `m`: Custom message
* `n`: Number of rain drops
**Example**
Why does it look like it's raining upwards?
Edit: I should mention that this is my customized 23x100 character R-studio console. The dimensions are hardcoded into the function but one could in principle use `getOption("width")` to make it flexible to console size.
[![enter image description here](https://i.stack.imgur.com/9yI2l.gif)](https://i.stack.imgur.com/9yI2l.gif)
**Ungolfed and explained**
```
f=function(w,t,m,n){
    for(i in 1:t){
        x=matrix(" ",100,23);             # Initialize matrix of console size
        x[sample(2300,n)]="/";            # Insert t randomly sampled "/"
        cat("\f",rbind(x,"\n"),sep="");   # Add newlines and print one frame
        Sys.sleep(w)                      # Sleep 
    };
    cat("\f",g<-rep("\n",11),rep(" ",(100-nchar(m))/2),m,g,sep="")  # Print centered msg
}
```
[Answer]
## C 160 bytes
```
f(v,d,w,char *s){i,j;char c='/';for(i=0;i<v;i++){for(j=0;j<d;j++)printf("%*c",(rand()%100),c);fflush(stdout);sleep(w);}system("clear");printf("%*s\n",1000,s);}
v-Time the raindrops are visible in seconds.
d-Number of drops per iteration
w-Wait time in seconds, before the next iteration
s-String to be passed on once its done
```
Ungolfed version:
```
void f(int v, int d, int w,char *s)
{ 
   char c='/';
   for(int i=0;i<v;i++)
   { 
      for(int j=0;j<d;j++)
         printf("%*c",(rand()%100),c);
      fflush(stdout);
      sleep(w); 
   }   
   system("clear");
   printf("%*s\n", 1000,s);
}
```
[![Testcase on my terminal](https://i.stack.imgur.com/JbX1I.gif)](https://i.stack.imgur.com/JbX1I.gif)
```
v - 5 seconds
d - 100 drops
w - 1 second wait time
s - "Raining Blood" :)
```
[Answer]
# R, 163 chars
```
f=function(w,t,n,m){for(i in 1:t){cat("\f",sample(rep(c("/"," "),c(n,1920-n))),sep="");Sys.sleep(w)};cat("\f",g<-rep("\n",12),rep(" ",(80-nchar(m))/2),m,g,sep="")}
```
With indents and newlines:
```
f=function(w,t,n,m){
    for(i in 1:t){
        cat("\f",sample(rep(c("/"," "),c(n,1920-n))),sep="")
        Sys.sleep(w)
    }
    cat("\f",g<-rep("\n",12),rep(" ",(80-nchar(m))/2),m,g,sep="")
}
```
It's adapted to a terminal size of 24 lines by 80 columns. `w` is the waiting time, `t` the number of frames, `n` the number of raindrops and `m` the final message.
It differs from [@billywob's answer](https://codegolf.stackexchange.com/a/107551/6741) in the different use of `sample`: if the output size is omitted, `sample` gives a permutation of the input vector (here a vector containing the needed number of raindrops and the corresponding number of spaces, thanks to the fact that argument `times` of function `rep` is vectorized). As the size of the vector corresponds exactly to the size of the screen, there is no need to add newlines, or to force-shape it into a matrix.
[![Gif of output](https://i.stack.imgur.com/Pm2kB.gif)](https://i.stack.imgur.com/Pm2kB.gif)
[Answer]
# NodeJS: 691 158 148 Bytes
## Edit
As requested, additional features removed and golf'd.
```
s=[];setInterval(()=>{s=s.slice(L='',9);for(;!L[30];)L+=' |'[Math.random()*10&1];s.unshift(L);console.log("\u001b[2J\u001b[0;0H"+s.join('\n'))},99)
```
The rules specify disregard for size, but this version includes a glitch for the first few frames. It is **129 bytes.**
```
s='';setInterval(()=>{for(s='\n'+s.slice(0,290);!s[300];)s=' |'[Math.random()*10&1]+s;console.log("\u001b[2J\u001b[0;0H"+s)},99)
```
---
**Previous answer**
Perhaps not the best golfing, but I got a bit carried away. It has optional wind direction and rain factor.
`node rain.js 0 0.3`
```
var H=process.stdout.rows-2, W=process.stdout.columns,wnd=(arg=process.argv)[2]||0, rf=arg[3]||0.3, s=[];
let clr=()=>{ console.log("\u001b[2J\u001b[0;0H") }
let nc=()=>{ return ~~(Math.random()*1+rf) }
let nl=()=>{ L=[];for(i=0;i<W;i++)L.push(nc()); return L}
let itrl=(l)=>{ for(w=0;w<wnd;w++){l.pop();l.unshift(nc())}for(w=0;w>wnd;w--){l.shift();l.push(nc())};return l }
let itrs=()=>{ if(s.length>H)s.pop();s.unshift(nl());s.map(v=>itrl(v)) }
let d=(c,i)=>{if(!c)return ' ';if(i==H)return '*';if(wnd<0)return '/';if(wnd>0)return '\\';return '|'}
let drw=(s)=>{ console.log(s.map((v,i)=>{ return v.map(  c=>d(c,i)  ).join('') }).join('\r\n')) }
setInterval(()=>{itrs();clr();drw(s)},100)
```
[See webm of it working here](http://zippy.gfycat.com/RecentBackCockatoo.webm)
[Answer]
# [Noodel](https://tkellehe.github.io/noodel/), noncompeting 44 [bytes](https://tkellehe.github.io/noodel/docs/code_page.html)
I had centering text on my list of things to do since I made the language... But, I was lazy and did not add until after this challenge. So, here I am not competing, but had fun with the challenge:)
```
ØGQÆ×Øæ3/×Æ3I_ȥ⁻¤×⁺Æ1Ḷḋŀ÷25¶İÇæḍ€Æ1uụC¶×12⁺ß
```
The console is size is hard coded to 25x50 which does not look good in the online editor, but does for the snippet.
[Try it:)](https://tkellehe.github.io/noodel/editor.html?code=%C3%98GQ%C3%86%C3%97%C3%98%C3%A63%2F%C3%97%C3%863I_%C8%A5%E2%81%BB%C2%A4%C3%97%E2%81%BA%C3%861%E1%B8%B6%E1%B8%8B%C5%80%C3%B725%C2%B6%C4%B0%C3%87%C3%A6%E1%B8%8D%E2%82%AC%C3%861u%E1%BB%A5C%C2%B6%C3%9712%E2%81%BA%C3%9F&input=0.2%2C%2050%2C%20%22Game%20Over%22%2C%2030&run=true)
---
### How It Works
```
Ø                                            # Pushes all of the inputs from the stack directly back into the stdin since it is the first token.
 GQÆ×Ø                                       # Turns the seconds into milliseconds since can only delay by milliseconds.
 GQ                                          # Pushes on the string "GQ" onto the top of the stack.
   Æ                                         # Consumes from stdin the value in the front and pushes it onto the stack which is the number of seconds to delay.
    ×                                        # Multiplies the two items on top of the stack.
                                             # Since the top of the stack is a number, the second parameter will be converted into a number. But, this will fail for the string "GQ" therein treated as a base 98 number producing 1000.
     Ø                                       # Pops off the new value, and pushes it into the front of stdin.
      æ3/×Æ3I_ȥ⁻¤×⁺                          # Creates the correct amount of rain drops and spaces to be displayed in a 50x25 console.
      æ3                                     # Copies the forth parameter (the number of rain drops).
        /                                    # Pushes the character "/" as the rain drop character.
         ×                                   # Repeats the rain drop character the specified number of times provided.
          Æ3                                 # Consumes the number of rain drops from stdin.
            I_                               # Pushes the string "I_" onto the stack.
              ȥ                              # Converts the string into a number as if it were a base 98 number producing 25 * 50 = 1250.
               ⁻                             # Subtract 1250 - [number rain drops] to get the number of spaces.
                ¤                            # Pushes on the string "¤" which for Noodel is a space.
                 ×                           # Replicate the "¤" that number of times.
                  ⁺                          # Concatenate the spaces with the rain drops.
                   Æ1Ḷḋŀ÷25¬İÇæḍ€            # Handles the animation of the rain drops.
                   Æ1                        # Consumes and pushes on the number of times to loop the animation.
                     Ḷ                       # Pops off the number of times to loop and loops the following code that many times.
                      ḋ                      # Duplicate the string with the rain drops and spaces.
                       ŀ                     # Shuffle the string using Fisher-Yates algorithm.
                        ÷25                  # Divide it into 25 equal parts and push on an array containing those parts.
                           ¶                 # Pushes on the string "¶" which is a new line.
                            İ                # Join the array by the given character.
                             Ç               # Clear the screen and display the rain.
                              æ              # Copy what is on the front of stdin onto the stack which is the number of milliseconds to delay.
                               ḍ             # Delay for the specified number of milliseconds.
                                €            # End of the loop.
                                 Æ1uụC¶×12⁺ß # Creates the centered text that is displayed at the end.
                                 Æ1          # Pushes on the final output string.
                                   u         # Pushes on the string "u" onto the top.
                                    ụC       # Convert the string on the top of the stack to an integer (which will fail and default to base 98 which is 50) then center the input string based off of that width.
                                      ¶      # Push on a the string "¶" which is a new line.
                                       ×12   # Repeat it 12 times.
                                          ⁺  # Append the input string that has been centered to the new lines.
                                           ß # Clear the screen.
                                             # Implicitly push on what is on the top of the stack which is the final output.
```
---
```
<div id="noodel" code="ØGQÆ×Øæ3/×Æ3I_ȥ⁻¤×⁺Æ1Ḷḋŀ÷25¶İÇæḍ€Æ1uụC¶×12⁺ß" input='0.2, 50, "Game Over", 30' cols="50" rows="25"></div>
<script src="https://tkellehe.github.io/noodel/noodel-latest.js"></script>
<script src="https://tkellehe.github.io/noodel/ppcg.min.js"></script>
```
[Answer]
# Ruby + GNU Core Utils, 169 bytes
Parameters to the function are wait time, number of iterations, message, and number of raindrops, in that order. Newlines for readability.
Core Utils were needed for `tput` and `clear`.
```
->w,t,m,n{x=`tput cols`.to_i;z=x*h=`tput lines`.to_i
t.times{s=' '*z;[*0...z].sample(n).map{|i|s[i]=?/};puts`clear`+s;sleep w}
puts`clear`+$/*(h/2),' '*(x/2-m.size/2)+m}
```
[Answer]
# Python 2.7, ~~254~~ 251 bytes
This is my own try without using ncurses.
```
from time import*;from random import*;u=range;y=randint
def m(t,m,w,n):
    for _ in u(t):
        r=[[' 'for _ in u(40)]for _ in u(40)]
        for i in u(n):r[y(0,39)][y(0,39)]='/'
        print'\n'.join(map(lambda k:' '.join(k),r));sleep(w);print '<esc>[2J'
    print' '*33+m
```
Thank to @ErikTheOutgolfer for correcting and saving me bytes.
[Answer]
# SmileBASIC, 114 bytes
```
INPUT W,T,M$,N
FOR I=1TO T
VSYNC W*60CLS
FOR J=1TO N
LOCATE RND(50),RND(30)?7;
NEXT
NEXT
LOCATE 25-LEN(M$)/2,15?M$
```
Console size is always 50\*30.
[Answer]
## Perl 5, 156 bytes
**154 bytes code + 2 for `-pl`.**
```
$M=$_;$W=<>;$I=<>;$R=<>;$_=$"x8e3;{eval'$-=rand 8e3;s!.{$-}\K !/!;'x$R;print;select$a,$a,$a,$W;y!/! !;--$I&&redo}$-=3920-($l=length$M)/2;s;.{$-}\K.{$l};$M
```
Uses a fixed size of 160x50.
[See it online!](https://asciinema.org/a/1uVVjQCOFhecO1aNfjh3rtfBg)
---
## Perl 5, 203 bytes
**201 bytes code + 2 for `-pl`.**
```
$M=$_;$W=<>;$I=<>;$R=<>;$_=$"x($z=($x=`tput cols`)*($y=`tput lines`));{eval'$-=rand$z;s!.{$-}\K !/!;'x$R;print;select$a,$a,$a,$W;y!/! !;--$I&&redo}$-=$x*($y+!($y%2))/2-($l=length$M)/2;s;.{$-}\K.{$l};$M
```
Uses `tput` to determine the size of the terminal.
]