51

(46 replies, posted in General)

Ok, I feel this limits the extensibility of the system though as it won't allow for using lua's more advanced features to make nicer/better/cleaner interfaces for plugins without shipping a plugin with a build for each platform, a header, and the entire lua interface in separate files to be dofile'd in the scene files. Especially for rapid prototyping, I think that's far too much hassle for potentially simple features.

If you're not happy with this kind of thing to be in Maratis, I guess I can quite easily make a plugin to replace MScript that includes an event system, so we can have an "advanced" interface if the plugin's used.

As a side note. I'll be on "holiday" for 3 weeks starting on Wednesday 3rd. I was going to pick up a little freelance work over the time, but I haven't had confirmation from work that they're happy with me doing so, and I don't want to upset the legal department. However, I will want to do some coding, so... if anyone has any requests, I might be able to get it done in the github mirror and ready for testing and to be (potentially) merged into the official repository if successful and relevant.

52

(46 replies, posted in General)

I had a quick attempt at this last night, but it occurred to me that any solution is going to be difficult and seem pretty hacked in. There is no real concept of a lua environment that I can add to because the lua_State gets cleared when you start a new scene. In the MScriptableBehaviour component I have sort of worked around this by (re)loading the relevant behaviour script whenever a behaviour of that type is created, which obviously has a number of issues.

I have come up with the following possible solutions:

1. Create an event system that you can subscribe to, so if you get an event of MEventScriptEnvironmentInit then you know to load the scripts at the right time
2. Be able to add to the environment by cacheing the scripts. This is probably the easiest solution, but would require to keep a local copy of all environment scripts in memory, or to write them to temporary files...
3. Use something like lua rings, which will allow multiple states to be active, so we could pretty much have the event system in lua, and the master (environment) state could set up a recreated slave (game) state.

Unfortunately, my "ideal" solution of having a clean environment state that we clone doesn't seem like an option, I haven't found any way of cloning a state (yet)

53

(46 replies, posted in General)

Well, what I would like in future is to be able to write lua scripts like this:

savefile = MSaveFile("somesave.file")
savefile:setInt("some.key", 12)
savefile:destroy()

or even to be able to serialise tables fully. To do this, it's possible to write the supporting code in C++, as you have with the vec3 code etc. but I feel that exposing this amount of stuff in the MScript interface would probably make it weaker. The alternative options are to either give MScript some lua string to parse (so, something like this would work script->Parse("-- some lua script\nprint(\"being printed from lua\")); ) or, alternatively, leave MScript as it is, and add to the Maratis "virtual filesystem" so that you can embed entire files, possibly as follows

extern const char* scriptData;
extern const int scriptSize;
//...
MEmbedFile(scriptData, scriptSize, "MSaveFile/MSaveFile.lua");

which would allow for MScript to become more abstract if people want to extend it later and add more language support, then more files could be embedded to support the relevant language support. the embedded files could then be opened "normally" by M_fopen. Obviously this is more work than just making an MScript::Parse but... I think overall a better solution

54

(46 replies, posted in General)

Thank you.

With regard to the embedded script stuff. What should you like to do? The easiest solution is to allow parsing of a lua string passed to MScript, but that technically could break the abstraction as it requires that MScript always deals with lua, and couldn't be extended to support other languages later. Personally I quite like the idea of allowing embedded files because it then lets us package small amounts of assets with plugins automatically

55

(46 replies, posted in General)

When using it in game (or from another plugin) it uses a macro to cast it. You still need the MSaveFile header to compile, but because it is pure virtual, it doesn't do any linking.

56

(46 replies, posted in General)

Update to github branch
1. Removed MSaveFile
2. Added more output on plugin load failure
3. Added MResource interface

Updates to MSaveFile
1. Added binary file support
2. Moved from Maratis to plugin
3. Implemented MResource interface
4. Lua integration
TODO for MSaveFile:
1. Unit tests
2. Extended lua integration
3. Hierarchical binary files

The lua integration is very straightforward, but I would also want to make a more "OOP-like" interface if possible. However without significantly extending MScript to allow exposing classes with something like luabind. The easier way to do it would be to do it in lua, but that would require either giving MScript a string of a lua "file" to load, or to extend the Maratis filesystem to allow named embedded files to be opened by M_fopen. So yes, still some work to do.

XML files are currently saved by breaking down a key such as "some.random.key" into hierarchical elements, but the binary files are saved with entirely flat paths, which I'd like to change, and that would mean I'd probably need to add file versioning also.

That's all for now smile

Edit: Updated to have a very basic lua interface

57

(46 replies, posted in General)

I've been wrestling with this a little. There is an issue with the plugin system currently. It works great for standalone plugins but if you want to reference them from the game plugin, you have to link against it... but you don't want to use dynamic linking because MPlugin is loading it manually anyway.

