You, a renowned warrior known as the Doom guy, found yourself in an unexpected situation. Your spacecraft was hit, forcing you to land on the Moon immediately. To your surprise, you discovered that the Moon had rivers teeming with fish. This revelation reignited your long-forgotten childhood dream – to become a fisherman. Tired of the constant battles you've endured, you saw this as an opportunity to finally lay down your arms and embrace a more peaceful existence. However, your respite was short-lived. Monstrous beings soon emerged, intent on plundering your hard-earned catch. Your warrior instincts kicked in, and you realized that you had no choice but to defend your newfound livelihood from these menacing creatures. Despite your initial desire for tranquility, you found yourself once again in the familiar position of having to eliminate every last one of these invading monsters.
This project features:
The game's construction relies on three fundamental components: Map, Actor, and Controller. The Map component serves as a container that maintains collections of both Actors and Controllers. Controllers can possess any Actor by referencing their unique identifier (ActorUID). Actors are versatile entities representing any game element - from spawn locations to enemies to the player character (Doom warrior). Each Actor references a predefined actor template from a static collection maintained by the game.
The game uses a flexible, data-driven architecture where an Actor's characteristics are defined entirely through XML configuration files. When the game reads these XML files, it populates ActorDefinition instances with the specified values and properties. Each XML section contains the defining attributes that shape what type of game entity the Actor becomes - this could be enemy behaviors, player stats, spawn point properties, or any other game element. This approach means that creating new game content or modifying existing entities can be done by editing XML files rather than changing the code itself. Here are some entities that share the same class Actor but have a different ActorDefinition:
Doom warrior
Moon's demon
Moon's fishes
Buy Station
The map creation process uses a color-coded system where each pixel in a map image corresponds to a specific TileDefinition. Here's how it works:
First, there's a set of TileDefinitions where each one is associated with a specific color code
The game loads a map image where each pixel represents a tile using these color codes
For each pixel in the image, the game:
Reads the pixel's color data
Searches for the matching TileDefinition using that color code
Creates a tile using the found definition
Applies the appropriate textures to each side of the tile based on what's specified in the TileDefinition
This means you can effectively "draw" a map using an image editor, where different colors represent different types of tiles (like walls, floors, or special areas), and the game will automatically construct the 3D environment based on these color codes and their associated tile definitions.
+
+
=
The fish has an AI system with these key elements:
The fish navigates using a distance-based float field
It always moves toward adjacent tiles with lower values
When reaching a tile with value 0 (destination):
Randomly selects a new target position
Validates pathfinding by checking if there's a continuous path from the current position to the target (decreasing values)
If no valid path exists, it generates a new target position and recalculates
Continuously monitors tiles within its defined sight radius
When bait is detected, may interrupt its patrol pattern
Each fish has a probability value for eating bait
This probability creates an interesting risk-reward system:
Fish with a higher probability of eating bait will yield less money when caught
Fish with a lower probability offer better rewards but are harder to catch
This creates a strategic element where players must balance between targeting easier-to-catch fish with lower rewards versus the more challenging but more valuable fish.
Projectiles and hitscan are two different weapon systems in the game:
Physical objects that travel through space over time
Need to check for collisions with map objects as they move
Have travel time, meaning players need to lead their shots
Instant rays that trace from the weapon to the target
Require 3D raycasting to determine what they hit
No travel time - damage is immediate on trigger pull
This combination offers varying gameplay styles: projectiles for skill shots and area control, and hitscan for precise instant-hit weapons.
For hitscan weapons, the map uses a fast raycasting method for the 2D grid system. At each step, it compares X and Y distances to find the shortest path to the next tile, moves there, and checks if it's the target tile. If not, it continues stepping. This grid-based approach is much faster than traditional raycasting since it only checks tiles the ray actually passes through. Here is the implementation for XY raycasting:
Since we're working with a fixed height range of 0 to 1 unit for the game world's Z-axis, we can perform a simple and efficient raycast check. The ray just needs to test for collisions with these two fixed boundaries (floor at Z=0 and ceiling at Z=1), making it a straightforward intersection calculation rather than needing to check multiple height levels. Here is the implementation for Z raycasting: