IdleQuest is an idle/incremental game based on EverQuest, the iconic MMO released in 1999. Designed to progress on its own, players interact by making strategic choices to determine how the game plays out in an automated way. The goal is to recreate as much of the original EverQuest experience as possible using a database dump from the EverQuest emulator (EQEmu) project, which itself is data from scraping the original game. This data, rooted in the original game, allows for a nostalgic and detailed exploration of EverQuest’s world in a more casual, low commitment way.
The game content and mechanics are as true to the original experience as can be reasonably done with a single developer - the interface, classes, races, zones, items, NPCs, loot drops, skills, spells, etc are all very close to original EverQuest content.
Though there may be implementation of 3D graphics in the future, the current focus on this project is text-based adventuring with some visual aids. EverQuest was originally created from the era of MUDs (multi-user dungeons) which were basically EverQuest without graphics. It's fun to now return to the MUD heritage of the game, but with the addition of LLMs for dynamic quests, dialogue, and storytelling.
I would like to give credit to Eric Fredricksen, the creator of ProgressQuest from 2002, which is also interestingly the example project used for the "idle games" article on Wikipedia. Though ProgressQuest is much simpler in nature and doesn't contain content from the real game, I want to recognize that this isn't a wholly original idea on my behalf, and I have fond memories of playing ProgressQuest 20+ years ago.
This project is very much in its early phase, and the casual nature of the README and documentation reflect this.
This project is built using React/TypeScript and Zustand. Long term this will probably transition to having a RESTful API backend but is currently all running locally off a SQLite database.
To run it:
pnp run dev
There is also an assortment of one-off scripts in the /data folder, for example:
python ./data/add_table_to_db_from_csv.py
as needed, but also don't do this bc it makes all fields text values
The data in the SQLite file is fairly comprehensive at this point though, so it is unlikely much more data import work will need to be done.
TLDR: NPCs have a loottable ID, loottables have lootdrops, lootdrops have items.
NPCs: Characters not controlled by players. Each has a loottable_id
determining potential item drops.
loottable: Lists possible item sets an NPC can drop. Each row is a unique set identified by an id.
loottable_entries: Links loot tables to items. Each row represents a possible item drop, connecting loottable_id
to lootdrop_id
.
lootdrop: Represents collections of items that can be dropped together. Each row is a unique collection.
lootdrop_entries: Links loot drops to actual items. Each row represents an item in a loot drop, connecting lootdrop_id
to item_id
.
loottable_id
loottable_entries
lootdrop_id
lootdrop_entries
item_id
to identify actual itemsThis structure allows for flexibility, enabling multiple NPCs to share loot tables and multiple loot tables to include the same loot drops.
Example SQL Query:
SELECT items.
FROM items
INNER JOIN lootdrop_entries ON items.id = lootdrop_entries.item_id
INNER JOIN loottable_entries ON lootdrop_entries.lootdrop_id = loottable_entries.lootdrop_id
INNER JOIN npc_types ON loottable_entries.loottable_id = npc_types.loottable_id
WHERE npc_types.id = #;
The NPC spawn system is managed through three SQL tables originally named: spawngroup
, spawn2
, and spawnentry
.
I've renamed "spawn2" to "spawnlocation" because the name makes much more sense.
Define a spawngroup (spawngroup table)
Add mobs to the spawngroup (spawnentry table)
Specify spawn locations (spawnlocation table)
Create spawngroup
INSERT INTO spawngroup (id, name) VALUES (1, 'Plane of Disease Rats');
Add mobs to spawngroup
INSERT INTO spawnentry (spawngroupID, npcID, chance) VALUES
(1, 40010, 20), -- a_diseased_rat lvl 50
(1, 40011, 20), -- a_diseased_rat lvl 51
(1, 40012, 10), -- a_diseased_rat lvl 52
(1, 40020, 25), -- a_swamp_rat lvl 52
(1, 40021, 25); -- a_swamp_rat lvl 54
Set spawn locations
INSERT INTO spawnlocation (id, spawngroupID, zone, x, y, z, heading, respawntime) VALUES
(1, 1, 'podisease', 1000, 10, 100, 0, 120),
(2, 1, 'podisease', 500, 500, 100, 0, 120);
variance
in spawnlocation adds randomness to respawn time, useful for boss monsters.pathgrid
in spawnlocation sets a movement path for spawned NPCs.timeleft
in spawnlocation is used by the game to track respawn timers.(from simple boilerplate this project started from)
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
parserOptions
property like this:export default tseslint.config({
languageOptions: {
// other options...
parserOptions: {
project: ["./tsconfig.node.json", "./tsconfig.app.json"],
tsconfigRootDir: import.meta.dirname,
},
},
});
tseslint.configs.recommended
to tseslint.configs.recommendedTypeChecked
or tseslint.configs.strictTypeChecked
...tseslint.configs.stylisticTypeChecked
// eslint.config.js
import react from "eslint-plugin-react";
export default tseslint.config({
// Set the react version
settings: { react: { version: "18.3" } },
plugins: {
// Add the react plugin
react,
},
rules: {
// other rules...
// Enable its recommended rules
...react.configs.recommended.rules,
...react.configs["jsx-runtime"].rules,
},
});
Similar to ProgressQuest, this project falls under fair use because it transforms elements of the original EverQuest game for a different purpose—an idle game experience rather than an active MMORPG. It does not replicate the gameplay mechanics or experience in a 1:1 manner but instead serves as a commentary and nostalgic parody of EverQuest’s legacy, which fits within the definition of transformative use. Additionally, IdleQuest is non-commercial, and the use of EverQuest’s content is limited and for purposes that add new meaning, context, and value.