SimFantasy

Simulator

Contains the primary classes and code required for running and managing simulations.

class simfantasy.simulator.Simulation(combat_length: datetime.timedelta = None, log_level: int = None, log_event_filter: str = None, execute_time: datetime.timedelta = None, log_pushes: bool = None, log_pops: bool = None, iterations: int = None, log_action_attempts: bool = None) → None[source]

Bases: object

Business logic for managing the simulated combat encounter and subsequent reporting.

Parameters:
  • combat_length (Optional[datetime.timedelta]) – Desired combat length. Default: 5 minutes.
  • log_level (Optional[int]) – Minimum message level necessary to see logger output. Default: logging.INFO.
  • log_event_filter (Optional[str]) – Pattern for filtering logging output to only matching class names. Default: None.
  • execute_time (Optional[datetime.timedelta]) – Length of time to allow jobs to use “execute” actions. Default: 1 minute.
  • log_pushes (Optional[bool]) – True to show events being placed on the queue. Default: True.
  • log_pops (Optional[bool]) – True to show events being popped off the queue. Default: True.
  • iterations (Optional[int]) – Number of encounters to simulate. Default: 100.
  • log_action_attempts (Optional[bool]) – True to log actions attempted by Actor decision engines.
Variables:
  • actors (List[simfantasy.actor.Actor]) – Actors involved in the encounter.
  • combat_length (datetime.timedelta) – Length of the encounter.
  • current_iteration (int) – Current iteration index.
  • current_time (datetime.datetime) – “In game” timestamp.
  • events (queue.PriorityQueue[simfantasy.event.Event]) – Heapified list of upcoming events.
  • execute_time (datetime.timedelta) – Length of time to allow jobs to use “execute” actions.
  • iterations (int) – Number of encounters to simulate. Default: 100.
  • log_action_attempts (bool) – True to log actions attempted by Actor decision engines.
  • log_event_filter (Optional[Pattern]) – Pattern for filtering logging output to only matching class names.
  • log_pops (bool) – True to show events being popped off the queue. Default: True.
  • log_pushes (bool) – True to show events being placed on the queue. Default: True.
  • start_time (datetime.datetime) – Time that combat started.
in_execute

Indicate whether the encounter is currently in an “execute” phase.

“Execute” phases are usually when an enemy falls below a certain health percentage, allowing actions such as simfantasy.jobs.bard.MiserysEndAction to be used.

Returns:True if the encounter is in an execute phase, False otherwise.
Return type:bool

Examples

A fresh simulation that has just started a moment ago:

>>> sim = Simulation(
...     combat_length=timedelta(seconds=60),
...     execute_time=timedelta(seconds=30)
... )
>>> sim.start_time = sim.current_time = datetime.now()
>>> print("Misery's End") if sim.in_execute else print('Heavy Shot')
Heavy Shot

And now, if we adjust the start time to force us halfway into the execute phase:

>>> sim.current_time += timedelta(seconds=45)
>>> print("Misery's End") if sim.in_execute else print('Heavy Shot')
Misery's End
relative_timestamp

Return a formatted string containing the number of seconds since the simulation began.

Returns:A string, with precision to the thousandths.
Return type:str

Examples

For a simulation that has been running for 5 minutes (300 seconds):

>>> sim.current_time = sim.start_time + timedelta(minutes=5)
>>> sim.relative_timestamp
'300.000'

And in another 30 seconds:

>>> sim.current_time += timedelta(seconds=30)
>>> sim.relative_timestamp
'330.000'
run() → None[source]

Run the simulation and process all events.

schedule(event, delta: datetime.timedelta = None) → None[source]

Schedule an event to occur in the future.

Parameters:
  • event (simfantasy.event.Event) – The event to schedule.
  • delta (Optional[datetime.timedelta]) – An optional amount of time to wait before the event should be executed. When delta is None, the event will be scheduled for the current timestamp, and executed after any preexisting events already scheduled for the current timestamp are finished.

