About making a dll library for use by game

Started by dullman, July 26, 2014, 02:59:11 pm

Previous topic - Next topic

dullman

Hello i have a problem, im in moment when i need to modify sprite (100 pixels height) with given colors by function, so i know the use of ruby is slow and would take forever, on other hand if i could create a dll which use win32api function it will resolve lags in game, but my problem is i can't find any tutorials on writing win32api dll's (or it's a question if i write a standard dll in c it will work??) I will be very grateful for fast answer.

KK20

There's a few good links posted in here to get you started.
http://forum.chaos-project.com/index.php/topic,14127.0.html
Have fun learning bitmaps

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

dullman

Thanks it helps a lot, i write a library that change color on sprite and it's a hell faster than in ruby, now i want to create editor that will modify base rxdata files and save additional stats for all characters (e.g. like charisma eventually the character will loosely based on dnd), and also load them by load_data so i need to modify dll file to support more complicated stuff like custom classes etc. is it even possible and if yes could you give me an example (a simple one is the best)

ThallionDarkshine

Saving and loading custom data structures from files in c++ is a lot more difficult than in ruby (especially if you want them to be readable from ruby). I was pretty sure that there was a library for c++ to save and load files made with Marshal.dump. However, I don't remember the name of it at the moment. My advice would be to create a custom file format for the different types of data you need to manipulate and create loading and saving methods in c++ and ruby.

Blizzard

The funny thing is that Marshal with Ruby classes is actually pretty fast. So you might want to consider using Ruby for "simple" data classes that are supposed to be serialized and don't contain any CPU-heavy methods since they will be much easier to write and fast to serialize and deserialize.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

dullman

July 27, 2014, 02:40:03 pm #5 Last Edit: July 27, 2014, 02:44:10 pm by dullman
Hmm you say using a marshal, but what i planned to do is write editor in c# so i don't know if i could have access to ruby methods (marshal in that case) if there is a dll written in c++/c# that serialize files with marshal compatible i want to know, if not then i should write editor with ruby but it's pain in ass to create window application in it.

Edit : I didn't see the answer before blizzard post
if there exist such library i want her, but as loading from ruby i was working on project which loading files from xml takes about 15 sec (need to use graphic.update during it) and it on desktop computer, on weakers it takes more so i wanted to use something which is really fast to load custom database i want to create.

ForeverZer0

July 27, 2014, 04:14:47 pm #6 Last Edit: July 27, 2014, 04:20:30 pm by ForeverZer0
I have always used IronRuby embedded in C# to read RMXP data.

IronRuby's Zlib#deflate is not compatible with native Ruby's. I entered a ticket, but development has ceased. I did find a work-around using another Zlib library, though. I can pull up some old source code if you want.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Blizzard

IronRuby uses Marshal 4.8 like RMXP's version 1.8.1 of Ruby?
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

ForeverZer0

I never even checked which version of Marshal it uses, but I know it works.
I can save/load data back and forth between RMXP and whatever app I am making with no problem. The only I ever has was using Zlib to compress the scripts. RMXP couldn't read the format. Using zlib.net solves that problem, though.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

dullman

so if i understand well you use ironruby to read data, whilst zlib.net to pack data and that's enough to be readable by game, and yes source codes are always welcome (since i learning from it much more than books)

ForeverZer0

No, IronRuby can be used to Marshal data both ways. Zlib only needs used with Scripts.rxdata. The text of the scripts are not saved as just plain strings, but are compressed with Zlib first. You will only need the Zlib library for compressing the scripts before using IronRuby's Marshal to actually save them.

Honestly, I would highly recommend you familiarize yourself with the data structures and formats before taking this on. You are going to need to be in order to make anything work. I can show you some source code which will put you far ahead, but you still won't be able to work with it until you understand it.

And as KK20 pointed out, Bitmap's are a whole different animal. You have to understand exactly how they are structured in memory, and work directly with the memory to make any changes. This requires the use of pointers, or at the very least using LockBits and UnlockBits, which if you are unfamiliar with, you will have to learn as well.

And finally there is the fact that Ruby cannot just use Win32API to work with .NET assemblies by default, like it could with a C library. I did create a tool that will allow you to decorate your methods to export in the same way, but it does add complication.  I don't mean to discourage you, and I will help you out by imparting any knowledge I have about the matter, but attempting this without fully understanding it is going to lead to only frustration. I am pretty good with both languages, and probably more familiar than anyone about interop between C# and RMXP (as far as I am aware, the only one to do it), and it is not a simple thing. I will pull together some code to help out with what I can.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

dullman

Hmm you sound like it is a hard to do something like that. As for being familiar with datastructures and formats maybe i didn't say it clearly but i want to add entirely new properties to class e.g. for Stats instead of modifying the old ones properties i want to add new one hash with 7 different stats as Keys and it's value will be a value of stats (we will be able to increase stat by one every 4 levels, also it will be modified by traits, states and items). Also it will be modified in Game Character class since i want enemies with similar build (which i make to use new stats by blizz-abs). Second problem is to create completely new classes like Game_item (a class for items, weapons, armors that will have availbility to create a single weapon with random stats - similar to diablo). And because of this i need to create a custom editor. As for sample code i just need to see how it's achieved and with trials and errors i can make it work somehow, if not then the last thing is call for help on forum)

ForeverZer0

You specified two things you are trying to do:
Quote from: dullman on July 26, 2014, 02:59:11 pm
Hello i have a problem, im in moment when i need to modify sprite (100 pixels height) with given colors by function, so i know the use of ruby is slow and would take forever, on other hand if i could create a dll which use win32api function it will resolve lags in game.


This, the original question, is more complicated, and what I was referring to.


Quote from: dullman on July 27, 2014, 02:40:03 pm
...but what i planned to do is write editor in c# so i don't know if i could have access to ruby methods (marshal in that case) if there is a dll written in c++/c# that serialize files with marshal compatible i want to know

This is much easier, but you still need to have a good understanding of how it works.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

dullman

Quote from: ForeverZer0 on July 28, 2014, 11:10:36 am
You specified two things you are trying to do:
Quote from: dullman on July 26, 2014, 02:59:11 pm
Hello i have a problem, im in moment when i need to modify sprite (100 pixels height) with given colors by function, so i know the use of ruby is slow and would take forever, on other hand if i could create a dll which use win32api function it will resolve lags in game.


This, the original question, is more complicated, and what I was referring to.


Quote from: dullman on July 27, 2014, 02:40:03 pm
...but what i planned to do is write editor in c# so i don't know if i could have access to ruby methods (marshal in that case) if there is a dll written in c++/c# that serialize files with marshal compatible i want to know

Yes i know i tried to use this topic and ask new question without opening new topic it's my fault that you misunderstood
This is much easier, but you still need to have a good understanding of how it works.

ForeverZer0

RPG Module (Ruby Script)

RMXP Hidden Classes (Ruby Script)

Ruby Class (C#)

Add references to:

  • IronRuby

  • IronRuby.Libraries

  • Microsoft.Dynamic

  • Microsoft.Scripting

  • Microsoft.CSharp

  • zlib.net



To load data:
dynamic actors = Ruby.MarshalLoad(@"Data\Actors.rxdata")


To save data:
Ruby.MarshalDump(@"Data\Actors.rxdata", actors)


There are a few things you need to be careful about, such as handling strings and string encoding, how to dynamically add data to Ruby classes at run-time, etc., but you seem to know what you are doing with that. Let me know if you need anything else.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

dullman

August 08, 2014, 08:18:52 pm #15 Last Edit: August 08, 2014, 09:58:08 pm by dullman
So i was following you instruction (I know it's late but decided to rewrite base classes first) and what i get is error (null reference even though the data is array of byte), is there any other thing to take care of??

EDIT: Sorry i resolved a problem just forgot to initialize ruby class, now i have a question how to add to ruby object new field (like for actor field attack) also new class object (like add new actor to Actors).

I thought about way around this just save modified class one more time from game, but it will require to do that every time i want to add new skill/trait/actor etc.



ForeverZer0

To create a new Ruby object in C#:

dynamic actors = Ruby.Eval("$data_actors");
dynamic actor = Ruby.Eval("RPG::Actor.new")
actors.Add(actor)
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

dullman

Eval there isn't any method in Ruby class with this name, so it causes an error.
ps. After tinkering with editor in c# i'm starting thinking that keeping values in xml files(or json i don't still know which is faster to read) is easier and much more desirable since i made many changes in Game_battler since i wanted game_enemies and game_actors similar to each other (e.g. both have levels, traits, the same way hp and mp are counted etc.). Even if i had a long time loading new actors, that on other hand easier to make editor for game (or even without it will be fine if i know the file structure), so what do you think which approach will be better for me?

ForeverZer0

Oops, I thought I included the method in the code I gave you.
Spoiler: ShowHide
		public static dynamic Eval(string code)
{
return Engine.Execute(code, Scope);
}

public static T Eval<T>(string code)
{
return Engine.Execute<T>(code, Scope);
}


I personally don't see any reason to use XML or JSON, IronRuby interops very well with C#, allowing you to call C# code from Ruby, and Ruby code from C#, I would highly suggest you look into it, it is actually quite simple if you have a pretty good grasp on both languages.

I built an editor for RMXP using C#, actually just needed to finish the animation tab in the database, and make some tweeks, and it was easy using the two together.

If you are unfamiliar with the "dynamic" keyword in C#, it makes all this very easy, and you do not even need to build C# classes for anything. For example, using the code above I gave you:

Spoiler: ShowHide
			var weapons = Ruby.MarshalLoad(@"Data\Weapons.rxdata");
var actors = Ruby.MarshalLoad(@"Data\Actors.rxdata");
var firstActor = actors[1];
var weapon = weapons[firstActor.weapon_id];
MessageBox.Show(weapon.name.ToString());


Just remember that a Ruby string is a MutableString, not a System.String, so you will need to convert it to a System.String before you can use it as such, simply by using #.ToString() on it. I made an extension method to convert it back to a MutableString.

Spoiler: ShowHide
		public static MutableString ToRubyString(this string clrString)
{
return MutableString.Create(clrString, RubyEncoding.UTF8);
}

I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

dullman

August 09, 2014, 10:25:06 am #19 Last Edit: August 09, 2014, 12:17:28 pm by dullman
Quote
Just remember that a Ruby string is a MutableString, not a System.String, so you will need to convert it to a System.String before you can use it as such, simply by using #.ToString() on it. I made an extension method to convert it back to a MutableString.


Uuu it's means that i need write a converter for all strings (i use wpf application so to easy to Bind to value (although there where some problems with it but resolved)).
Also one more question to access hash from ruby e.g. i have a stats hash which keep the stats for both actor and enemies, so access i need write something like that:
actor.stats['stat_name'] = value

or it's wrong way to access from c# to hash value?

ps. I resigned from keeping values in external json or xml files since i don't want to spend my time for writing library in ruby to parse them (since using require doesn't work, althougth i read that json library is included in 1.9.2 Core libs in ruby so if i wanted to use XPA it will be possible)

EDIT One more question is there a clone method for dynamic object (like i want to clone system when making some changes)