These are chat archives for ZaneDubya/UltimaXNA

10th
Aug 2015
Zane Wagner
@ZaneDubya
Aug 10 2015 11:24
@denizsokmen When your UOP branch can load 100% of the UOP files distributed with the new client, please open a new pull request.
You are right - there needs to be a way to pick which set of resource loaders to use.
I will start working on this.
It is likely that these necessary changes would break your existing code, so you may not want pull from my repo into your UOP development branch. ;)
Deniz Sökmen
@denizsokmen
Aug 10 2015 12:21
you can actually pull my changes because it doesn't have any effect on the functionality yet
I rebased with the current origin head and it works without a problem, the loading functionality isn't used yet
Zane Wagner
@ZaneDubya
Aug 10 2015 12:28
@denizsokmen I haven't implemented any changes yet. :)
I'm not going to pull your changes until I can actually test them.
Correction: until the changes implement the desired functionality. Otherwise it's just code that's never called.
WIndows 10 UAP framework is built on .NetCore... so lame.
UWP*
Zane Wagner
@ZaneDubya
Aug 10 2015 19:23
I have a new least favorite class in the xna client:
Jeff Boulanger
@jeffboulanger
Aug 10 2015 19:23
haha
ive looked at that
Zane Wagner
@ZaneDubya
Aug 10 2015 19:23
That is just... a mess. One big hack supported by twenty smaller hacks.
Jeff Boulanger
@jeffboulanger
Aug 10 2015 19:23
that class is actually what prevented me from refactorig
Zane Wagner
@ZaneDubya
Aug 10 2015 19:24
Really? Hahaha color me unsurprised.
Jeff Boulanger
@jeffboulanger
Aug 10 2015 19:24
i got to that class and saw how inter-twined it was, and said, welp, im done
Zane Wagner
@ZaneDubya
Aug 10 2015 19:24
I mean, it's kinda neat, really. It's a html layout engine! It's just... not very well programmed. ;)
Jeff Boulanger
@jeffboulanger
Aug 10 2015 19:24
ya
Zane Wagner
@ZaneDubya
Aug 10 2015 19:25
I've seen two interesting C# HTML layout engines...
All managed code.
Might be worth looking into.
License is compatible with GPL
We would only need the DOM layout portion, might also be able to replace our current HTML parser with that.
The only problem is that it's REALLY comprehensive. Not really necessary for drawing a small number of strings.
Jeff Boulanger
@jeffboulanger
Aug 10 2015 19:44
problem is, uo html isnt 100% valid though right?
its html in the sence that its a markup language, but it doesnt 100% validate as true html
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:03
So, apparently my avatar just got wiped, thanks a lot github :(
hah, yours too
wonder who fucked that one up
now its fixed
weird
Zane Wagner
@ZaneDubya
Aug 10 2015 20:07
Some github intern just crapped their pants ;) Or else the cloud hiccuped.
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:07
hahaha
Zane Wagner
@ZaneDubya
Aug 10 2015 20:07
Right! UO Html uses tags that are non-standard, and they don't close tags.
So it wouldn't validate.
I've narrowed down the problematic layout code to 400 lines. I'll take a swing at it tonight.
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:08
funny thing is, i think some intern probably just learned how to write a ROLLBACK statement ;)
Zane Wagner
@ZaneDubya
Aug 10 2015 20:09
Education in action!
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:09
in reality you need to treat the html stuff more like a language and less like a direct translation to rendering
Zane Wagner
@ZaneDubya
Aug 10 2015 20:12
BTW, I've implemented a new Resource paradigm (for all the mums/uop): you request the object implementing IResourceProvider from the service registry. The base UltimaResourceProvider currently provides only MUL resources, but you should be able to override every routine in UltimaResourceProvider that provides a resource. Big step in the right direction for UOP support; would also work for any other file out there.
*mums/uop = mul/uop
*thanks autocorrect
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:13
you basically are doing what i did with openuo
lol
a little less abstract though
Zane Wagner
@ZaneDubya
Aug 10 2015 20:13
I'm learning ;)
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:13
u should look at openuo
you dont have to do anything but give it the type of resource you want
ArtworkFactory.GetLand<Texture2D>(id);
Zane Wagner
@ZaneDubya
Aug 10 2015 20:14
I do a little of that:
T GetResource<T>(int resourceIndex);
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:14
it does all of that for you
ya but it manages the provider for you
same idea, only abstracted 1 more layer
the difference being
i dont care about the provider ever
because i have something called InstallationLocator
which gives me installs it finds, then you just use the file index it gives back for the files
it manages the fact that its uop/mul
you dont have to know, ever
which would get rid of your 2 implementations
you just want access to the mul
you dont really care where its coming from
just give me the stream ;)
Zane Wagner
@ZaneDubya
Aug 10 2015 20:17
Is ArtworkFactory a global static?
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:17
no
public class AnimationFactory : AdapterFactoryBase
{
but you send in the install when you create it
    public AnimationFactory(InstallLocation install, IContainer container)
        : base(install, container)
    {
    }

