# Arbimud While Andre's brilliant [Rarity project](https://rarity.fandom.com/wiki/Rarity_Wiki) is focused on creating an incredibly intricate DnD inspired world, Arbimud has much less lofty ambitions. It's intended to be a quick and dirty proof-of-concept that focuses more on the multiplayer aspect, inspired by other on-chain dungeon crawlers like [Ethernal](https://github.com/0xgen0/ethernal). The goal for me is to work on something light-hearted to kick off the NFT and gaming community on Arbitrum, while also learning about deployment on rollups. At launch, users will be able to: - Create a character from one of 3 classes - Venture into a dungeon with friends - Fight monsters and acquire gold - Gain experience and level up # The Contracts ## Character.sol This is how users get started playing the game, an ERC721 that is capped to 1 per address at launch. Each Character has the following struct for its data: ``` struct CharacterData { uint256 stamina // How many actions the Character can take per turn uint256 health // How many hits the Character can take until they're out for the day uint256 class // 0, 1, and 2 (actual class names TBD) uint256 exp // Amount of experience gained from various actions } ``` Similar to Rarity, we let the actual Dungeon contracts handle combat attributes, as they might change from Dungeon to Dungeon. The Character contract can let other contracts make updates to `CharacterData`, like Dungeons. Users interact by calling `createCharacter(uint256 classId)`. ## Dungeon.sol Dungeons provide the main entry point for user interaction. For this proof-of-concept, we'll also let the Dungeon handle combat data and monster information. The key data structure for the Dungeon is the `rooms[][]`, as 2D array. Each room can be one of 4 types: Unexplored, Gold, Monster, or Empty. Distribution of these 4 types differs from Dungeon to Dungeon. Each Dungeon has a max player count and a size. All Dungeons start with all `rooms` in the Unexplored state. Users enter into a non-full Dungeon by calling `spawn(characterId)` which starts them in `rooms[0][0]`. From there, they call `explore(uint256 characterId, uint256 direction)` which succeeds as long as they don't go off the edge of the map. Characters are free to occupy the same space; we assume they are very comfortable with each other. After `explore` is called, we deduct 1 stamina from the Character. (Once a Character's stamina hits 0, they can't explore anymore for the day.) Then, we use some RNG (method TBD) to decide what type of room is uncovered. Then, depending on the type of room, we do the following: - Empty: nothing happens - Gold: the user gains a variable amount of Gold (simply a mapping in the Dungeon to start, not an ERC20) - Monster: the user loses a variable amount of health, and then is forcibly moved back a space. Monsters have their own `health` and `range`. If there are Monsters in a room, users will also have the option to `attack(uint256 characterId, uint256 roomX, uint256 roomY)` as long as the Manhattan distance between the Character and the Monster is less than the Character's range (specified by the Dungeon). Characters deal a variable amount of damage depending on the Monster type and the Dungeon parameters. Then, the Monster attempts to counterattack, as long as the Character is within the Monster's attack radius. When a Monster's health reaches 0, all Characters who dealt damage receive a proportional share of a variable amount of EXP. ### Dying If a Character's health reaches 0, they cannot take any more actions for the day, even if they have stamina left. The next day. they can call `spawn` again to rejoin the dungeon with full health. ### Achievement If an entire Dungeon's rooms are no longer in the Unexplored state, then everyone in the Dungeon can claim an EXP bonus. # The MVP - For Characters.sol - Figure out the 3 classes to start - Write the code, should be pretty straightforward - For Dungeon.sol - Figure out what to do for RNG (probably have nonce that increments, and then something like `keccak256(nonce, msg.sender, charId, roomX, roomY)`) - Figure out range/damage for Dungeon 1. - Figure out starting size/player count for Dungeon 1. - Write Dungeon 1 code. - To deploy: - Deploy Characters.sol to Arbitrum - Deploy Dungeon1.sol to Arbitrum, add Characters.sol address - For the future: - Create a front-end with nice pixel art - Create DungeonFactory to easily create new Dungeons - Turn Gold into an ERC20 - Probably overhaul data model