# Reaching cocos objects

8 Ball Pool is a cocos2d game running a Cocotron Objective-C runtime on both iOS and Android, so on either build the `ffi` capability's [`objc`](/base/objc/), [`cocos`](/base/cocos/) and [`memory`](/base/memory/) globals reach the game's own objects, and [`reflect`](/base/reflect/) reads their fields by name. Use these when you need something the `pool` namespace does not already hand you; for everything the namespace covers, prefer the namespace.

These globals are gated (`ffi` for `memory`/`ffi`/`objc`/`cocos`, `reflect` for `reflect`). `memory`/`ffi` work on every build; `objc`/`cocos` work on the cocos (Cocotron) builds — iOS and Android — and are `nil` on non-cocos games. Always guard.

## Walking the scene

```lua
if cocos then
  local root = cocos.running_scene()
  if root then
    for _, child in ipairs(root:children()) do
      client.log(child:name(), child:position())
    end
  end
end
```

## Messaging a node

```lua
-- hide a node by sending it setVisible: through objc
if objc and cocos then
  local node = cocos.running_scene():child("SomeOverlay")
  if node then
    objc.object(node:pointer()):msg("setVisible:", "v(b)", false)
  end
end
```

## Reading a field by name

`n:field(...)` on a node returns a [reflect](/base/reflect/) handle you can read typed values from. Handles are frame-scoped: take and read in the same frame.

```lua
if cocos then
  local node = cocos.running_scene():child("GameLayer")
  if node then
    local n = node:field("someIntField"):i32()
    if n then client.log("field =", n) end
  end
end
```

Reads never crash on a bad address; they return `nil`. Selector and class strings come from your script, never from the game binary.