Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!

1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


Member Since 21 Aug 2004
Offline Last Active Today, 07:14 PM

#5235625 Game entity system: Interactions between Lua and C++

Posted by Roots on 19 June 2015 - 12:44 AM

The RPG I'm working on uses a custom C++ engine and Lua for scripting. It's open source, well commented, and has a decent amount of documentation, so maybe you could snoop around what we've done there and get some ideas.


I've been thinking about putting a video together on our youtube channel to explain how the map exploration code in the game works and how you build a script with it, but unfortunately won't get around to that until next month at the earliest. Here's some general designs that we've implemented.



First, we use Luabind to connect our C++ and Lua code. Luabind allows us to specify which classes and functions we want to be available within our Lua files. Most of the code that processes what happens on a map happens on the C++ side (or Lua calling into the C++ functions). For example, path-finding, animations, and drawing all happen in C++. The things that happen in Lua for a map are some large functions that populate the map with sprites, objects (like treasures), zones (defined areas of the map used for different purposes), and events (things that happen on a map). Lua will also have a number of small custom functions to do specialized things that we need, for example shaking the screen during an earthquake scene, moving the camera to a different location, or telling a sprite to move to a specific destination.


Most of the class objects we create in Lua we send a call to the corresponding manager class in C++ to handle that object. So every sprite we create is sent to a sprite manager, for instance, so that the sprite manager can figure out which sprites need to be updated, drawn to the screen, and handle collision detection between sprites. When we do this, we also tell C++ "I created this object in memory. I'm now giving it to you with the responsibility of destroying it when you are done". This isn't something you have to do, but it helps us to keep all object destruction contained in a single place rather than rely on Lua's garbage collector. (We use special arguments in our Luabind binding code to make this happen).


Now one thing I want to describe in detail is our event management system. Our maps all have an event manager, which holds event objects of various types. You may have an event that moves a sprite to a destination, an event to display a dialogue between characters, an event that causes a battle to occur, an event that plays an audio file, and so on. We also have custom events that contain pointers to Lua functions to run. Events can be chained together so that after one event finishes, another will begin automatically. This is useful for sequences where we want to have several things happen one right after another. You can specify how long to wait after an event finishes before the next one to begin, or you can start another event at the same time that the current event begins. Every event has two functions: a "Start" function that runs when the event begins, and an "Update" function that updates the event as necessary, and returns true when the event is finished. So a sprite move event would specify the desired location for the sprite in "Start" and the "Update" function wouldn't return true until the sprite reaches that destination. This is a simple system that offers great flexibility, which is what you need to build maps that are interesting.


