Some small improvements on your code:
Code:
alias rules {
  var %i = 1[color:red], %lines = $lines(rules.txt)[/color][color:green], %nick = $$1[/color]
  while (%i <= [color:red]%lines[/color]) {
    msg [color:green]%nick[/color] %i $+ : $read(rules.txt,[color:blue]tn[/color],%i) 
    inc %i
  }
}
on *:TEXT:!rules:#:rules [color:green]$nick[/color]

By using %lines mIRC won't have to determine the number of lines in rules.txt every time it checks the condition in the while loop
By passing $nick as $1 You won't have to use a global variable, which most people will agree is best to avoid. Also, now you can do /rules <nick> anywhere and it will msg that nick your rules. (Using double $'s will halt the alias if you don't specify a nickname)
Using the tn switches with $read is usually recommendable, or you have to make sure the first line of the file is not a number (t) and everything that can be evaluated should be evaluated (all words starting with % or $ are meant as variables and identifiers) (n)


$input(Me like stars, You too?)