Examples

>>> event.timestamp is None
True
>>> sim.schedule(event)
>>> event.timestamp is sim.current_time
True
unschedule(event) → bool[source]

Unschedule an event, ensuring that it is not executed.

Does not “remove” the event. In actuality, flags the event itself as unscheduled to prevent having to resort the events list and subsequently recalculate the heap invariant.

Parameters:event (simfantasy.event.Event) – The event to unschedule.
Returns:True if the event was unscheduled without issue. False if an error occurred, specifically a desync bug between the game clock and the event loop.
Return type:bool

Examples

Unscheduling an upcoming event:

>>> sim.schedule(event)
>>> event.unscheduled
False
>>> sim.unschedule(event)
True
>>> event.unscheduled
True

Rescheduling a previously-unscheduled event will reset its unscheduled flag:

>>> event.unscheduled
True
>>> sim.schedule(event)
>>> event.unscheduled
False

Unscheduling an event that has already occurred will fail:

>>> sim.schedule(event, timedelta(seconds=-30))
>>> event.timestamp < sim.current_time
True
>>> sim.unschedule(event)
False
>>> event.unscheduled
False
simfantasy.simulator.configure_logging(log_level: int = None) → None[source]

Set logging options.

Parameters:log_level (Optional[int]) – The minimum priority level a message needs to be shown.

Action

Abilities and weaponskills that can be performed by an actor.

class simfantasy.action.Action(sim: simfantasy.simulator.Simulation, source: simfantasy.actor.Actor) → None[source]

Bases: object

An ability that can be performed by an actor.

Parameters:
Variables:
  • animation (datetime.timedelta) – Length of the animation delay caused by the action. Default: 0.75 seconds.
  • base_cast_time (datetime.timedelta) – Length of the action’s cast time. Default: Instant cast.
  • base_recast_time (datetime.timedelta) – Length of time until the ability can be used again. Default: base GCD length, 2.5 seconds.
  • can_recast_at (datetime.datetime) – Timestamp when the action can be performed again.
  • cost (Tuple[simfantasy.enum.Resource, int]) – The resource type and amount needed to perform the action.
  • guarantee_crit (bool) – Ensures the damage will be a critical hit. Default: False.
  • hastened_by (simfantasy.enum.Attribute) – The attribute that contributes to lowering the cast/recast time of the action. Default: None.
  • is_off_gcd (bool) – True for actions that are not bound to the GCD, False otherwise. Default: False.
  • potency (int) – Potency of the action’s impact, i.e., damage healed or inflicted. Default: None.
  • powered_by (Attribute) – The attribute that contributes to the total impact of the action. Default: None.
  • shares_recast_with – (Union[simfantasy.action.Action, List[~simfantasy.action.Action]]): Action(s) that are on the same recast timer. Default: None.
  • sim (simfantasy.simulator.Simulation) – The simulation where the action is performed.
  • source (simfantasy.actor.Actor) – The actor that performed the action.
animation_execute_time

Helper function to return whatever is longer, the action’s animation or cast time.

Returns:datetime.timedelta
name

Name of the action.

Should be overridden with a friendlier name. Returns the class name by default.

Returns:Name of the action.
Return type:string

Examples

>>> class MyAction(Action): pass
>>> MyAction(None, None).name
'MyAction'
>>> class MyNamedAction(Action):
...     @property
...     def name(self):
...         return 'CustomName'
>>> MyNamedAction(None, None).name
'CustomName'
perform()[source]

Perform the action.

Automatically schedules common action side effects when appropriate.

Examples

Actions that share a recast timer will have their recast times set:

>>> bloodletter.shares_recast_with = rain_of_death
>>> rain_of_death.can_recast_at is None
True
>>> bloodletter.perform()
>>> bloodletter.can_recast_at is not None
True
>>> bloodletter.can_recast_at == rain_of_death.can_recast_at
True
ready