The image below hopefully helps illustrate this idea of event chaining. We use Lua code to setup an event chain and to check for the conditions when an event chain should begin (for example, when a sprite walks into a certain area of the map). Lua tells the event manager to start the first event in the chain, and from there the C++ code handles the rest, processing each event until the sequence is complete (or processing it infinitely if there's a loop in the event chain).





I know that's a lot of ideas and words I'm throwing around, but hopefully some of what I said makes sense and helps you get a better idea of how C++ and Lua can co-exist. This was one of the most difficult problems for me to figure out myself, so my best advice to you is to experiment and figure out what works best for your situation. Maybe it's something like we've done, or maybe it's something entirely different. There's really not a right or wrong answer to how to mix Lua and C++ together.

#5229934 A whole lot of constants.... good or terrible? :/ (c++)

Posted by Roots on 19 May 2015 - 06:08 PM

Magic numbers... You mean numbers that change a lot?


No. Magic numbers mean random values that appear in the code without any apparent meaning. For example:

for (int i = 0; i < 67; ++i) {
    // do something...

What is 67 (the "magic number") supposed to represent? It's not obvious and makes for code of poorer quality (and more bugs potentially). Instead you should be doing something like this:

// Line below done from another file or class
const int MAX_FRAME_RATE = 67;

for (int i = 0; i < MAX_FRAME_RATE; ++i) {
     // do something...

You might think it's just a minor improvement, but it's a pretty big fucking deal. Especially when you're dealing with a code base with hundreds of thousands of lines and magic numbers popping up everywhere.

#5229767 How To Do RPG Interiors

Posted by Roots on 18 May 2015 - 11:24 PM

The problem of basements and second floors will be a tough one though, I'll hit it head-on and be back when I find an obstacle!


I made a video of our map editor earlier this year where I explain how we do something like that. Here's a link to where I being discussing that (5:55 mark). I talk about it until around 6:45 or so.




Essentially the way we handle interiors, basements, etc. is the following:

  • Each map contains a number of "contexts". For a town the base/default context is typically the exterior of the town.
  • We create a separate context for each unique "view" of the map. In the video, I have two more contexts: one representing the inside of the house, and one representing the basement
  • In the map script, I specify areas of the map called transition zones, which when the sprite pointed to by the camera walks over, the view switches from one context to another
  • In the video, the transition zones would be at the front door (switching from exterior <-> interior) and the stairs (switching from interior <-> basement)


So when I go in the door, I switch the tiles representing the outside of the house to those of the inside. When I walk on the stairs, those tiles are changed a second time to show the basement area. It's pretty nice. You can specify how any tile on the map changes in one context or another. So if I want to show portions of the "outside" context that are close to the windows of a house when inside, I'm able to do that.



Hope that gives you some ideas. All the code for my game and editor are open source too, by the way (C++ is the primary language). If you're interested in taking a look, I can point you in the right direction to where this functionality happens. Just let me know.

#5229516 How To Do RPG Interiors

Posted by Roots on 17 May 2015 - 07:18 PM

In my opinion SiCrane is right. If it is an small area with a few floors, I would prefer the transparency. It is annoying (for me) to get into another zone, just to get one item or talk to an unimportant person. Additionally you could leave and enter the area easily and if you are in the wrong house you just walk out there. With transitions this is just annoying.
But if there is an unique looking house with lots of floors (like an hotel or labyrinth) you should use another zone.


Agreed. Players want to explore the map, not sit through the same transition effect over and over as you walk from one room to the next. I would only do a transition between maps/levels (eg, from a town to a forest).



There's one thing you have to consider though. If you do the transparent roof option, you're going to need to make your houses much bigger than they otherwise could be. Consider a game like FFVI where you had nice looking towns with very small houses:




Once you walk in those doors, the interiors are much larger because they are essentially their own map. You can't make a 3x3 tile house work if you go the transparent roof option. Its something I never really thought about until I started working on my own game that did this, and realized that medium-sized houses pretty much take up an entire screen worth of space.

#5228970 I'm having trouble attracting contributors to my project as it gets older

Posted by Roots on 14 May 2015 - 08:55 AM

Oh, I would love it if I could find someone that would do that. I'd actually prefer to give Mercurial a try over git though, as they both offer pretty much the same thing, but Mercurial is a little more user friendly. I've worked on projects on github and was tearing my hair out sometimes with trying to resolve conflicts during branch merging, etc. A lot of our developers come from backgrounds that don't use git, and I don't want their initial experience to be a frustrating one as they try to learn how to use this tool.

#5228875 I'm having trouble attracting contributors to my project as it gets older

Posted by Roots on 13 May 2015 - 06:24 PM

So after taking in everyone's feedback and looking at where things stand, here's the course I've decided on.


Rebuilding a Team

  1. Continue working solo for now. Get a development release out that people can play. Upload a playthrough video showing it in action so people don't even have to install it to see it in action.
  2. Update the website to better explain the product, its major features, and design goals. Sell it to the audience to get them interested and excited about playing it.
  3. Once the previous steps are complete, try recruiting once more. Include latest gameplay videos and a link to the section on the site explaining the product in more detail. Explain that we're seeking people passionate about this type of game that want to contribute their ideas and talents to building it.


Project Status

  1. Depending on the size of the team and ability to complete work in a timely manner, cut extra features as necessary and where it makes sense to. We can't keep having such ambitious goals for a project if we don't have the resources to complete them in a matter of months.
  2. Set a finishing point for the project that is much closer than originally planned (a few hours of game content as opposed to 40+ hours). Make that the current "long-term goal" and don't worry about anything beyond that.
  3. After reaching the end goal, re-evaluate the project status, team status, and desire to continue. At that point figure out whether the project should continue or if it should be marked as complete.

Other Ideas

  1. Consider a "soft reboot" of the project. Bring in a new team of enthusiastic people and explain to them what assets, technology, and story currently exists. Start from scratch, making a game that this new team is interested in while reusing as much of the old work as we can.
  2. I forgot to mention it earlier, but there's a fork of our project called Valyria Tear. I've been a contributor to that project throughout the couple of years it has existed. Maybe if things don't work out with this project, I could just continue my work over there instead. They've seen a lot of great progress (and a full release) in the last few months.



Thanks again for your input, everyone. I feel much better (and perhaps more realistic) about the next steps to take moving forward.

#5228873 I'm having trouble attracting contributors to my project as it gets older

Posted by Roots on 13 May 2015 - 06:05 PM

Thanks for your comments, everyone. I've read them all, agree with most, and have done some thinking. I've got a lot to respond to, so I'm going to give succinct responses.



If you want to create a game by a team  you need to be really fast at finishing it, until time will disintegrate the team.

A lesson I've surely learned now, and wish I knew sooner. The biggest mistake that our initial team made was diving head first into a large and complex project with zero prior experience. Hence why the first couple of years were really a learning experience.



From the point of view of an artist, they want their work to be enjoyed by a lot of players. They want recognition.

I fully agree, and this is something we learned a few years back. Artists are generally not inclined to checkout the code and compile/build the game themselves to see their work in action. We started producing more internal screenshots and releases so that non-technical people on our team could see the progress, but it was too little too late I"m afraid. Right now, the project is in the best position that it's ever been for artists to see their work enjoyed by others.



From my perspective it kinda sounds like what you want is not contributors, but friends to work on the project with you in your collective off-time.

Exactly. I want people who love this type of game (a 2D JRPG with an interesting story and solid gameplay) and are passionate about beinga member of the creative process to build one. I tried to get people who joined to take ownership of the project and have them share their ideas, rather than being the one who always dictated what we should build and what we should do. It worked with some people, others preferred to remain more aloof and just get assigned things to do. Maybe I should use that sort of language in my recruitment posts.



I took a look at your project's forum and it's the very definition of dead.

Yup. I wish there were people active there because I like to post a lot and share my ideas and plans with others as a kind of sounding board. There are some people that still drop by our IRC channel occasionally and chat, but that's about it. I was hoping that posting more to the forum myself would entice others to do so, but there's really no one to read/respond to new posts.



Are you sure this isn't just an excuse to "have a life" and "watch the occasional TV show"?

I wasn't meaning to use "I'm busy" as an excuse. I've been much, much busier in my life and still made more time for this project then than I do now. I was pretty miserable during my workaholic years, and I don't want to fall back into that lifestyle. Ever. If I'm not having fun working on this project, there's no point in me continuing to work on it. I want to enjoy this process, even if it means it will take a long time.



But, how much of the original idea is left?

Actually, quite a lot. We've remained pretty darn true to the original design discussions we had with our initial team. And we've continued to follow our core design philosophies as we've worked out the details and built the game. Although the game has had a lot of features added on that increased development time, asset requirements, etc. I think one failure of this project (and myself as a team leader) was allowing this kind of bloat continue to pile on for things that we really did not need. (Example: we used to do random encounter battles, which are really easy, but now we have enemy sprites roam around the map and chase after the player character, who can use a stamina meter to try and outrun them).



It looks as if the project needs a reboot.

I was thinking something along the lines of this. What I was imagining was forming an entirely new team and starting somewhat fresh. We'd still use the same code and assets and story, but we'd brainstorm about what kind of game we want to build with it. I thought of this because its hard to be enthusiastic about joining a project that pretty much has most of the core mechanics and gameplay nailed down that were decided by a group of people years ago who have long since parted ways with this project. So I've been wondering if I could roll with that sort of mindset, attract a new team of enthusiastic people and share what we have to work with, and see where we want to go from there.



Try a kick starter, get donations, etc.

This isn't a for-profit project. We're not trying to make any money from it, even donations. It's just a hobbyist project to use our talents to build a game for people to play. It's as simple as that. Hence one reason why this is such a long endeavor. If I could make this my full-time job, I would have. But its never been our intention to charge people for this. And I wouldn't feel comfortable starting to ask for money seeing as how many people have worked so hard on this project for nothing for so many years. Its not fair to them if someone makes money off of their work.



Let it go. Maybe have a final release as a goodbye and do something fresh. It could be another RPG or even a smaller minigame. The world's your oyster.

Definitely thought about this many times as well. I wouldn't let it go without having some form of final release. Probably a much shorter version of what the full game was intended to be (maybe a few hours of content). I have a clear stopping point in my mind of where the game could potentially end if it were to end pre-maturely. So once I get to that point, I'll re-evaluate whether it makes sense to continue going forward or to call it done.



The front page of the site tells me nothing about the project.

Yes! I realized this myself a couple months ago. Our website does not explain nor "sell" the idea of the product well at all. I want to improve this, but kept telling myself "if you're going to work on this project, work on the product". But I think this is important enough that I should spend some serious time working on our about page to explain what this game is and what makes it special.

#5228284 I'm having trouble attracting contributors to my project as it gets older

Posted by Roots on 10 May 2015 - 05:25 PM

I've been working on an open source RPG for a number of years [link]. In the first 3-4 years, finding help was never a problem for us. However, as our project has gotten older it has been more and more difficult to find people to help out. I made a post on our website recently explaining that this project has essentially become a 'one-man army' now because despite my efforts, I've failed utterly at recruiting others to join the project. I've tried recruiting from multiple different sites (including here, where the majority of our contributors have come from historically). I've tried making the on-boarding process as simple as possible. I've documented and organized all the information that someone new would need to know to get started. I've been sharing screenshots and videos of the latest progress I've been making.


I'm really running out of ideas here on what I can do to attract help. My next attempt is to publish a new development release, but it takes a long time when I have to do the work all by myself.



What would you suggest I do to attract contributors to this project again?

Keep in mind I'm working solo right now and don't have a lot of time to spare. So suggestions like "completely overhaul your website" just aren't going to happen. Some people have suggested that because we're not using the new popular services like GitHub, we're not going to attract help. While I'm not against migrating to a new hosting service or revisioning system, it seems odd to me that that would be the lone reason why I can't get any help. Plus I don't really consider doing things like this a priority right now when I'm working alone. I'd rather invest what little time I have in making progress on the title, not the services we use surrounding it.



Are people generally ageist against joining older projects?

I can totally understand why an older project might not be as attractive as a new one. Much of the vision in gameplay, artwork, and music has been more or less defined now. It's harder to put forth your ideas and have them considered if it requires a major redesign to implement them. And there's perhaps not as much excitement as there is for a newly birthed project. I just hope people realize that an established project has its own set of benefits. I find it ironic how so many people were willing to jump on my train when we were starting out. I was so ignorant and naive in those early days, but perhaps we all were then.

#5214346 Best way of handling Auto-tiling?

Posted by Roots on 03 March 2015 - 08:02 PM

We have had a little experience with it. Here's some old documentation on how we originally went about handling transition tiles in our title: [LINK].


While in theory this sounds nice, it was really a pain to implement and support it. We've pretty much thrown away all support for this sort of programmable transition tile. We achieve the same effect now by simply using multiple tile layers and having transparency in several of our tiles that do the blending. Adding support to our editor to automatically detect the proper transition tiles and enter it accordingly is not worth the effort for us (we are a very small team of unpaid hobbyists). Instead, we focused on making our editor easy to use in other areas and add in the extra tiles necessary into our tilesets to achieve nice looking transitions.


Here's a long-ish video I released recently of several major changes that I made to our editor. You can kind of get an idea of how we build maps using tilesets, layers, and a feature we call "map contexts". If you're not interested in watching the whole thing, I would skim around and take a look at the different things we can do with it.




My opinion is that custom support for transition tiles in your editor/game is "nice to have", but probably shouldn't be a high priority. There's likely much more important things you can invest your teams time in, and I don't think adding any fancy transition tiles will save you much time in map design (at least not for a game like ours). But take my opinion with a grain of salt, as I haven't worked extensively with this sort of technology myself.

#5210486 Very basic 2D RPG game

Posted by Roots on 13 February 2015 - 09:02 AM

Well typically 2D RPG maps are built using layers. A layer may contain either tiles or objects (sprites). Typically you don't want to have something like a house be an object, because such a large, static structure is better constructed using tiles (since you can change up the size and display of the house more easily that way). I'll give you a simplified explanation of the class modeling in my own RPG.


We have a class called MapMode which is the highest level class and implements the main loading, update and draw code. This class got really big in the past because there's so many different things it needs to do, so we decided to create some helper classes to it that are responsible for handling specific operations on the map. Two of these classes are called TileSupervisor, which manages everything having to do with tiles and tile layers, and the ObjectSupervisor, which manages all of the sprites and the map's collision grid. Naturally, our tile layers are managed by TileSupervisor while the object layers are managed by ObjectSupervisor. We can have any number of tile/object layers and their draw order can be arranged and re-arranged in any way we like, but for simplicity let's assume we'll always have 3 tile layers and 1 object layer.



Our map is built using several layers of tiles, where each layer is like a 2D array. The same tile image may be drawn in more than one location, so it's inefficient to store several copies of the images. The TileSupervisor class maintains a vector of tile images, and our layers are nothing more than integers that index into that vector to extract the desired image to draw. Now we could either create a 2D array for every tile, or we could create a single 2D array and store the layer information for all tiles in there. We went with the latter approach. The MapTile class is a very simple wrapper around a 1D vector. This vector contains the indexes into the tile images container for each tile layer. So if we wanted to draw a tile that was located at the X, Y position on the map for a layer Z, we would access the 2D array of MapTile objects, index the X, Y element of this array, extract the Zth element from the MapTile object, and use this integer to index into the tile images container to extract the image to draw.



Now let's talk about objects. We define a MapObject as an entity with an x, y position on the map that has a height and length property, indicating how large the object is. We also have other properties we can set for objects such as whether or not to draw the object if it is on the screen (visibility toggle). We have a base class called MapObject which is abstract and contains these common properties, as well as pure virtual functions for drawing and updating the object. We have a number of classes derive from MapObject to support different types of objects on a map.

  • PhysicalObject is a static object that does not move. A tree could be a physical object, for instance.
  • TreasureObject is derived from PhysicalObject and can be interacted with by the player to extract treasure contents.
  • VirtualSprite is a sprite (moving object) with no image. This serves both as a base class for other sprites, and can also be used as a map camera (our camera is always focused on a map object).
  • MapSprite implements NPCs and player-controlled sprites. They can have dialogs, be given movement commands, etc.
  • EnemySprite is derived from MapSprite and causes a battle to occur when it collides with the player controlled sprite.


The ObjectSupervisor maintains a vector of MapObjects for each object layer. When it's time to update the map, the code will go through and call the update function on every object to update their animations, change their position, perform collision detection, etc. To improve performance, we keep the objects in this container sorted based on their draw order (you want to draw objects on the screen from top to bottom). So when we call the draw function, we already have a draw-order sorted container of objects and can simply iterate through the container and draw each object that should be visible on the screen.




Hope that starts to get the gears moving in your head about how you can go about implementing tiles and objects and layers on a map. The map code for an RPG is probably the most complex piece of the game and it will take time and practice before things start to make sense. I didn't even get into other map aspects like dialogues, events, pathfinding, and so on. My project is reasonably well documented (certainly more so than most) and the code is open source, so you are welcome to study it and learn if you like.



Documents the design and structure of our map code. Somewhat incomplete, but covers the most important aspects.



Source code - main directory



Source code - map directory



You can also download it and run Doxygen on the source tree. This tool will build the API documentation and can also do things like construct class hierarchy diagrams to give you a better understanding of each piece of the code and how they all tie together. Again though, this is pretty complex and is definitely above the scope of what you're aiming to do with your project. Hope you find this information helpful.

#5210465 Very basic 2D RPG game

Posted by Roots on 13 February 2015 - 07:51 AM

FYI, even a simple 2D RPG is quite an ambitious project and not very suitable for a beginner IMO. I was in the same position as you ten years ago and went ahead anyway. I suggest making an extremely basic game first and build up from there. Start small and work your way up instead of trying to add everything you need all at once. For example, your milestones could be something like this.


  • A single map that you can walk around in.
  • Add NPCs that randomly walk around the map
  • Add dialogue to the NPCs
  • Add random enemy encounters (with a very simple battle system where all you can do is select "Attack")
  • Add a basic character management menu
  • Add a second map


And so on. I'll second KnolanCross that if you just want to make a RPG, use one of those tools he listed above. You may think that coding a simple 2D RPG isn't that difficult, but it is. My project is currently hovering around 250K lines of code that were written (and re-written) over many years. If you want to make an RPG from scratch, be prepared for the enormous amount of time and effort it will take.

#5210186 Modern game development/programming for a not-quite beginner?

Posted by Roots on 11 February 2015 - 09:47 PM

Maybe take a look at these courses:







They pretty much dive right in and you'll make simple clones of popular games like Asteroids. I think this would be a good way to both refresh yourself on the fundamentals of programming, get some experience making games again, and learn a popular new language in the process. I got about half of the first course a couple years ago to refresh myself on Python and I thought it was run very well.



C++ has evolved quite a bit, but as long as you still know how to do memory management and understand the basics of object oriented programming, it shouldn't be too difficult to pick up again. C# would more or less tie you to Windows. There's unofficial support to run the language on other systems, but I'm not sure about the effectiveness of writing C# applications for non-Windows systems.



If you're making a simple 2D clone to get some practice, using SDL or SMFL is a solid and reasonable choice. If you're planning to do anything really complex though, I would suggest using an existing game engine library instead of rolling your own.

#5209315 Should i use sdl or some higher level framework?

Posted by Roots on 07 February 2015 - 04:40 PM

Is your goal to make a game? Use an existing game engine. Is your goal to learn as much as possible? Use SDL and make your own (simple) engine.



It's not quite as simple as that, I'm afraid. But in a lot of cases that's what it boils down to. Ten years ago I, being incredibly ignorant, decided to use SDL and make my own engine. I learned a ton from the process, but I paid dearly because it took a long, long time (several years) until we had a useful and stable engine that could do what we needed it to. My project would be years forward ahead of where it is if we used an existing engine.

#5209313 Looking for critique on my new RPG forest theme...

Posted by Roots on 07 February 2015 - 04:12 PM

I pretty much second everything Elahrairah said. Thematically, I think you hit the nail on the head. But it does sound "too busy" as was said. I think maybe it could be improved if you added in some softer, less intense sections in the tune that perhaps focus on one or two instruments. That would also help feel like the song is going somewhere, instead of just making slight changes to the melody here and there. Overall though, I think this is pretty awesome work!

#5208090 SDL2 and Linux [RANT]

Posted by Roots on 01 February 2015 - 03:56 PM

I think it's a little silly to be angry about a product which was provided to you to use for free. I'd understand if you expressed disappointment instead of anger though.



Anyway, no SDL2 is not perfect. Neither is any other piece of software in the wild. Many people rave about it because it's one of the best solutions of it's kind. Since it is free/open source software, you have a few options. You can fix it yourself, wait for it to be fixed by someone else, or find another alternative that hopefully works out better for you. If it was commercial software, you would have fewer options than that (and less money). Just trying to bring some perspective to your situation. I use SDL as well and I have had issues with it similar to yours, but I stuck with it because it was the best alternative out there for us at the time and now it's so entrenched in our code now that to take it out would require a lot of work. I think you should take a look around and compare it with other solutions to see if you have any better luck with them.