datasource db { provider = "sqlite" url = "file:../runtime/database/db.sqlite" } generator client { provider = "prisma-client-js" } /// Discord channels known to the server. model DiscordChannel { /// The ID of the channel in Discord. discordId String @id /// The last known name of this channel. name String /// True if this channel should be used to broadcast public game events. broadcastGame Boolean /// True if this channel should be used to send logs. sendLogs Boolean /// True if this channel can accept game commands. acceptGameCommands Boolean /// True if this channel can accept admin commands. acceptAdminCommands Boolean /// The priority of this channel when slowing down to account for rate limits. Higher is more important. priority Int /// The guild in which this channel exists, if it's known. guildId String? /// The ID of the webhook used to post to this channel. Deleted if the webhook 404's. webhookId String? /// The webhook token used to post to this channel. Deleted if the webhook 404's. token String? } /// User genders. model Gender { /// The internal ID associated with this gender. id String @id @default(cuid()) /// The human-readable name of this gender. Unique among genders. name String @unique /// The users with this gender. User User[] } /// In-game user data structure. model User { /// The internal ID associated with this account. /// It's separate from the Discord ID associated with this account. This supports a few things: /// 1) We can move the game off of Discord, or add the ability to play it as a separate phone app or webapp, /// without losing our database. /// 2) If necessary, we can support having multiple Discord users associated with the same user account, to /// support multi-account play. /// 3) If necessary, we can support changing the Discord user associated with a user account, if for any reason /// they are no longer using the old account and want to switch to a new account. id String @id @default(cuid()) /// The user's name, for the purposes of the game. This is completely separate from both their username and nickname /// as Discord sees it, though it defaults to their nickname at time of joining. It does not have to be unique, and /// can be changed at any time. name String /// The discord user associated with this account. discordUser DiscordUser? /// The user's gender, for the purposes of the game. This is purely cosmetic and can be changed at any time. gender Gender @relation(fields: [genderId], references: [id]) /// Relation field for Gender genderId String /// The number of units of currency this user is currently carrying. currency Int @default(100) /// The time and date at which this user joined. joinedAt DateTime @default(now()) /// The last time this user used a command. lastActive DateTime @default(now()) /// The last time this user retrieved their daily resources. lastDaily DateTime? /// List of units this user has ever seen/pulled. units UserUnit[] /// List of units currently in this user's party. summonedUnits SummonedUnit[] } /// Informmation about a Discord user. model DiscordUser { /// The Discord ID this record is for. A Discord snowflake. discordId String @id /// The last known username associated with this user. username String /// The last known discriminator associated with this user. discriminator String /// The User that this DiscordUser is associated with. user User? @relation(fields: [userId], references: [id]) /// Relation field for User userId String? @unique } /// Definitions of unit tiers. model Tier { /// The internal ID associated with this tier. id String @id @default(cuid()) /// The human-readable name of this tier. Unique among tiers. name String @unique /// The chance of pulling a unit of this tier. pullWeight Int /// The cost of /recalling a unit of this tier. recallCost Int /// The list of units with this tier. units Unit[] } /// An individual unit that can be summoned. model Unit { /// The combination of Name and Subtitle is unique among units, allowing for multiple versions of a unit. /// The internal ID associated with this unit. id String @id @default(cuid()) /// The name of this unit. name String /// The subtitle of this unit. subtitle String /// The description of this unit. description String /// The tier of this unit. tier Tier @relation(fields: [tierId], references: [id]) /// Relation field for Tier tierId String /// The unit's base health when summoned for the first time. baseHealth Int /// The unit's base strength when summoned for the first time. baseStrength Int /// Information about the bonds with users this unit has been summoned by. users UserUnit[] /// Information about this unit's summoned forms. summonedUnits SummonedUnit[] @@unique([name, subtitle]) } /// Connection between Users and Units, indicating how and when users have pulled this unit. model UserUnit { /// The User that summoned this unit at some point. user User @relation(fields: [userId], references: [id]) /// Relation field for User userId String /// The Unit that was summoned by this User at some point. unit Unit @relation(fields: [unitId], references: [id]) /// Relation field for Unit unitId String /// The first time this user pulled this unit. firstPulled DateTime @default(now()) /// The number of times this unit has been /pulled by this user. /// Greatly increases the user's bond with this unit. /// Higher bond means higher stats on being resummoned with /pull or /recall. timesPulled Int @default(1) /// The number of times this unit has been digested in this user's party, either with /feed or in battle. /// Slightly decreases the user's bond with this unit. /// If the total bond reaches zero, this unit can no longer be resummoned with /recall until they appear in /pull. timesDigested Int @default(0) /// The number of times this unit has digested other units, either with /feed or in battle. /// Does not influence bond, but may have an influence on other things (e.g., Talk lines). timesDigesting Int @default(0) /// The summoned form of this unit, if this unit is currently summoned. /// Created on pulling or recalling, destroyed on digestion. summonedUnit SummonedUnit? @@id([userId, unitId]) } /// Instances of summoned units. model SummonedUnit { /// The User this unit was summoned by. user User @relation(fields: [userId], references: [id]) /// The Unit this summoned unit is an instance of. unit Unit @relation(fields: [unitId], references: [id]) /// The user-unit pair this SummonedUnit originates with. userUnit UserUnit @relation(fields: [userId, unitId], references: [userId, unitId]) /// Relation field for User and UserUnit userId String /// Relation field for Unit and UserUnit unitId String /// The unit's current health. If 0, the unit is unconscious and cannot participate in fights. /// At -MaxHealth, the unit has been fully digested and this record will be deleted. currentHealth Int /// The unit's maximum health. maxHealth Int /// The unit's strength. strength Int @@id([userId, unitId]) }