Flag that indicates if the action can be performed or not.

Returns:True if the action can be performed, False otherwise.
Return type:bool
schedule_aura_events(target: simfantasy.actor.Actor, aura: simfantasy.aura.Aura)[source]

Schedule events to apply and remove an aura from a target.

For a new aura, simfantasy.event.ApplyAuraEvent and simfantasy.event.ExpireAuraEvent will be scheduled. If the aura already exists on the target, a simfantasy.event.RefreshAuraEvent will be scheduled instead, which will subsequently adjust the timestamps of the existing events.

Parameters:

Examples

A new aura will have its events scheduled for the first time:

>>> aura.application_event is None
True
>>> aura.expiration_event is None
True
>>> action.schedule_aura_events(actor, aura)
>>> aura.application_event 
<simfantasy.event.ApplyAuraEvent ...>
>>> aura.expiration_event 
<simfantasy.event.ExpireAuraEvent ...>

An existing aura will not receive new events, but instead will have its expiry event adjusted and rescheduled accordingly:

>>> original_expiry = aura.expiration_event
>>> action.schedule_aura_events(actor, aura)
>>> original_expiry is aura.expiration_event
schedule_damage_event()[source]

Schedules an event to inflict damage.

Notes

The potency must not be None.

When the action is performed, i.e., after its animation_execute_time has passed, a simfantasy.event.DamageEvent will inflict damage based on the amount defined in the potency.

schedule_resource_consumption()[source]

Schedules an event to consume the resource needed to perform the action.

Notes

The cost must not be None.

When the action is performed, i.e., after its animation_execute_time has passed, a simfantasy.event.ResourceEvent will occur that consumes the resource cost defined in the cost.

set_recast_at(delta: datetime.timedelta)[source]

Sets the timestamp when the action can be performed again.

Based on the given delta, sets the recast timestamp by adding it to the simulation’s current timestamp. If the action shares a recast with one or more other actions, those will have their recast timestamps set as well.

Parameters:delta (datetime.timedelta) – The amount of time that must pass to perform this action again.

Examples

>>> action.set_recast_at(timedelta(seconds=30))
>>> action.can_recast_at == sim.current_time + timedelta(seconds=30)
True

Actor

class simfantasy.actor.Actor(sim: simfantasy.simulator.Simulation, race: simfantasy.enum.Race = None, level: int = None, target: typing.Union[simfantasy.actor.Actor, NoneType] = None, name: str = None, gear: typing.Dict[simfantasy.enum.Slot, simfantasy.equipment.Item] = None) → None[source]

Bases: object

A participant in an encounter.

Warning

Although level is accepted as an argument, many of the formulae only work at level 70. This argument may be deprecated in the future, or at least restricted to max levels of each game version, i.e., 50, 60, 70 for A Realm Reborn, Heavensward, and Stormblood respectively, where it’s more likely that someone spent the time to figure out all the math.