    public Frame
    public Frame<T>[] GetAnimation<T>(int body, int action, int direction, int hue, bool preserveHue)
    {
        return GetAdapter<IAnimationStorageAdapter<T>>().GetAnimation(body, action, direction, hue, preserveHue);
    }
it calls wrapped base functionality to return the proper storageadapater
which then determins uop/mul for you
    public override void Initialize()
    {
        base.Initialize();

        var install = Install;

        _fileIndex =
            install.IsUopFormat
                ? install.CreateFileIndex("artLegacyMUL.uop", 0x10000, false, ".tga")
                : install.CreateFileIndex("artidx.mul", "art.mul");
    }
this is how it handles uop
inside each of the adapaters
then for each adapter you implement the interface for what it can return
    public unsafe Texture GetLand(int index)
    {
this way, you never need to know wether its UOP or not, they are handled in the same spot
the only difference between them is the file index handling
    public FileIndexBase CreateFileIndex(string uopFile, int length, bool hasExtra, string extension)
    {
        uopFile = GetPath(uopFile);

        FileIndexBase fileIndex = new UopFileIndex(uopFile, length, hasExtra, extension);

        if(!fileIndex.FilesExist)
        {
            Tracer.Warn(
                "FileIndex was created but {0} was missing from {1}",
                Path.GetFileName(uopFile),
                Directory);
        }

        fileIndex.Open();

        return fileIndex;
    }

    public FileIndexBase CreateFileIndex(string idxFile, string mulFile)
    {
        idxFile = GetPath(idxFile);
        mulFile = GetPath(mulFile);

        FileIndexBase fileIndex = new MulFileIndex(idxFile, mulFile);

        if(!fileIndex.FilesExist)
        {
            Tracer.Warn(
                "FileIndex was created but 1 or more files do not exist.  Either {0} or {1} were missing from {2}",
                Path.GetFileName(idxFile),
                Path.GetFileName(mulFile),
                Directory);
        }

        fileIndex.Open();

        return fileIndex;
    }
both return a FileIndexBase, thats the implementation that changes, not the actual lookups
Zane Wagner
@ZaneDubya
Aug 10 2015 20:21
        var install = Install;
What is Install?
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:21
or how the data is handled
this
gets returned from this
i even have a comboxbox control that provides the installs to choose from
Heres a form that allows you to choose the install
My unit testing engine uses it to choose the install before running tests
public class TestingBase
{
    private static bool _configuredInstallForTest;
    private static InstallLocation _install;

    protected static InstallLocation Install
    {
        get
        {
            if(!_configuredInstallForTest)
            {
                using(var form = new SelectInstallForm("CoreAdapterTests"))
                {
                    form.ShowDialog();
                    _install = form.SelectedInstall;
                    _configuredInstallForTest = true;
                }

                //Outputs Trace warnings and errors to the Visual Studio Output Console.
                new DebugOutputEventListener();
            }

            Guard.RequireIsNotNull(_install, "Ultima Online is not installed");

            return _install;
        }
    }
}
abstraction is more complex, but so much easier to re-use ;)
Zane Wagner
@ZaneDubya
Aug 10 2015 20:24
I like this - I'll definitely return to it at some point.
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:24
:)
You probably could just dump your file handling stuff and put this in, just use OpenUO
probably wouldnt be to hard
I can even try to do it if you want
and if you find bugs, i can fix haha
or you can and submit pull
Vorspire ended up using it in ServUO and PlayUO forks
havent heard much issue
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:30
you could even stick another layer on top of this, call it something like you iutilimaresourceprovider
have it do some of the caching
that way you aren't constantly reading fro mdisk
if you made it so you had a base class for each of the textures too, you could do your own reference counting, and when disposing the object and the reference gets to 0, remove it from cache, or queue it for removal in x time.
Zane Wagner
@ZaneDubya
Aug 10 2015 20:33
Very interesting...
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:33
this would also give you a good base for finding memory usage at runtime
Zane Wagner
@ZaneDubya
Aug 10 2015 20:34
... and I like that too ;)
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:34
;)
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:39
I also think your data model should be slighly tweaked so that when a map sector is asked for, if its not loaded from disk, it should return an empty 8x8, then queue a background load of the 8x8 sector. Once loaded, it can be used
of course, this requires a bit of threading/locking
but you wouldnt sacrifice frametime for disk IO
if you were to constantly monitor the players movement
and maybe 30+ tiles out (maybe more depending on resolution) start the loading of the 8x8's just off screen
you would probably never notice the load via frametime
Zane Wagner
@ZaneDubya
Aug 10 2015 20:41
I agree with you.
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:41
all that would require a lot of abstraction of the current code though
Zane Wagner
@ZaneDubya
Aug 10 2015 20:42
Well, one more thing to change, right? ;)
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:42
;)
Zane Wagner
@ZaneDubya
Aug 10 2015 20:42
Or rather, quite a lot.
haha
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:42
this is why i liked the idea behind a dll and a client, you could test everything without rendering the game
lemme know if you wanna look into using openuo
i can write up the adapters pretty fast
for xna
Zane Wagner
@ZaneDubya
Aug 10 2015 20:43
I haven't deleted my progress on the refactor, although it doesn't work. I came to a point where - like you pointed out - things were just too interdependent to move forward. My breaking point was the Map/AEntity business.
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:43
yup
ithink because of how interwtinned some of the stuff is
it has to be done in very small chunks
at a time
Zane Wagner
@ZaneDubya
Aug 10 2015 20:44
Why don't we take a look at it at the end of August? I should have most of Milestone 0.7 finished then.
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:44
focus on cleaning up small, really bad pieces
whenever ;)
like rendertext
that'd probably be the best place to start
cause thats where it fell apart for both of us
Zane Wagner
@ZaneDubya
Aug 10 2015 20:44
I'm going to start there this evening, actually!
I want to add the css attribute position: absolute
And rather than adding one more bandaid, I'm going to make the RenderedText class follow more of a DOM model when doing layout.
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:46
this is out there, but it'd be really cool to unify the entire UI framework into a markup language, then just create your UIs with that in the future, translate packets fro mthe server to that framework and render.
maybe thats a bad idea
haha
nm
it would be nice not to have to write all these client side gumps in code
cause that shit sux
Zane Wagner
@ZaneDubya
Aug 10 2015 20:49
How would you handle the client side responses to buttons being pushed, etc.?
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:50
gumps from the server are differnt
im talking about options/paperdoll/journal/status/etc
login/world/etc
Zane Wagner
@ZaneDubya
Aug 10 2015 20:51
That's what I meant. How would you hook into a button being pushed if the client side bumps are written in gumpml?
Jeff Boulanger
@jeffboulanger
Aug 10 2015 20:55
something like
loginGump.FindByName("LoginButton").Clicked+=onLoginClicked;
the better thing to do might be to use the dynamic approach, and just let it resolve stuff at runtime
have the xaml/xml/whatever actually build out the controls via name
loginGump would be
dynamic loginGump;
then you do loginGump.LoginButton.Clicked +=
let it figure that out at runtime
its not gonna do it on each frame
just on 1 frame when its crated
created*
so perf hit for it being dynamic would be meaningless