-
-
Notifications
You must be signed in to change notification settings - Fork 13
Technical and Development Process
Low-end gaming computer
Godot, GDScript, GDNative in Rust is planned, specifically for Rapier Physics integration.
Game is currently on Godot 3.5 and will move to Godot 4 after a pre-alpha demo release.
Will later be rebuilt with network code during or after a refactor to Godot 4.
Major directories:
- core/ai - AI
- globals - singletons, autoloads, settings
- resources - art generally - sound effects, voices, images, models & meshlibs, materials, fonts, texts
- scenes - scenes and scripts - UI, objects, characters, effects, sensors, worlds
Minor directories:
- script_templates - pretty script guideline defaults
- utils - scripts and tools outside the rest of the above structure
Navmesh generation Other world generation AI & navigation Animations Player controller Inventory/grabbing/throwing UI/Settings/Music
- Character inherits from KinematicBody, Player and Neophyte (Cultist) inherit from Character
- Player Controller is abstraction that allows other future controllers such as top-down or 3rd person, but for now uses fps_control_mode.gd
- Cultist AI is currently a Behavior Tree with plans to move to a GOAP system
- Needs move to a more RigidBody controller like it used to have to avoid some of the glitchy physics interactions that can come from no inertia or infinite inertia
- Character, Player, and Neophyte are all quite messy and can be scened out and cleaned up in many ways; this is the number one system in need of a rewrite
- Most complicated system, especially procedural navmesh generation; nevertheless, rarely a source of bugs
- Current dungeon gen uses an adapted 2D version of https://vazgriz.com/119/procedurally-generated-dungeons/
- Rooms are purposed then filled appropriately
- Spawning overview at #682
- Objects can have different sizes that determine how they can be interacted with. Tiny items can be held in infinite amounts, small items take up an inventory slot, medium items such as swords and longguns can only be used in the main hand and suffer penalties if anything is in the off-hand, bulky items can be equipped but not stored in inventory, large items are RigidBodies in the world to be grabbed and dragged but not equipped
- Inventory is a complex system due to item sizes, bulky item (can equip, but can't story in inventory), empty hands, and the two that you have a main and an off-hand.
- Files involved: inventory.gd, player_controller.gd, hotbar.gd, hotbar_slot.gd, pickable_item.gd, equipmemt_item.gd
- Frequent source of bugs
- Needs a lot of cleanup, different HUD elements are scattered through character, player, multiple other UI and HUD places
- Standardizing an effects system would help too
- Settings has been revamped to a flexible system
Story, enemies, and some secret design done in text files and released as we build it. Most of the design notes in the Github wiki (that you're reading) and using Issues by Milestone here in Github. The milestones are most like projects and we could use Github Projects board...but it didn't end up like that. Milestones are currently the rough order of progress.
Here is a checklist before PRing. Please take note of this, it's good general practice for any git project.
Found a bug? Have a cool feature idea? Make or comment on an Issue.
If you're a beginner with git, feel free to join our Discord server to get help.
If you'd like to make a one-off art contribution, like a model, sound effect, or piece of music, feel free to just post it to our Discord server with a license file. Compatible art licenses for us are CC0, CC-BY, and CC-BY-SA and their equivalents.
If you'd like to work with the project on a deeper level, you will use need to use git (there are many good GUIs for it) and download the project's files to your computer. This is a pretty good guide on how this works. Here's an overview of the steps:
- Fork the project.
- Clone to your computer (you will need at least 20GB free space as of August, 2023).
- Checkout dev.
- Create a new branch named after the issue or feature you're working on.
- Make awesome stuff.
- Test it.
- No really...test it. Test any related things you might have affected. If you worked any anything that touched inventory, test item switching, throwing, picking up, grabbing, etc.
- Is your code well-commented? Would someone fresh to this part of the code understand what's going on?
- Did you name everything according to code style? When in doubt, look at how other similar things are named in the project. It's especially important to use snake_case and no capitals or special characters in filenames. Node names are always PascalCase. Vars are snake_case.
- Did you use spaces between operators (a + b not a+b)?
- Did you put two newlines between class_name/extend and signals/consts/vars? How about two newlines between those and funcs, and between each func, and a single newline at the end?
- Did you prune each of your commits of unwanted changes before committing so you don't end up PRing changes you didn't intend to make?
- Did you update your local dev from origin and merge dev into your branch and push that before PRing? Scene (.tscn) merges can be especially hard - feel free to reach out on Discord for help. Often it's best to accept origin's scene and redo your changes to that scene file after the merge.
- Great! Pull Request when you have a draft or think you're done. Someone with merge permissions will review it shortly. If you like, you can join our Discord and let us know you've made a PR as well.
- That's it for now! Take a break or start on another improvement.
- You'll either see your PR accepted and merged or we'll come back at ya with any changes we'd like to see before we can merge it. It's a discussion, so if you have reasons why you think the way you did it is better, tell us.
- If you're on our Discord and this is your first contribution, let us know and we'll give you Contributor status and put you in the Credits. You're part of the team! :) Let's make some memories...
Some helpful hints:
- Keep your main and dev branches clean. This means you can easily pull changes made to this repository into yours.
- Create a new branch for each new feature or set of related bug fixes. Do not ever commit changes to your dev or main.
- Never merge from your local branches into your dev branch. Only update dev by pulling from upstream/dev.
- Attribute any art assets by adding a text file in the same folder with the name_of_the_asset_license.txt. Use the TASL attribution style.
Model/mesh and collisions (applies to anything below that has a mesh)
- Export as GLTF from your modeling software; filename should be in snake_case, new snake_case named folder in /resources/models/etc
- Keep source files (.blend but not backups such as .blend1)
- Open the GLTF/GLB in Godot, Open Anyway
- Copy the Skeleton node if it has one, or the MeshInstance node if not, then paste it into your new/inherited item scene (as described below) - if Skeleton, may have to right-click the named Spatial under MeshInstance, Make Local
- -z is forwards, x is right (so rotate as needed)
- Origin should be center of mass
- If possible, Sphere, Cylinder, Capsule, Box, if not appropriate: Create Simplified Convex Collision Sibling (if not good, then Single, then Multiple; never use Trimesh)
- Use the inherited collision layers or look to similar items for the correct collision layers
Tiny item
- A character can have an unlimited number of tiny items, things that take up no hotbar space, thus can't be equipped.
- Tiny items are just a resource, inheriting from https://github.com/Mooses2k/SecretHistories/blob/dev/resources/tiny_items/tiny_item_data.gd
- If there's a model that can be picked up that corresponds to this tiny item, you can add it in https://github.com/Mooses2k/SecretHistories/tree/dev/resources/models/items/tiny_items
- If you have a model for it, then you'll also want to make a scene for it using that model here https://github.com/Mooses2k/SecretHistories/tree/dev/scenes/objects/pickable_items/tiny that inherits from _tiny_item.tscn
- Name the file in snake_case, Name the root node in PascalCase, set the item name in 'Capitalize first letter of first word unless Proper Noun' case
Melee weapon
- Put your model/materials in a folder in https://github.com/Mooses2k/SecretHistories/tree/dev/resources/models/items/melee
- Put your scene in a folder in https://github.com/Mooses2k/SecretHistories/tree/dev/scenes/objects/pickable_items/equipment/melee and inherit from https://github.com/Mooses2k/SecretHistories/blob/dev/scenes/objects/pickable_items/equipment/melee/_melee_item.tscn
- Name the file in snake_case, Name the root node in PascalCase, set the item name in 'Capitalize first letter of first word unless Proper Noun' case
- Set an appropriate mass in kg.
- -Z faces forward.
- Origin should be at what you estimate to be the center of mass.
- Set the appropriate item size. If the size of a skull or smaller, Small Item. Arming sword or longsword size, Medium Item. Polearm sized, Bulky Item.
- Choose a weapon type most closely matching the moveset of this weapon.
- Primary (L-Click thrust) and secondary (R-Click swing) attacks can each do two different types of damage, like how an axe does both bludgeoning and slashing damage to simulate 'chopping'. Set these are best you can. A neophyte has 40 HP, as an example.
- See other melee items as examples.
Ranged weapon
- Put your model/materials in a folder in https://github.com/Mooses2k/SecretHistories/tree/dev/resources/models/items/ranged
- Put your scene in a folder in https://github.com/Mooses2k/SecretHistories/tree/dev/scenes/objects/pickable_items/equipment/ranged and inherit from https://github.com/Mooses2k/SecretHistories/blob/dev/scenes/objects/pickable_items/equipment/ranged/_gun_item.tscn
- Name the file in snake_case, Name the root node in PascalCase, set the item name in 'Capitalize first letter of first word unless Proper Noun' case
- The business end should point to -Z.
- Origin should be at what you estimate to be the center of mass.
- Set the appropriate item size. If the size of a pistol or sawed-off shotgun, Small Item. Longgun, Medium Item. Minigun, Bulky Item.
- For Ammo Types, choose size 1 (or more if this weapon shoot multiple ammo types), then drag the appropriate ammunition resource from https://github.com/Mooses2k/SecretHistories/tree/dev/resources/tiny_items/ammunition onto that box in the inspector.
- Ammunition capacity is magazine capacity excluding chamber, or size of the revolver cylinder or simply the number of chambers (e.g. two for a double-barrel shotgun).
- Reload amount is the amount of ammo that is loaded into the weapon per press of R.
- Reload time is how long that takes in seconds.
- Damage offset should have a minus amount if this weapon doesn't allow all the propellant to burn inside the barrel, such as a sawed-off weapon.
- Dispersion offset should have a POSITIVE amount if this weapon is less precise (perhaps due to being sawed-off) than a typical weapon that shoots this ammo.
- Cooldown is the minimum time between shots.
- Handling is the amount that recoil is reduced.
- Melee damage type and style refer to the type of damage and moveset of attempting to melee with this weapon.
- Set an appropriate mass in kg.
Tool
- Tool use not coded yet.
Consumable
- Consumable use not coded yet (except for bombs).
Bomb
- Put your model/materials in a folder in https://github.com/Mooses2k/SecretHistories/tree/dev/resources/models/items/consumables/bombs
- Inherit your scene from https://github.com/Mooses2k/SecretHistories/blob/dev/scenes/objects/pickable_items/equipment/consumable/bomb/_bomb.tscn
- Name the file in snake_case, Name the root node in PascalCase, set the item name in 'Capitalize first letter of first word unless Proper Noun' case
- Check https://github.com/Mooses2k/SecretHistories/tree/dev/scenes/objects/pickable_items/equipment/consumable/bomb/grenade as an example.
Refillable light-source
- Refillable light-sources are prototypically lanterns. They're considered tools and are found in https://github.com/Mooses2k/SecretHistories/tree/dev/scenes/objects/pickable_items/equipment/tool/light-sources and inherit from https://github.com/Mooses2k/SecretHistories/blob/dev/scenes/objects/pickable_items/equipment/tool/light-sources/_lantern_item.tscn
- Name the file in snake_case, Name the root node in PascalCase, set the item name in 'Capitalize first letter of first word unless Proper Noun' case
- -Z faces forward.
- Origin should be at what you estimate to be the center of mass.
- Set an appropriate mass in kg.
- Create/edit the flicker animation track as per other lanterns, using about the same brightnesses.
- Check other lanterns for examples.
Disposable light-source
- Any new disposable light-source may be a new category of thing, so may require code, otherwise inherit from or copy from the torch or candle.
Large object/furniture
- Models/materials go in https://github.com/Mooses2k/SecretHistories/tree/dev/resources/models/large_objects in appropriate folder
- Scenes go in https://github.com/Mooses2k/SecretHistories/tree/dev/scenes/objects/large_objects in appropriate folder
- Name the file in snake_case, Name the root node in PascalCase, set the item name in 'Capitalize first letter of first word unless Proper Noun' case
- Please set the mass to something reasonable in kg
- Origin should be at what you estimate to be the center of mass
- Add to group CLAMBERABLE if player should be able to clamber onto it
- When in doubt, duplicate what's been done with other large objects
Modular level piece - updating meshlib
- Discuss on Discord what new piece you'd add or improve - if it's a new type of piece, that's more difficult as much code may have to be written to support it; this guide below assumes you're adding a better model to an existing piece (wall, doorway, floor, etc)
- Place your model in resources/models/gridmap/modular_pieces/(eventually name of branch)/
- Open your .glb from where you placed it in resources/models/gridmap/modular_pieces/(eventually name of branch)/ and choose 'Open Anyway'
- Click on the MeshInstance with your mesh on the Nodetree on the left of Godot
- On the right of Godot, in the Inspector, click the down-arrow to the right of the image next to 'Mesh' and choose 'Copy'
- In resources/mesh_libraries, open the modular_pieces.tscn (eventually there will be one for each dungeon branch)
- Find the MeshInstance on the left that corresponds to the your model; if making a new item, all modular pieces names shall now be in the format: wall/floor/ceiling/pillar/spiral_stair/straight_stair/whatever[UNDERSCORE]#mx#m[UNDERSCORE]whatsspecialaboutit. Examples: wall_3mx3m_broken, ceiling_1_5mx1_5m_stepped_grated
- In the Inspector, click the down-arrow to the right of Mesh and choose 'Paste'
- If you mesh's collisions differ significantly (they probably shouldn't), adjust them (they are children of the MeshInstance in the Nodetree)
- On the menu bar, go to Scene, Convert To, MeshLibrary, uncheck 'Merge With Existing', check 'Apply Mesh Transforms'
- Overwrite resources/mesh_libraries/modular_pieces.meshlib (or whichever one is the one for the branch you're working on)
Humanoid Character
- To make a new NPC, you should be ready with a rigged model, all the AI behaviors you want the character to exhibit, and possibly a voice pack (can be added later)
- Inherit from https://github.com/Mooses2k/SecretHistories/blob/dev/scenes/characters/character.tscn
- You'll need to have a rigged model, collisions setup on that model, sensors (direct_player_sight, sound_listener, touch_sensor, etc), AI nodes, etc.
- Name the file in snake_case, Name the root node in PascalCase, set the item name in 'Capitalize first letter of first word unless Proper Noun' case
- Check https://github.com/Mooses2k/SecretHistories/blob/dev/scenes/characters/cultists/neophyte.tscn as an example.
AI behavior
- Check https://github.com/Mooses2k/SecretHistories/blob/dev/scenes/characters/cultists/neophyte.tscn as an example. The Behavior Tree AI is built using the BT nodes in a tree structure.
- Behavior Tree scripts can be found here: https://github.com/Mooses2k/SecretHistories/tree/dev/core/ai
RoomPurpose or RoomRequirement
Loadscreen quote
- Add to this file: https://github.com/Mooses2k/SecretHistories/blob/dev/resources/text/loadscreen_quotes/list1.txt
Voice pack
- Visit the #sound channel on our Discord and let us know which character you'd like to do a voice for. We'll give you some test lines and advice.
- Clean audio, no background noise. Gain should show that your voice shouldn't ever hit the top of the waveform bar. Somewhere in the middle at loudest.
- Try to do three takes of each line with three second breaks.
- Name your folder character_-_your_name
- For each file, name_the_file_in_snake_case.ogg
- Prefer .ogg exports
- Put the files in folders based on the category of speech (idle, partial_detection, fight, etc)
- Try to record them all at the same distance from the mic in the same room under the same conditions. If something sounds mechanical or with too much echo, try somewhere else. Feel free to ask on our Discord for advice.
- Not an exaggerated style, this is trying to be realistic, sometimes less is more here. Yes, many of the lines are pretty funny, but please play them straight, as it'll usually be funnier.
Effect
- Best scene out the effects - we may have a system eventually to build your own from nodes, but for now, just try to put the effects in a separate scene
- Name the file in snake_case, Name the root node in PascalCase, set the item name in 'Capitalize first letter of first word unless Proper Noun' case
- Ensure particles always local_coords = false
Anything else...
- Well, please code up that new system for us!
The crypts dungeon is based on work by Vazgriz. We intend to use other algorithms as well in the future for dungeon gen.
We will be doing procedural room decoration too. Some examples of software that do this are Dungeon Alchemist, Houdini, and Shadows of Doubt.
Variety is the objective, not pure random (10,000 bowls of oatmeal problem). We want to avoid art fatigue. Background can be filler and repetitive, but important stuff has to be characterful, unique (would someone write a fanfic for this generated item?).
Realistic and photogrammetry are good for this.
Material/texture size rules:
- 512 for small things
- 1024 for most equipment held or seen near camera
- 2046 for large hero assets, detailed large characters/faces
Material size rules reasoning: Game download size: smaller the better Smaller textures allow running the game on a wider range of computers Larger textures can be mipmapped and downscaled easily Best practices here are still an open question with a wide range of opinions
For export files: use glbs/gltf - If it's not a modular set, on the same skeleton (firearms), or a 'broken version of an item' set, every single item should be in a separate glb (for ease of adding to item scenes).
I actually don't have the specs on the corner pillars, since they're pretty new and the dev has recently tweaked them. My guess is radius about 0.25m radius Walls are 1.5m or 3m wide, and 3m tall (more is acceptable in the Archs, Columns project, if needed Floors are 1.5m x 1.5m or 3m x 3m, arranged so the top of the floor where the character would stand is at origin and if there's any depth, it's below origin no more than 0.05 meters Walls are 0.15m in from the side of the grid Ceilings can be anywhere from 2m above the ground to 2.65 (giving a 0.3m clearance to any floor on a level above it) Doors are adjustable in width. Standard is a single doorframe of 2m x 1m, with a door of about 2m x 0.8m (a little less so physics works) Those metal grates can just be whatever makes sense when you size it correctly. Player height is 1.7m 0.3m radius
Oh, for style... Eventually, most of the dungeon will be made out of the 3x3 sections, with 1.5m sections being for narrow, smaller corridors, mainly. Almost every room will be built in 3x3m blocks, so the random gen will basically make sure rooms have an even amount of tiles 1.5m tiles. Rooms may have pillars in the middle or not, but will always have pillars if >= 9m on at least one side Just some style info.
So the material idea is something like this: atlas the modular part of the place, generic materials for anything else, and specific textures for specific assets like NPCs or hero assets. If this is it, probably naming it like generic_material or asset_name, so, generic_darkwood1, generic_rustymetal2, asset_vodkapistol, asset_torch
About the export settings for the format we are using:
There is a specific way to do stuff. This is the correct material standard to export models with materials:
We need to compress the ROUGHNESS, METALLIC, and AO into a single image. It looks like this:
This is the door image. To do this, in GIMP, create a new file with the size of the texture, go to color > decompose > rgb. It will create another file with red green and blue channels. Blue is METALLIC. If the image uses no metallic, keep it black. GREEN is roughness and RED is AO. Just drag the textures in, and rename then to red green blue, color > compose > rgb.
In this image as no metallic, and no AO:
To be fair we don't know if you need to decompose a white image before, maybe just add the layers, and rename then correctly. In Blender, we setup like the image above, that special glTF Settings is just an empty group to plug the AO. The addon will recognize that and export it.
This is the group, literally empty:
https://github.com/Mooses2k/SecretHistories/issues/406#issuecomment-1562871508