Classes and Objects

A class is a template for creating objects that bundle data and behaviour together. The data items are called attributes; the functions are called methods. Together they make up an object.

You have been using objects all along — lists, dictionaries, and strings are all objects. When you call inventory.append("sword"), append is a method on the list object. When you call player_stats.get("gold", 0), get is a method on the dictionary object.

Now you will learn to build your own.

Defining a Class

Use the class keyword followed by the class name. By convention, class names use CapitalWords (also called PascalCase):

class Player:

    def __init__(self, name, health=100):
        self.name   = name
        self.health = health
        self.score  = 0

    def take_damage(self, amount):
        self.health -= amount
        if self.health <= 0:
            print(f"{self.name} has been defeated!")

    def add_score(self, points):
        self.score += points

Key parts:

  • __init__ is the constructor — Python calls it automatically when you create a new object. This is where you set up the object’s initial state.

  • self refers to the specific object the method is acting on. Every method must list self as its first parameter, even though you never pass it explicitly when calling the method.

  • self.name, self.health, self.score are instance attributes — each object gets its own independent copy.

The class definition is just a template (like a cookie cutter). No object exists yet and no code inside the class runs until you construct an object.

Creating and Using Objects

Construct an object by calling the class like a function:

hero    = Player("Aria")
villain = Player("Malachar", health=200)

Python creates a new object, calls __init__ on it, and returns the result. Now hero and villain are independent objects — each has its own copy of all attributes:

hero.take_damage(30)     # hero: 70 hp, villain unchanged
villain.take_damage(50)  # villain: 150 hp
hero.add_score(500)

You can inspect an object’s attributes and methods with dir():

>>> dir(hero)
[..., 'add_score', 'health', 'name', 'score', 'take_damage']

Object Lifecycle

An object is constructed when you assign it to a variable. It is destroyed (garbage-collected) when nothing refers to it any more. In practice:

hero = Player("Aria")   # object created, __init__ runs
hero = 42               # old Player object is discarded

For game objects, the important habit is: always store objects on self (as instance attributes) if they need to outlive the method that creates them. A local variable inside __init__ is gone as soon as __init__ returns; self.hero persists for the life of the enclosing object.

Many Instances

The real power of classes is creating many independent objects from one template:

enemies = [
    Enemy("Goblin",  health=30,  reward_xp=10),
    Enemy("Orc",     health=80,  reward_xp=25),
    Enemy("Dragon",  health=500, reward_xp=200),
]

for enemy in enemies:
    print(f"{enemy.name}: {enemy.health} HP")

Each enemy has its own health — damaging one does not affect another.

Inheritance

A class can inherit from another class, getting all of its attributes and methods automatically. Use parentheses after the class name to declare the parent class:

class Character:

    def __init__(self, name, health):
        self.name   = name
        self.health = health

    def take_damage(self, amount):
        self.health -= amount

class Enemy(Character):

    def __init__(self, name, health, reward_xp):
        Character.__init__(self, name, health)   # run parent's __init__
        self.reward_xp = reward_xp

    def on_defeat(self):
        print(f"Defeated {self.name}! Gained {self.reward_xp} XP.")

Enemy inherits everything Character has (name, health, take_damage) and adds reward_xp and on_defeat.

Calling Character.__init__(self, name, health) is how you let the parent class set itself up before you add your own data. This is standard Python — always call the parent constructor first.

This Is Exactly How Acron Works

Every Acron program is a class that inherits from ShowBase:

from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)   # let the engine initialise
        # your game setup goes here

app = MyApp()
app.run()

ShowBase is the parent class. By inheriting from it, MyApp automatically gets a 3D window, a scene graph, a task manager, an event system, asset loaders — everything the engine provides. You call ShowBase.__init__(self) first, exactly like the Character.__init__(self, name, health) call above, so the engine can set itself up before your code runs.

Once you see the pattern, the Hello World tutorial reads like familiar territory.