The issue is factory functions. I can't find a nice way to call, say MSaveFile::getNew within the game plugin, because it clearly needs to resolve it.

I have an idea, but I'm not sure whether I like it. There could be a base object type:

class MResource
{
public:
    typedef MResource*(objectFactory)();
    static MResource* getNew(const char* type);
    static void addFactory(objectFactory factory);
};

then we can do something like this in the plugin header:

#define MSaveFileGetNew(save, file, mode) \
{\
    save = (MSaveFile*)MResource::getNew("MSaveFile");\
    save->load(file, mode); \
}

and use it

MSaveFile* save = NULL;
MSaveFileGetNew(save, "someFile.sav", M_SAVE_FILE_BINARY);
if(save)
{
//...

Edit: renaming badly named example to what  implemented

58

(46 replies, posted in General)

I think there needs to be a further discussion then before MSaveFile is accepted into the official repository. If you don't see it as a core engine component, then it shouldn't be added. I think it would be a useful thing to have it available for Maratis as standard in some form, so I think we should try to find an agreeable solution. The options I think are:

1. Build it into Maratis/MSDK. The benefits here are that it's easy to integrate with lua, it's available both for game code and editor variables, and also, it's already done. The issues with it are that it is an enforced component in all projects, whether you need it or not.

2. Create it as a plugin. The only real benefit I see in this over #1 is that you can choose whether or not to have the support in your project. The disadvantage is that the editor can no longer access it as it isn't a general solution.*

3. Create it as a static lib. This is a pretty nice all-round solution. It can be linked into the editor executable and any plugins that need it, but the problem is that, for one, it creates extra complexity (having external static lib dependencies for plugins) and that it's no longer possible to easily expose save file functionality to lua without creating a plugin.

* Editor-specific plugins _should_ be a thing. I have intended to add them, but I haven't got around to it yet. But even that wouldn't solve this problem because you would then have two (identical?) plugins for a project that needs save data, which could cause confusion both for users, and for code compatiability (editor plugin is old version, project one is newer)

Anyway, as I said, I'm happy to go with whatever you want for this, but I think it needs a little further discussion regarding what is the best solution.

59

(46 replies, posted in General)

I'm well aware that a full time job can leave with you with no time (oh, very very aware) the reason behind the github fork, as I said was so that potentially "we", the community can try to work on the engine and then when the fixes are stable enough and got your approval, they can be merged up. I don't think anyone is complaining about anything here smile

I've already had a couple of "bugs" about the plugin system, such as com3D's one where I'm just checking for *.so*/*.dll*/*.dylib* which I think should probably be fixed before I submit it, but that's pretty minor.

With regards to making a plugin for MSaveFile, I can easily do that, but that means that we lose the ability to have editor savedata/preferences, unless I keep MSaveFile in MCore but move MSaveFileImpl to a plugin, but at the same time, that means that we have to have the plugin available both on an editor level (currently, I don't load editor plugins at all... so...)

I definitely agree with an overhaul of MGui because it's currently a bit difficult to extend the editor interface at all. But I think this is perfect for a separate thread.

60

(46 replies, posted in General)

Just a small update that I've been playing about a bit the last few days on my commute, I present to you:

MSaveFile!

I will admit to have been "inspired" by Unity's PlayerPrefs system a little. At the moment it only reads/writes text files (XML) but I'm part way through adding some very basic binary file support. After that's done (maybe by the weekend) I will probably add some lua hooks in for save data.

For now, you can do as follows:

MSaveFile* save = MEngine::getInstance()->getNewSaveFile("path/to/save/file", M_SAVE_FILE_MODE_TEXT);

save->setString("some.key", "value");
save->setInt("some.other.key", 1);
save->setFloat("yet.another.key", 12.55f);

char testStr[256];
save->getString("some.key", testStr);
int testInt;
save->getInt("some.other.key", &testInt);
float testFloat;
save->getFloat("yet.another.key", &testFloat);

save->destroy();

The class is pretty much an RIIA object, so it will load on construction and save on destruction, you can also call save/load manually if required. When the binary mode is added, it will be pretty much seamless. If you specify binary, but it loads text, when it saves again, it will convert it to binary and similarly the other way around. You can also specify M_SAVE_FILE_MODE_ANY and it will default to whatever it reads in, or binary if making a new file.

This can then be used internally for Maratis Editor to save preferences, such as the last opened project directory. I haven't done this yet... if anyone were to send me a pull request with this added, I would definitely appreciate it *hint hint* tongue

Anyway, let me know what you think.

Anaël, could we at some point discuss about potentially merging some of these changes back into the official repository? I would very much like it if we could continue to maintain this "community" Maratis branch and then I/you/someone could merge back changes that would be suitable for the official repo.

61

(46 replies, posted in General)

Oh. Yes, I'm just checking for .so (/.dll/.dylib) I didn't think that I should make sure that there wasn't anything after it. I'll fix this.

The current Maratis lua API references objects by their pointer, and behaviours by their index within the object. At the moment all you can do with the behaviour ID is call {get,set}BehaviourVariable, which, as it's the current behaviour, is pretty pointless, even if the variables were to work. Basically, the reason I added it anyway was that it would then make it easier to build a more robust behaviour system in lua on top of it where you can reference behaviours on an object by name.

I'll have to think about the deactivation. I don't think there's currently a way without making an Active variable which update respects

62

(46 replies, posted in General)

That's fine com3D. Which plugin was causing the problem?

com3D wrote:

With an onBegin function and ability to set variables in the editor it will be a perfect tool.

I did have a sample for the editor-lua variables but it was never finished and in my infinite wisdom, I deleted it. The main problem is that MVariable expects variables with the lifetime of the MBehavior, if I pull values from lua, the lua state manages their lifetime and will clean up the returned values shortly after they're returned (I believe) The only way I can think of getting around this is to load all the variables from lua on the first update and store them within the C++ class, and then every update pump the values to/from lua. The only problem is, if both the lua and the C++ side changes, which one takes precedence?

I know I can get around this by pushing a load of lua code to handle checking in... but I am not embedding any lua (yet) and I don't want to say "you can use this plugin, but you first need to add these huge lua scripts to get it to work" because that will remove from the simplicity.

The variables are definitely on the todo list, and pretty high, I just need to work out the best method of doing so.

As for onBegin. That's not a problem at all, while I'm at it, are there any other callbacks you'd be interested in?

63

(46 replies, posted in General)

com3D wrote:

Hey Nistur,

Very exciting stuff.

However, there seems to be a compatibility issue with regular Maratis.
Jules demo crashes the editor at loading, maybe due to the behaviors.

Cheers,

Edit: the bug is in the fork, not the plugin

I will take a look at this quickly Thanks for letting me know

Sponk wrote:

Nistur: You actually can change the theme. Just change the 'default.theme' file in the 'gui' directory and you should be fine.

Yes, I'm just thinking of serialising the current editor theme to a config file though. Then even without a GUI selector, people can (relatively) easily change the config without renaming files the whole time. (Plus this means that you could store the last loaded project directory for the file browser in the config file... which would make re-opening projects SO much easier)

64

(46 replies, posted in General)

Update!

I've updated the github mirror to r203 from svn, and I've also made some more minor changes:

1. I extended MScriptContext::callFunction to be able to take functions within lua tables (so you can call, for example, player.update)
2. I added optional userdata to the registration of MBehavior factories. The reason for this is that you can then use one base class with different options (see #4)
3. I added MScriptContext::addScript which is pretty much the same as MScriptContext::runScript but only will load the script if the state has already been created, and won't clear the state, or do anything if it fails.
4. I made a plugin. It is pretty rough and dirty right now, but it works. If you drop this into the project folder and then create a "behaviors" folder along side it, and populate it with lua scripts, it will add one behaviour to Maratis for each script. It currently expects the script to have a similarly named table within it, with an update function. I haven't yet done the variable translation between lua and C++(/editor) but at least it's a start

Example behaviour script:

player = {
    update = function(object, behaviour)
        
    end
}

Edit: I totally forgot, I also merged in a change from Sponk! Maratis editor is now themable! There are two themes provided (default and grey) although currently there's no way to switch them without recompiling

Let me know what you think

65

(46 replies, posted in General)

I just thought I'd mention that, as all the current github mirrors of Maratis seem to be unmaintained, I have started my own one at
https://github.com/nistur/maratis

I will try to keep the mirror up to date with the official repository.

I've also made a minor change over the stock Maratis for it, it will now support multiple plugins. I haven't yet added static lib support into the plugins (which would be needed for iOS builds) because to do so, I would want to do some changes to the publish framework which I don't have time to do right now. Hopefully the plugin feature can be added back into the official stock Maratis soon too then we can all start making and sharing plugins.

66

(3 replies, posted in Gossip)

Thanks for the reply (and apologies for not being on for so long, been stressful, but that's not important)

I think what I was trying to suggest got a bit misunderstood here. I wasn't wanting to decode and play a movie in game (although this would always be useful) but rather use the Maratis Engine and Editor to work as a scene manager for rendering video. The backwards issue was to be to make iteration over the scene easier (rather than resetting back to the initial state and replaying only in one direction) An example of what I mean is in the talk by Bret Victor.

This was basically just a dream project, something I thought would be pretty cool to do smile Not sure how feasible.

67

(24 replies, posted in Engine)

I will have to check up on this, but I think the standard lua API should be able to cover this... at least the tan... try

math.tan(0.5)

I'll take a look at the aspect stuff, shouldn't be too hard to add, although I don't see anything which could help in the current Maratis 3D lua API.

68

(6 replies, posted in General)

It was pointed out that my reply may not have been entirely clear. I'm sorry about that.

Usually, there are two steps to a save system, collecting the data to save, and then writing to file. The collecting shouldn't take too long (depends, of course how much data you have to save, but this should be fairly minimal) Writing to file, however takes considerably longer.

For a standard menu-based load/save system you could do both of these one after the other and would hardly notice... I mean, it takes a while to save, so what? However, for a quicksave system, one thing you do not want is for the game to pause for a second or two when you hit save. To achieve this, the best way would be to collect the data as normal, when you press F5 or whatever your chosen key is, which should go fairly un-noticed, then start a background thread to write the savedata to file. As it's not in the main game loop, it shouldn't affect the normal gameplay and everything should happen smoothly.

There's a lot of 'should's there. One issue is that, when working with threads, you don't have two threads changing the same data, which could lead to crazy stuff happening, or threads waiting for other threads to release data, which would lead to locks, causing more freezes than the initial problem.

Anyway. for this reason, quicksave is a little more complicated than a standard save system.

And, while I remember, I should mention loading. There are currently no loading screens (this, again, would probably need a background thread...) so you would get a significant pause when "quickloading" which might not be ideal, although if you showed a prompt, I guess it would be better. The main issue with loading is clearing the "world" and resetting it to the exact state you want it in before.

69

(6 replies, posted in General)

Save/Load is very specific to each game. A quicksave (or, any save-) system would have to be implemented in the game. There's no real way to be able to save in a generic way, unless you wanted to save the entire world. This would be incredibly slow and guaranteed to miss custom object states. and such.

One issue with a quicksave system, compared with a standard menu save system is that Maratis currently doesn't have any threading code in it, it wouldn't be too hard to add a reasonable cross platform solution... but...

The issue with saving, is that writing to a central place (the MSaveData for example) is pretty quick, and can be done on the fly, however writing to file is slow, If you really wanted a quicksave system, hitting quicksave would cause the game to freeze for a short amount of time while it writes the savedata to disk. Ideally what you do is write to savedata on the fly, then kick off a separate thread to write to disk. This does mean a reasonable amount of work to make sure things can be made (reasonably) threadsafe.

70

(6 replies, posted in General)

Just let me know how urgent this is and what degree of integration you'd like and I'll see what I can do smile

By the way, my solution is currently that there will be a config file system with semi-DOM-esque accessing, and then a semi-singleton config file that can be used similarly to Unity's PlayerPrefs. The basic usage from code would be:

void SomeClass::save(std::string root)
{
    std::string key = root + "Something.";
    MSaveData::write(key + "SomeVal", &someVal);
}
void SomeClass::load(std::string root)
{
    std::string key = root + "Something.";
    MSaveData::keyExists(key + "SomeVal", &someVal);
}

I haven't decided how I can do save/load stuff in script, but I guess it would be something similar. Thoughts?

Also, so far, I've only got it reading and writing binary files (I can put the spec here if required). I was intending to add some form of human readable format to it too, I'm not sure what to use, the choices seem to be xml, yaml, json or a home rolled format. Any preferences?

71

(6 replies, posted in General)

Hi there!
Great to have another new user smile

There's no save/load system in the engine right now. However, (as with everything else, it seems) it's something I've got on my todo list, and I've been working on a solution. I've not integrated it with Maratis itself yet, so it would have to be added as part of a game plugin at this point

72

(21 replies, posted in Tutorials/Examples)

Unfortunately I've not had the time to watch your videos yet (the only real "free" time I have is during my commute, where I can't really watch videos) It's great that there are more people contributing tutorials to the Maratis community, so even without having seen them yet, thank you! smile I'll make sure to work my way through them soon.

73

(3 replies, posted in Engine)

I can try and polish this up and upload the code for this somewhere. I think it should be usable with stock Maratis.

Basically, the way it works is that, on update, it just calls a lua function with the object as a parameter. It's obviously not the fastest or most ideal way to do things, but it works, and should be more than suitable for non-CPU intensive behaviours.

74

(47 replies, posted in Tutorials/Examples)

Hi, I'm sorry about the delay, I've been pretty busy.

The -> is the crappy web formatting. I thought I managed to fix it all, it's meant to be ->. It's replacing > with >. If you notice any of these, can you please let me know which tutorials it's on and I will fix it.

In other news, I've started working on this stuff again, so I might have another tutorial up soon. I think I'm going to leave the video tutorials for a bit though tongue

75

(26 replies, posted in Engine)

I had a go with using gDEBugger, but it's made by AMD so it only really supports ATI graphics cards. It claims to also have some support NVidia too, but neither of those would help my crappy Intel graphics chip. Oh well. Back to trying to trying to do this the slow way tongue