Building blocks of Life
There's a lot that you can streamline here. For your Point record:

; A 2D point representing a coordinate, or any pair of numbers
(defrecord Point [x y])


If you were only going to use a Point to represent a 2D Cartesian coordinate pair, this record may have some value, but not very much. The problem is the "or any pair of numbers" part. If you want to represent a pair of numbers in Clojure, just use a vector:

[4 2]


Vectors are very easy to destructure:

(defn prettify [point]
  (let [[x y] point]
    (str "(" x ", " y ")")))

(prettify [4 2])
;=&gt; "(4, 2)"


Or if you want to just get the first or second element in a pair, you can do that as well:

(first [4 2])
;=&gt; 4

(second [4 2])
;=&gt; 2


You're creating a fair bit of extra work (e.g. the index-of functions) for yourself by representing your 2D world as a 1D vector. Using a 2D vector instead would eliminate the need for all three of those functions, as well as the Enviro record itself:

(def enviro (vec (repeatedly 10 (fn [] (vec (repeatedly 10 (fn [] (rand-int 10))))))))

(pprint enviro)
;; [[3 7 6 2 9 8 5 7 0 2]
;;  [0 6 4 7 1 7 0 7 1 9]
;;  [1 8 0 5 6 9 7 7 8 3]
;;  [7 9 0 8 4 3 3 7 8 6]
;;  [8 9 3 5 1 4 6 5 0 2]
;;  [6 2 3 2 9 4 8 0 3 1]
;;  [0 5 7 7 7 9 0 0 9 5]
;;  [3 8 9 8 2 0 6 3 1 9]
;;  [9 7 4 1 5 8 0 5 1 2]
;;  [9 9 1 9 4 6 3 1 8 2]]
;=&gt; nil

(get-in enviro [4 2])
;=&gt; 3


Or, if your matrix is sparse, you could use a map from points to values instead:

(def enviro (into {} (repeatedly 10 (fn [] [[(rand-int 10) (rand-int 10)] (rand-int 10)]))))

(pprint enviro)
;; {[2 8] 7,
;;  [5 4] 2,
;;  [4 2] 6,
;;  [7 8] 1,
;;  [9 6] 5,
;;  [1 7] 2,
;;  [2 6] 3,
;;  [6 0] 5,
;;  [3 5] 4,
;;  [0 1] 5}
;=&gt; nil

(get enviro [4 2])
;=&gt; 6


If you just use a plain hash map for this, you'll lose some of the spatial query capabilities of a vector, but you could get some of those back by using a quadtree or some other spatially indexed data structure. I'll leave it up to you to decide how to go about doing that in Clojure if you want to take that route.

Your generate-neighbor-points function looks pretty good. Since range and for return lazy sequences, your implementation doesn't have any real performance issues. If I were to write it myself, though, I would probably be a bit more terse:

(defn neighbors [point radius]
  (let [[xs ys] (map #(range (- % radius) (+ % radius 1)) point)]
    (for [y ys x xs :when (not= point [x y])]
      [x y])))


There's nothing wrong with just returning the sequence of neighbor points and then leaving it up to the caller to decide what to do with them. I wouldn't recommend complecting the "find all the neighbor points" logic and the "do something with each of those neighbor points" logic into the same function, because I think it would make more sense to put that second bit in a separate function:

(defn update-all [enviro points f]
  (reduce #(update-in %1 %2 f) enviro points))


Example (using the 2D vector enviro example above):

(pprint (update-all enviro (neighbors [4 3] 2) #(mod % 2)))
;; [[3 7 6 2 9 8 5 7 0 2]
;;  [0 6 4 7 1 7 0 7 1 9]
;;  [1 0 0 1 0 1 7 7 8 3]
;;  [7 1 0 0 0 1 3 7 8 6]
;;  [8 1 1 5 1 0 6 5 0 2]
;;  [6 0 1 0 1 0 8 0 3 1]
;;  [0 1 1 1 1 1 0 0 9 5]
;;  [3 8 9 8 2 0 6 3 1 9]
;;  [9 7 4 1 5 8 0 5 1 2]
;;  [9 9 1 9 4 6 3 1 8 2]]
;=&gt; nil