Lesson 6 of 10
Default values
- 12 min
- 5 checks
- 3 hints
- Go to task
Goal
setmetatable and the __index field
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 }).
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- A new enemy gets the default values
- A value you set on an enemy overrides the default
- Changing defaults reaches existing enemies
- Writing to one enemy doesn't change the others
- newEnemy works without an argument