The Clojure API

Travis Thieman edited this page Jan 12, 2014 · 6 revisions
Clone this wiki locally

JNIBWAPI, and by extension Korhal's Clojure API, exposes a whole bunch of functions. The Clojure API ports almost all of these, and in some cases provides more Clojure-like interfaces to them. All code dealing with JNIBWAPI directly is relegated to the korhal.interop namespace. This is where you'll want to look to find the right Clojure functions to use to upgrade ion thrusters, lift your command center, or attack the nearest filthy Protoss.

interop.clj

Every function exposed by the Clojure API is contained in interop.clj. This module roughly does two things:

  1. Manually create a bunch of functions through (defn ...) calls.
  2. Import a whole bunch of types from interop_types.clj and create functions by running those lists through macros.

A quick search through these files is usually sufficient to find the Clojure function you want. If you want to know what's going on in the internals, you should check out the BWAPI Wiki or the JNIBWAPI source, which typically will include links back to the BWAPI wiki explaining things.

Unit Functions

Functions that apply to units are created using macros. To inspect what functions are available, check out the unit-fn-maps list in interop_types.clj. The names on the left are Clojure names that map to the Java names on the right. When you want to find a function to call on a unit, you should search for it in this list. For example:

; this unit-fn-map declaration
(def unit-fn-maps
  ['shields 'getShields
   ...])

; gets expanded to this function
(defn shields [unit] (. unit getShields))

Type Collections

The types in interop_types.clj are collected into type collections by macros within interop.clj. These are of the following form:

(def unit-type-ids
  {1 <marine-static-type>
   2 <ghost-static-type>
   3 <vulture-static-type>
   ...})

(def unit-type-kws
  {:marine <marine-static-type>
   :ghost <ghost-static-type>
   :vulture <vulture-static-type>
   ...})     

Important: The static types returned by these will not work for any call expecting a proper UnitType. To get the UnitType from the static type, use (get-unit-type static-type).

The following type collections are provided in both -kws and -ids varieties:

  1. unit-type
  2. upgrade-type
  3. tech-type
  4. unit-command-type
  5. race-type
  6. unit-size-type
  7. weapon-type
  8. bullet-type
  9. damage-type
  10. explosion-type
  11. order-type

Supply Functions

All supply functions in the Clojure API provide the true supply value, e.g. a marine costs 1 supply and a zergling costs 1/2 supply. Fractions use Clojure's Ratio type. This is a difference from JNIBWAPI which doubles all supply values so that it can always return ints. We reject this approach as part of the glorious, dynamically-typed Conj.

Convenience Functions

A series of convenience functions not found in JNIBWAPI are provided. Here is a sampling, but you can find all of them in interop.clj.

  1. Unit type predicates, e.g. (is-scv? unit) or (is-command-center? unit).
  2. Own unit type collections, e.g. (my-marines) or (my-factories). The correct plural is used in all cases, so if you're building a Zerg AI you should do (my-larvae).
  3. Player unit collections, e.g. (my-units) and (enemy-units).
  4. Geographic functions, e.g. (enemy-start-locations)
  5. Unit type dispatched point functions, e.g. (pixel-x unit) and (tile-x unit).
  6. Unit type dispatched cost functions, e.g. (mineral-price unit).
  7. Tile type dist functions, e.g. (dist unit1 unit2), (dist-tile unit1 unit2), and (dist-choke unit chokepoint).