Parameters:
Variables:
  • _target_data (Dict[Actor, TargetData) – Mapping of actors to any available target state data.
  • animation_unlock_at (datetime.datetime) – Timestamp when the actor will be able to execute actions again without being inhibited by animation lockout.
  • auras (List[simfantasy.aura.Aura]) – Auras, both friendly and hostile, that exist on the actor.
  • gcd_unlock_at (datetime.datetime) – Timestamp when the actor will be able to execute GCD actions again without being inhibited by GCD lockout.
  • gear (Optional[Dict[Slot, Union[Item, Weapon]]]) – Collection of equipment that the actor is wearing.
  • job (simfantasy.enum.Job) – The actor’s job specialization.
  • level (int) – Level of the actor.
  • name (str) – Name of the actor.
  • race (simfantasy.enum.Race) – Race and clan of the actor.
  • resources (Dict[Resource, Tuple[int, int]]) – Mapping of resource type to a tuple containing the current amount and maximum capacity.
  • sim (simfantasy.simulator.Simulation) – Pointer to the simulation that the actor is participating in.
  • statistics (Dict[str, List[Dict[Any, Any]]]) – Collection of different event occurrences that are used for reporting and visualizations.
  • stats (Dict[Attribute, int]) – Mapping of attribute type to amount.
  • target (simfantasy.actor.Actor) – The enemy that the actor is targeting.
animation_up

Determine if the actor is animation locked.

Many actions have an animation timing of 0.75s. This locks out the actor from performing multiple oGCD actions simultaneously. This lockout is tracked and can inhibit actions from being performed accordingly.

Returns:True if the actor is still animation locked, False otherwise.
Return type:bool

Examples

Consider an actor that has just performed some action, and is thus animation locked for 0.75s. During this period, the actor will be unable to perform actions that also have animation timings:

>>> actor.animation_unlock_at = sim.current_time + timedelta(seconds=0.75)
>>> actor.animation_up
False

However, once the simulation’s game clock advances past the animation lockout timestamp, the actor can once again perform actions:

>>> sim.current_time += timedelta(seconds=1)
>>> actor.animation_up
True
apply_gear_attribute_bonuses()[source]

Apply stat bonuses gained from items and melds.

Examples

Consider the Kujakuo Kai bow for Bards:

>>> kujakuo_kai = Weapon(item_level=370, name='Kujakuo Kai', physical_damage=104, magic_damage=70,
...                      auto_attack=105.38, delay=3.04,
...                      stats={
...                          Attribute.DEXTERITY: 347,
...                          Attribute.VITALITY: 380,
...                          Attribute.CRITICAL_HIT: 218,
...                          Attribute.DIRECT_HIT: 311,
...                      })

Equipping this item will add its stat bonuses to the actor:

>>> actor.equip_gear({Slot.WEAPON: kujakuo_kai})
>>> actor.apply_gear_attribute_bonuses()
>>> actor.stats[Attribute.DEXTERITY] == 347
True

Bonuses from melded materia are also applied:

>>> savage_aim_vi = Materia(Attribute.CRITICAL_HIT, 40)
>>> kujakuo_kai.melds = [savage_aim_vi, savage_aim_vi]
>>> actor.stats = {}
>>> actor.equip_gear({Slot.WEAPON: kujakuo_kai})
>>> actor.apply_gear_attribute_bonuses()
>>> actor.stats[Attribute.CRITICAL_HIT] == 218 + 40 + 40
True
arise()[source]

Prepare the actor for combat.

calculate_base_stats() → typing.Dict[simfantasy.enum.Attribute, int][source]

Calculate and set base primary and secondary stats.

Base stats are determined by a combination of level, job and race/clan affiliation.

Returns:Mapping of attributes to amounts.
Return type:Dict[Attribute, int]
calculate_resources()[source]

Determine the resource levels for the actor.

In particular, sets the HP, MP and TP resource levels.

decide() → typing.Iterable[source]

Given current simulation environment, decide what action should be performed, if any.

The “decision engine” for each actor is a generator function that yields the desired actions. This method should be constructed as a priority list, where more important actions are towards the top, and less important actions towards the bottom. A notable exception is for filler spells, i.e. MeleeAttackAction and ShotAction. Auto-attack actions don’t interfere with other skills and happen at regular intervals, so they can (and should) be safely placed at top priority.

See also

Refer to simfantasy.event.ActorReadyEvent.execute() for clarification on what happens with actions yielded from the decision engine.

Yields:Optional[simfantasy.action.Action] – An instance of an action that will attempt to be performed. If None is yielded, no further attempts to find a suitable action will be made until the actor is ready again.
equip_gear(gear: typing.Dict[simfantasy.enum.Slot, simfantasy.equipment.Item])[source]

Equip items in the appropriate slots.

gcd_up

Determine if the actor is GCD locked.

The global cooldown, or GCD, is a 2.5s lockout that prevents other GCD actions from being performed. Actions on the GCD are constrained by their “execute time”, or \(\max_{GCD, CastTime}\).

Returns:True if the actor is still GCD locked, False otherwise.
Return type:bool

Examples

Consider an actor that has just performed some action, and is thus gcd locked for 2.5s. During this period, the actor will be unable to perform actions that are also on the GCD:

>>> actor.gcd_unlock_at = sim.current_time + timedelta(seconds=2.5)
>>> actor.gcd_up
False

However, once the simulation’s game clock advances past the GCD lockout timestamp, the actor can once again perform GCD actions:

>>> sim.current_time += timedelta(seconds=3)
>>> actor.gcd_up
True
target_data

Return target state data.

For new targets, or at least ones that the actor has never switched to before, there will not be any target data available. In that scenario, this property initializes a new instance of the target data class and returns it. If there is already target state data, it will be returned directly.

Returns:Contains all the target state data from the source actor to the target.
Return type:simfantasy.actor.TargetData

Aura

class simfantasy.aura.Aura(sim: simfantasy.simulator.Simulation, source: simfantasy.actor.Actor) → None[source]

Bases: abc.ABC

A buff or debuff that can be applied to a target.

Variables:
  • application_event (simfantasy.event.ApplyAuraEvent) – Pointer to the scheduled event that will apply the aura to the target.
  • duration (datetime.timedelta) – Initial duration of the aura.
  • expiration_event (simfantasy.event.ExpireAuraEvent) – Pointer to the scheduled event that will remove the aura from the target.
  • max_stacks (int) – The maximum number of stacks that the aura can accumulate.
  • refresh_behavior (simfantasy.enum.RefreshBehavior) – Defines how the aura behaves when refreshed, i.e., what happens when reapplying an aura that already exists on the target.
  • refresh_extension (datetime.timedelta) – For simfantasy.enums.RefreshBehavior.EXTEND_TO_MAX, this defines the amount of time that should be added to the aura’s current remaining time.
  • stacks (int) – The current number of stacks that the aura has accumulated. Should be less than or equal to max_stacks.
apply(target) → None[source]

Apply the aura to the target.

Parameters:target (simfantasy.actor.Actor) – The target that the aura will be applied to.

Examples

>>> class FakeActor:
...     def __init__(self):
...         self.auras = []
>>> actor = FakeActor()
>>> aura = Aura()
>>> aura in actor.auras
False
>>> aura.apply(actor)
>>> aura in actor.auras
True
expire(target) → None[source]

Remove the aura from the target.

Warning

In the event that the aura does not exist on the target, the exception will be trapped, and error output will be shown.

Parameters:target (simfantasy.actor.Actor) – The target that the aura will be removed from.
name

Return the name of the aura.

Examples

By default, shows the class name.

>>> class MyCustomAura(Aura): pass
>>> aura = MyCustomAura()
>>> aura.name
'MyCustomAura'

This property should be overwritten to provide a friendlier name, since it will be used for data visualization and reporting:

>>> class MyCustomAura(Aura):
...    @property
...    def name(self):
...        return 'My Custom'
>>> aura = MyCustomAura()
>>> aura.name
'My Custom'
remains

Return the length of time the aura will remain active on the target.

Examples

For auras with expiration events in the past, we interpret this to mean that they have already fallen off, and return zero:

>>> aura = Aura()
>>> aura.remains == timedelta()
True

On the other hand, if the expiration date is still forthcoming, we use its timestamp to determine the remaining time. Consider an aura that is due to expire in 30 seconds:

>>> sim = Simulation()
>>> sim.current_time = datetime.now()
>>> from simfantasy.event import ExpireAuraEvent
>>> aura.expiration_event = ExpireAuraEvent(sim, None, aura)
>>> aura.expiration_event.timestamp = sim.current_time + timedelta(seconds=30)

Obviously, the remaining time will be 30 seconds:

>>> aura.remains == timedelta(seconds=30)
True

And if we move forward in time 10 seconds, we can expect the remaining time to decrease accordingly:

>>> sim.current_time += timedelta(seconds=10)
>>> aura.remains == timedelta(seconds=20)
True
up

Indicates whether the aura is still on the target or not.

Quite simply, this is a check to see whether the remaining time on the aura is greater than zero.

Returns:True if the aura is still active, False otherwise.
Return type:bool
class simfantasy.aura.TickingAura(sim, source) → None[source]

Bases: simfantasy.aura.Aura

An aura that ticks on the target, e.g., a damage-over-time spell.

Variables:tick_event (simfantasy.event.DotTickEvent) – Pointer to the event that will apply the next tick.
potency

Defines the potency for the dot.

Returns:Amount of potency per tick.
Return type:int
ticks

Return the base number of times that the aura will tick on the target.

Damage-over-time effects are synchronized to server tick events, so by default we assume that the number of ticks is \(\frac{duration}{3}\).

Returns:Number of ticks.
Return type:int

Examples

Consider a damage-over-time spell that has a base duration of 30 seconds:

>>> class MyDot(TickingAura):
...     duration = timedelta(seconds=30)
...     potency = 100

Since server ticks occur every 3 seconds, we can expect \(\frac{30}{3} = 10\) ticks:

>>> aura = MyDot()
>>> aura.duration = timedelta(seconds=30)
>>> aura.ticks
10

Equipment

class simfantasy.equipment.Item(item_level: int, slot: simfantasy.enum.Slot, stats: typing.Dict[simfantasy.enum.Attribute, int], melds: typing.List[simfantasy.equipment.Materia] = None, name: str = None)[source]

Bases: object

A piece of equipment that can be worn.

Parameters:
  • item_level (int) – Level of the item.
  • slot (simfantasy.enum.Slot) – The slot where the item fits.
  • stats (Dict[Attribute, int]) – Attributes added by the item.
  • melds (Optional[List[Materia]]) – Materia affixed to the item.
  • name (Optional[str]) – Name of the item, for convenience.
Variables:
  • item_level (int) – Level of the item.
  • melds (Optional[List[Materia]]) – Materia affixed to the item.
  • name (Optional[str]) – Name of the item, for convenience.
  • slot (simfantasy.enum.Slot) – The slot where the item fits.
  • stats (Dict[Attribute, int]) – Attributes added by the item.
class simfantasy.equipment.Materia(attribute: simfantasy.enum.Attribute, bonus: int, name: str = None)[source]

Bases: object

Provides a bonus to a specific stat.

Parameters:
  • attribute (simfantasy.enum.Attribute) – The attribute that will be modified.
  • bonus (int) – Amount of the attribute added.
  • name (Optional[str]) – Name of the materia, for convenience.
Variables:
  • attribute (simfantasy.enum.Attribute) – The attribute that will be modified.
  • bonus (int) – Amount of the attribute added.
  • name (Optional[str]) – Name of the item, for convenience.
class simfantasy.equipment.Weapon(item_level: int, magic_damage: int, physical_damage: int, delay: float, auto_attack: float, stats: typing.Dict[simfantasy.enum.Attribute, int], melds: typing.List[simfantasy.equipment.Materia] = None, name: str = None)[source]

Bases: simfantasy.equipment.Item

An Item that only fits in SLOT_WEAPON.

Parameters:
  • item_level (int) – Level of the item.
  • magic_damage (int) – Magic damage inflicted by the weapon. May be hidden for non-casters.
  • physical_damage (int) – Physical damage inflicted by the weapon. May be hidden for casters.
  • delay (float) – Weapon attack delay.
  • auto_attack (float) – Auto attack value.
  • stats (Dict[Attribute, int]) – Attributes added by the item.
  • melds (Optional[List[Materia]]) – Materia affixed to the item.
  • name (Optional[str]) – Name of the weapon, for convenience.
Variables:
  • auto_attack (float) – Auto attack value.
  • delay (float) – Weapon attack delay.
  • item_level (int) – Level of the item.
  • magic_damage (int) – Magic damage inflicted by the weapon. May be hidden for non-casters.
  • melds (Optional[List[Materia]]) – Materia affixed to the item.
  • name (Optional[str]) – Name of the weapon, for convenience.
  • physical_damage (int) – Physical damage inflicted by the weapon. May be hidden for casters.
  • stats (Dict[Attribute, int]) – Attributes added by the item.

Events

class simfantasy.event.ActorReadyEvent(sim: simfantasy.simulator.Simulation, actor)[source]

Bases: simfantasy.event.Event

An event indicating that an Actor is ready to perform new actions.

class simfantasy.event.ApplyAuraEvent(sim: simfantasy.simulator.Simulation, target, aura: simfantasy.aura.Aura)[source]

Bases: simfantasy.event.AuraEvent

An event indicating that an aura should be added to an Actor.

execute() → None[source]

Add the aura to the target and fire any post-application hooks from the aura itself.

class simfantasy.event.AuraEvent(sim: simfantasy.simulator.Simulation, target, aura: simfantasy.aura.Aura)[source]

Bases: simfantasy.event.Event

An event that deals with an “aura”, i.e., a buff or debuff that can be applied to an Actor.

class simfantasy.event.CombatEndEvent(sim: simfantasy.simulator.Simulation)[source]

Bases: simfantasy.event.Event

An event indicating that combat has ceased.

execute() → None[source]

Clear any remaining events in the heap.

class simfantasy.event.Event(sim: simfantasy.simulator.Simulation)[source]

Bases: object

Emitted objects corresponding to in-game occurrences.

execute() → None[source]

Handle the event appropriately when popped off the heap queue.

class simfantasy.event.ExpireAuraEvent(sim: simfantasy.simulator.Simulation, target, aura: simfantasy.aura.Aura)[source]

Bases: simfantasy.event.AuraEvent

An event indicating that an aura should be removed from an Actor.

execute() → None[source]

Remove the aura if still present on the target and fire any post-expiration hooks from the aura itself.

Miscellany

Common math and constants

simfantasy.common_math.get_base_resources_by_job(job: simfantasy.enum.Job) → typing.Dict[simfantasy.enum.Resource, int][source]

Get base main stats by job.

Parameters:job – Job.
Returns:Dictionary mapping Attribute to integer bonus values.
simfantasy.common_math.get_base_stats_by_job(job: simfantasy.enum.Job) → typing.Dict[simfantasy.enum.Attribute, int][source]

Get base main stats by job.

Parameters:job – Job.
Returns:Dictionary mapping Attribute to integer bonus values.
simfantasy.common_math.get_racial_attribute_bonuses(race: simfantasy.enum.Race) → typing.Dict[simfantasy.enum.Attribute, int][source]

Get main stat bonuses by clan.

Parameters:race – Clan.
Returns:Dictionary mapping Attribute to integer bonus values.

Enumerations

class simfantasy.enum.Attribute[source]

Bases: enum.Enum

Primary and secondary attributes.

class simfantasy.enum.Job[source]

Bases: enum.Enum

Base classes and job specializations.

class simfantasy.enum.Race[source]

Bases: enum.Flag

Races and clans.

class simfantasy.enum.RefreshBehavior[source]

Bases: enum.Enum

An enumeration.

class simfantasy.enum.Resource[source]

Bases: enum.Enum

An enumeration.

class simfantasy.enum.Role[source]

Bases: enum.Enum

Class archetypes.

class simfantasy.enum.Slot[source]

Bases: enum.Flag

Slots where an item an be equipped.

Indices and tables