Simple SP RPG

Hello everyone! This is a very basic RPG that I’ve thrown together over the past week. Prior to this and a few small prototype files to remember what I was doing, I have not touched blender in over 3 years so go easy :slight_smile:

As I try to show in the video, the basic FRAMEWORK to create a much larger scale game is there, it is very easy to add new weapons and enemies because all they need is the “rayobj” property with their name to technically work (including the prefab to pickup a weapon, it’s just the mesh with “rayobj -> itemname”.

I had really forgotten how enjoyable Python is to use, I am having a blast working on this.

So, here’s a quick rundown:
Menu system - Any mesh with property[rayobj] -> menu and atleast 1 property with “msg” in its name will trigger a menu when you press E and are within range. VERY basic, I had just thrown that together moments before the video was recorded, still needs input options but that’s a project for tomorrow. The menu code is shown the entire video if anyone is interested.

Animation object knows which weapon is equipped. As shown in the end of the video, they are not just “invisible children” to the player.

Item stats - range, damage, attack delay. Animation adjusts accordingly with delay.

Item pickup/swap - self explanatory. The tricky part was making the stats (attack speed, damage etc) persist through to the next level. Super easy to add new items to the world, just add a mesh with a property with the equipment name and it works, so long as the equipment in question actually exists in prefabs.

Armor system (not shown, still in progress, but it works in a basic form … thats what the random cube floating above scene1 is for)

Simple AI - No NEAR or RADAR sensors, it’s all handled by code and properties. Idle, alert (player is near), walk, and attack states/animations. I’ve mass-tested with 50 AI and there was no FPS decrease.

Spawn system - empty with simple spawn script to add enemies, change the property text to spawn a different object. Player is added in a similar way but there’s a quick check if stats exist already etc.

Multi-material objects - easy, seperated RGB channels with nodes and applied materials accordingly. This means multiple normal/specular maps per object work fine, just paint vertex R G B.

Persistent stats/player/etc - Everything relevant to the player persists no matter where you go in the world

Easily add new levels - I show this at the end. Technically all a level needs to work is the scriptInitializer object and a respawn point.

I probably missed some stuff, there’s so much small stuff I’ve been working on I tend to forget what’s already done :stuck_out_tongue:

Everything in the game is script handled, otherwise I’d have more gameplay to show off… polishing scripts takes time :slight_smile:

My end goal is a Morrowind inspired game.

Here’s the video
Textures are from Poliigon and models are created by myself and my cousin.
I really wanted to add “entry points” to the levels before I recorded (if you go back to an old level you’d spawn near the correct door) but I got lazy. It could’ve been done in the time I typed all this, just a quick variable check in the init script :frowning:

https://youtu.be/X1LQPR6jQxM

Hey, it looks great!
Quite simple but you’ve got everything working.
You might want to take a look at walkmeshes to try and give the enemies some better pathfinding.

Also it seems your framerate is pretty good, why don’t you increase the view distance a little bit?
If you have trouble the level of detail system can help to keep the game running smoothly with long draw distances.

Hey, thanks! Most of the work so far has been getting everything working to a satisfactory state (0 bugs, no glitchy animation transitions etc etc) now that most of the framework is atleast started, theoretically I could very quickly create more actual game content for myself to play through hundreds of times trying to fail-proof the scripting :slight_smile:

The biggest thing that irks me at the moment is that when you switch weapons they don’t line up properly in the game world (the weapon you place on the ground… notice how the sword in the video rotates opposite what you’d expect) … again, easy fix because it’s just a problem with the mesh orientation in edit mode, but it’s not fixable without hardcoding a 90 degree rotation into the item switch method, which doesn’t make sense to me.

Currently on my never-ending list of things to implement is AI pathfinding, which I’m thinking will use empty objects with a specific name and just index through them to find the next path location while in the idle state. That’s the great thing about how I set up the sceneInit script, I can create the list in there when the scene is first loaded (based on how many path objects there are), which will in-turn apply to every scene since they all use the same init script, and then parse it from the AI script… Everything is simple :slight_smile:

The problem with LOD is I don’t have access to a computer with lesser hardware to test on to see if it’s needed, so I aimed small hoping it’d be handled by weaker hardware. I tried to stay under 300 verts for complex models (swamp tree was difficult though, it’s nearly 3k thanks to Sapling and x1 un-subdivide) – However, it doesn’t hurt to overkill, so maybe LOD is a good idea.

Thanks for your input! Gives me a goal to work towards today instead of getting excited about every idea and making too many things, I’ll see if I can throw up some updates tonight on Youtube.

Sorry for rambling so much :o I get excited.

Hey,
I really like this, looks cool! I actually reall like the small draw distance, I think the fog makes it more atmospheric. Concerning no the trees, have you seen this?
http://www.thatimst3r.com/bge-plant-kingdom
It’s a pack of low poly plants made by ThaTimst3r which are made for the BGE. The trees are a lot more optimized than the high poly meshes that the sapling generator makes (Sapling is great, but I think it’s often too high poly for games)

For weapons I often have two different models, one set up for using in a rigged character and the other for placing on the ground as a pick up. That works well with items such as armor or other stuff like bow and arrows too since you can show it folded up or togetjer with the quiver of arrows on the ground.

I use the same one for both as the animation is controlled by an empty on the player. The weapon object just has to have “rayobj -> weapon” and “type -> weapon_name” properties for it to be considered a weapon, but if it has stat properties too it’ll update the player stats. In other news, I finished an inventory prototype tonight. Very simple with very simple graphics but it’s a start.


It auto-updates based on items you pick up, but I only have 4 that can be picked up at the moment (2 armor, 2 weapons). The sequence of events for that image were-
-Picked up iron armor
-Picked up spear
-Press I for inventory
-Click squares 1 and 2 (squares are placeholder graphics showing which items you have … no items = no squares)

Super simple code, just took a while to plan out.

Inventory handler code:

import bge

cont = bge.logic.getCurrentController()
own = cont.owner

if own.parent[“menu”] == True:
scene = bge.logic.getCurrentScene()
grid =
for child in own.children:
grid.append(child.name)
grid = sorted(grid)
inv = bge.logic.globalDict[“Inventory”]
for index in range(0,len(inv)):
square = scene.addObject(“gridSquare”, own.children[grid[index]], 200)
square[“description”] = scene.objectsInactive[inv[index]][“description”]
square.setParent(own.children[grid[index]])

Grid button code:

import bge

cont = bge.logic.getCurrentController()
own = cont.owner

mOver = cont.sensors[“mouseOver”]
mClick = cont.sensors[“mouseClick”]

if mOver.positive:
if mClick.positive:
print("YOU CLICKED: " + own.name)
for child in range(0,len(own.children)):
print(own.children[child][“description”])

Next step is to add a property to each item specifying which inventory icon to use and make it add the proper one. Simple, just takes time to make icons that I don’t want to deal with tonight.

How much will this rpg cost?

Free … can’t imagine charging anything for it, it’s not that great by any stretch of the imagination haha.

I would love to play it when it is done.Could we add more levels if we like?

Sure! You can even create some now if you’d like them to be added. The only requirement is that there is an empty with the name “Respawn” where the player will spawn (numbers are fine too, code just looks for that name). To make items able to be picked up just give them a string property named “rayobj” and the current tags are [weapon, armor] and another property named “type” with the string value of the item to be picked up - So if your weapon object is named “scimitar” make sure “type” says “scimitar”. If you are going to make something, either leave the map untextured or use texture paint to assign the textures … green is grass, red is clay, blue is rock - because I have a node setup that looks for R G B values to assign materials. Prefabs in the scene can have textures though, only the terrain and water currently looks for RGB.

I attached a screenshot to help with item pickups. Thanks for the interest!


Preview of the new enemy I did today… swamp wraiths! This was the first real test of the framework because I have not added anything major prior to writing most of the code… glad to see it worked flawlessly :slight_smile:


In the process of experimenting with multiplayer using a server we wrote in Rust. Will update how it goes!

Biggest roadblocks are:
-AI are currently local to the client, so have to redo a bunch of code to make the client manage them based on server commands (location, ai state, etc are stored on the server now) as well as spawn them via server command.
-Pathing will have to be done on the server to make both players 100% in sync as far as where NPCs are.
-Collision detection is handled client-side but server needs to be able to figure some stuff out so stuff never shares the same collision position.
-Damage will need to be calculated client-side but sent to the server, server will handle death etc… if AI dies, send a message back saying to end the AI.

Using Json for data, so far it’s working very nicely.

Fairly easy stuff, just takes time to actually code it.

Server-client connection currently works 100% and is threaded with exception handlers.

Are you going to have a websight for the sp rpg videogame?

Yes, it will most likely be available for download but there is still alot to be done.

Today I got server spawns working 100% as well as movement (server ignores Z axis and only moves in small increments using UDP … blender detects the small movements and moves AI along its Z axis just as it should) … end result, smooth movement but slightly “laggy” due to server refresh rate (which could be increased, still experimenting!) all important server actions are done with TCP … goes something like this.

-Client starts game
-Server detects client
-Server sends client all current spawned object list including health, stats, position, etc
-Client batch-processes server commands … more on this below!
-Server updates client with batch commands, which is extremely fast.

So… batch commands? I set the client up to receive a long array of JSON data from the server (infinite number of commands in 1 array) and then a separate thread will parse each command, pop it out of the array, and move to the next command. Individual object data is manipulated in blender by adding it to a dictionary with a unique ID assigned by the server for each object which is included in every command (example … racoon AI is named 4392034a460g, server tells object 4392034a460g to move to a new position, or it was killed, attacking, etc)

So then I ran into the problem of what happens when an AI collides with something in the client? Now the server position and client position are out of sync for a brief moment… Well, my obsessive nature kicked in and I had to solve that! My solution was to have collision boxes (a 1x1x1 cube scaled around the object) and export the vertex positions of said box to a text file which is read by the server to tell it where AI cannot go. This script only needs to be run once each time something new is added to the map or something is moved.




I will try to post a video of the server/client in action tomorrow when it’s functional enough to show :slight_smile: currently the code is very messy because the server doesn’t send as a dict… it sends as an array of dicts within arrays due to how JSON exports by default, but that will be fixed in the morning.

Yes, it will most likely be available for download but there is still alot to be done.

Today I got server spawns working 100% as well as movement (server ignores Z axis and only moves in small increments using UDP … blender detects the small movements and moves AI along its Z axis just as it should) … end result, smooth movement but slightly “laggy” due to server refresh rate (which could be increased, still experimenting!) all important server actions are done with TCP … goes something like this.

-Client starts game
-Server detects client
-Server sends client all current spawned object list including health, stats, position, etc
-Client batch-processes server commands … more on this below!
-Server updates client with batch commands, which is extremely fast.

So… batch commands? I set the client up to receive a long array of JSON data from the server (infinite number of commands in 1 array) and then a separate thread will parse each command, pop it out of the array, and move to the next command. Individual object data is manipulated in blender by adding it to a dictionary with a unique ID assigned by the server for each object which is included in every command (example … racoon AI is named 4392034a460g, server tells object 4392034a460g to move to a new position, or it was killed, attacking, etc)

So then I ran into the problem of what happens when an AI collides with something in the client? Now the server position and client position are out of sync for a brief moment… Well, my obsessive nature kicked in and I had to solve that! My solution was to create a collision map script to export mesh vertex coords for the server. Exports as JSON and I made a quick visualizer “game” to confirm it was accurate. Now I have complete control server-side where things are allowed to move.



Cool i like it. :slight_smile:

Props = object.getPropertyNames()
list=[]
for prop in Props:
     list.append([prop , object[prop] ])


besides what icon to show it’s also a good idea to grab all properties out of the item when placing it in the inventory,

also a ‘type’ property can help sort out what info to grab from the properties to display in the inventory. (weapon stats etc)

when adding a object back to the main scene from inventory loop through and place all the properties into the new object :slight_smile:

really handy for things that have charges / ammo or even weapon mods/slots.

Thanks :slight_smile: all the item data is going to be handled by the server now though, all the inventory should need to do is request the data from the player’s ID and display it appropriately. I have a full backup from the last thing I did before I implemented connection capability but I am in the process of re-doing all of the code to work with the server on the copy.

ahh, in my game (single player at the moment) the inventory is stored in the actor gameobject as a list

When they open the inventory it builds a representation they can manipulate, and closing the inventory applies all the changes to the inventory state.(equip / drop / shuffle slots etc)

I have not really worked with client/server stuff yet :slight_smile:

That’s similar to what I have currently, except its stored in a globalDict entry so it can persist when you change scenes. I just used empties connected to a master empty to say where things can go… It’s a bit rough because I don’t believe in searching google for “how to make an inventory in bge” I prefer to come up with the ideas myself even if someone else has done it before … makes it fun :slight_smile: