thibaud-dt/trinitycore-models
Eloquent models for TrinityCore, the World of Warcraft server emulator database, letting Laravel apps query auth, characters and world tables through familiar Eloquent relationships instead of raw SQL.
This package gives you Eloquent models mapped onto an existing TrinityCore schema (auth, characters, world), so you can query game data with Laravel's query builder instead of hand-writing SQL against the emulator's database.
Minimal steps:
composer require --dev or require with an explicit constraint — 0.1.1-dev is a pre-1.0 dev tag, so pin it ("vendor/trinitycore-models": "0.1.1-dev") rather than floating on *.config/database.php. TrinityCore typically splits data across auth, characters, and world; point a connection at each and make sure the package's models resolve the right one (via $connection on the model or a package config file if one is published).getTable() and getConnectionName() before writing any logic.Where to look first: the Account model. It's the only model with relationships in this release, so it's both the reference implementation and the best indicator of the package's conventions (naming, key types, connection wiring). Read its source before assuming anything about the rest.
First use case: read-only reporting. Pull an account and its related rows to confirm the connection setup end-to-end:
$account = TrinityCore\Models\Account::find($id);
$account->load(/* whatever relations 0.1.1 ships */);
Don't build write paths on this yet — see gotchas.
Treat the package as a read layer. The TrinityCore schema is owned by the emulator, not by your app. Use these models for queries, dashboards, admin panels, and exports; avoid save()/create() unless you've verified that the specific table tolerates it. Password fields use TrinityCore's SRP6 hashing, so creating accounts through Eloquent will produce rows the auth server cannot log in with.
Multi-connection wiring. Because auth/characters/world live in separate databases, cross-database relationships are the main integration pain. Two workable patterns:
auth.account ↔ characters.characters on the same server).Fill in the missing relationships yourself. With only Account relations shipped, the pragmatic move is to define your own subclasses or local relation methods on top of the package models rather than waiting on the TODO list:
class Character extends TrinityCore\Models\Character
{
public function account()
{
return $this->belongsTo(Account::class, 'account', 'id');
}
}
This keeps upgrades cheap — your additions live in your namespace, and a package release that adds the same relation only means deleting your override.
Constrain and chunk everything. characters, item_instance, and the world tables are large. Always scope by account/guid and use chunkById or lazy() for anything unbounded. Avoid withCount on unindexed columns.
Pin the dependency in CI. Since the package is -dev and relationships are actively being added, a lockfile is not enough — pin the exact version string and review each bump, especially once the remaining relations land.
Account relationships. Anything you infer about relation names, foreign keys, or return types for other models is guesswork. Verify each relation against the actual schema before depending on it.created_at/updated_at, use non-id primary keys (guid, account), and occasionally use composite or non-incrementing keys. Expect to set $primaryKey, $incrementing, $keyType, and public $timestamps = false — either in the package or in your subclasses. Silent failures here usually show up as find() returning null.migrate against these connections. Migrations would try to own tables the emulator manages. Guard by never pointing DB_CONNECTION (the default) at a TrinityCore database; use only the explicitly named connections for these models.getConnectionName() on the model instance, and confirm the package isn't hardcoding a connection name that doesn't match your config/database.php.$guarded = ['*'] for your use case; if the package leaves them fillable, treat any fill() as a potential accidental write.composer update stays non-destructive. If the package publishes config, publish it and keep your overrides in config/ rather than in code.How can I help you explore Laravel packages today?