Lesson 6 of 10

Default values

Goal

setmetatable and the __index field

01

Explanation

You can attach a metatable to any table: a second table that tells Lua what to do in special situations. Its best-known field is __index. When you read a key that isn't in the table, Lua looks for it in __index before it returns nil.

That's how you build default values. You keep a single defaults table, and each enemy stores only what's different about it, so boss.hp comes from the boss itself and boss.speed comes from defaults. A thousand goblins share one table instead of a thousand copies, and any change to it reaches all of them. Writing doesn't go through __index, though: boss.speed = 8 writes to the boss alone.

The classic mistake here is writing setmetatable(boss, defaults). It looks right but doesn't work, because Lua doesn't search the metatable itself but its __index field. The correct version is setmetatable(boss, { __index = defaults }).

02

Your task

Fix newEnemy(fields) so it returns fields, or a new table if you pass it nothing, attached to a metatable that takes the missing values from defaults without copying anything from it.

Checks

5 checks
  1. A new enemy gets the default values
  2. A value you set on an enemy overrides the default
  3. Changing defaults reaches existing enemies
  4. Writing to one enemy doesn't change the others
  5. newEnemy works without an argument
main.lua
OutputLua 5.4 (wasmoon)

Loading Lua.

–/5

Checks start once the environment is ready.

5 checks listed under “Your task”.