Hats off!
You did more in a few weeks than me in 20 years of analysis paralysis

I like the "simple" ragdoll implementation and it looks amazing with the assets. You are the do-er !! Here's what I was thinking, loosely sorted from easy/important to hard/lesser important.
Editor
I suggest you make the editor with OS GUI because the CEGUI lacks menus and Tree Gadgets that will be important for your editor. I would use XML for "level" and prefab description. Also maybe to describe the editor features, and if you use Dialogs this may be helpful for extensibility. SQLite to have a DB with links to all "asset packs" and usable objects, including thumbnails for the textures, for fast browsing in the editor, categorize & sort files, add file names "hidden" in zip archives. Have different DB's for different projects or mods.
Create visible and invisible mesh (hit) boxes, spheres and cones to wrap around objects; use different colors, perhaps make them changeable. A cone could be a player or NPC spawn point, spheres a sound or effect source. You can click them, you can disable complex physics bodies and the editor should run faster perhaps.
Nodes and paths for animations, simple navigation, elevators.
Invisible geometry (in game) to create special function volumes and zones e.g. water, breakable, event triggers buttons and switches.
Using XML you could define special functions (object classes) associated with an entity or object - parameters, properties of an object class, create a dialog and create+store "object properties"; give it a name and unique Id etc.
Groups - grouping of objects is important. Export a group or the entire "level" as prefab.
Prefabs - each "map" can be exported / included as a prefab "asset" in XML format. The editor can include "prefab objects" and reuse them multiple times.
Plugin/add-on interface - for external tools e.g. "Import height map" dll or exe that creates a mesh without using the engine3d terrain functions. If it's via exe I would suggest a simple interface like the PureBasic compiler interface (tab separated parameters, heading number of bytes/lines/content followed by the content etc)
"AI" and NPC's
State machines - state machine definitions can also be stored in XML. A machine does only return a state as integer value but it may need a blackboard. They machines may not be changeable in the editor itself, need a separate one, but they might be important for behavioral things. They might also be used to handle game logic like the main loop, or just to handle the elevator or light switch. But they might be part of a group that receives trigger events e.g. someone steps in front of a light sensor and the state machine switches to "open the door"
Blackboard - use purebasic maps at first, especially if you don't have many NPC's; if you can do with only one data type of data use string or double. With only 20-40 NPC's use strings (everything can be put in a string e.g. "long:123" "float:123.4" "vec3: 12345.2, 234.3, 234.2" "string:player_name")
Code: Select all
Structure Blackboard
*InheritFrom.Blackboard
Flags.i
Map BB.d()
EndStructure
You could class and subclass using blackboards, so that a new NPC always has default values inherited from it's "class blackboard". Changes are only made at the top level blackboard. Additionally a "read only" flag may offer protection from writing in the "ancestor" blackboards. You may also use shared blackboards for example there might be a team blackboard and one for the individual characters. But you may also be interested of having extra data types or lists/maps/stacks/queues/callback-helper-functions available for e.g. an inventory, a list of things to do. This is where/why scripting is very popular at that level IMO, and OOP would be easier to make a good blackboard in native code. Nothing can discourage us today. The blackboard could best be stored in JSON format.
Also: if everything is "fixed" you don't need a map for your blackboard, you may simply use a structure as a blackboard, but this is more for simpler games or bodyless/constrained specific planners. A map would be more dynamic, but a little slower and heavier in bytes (but that shouldn't matter with 20-40 NPC's)
Code: Select all
Structure blackboard
ActorId.q ; can also be for DB / rowid "self"
NameId.s ; "Wood cutter ant #123"
EntityNumber.i ; current entity number
Tag.s ; "Moving to xyz"
Hungry.b
Freezing.b
Burning.b
HealthPoints.b
EnemiesNearby.b
HasWeapon.b
IsAlive.b
FriendliesNearby.b
; ... you must know ahead
inventory.w[64] ; 64 slots low byte = amount, hi byte = material types (0=bottle of air, 1=bottle water, ... 77 = charcoal .. 99=wood)
*MoreBrain ; friend/foe lists, list of memorized events (you stepped on my feet in 1978 at x,y,z coordinates and I haven't forgiven you)
*Waypoints
EndStructure
Actor Model - you might look into the actor model. Each "object" including the game program are "actors" (aka agents) and can send and receive messages. This makes it possible to let them run asynchronously or in threads, make them exchange messages without causing blocking. Using the actor model you could simply broadcast events to local objects or subscriber groups. One NPC can call the other for help, warn, barter, hear foot steps etc. Also basing everything (!) on the actor model and messaging could make it much easier to make a network-able game. I haven't entirely tried out yet, just like with most of what I write.
https://youtu.be/7erJ1DV_Tlo?t=51
(it's generally better to poll from a message queue than to push "interrupt" messages on a blocking actor who could DDOS - you can carry events over multiple frames without slowing the general game mechanics down)
Path-finding and navigation - planning routes and avoiding obstacles will be of growing importance as NPC's get smarter and the world gets richer and bigger. There are also third party libraries but they mostly come as OOP c++ interfaces; nevertheless many things can "easily" be done in PureBasic, too.
Spatial/environment DB - octrees, quadtrees, cells, hashmaps, sparse fields - to quickly find things that are near, the closest gas station, or the bathroom in case of an emergency.
State Trees/Behavior Trees - I would save the behavior trees for the finale. There are multiple also free editors for behavior trees. But many complain about the trees growing big, and debugging may be more difficult. State machines can get too complicated early. Both are not perfect for AI, but may be used by AI. "Smart objects" are often implemented as behavior trees; it's the Coke that made you drink it, really!
GOAP - Goal oriented action planning seems to be the easier alternative to creating complex behavior trees and complex state machines, and simpler than a big multi agent planner like PDDL and the newer things - "it doesn't need parameters" and you only need a blackboard and good helper functions (path finding, environment scan). But writing the planner might be challenging, as it should often/permanently run in background and check for alternate plans or situational changes (e.g. you wanted to go shop for groceries but found an apple in the kitchen, now you are not hungry anymore, and the "problem: hungry=80; goal: hungry=<20" plan can be checked. This is for the single NPC on his own.
STRIPS - if GOAP is not the right things the next best could be STRIPS, the predecessor of PDDL. It's simpler to process but has less features. Also you may just re-invent your own "language" or features based on the older "standard". This should make it easier for two agents to work together to reach a goal, but it should be slower and more complicated when running than GOAP (because more checks are done). This would be for a group leader NPC/city planner mainframe kind of AI usage.
https://en.wikipedia.org/wiki/Stanford_ ... lem_Solver (scroll down for example problem/goal files)
With a planner and path finder you can create agents/NPC's that could build their entire own city, and start doing incredible things.
At some level if you want to use behavior trees or just the state machines you will probably need a little "eval" function or "scripting" to do simple things like "if health<10 then return true else return false end", if you want to change & check for conditions dynamically and also allow some basic "modding" you will probably need a scripting language. This time I would chose python dll (or .so) without the 100s of libraries over Lua because at the moment I believe it to be more robust and easier portable (if the game has to run on all platforms).
That would be enough "help" for now - it's not an order list
