Flyweight¶
Intent: Share a single copy of expensive immutable data (mesh, texture, stats) across many instances so memory isn’t duplicated.
Acron Mapping¶
Pattern role |
Acron equivalent |
|---|---|
Shared intrinsic state |
|
Instance-specific state |
Each instance’s position, color, scale set via |
Instancing |
|
How to Implement¶
Load the shared model once:
shared = loader.loadModel('tree.bam').ModelPoolcaches it automatically on repeatedloadModel()calls with the same path.For each instance call
instance = shared.instanceTo(render)— this creates a newNodePaththat references the same underlying geometry without copying it.Set per-instance state on the returned
NodePath:instance.setPos(x, y, z),instance.setScale(s),instance.setColorScale(r, g, b, 1).Store instance-specific logical data (health, team, etc.) in a parallel Python dict keyed by
NodePathid, not on the node itself.
Code Sketch (Python)¶
import random
# Load geometry once — ModelPool prevents duplicate loading
tree_model = loader.loadModel('assets/tree.bam')
tree_model.setScale(1) # normalise once on the shared model
forest = []
for _ in range(1000):
instance = tree_model.instanceTo(render)
instance.setPos(
random.uniform(-200, 200),
random.uniform(-200, 200),
0
)
# per-instance tint — does NOT copy geometry
instance.setColorScale(
random.uniform(0.8, 1.0),
random.uniform(0.8, 1.0),
random.uniform(0.8, 1.0),
1
)
forest.append(instance)
Pitfalls¶
Don’t use
copyTo()when you want flyweight — it deep-copies geometry into a new node, defeating the purpose. UseinstanceTo()for shared geometry.Render attribute inheritance: attributes set on
tree_modelaffect all instances. Set shared visual state (LOD, shader) on the parent; set per-instance variation on the instanceNodePath.Removing instances: call
instance.detachNode()(notremoveNode()on the shared model) to destroy one instance while leaving others alive.