2
\$\begingroup\$

I'm having a very hard time trying to figure out a good way to add new resources to my game project in a way that's convenient for designers.

To try and better understand the problem, I'm trying to create a very simple game. It's in the style of an old text adventure. The user begins in a room, and at the start of each turn an image of the room is displayed and some text describing the room is printed. Then several options are shown (in a multiple choice format). The user picks one and option and the result of the action is printed to the screen. Then the turn ends and the next turn begins (the new image and description are shown, more options are printed, etc).

This game will require several resources: - String tables (to hold the text) - Images (Shown in each room) - Places (links to the image and description, as well as the list of options) - New Game Scenerio (used to initialize game. Just tells the user where the starting room is)

I would like to create an editor where designers can just start it up and then start adding and editing rooms.

The straight forward approach would be to create a simple, stand alone editor that can load and save independent Place files. It would use relative file paths to locate the linked images and string tables. These Place file format would be XML which would later be compiled to a binary form when the final resource archive containing all resources is compiled.

The trouble with using paths, though, is that if you rename and move files (as you likely will as the project get larger), the paths that point to it will break (at well as any relative paths it points to itself).

Relative paths can also be a problem if you need to refer to resources that are in a completely different branch off the root. For example, let's say I have the following resources in my project:

/item/MagicWand.xml /place/grassyPlain/castle/DarkTower.xml

If I want to place a MagicWand in my DarkTower, I'd have to use a relative path that looks something like "../../../item/MagicWand.xml". That's pretty cumbersome. It would be nicer to use something like "item.MagicWand".

Also, since these resources are going to be compiled, if I need to refer to them from my scripts I will need something to call them. If my user is in the DarkTower and selects the option "go to the griffon pen", I'm like to be able to do this with code similar to

getUser().setLocation("place.grassyPlain.castle.GriffonPen");

All this suggests importing my resources into some sort of super editor project that knows how to handle all resources and provides names for them (and even provide interactive editors for some of them). While this would simplify the naming problem, but would be a lot of work - especially if more than one person need to design resources at the same time. (for multiple users, I'd need a database-like locking mechanism to make sure multiple people weren't renaming things or working on the same file at the same time). The whole thing would have a look and feel that calls to mind the Flash editor.

My thinking keeps leaning toward this super-duper editor solution, since I've been exposed to tools like this before. However, this seems like a lot of work, especially for so simple a project. I can't help but think that I'm over thinking this. I would like to have a system for managing my game's resource that is simple yet, flexible and which integrates well with my code/scripts.

Does anyone have any thought on what makes a good resource managment/naming system?

\$\endgroup\$
3
\$\begingroup\$

I believe creating this super editor will distract you from your true goal, to create a game. From the sound of it the editor will be more difficult to create than the actual game.
Furthermore I don't believe you need such a tool for your project.

An easy way to approach this is by breaking all different resources the game needs into categories and create a different directory for each resource.
Then create a simple system to locate each resource based on its category.

resourceManager.Root = "/Reources";
resourceManager.Items = "/Items";
resourceManager.Places = "/Places";


resourceManager.GetItem("wand"); //located within Reources/Items
resourceManager.GetPlace("castle/DarkTower"); //located within Reources/Places/castle

This resourceManager can be initialized with the paths to each category and even have a specialized way to load up its resource. For instance, when you load a place it will parse an xml file and the load up all items this place may have.

If for any reason you need to change the path to any category you will need to change only a single path.

\$\endgroup\$
1
\$\begingroup\$

Building tools to aid in the development and management of content is an excellent idea. However, it costs quite a bit of time and energy, so you need to weigh those costs carefully against the needs of your project (and potential future projects which would use the same technology platform) and decide if it's going to be worth the investment or not.

Tools allow you to create abstractions that allow your game assets to be interpreted by two (often quite different) world views: that of the programmer consuming the resources in the game engine, and that of the designers producing those assets.

Renaming

For example, in an ideal world, you'd refer internally (that is, in code) to resources by a fixed identifier that will never change regardless of what you do to the resource (for example, a UUID). When assets are referred to by name, renaming or moving an assets correctly involves finding all existing references to that asset and update them. This can be quite slow, and cause quite a few problems (especially in larger teams). But using UUIDs sidesteps that problem entirely. You can move and rename assets all day long, and since the relationships between them are established via identifiers that never change, there's no problem.

Of course, UUIDs are ugly and cumbersome to remember and talk about. Thus, you build content management tools that expose primarily the names of assets, allowing designers to reason about assets by name, but which internally maintain the links between assets by GUID.

You can build anything along the sliding scale of that abstraction: you can have no tools, have designers hand-edit XML files and manually deal with UUIDs; you can build a complete toolchain for them that deals with everything; or you can do something in between.

For example, you can refer to everything by name, eschew UUIDs, and provide a much simpler tool that does assists in renaming or moving assets when needed (handling all the fixups, et cetera). This involves much less effort and investment and solves a good percentage of the serious problems involved with reference-by-name systems.

Collaboration

There are similarly two simple solutions for dealing with the collaboration problem you mentioned: either use exclusive editing... "locking," which you mentioned, which you can define by policy -- if somebody has a file checked out, don't edit it -- or enforce via tools; in both cases the practicality of this approach is gated by whether or not your source control system exposes that notion. Distributed systems like Git do not, but systems like Perforce do. If your SCM doesn't do it you'd have to manually implement it, and that's a fair bit of investment alone right there.

You can also design the pipeline to support merging. You can either choose a text-based format that is suitable for manually merging (XML is possible to hand-merge, but it's not the best option, and it's easy to make mistakes), or you can build a system where your content data is actually transactional when stored (instead of "this value is five" you store "this value is changed to five") and built a merge system yourself using that transactional data. We did this at ArenaNet for Guild Wars 2, and it is the crux of how the game can ship such extensive content updates every two weeks.

This again is a choice along a sliding scale: the system built at ArenaNet is powerful and saves tons of time. But it also took a lot of time to implement (two full-time engineers over a few months). You will need to make hard choices about what problems you really need to fix and what problems you can live with based on the needs of your project and your available resources; it's quite possible your team is small enough you can solve the collaboration problem with zero engineering effort by just having everybody talk to eachother and coordinate work.

Tips

If you're going to go and invest in building a full-featured editor for your content, I'd strongly advise you to consider an approach where you don't hand-build every editor screen. It's a massive time sink; instead, consider an approach where you can generate the UI based on the properties of the object you are editing (much like the Windows Forms PropertyGrid does). This approach, combined with a simple extensibility system for plugging in editors for the very few types that might need special editor views, is much easier to develop and maintain. It's the basic premise we used at ArenaNet for our tools platform, and it saved man-years of engineering time.

You should also focus on doing the smallest, fastest thing that could work first. Create a minimum viable product and iterate on that towards a larger future goal: don't stop all other development for two months sinking time into some kind of crazy super editor. Always keep in mind what you actually have to accomplish for your project and what your actual available resources are. Make sure you are chasing after features and tools you need and not those that sound cool or sound useful.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.