Coder Social home page Coder Social logo

messenger's Introduction

The Messenger Game Engine

Messenger is a 2D game engine with experimental concepts for Elm based on canvas.

This repository is a CLI tool to create messenger project. Main development is under messenger-core.

Games made with Messenger

Cool Features

  • Engine in a library. Messenger core is built in a library.
  • Message (or event) based. Faster development cycle, easier to divide work.
  • Functional, but OOP styled. Take advantages of both functional programming and OOP.

Conceptual Picture

Tutorial/Guide

The manual is under development, and may have some clarity issues now.

Full documentation is hosted on Typst.

messenger's People

Contributors

linsyking avatar yucxovo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

messenger's Issues

Delayed messages

  • A general case is that one may want to send a message later, like do something after 10 secs, or do something when mouse clicks next time, instead of doing something right now
  • planned effect:
type LayerMsg
    = ...
    | LayerMsgDelayedOnce (EnvC -> Maybe LayerMsg)       -- triggered only once
    | LayerMsgDelayed (EnvC -> Maybe LayerMsg)           -- always valid
  • example1: If one want to send 1 to a layer called "A" when mouse is clicked next time
updateModel env lmsg model =
    ...
    let cond fenv =
        case fenv.msg of
            MouseDown _ _ ->
                Just (LayerIntMsg 1)
            _ ->
                Nothing
    in
    (model, [(LayerName "A", LayerMsgDelayedOnce cond)], env)
  • example2: If one want to send 1 to layer "A" after some time, then write
updateModel env lmsg model =
    ...
    let cond fenv =
        case fenv.msg of
            Tick t ->
                let cond2 fenv2 =
                    case fenv2.msg of
                        Tick t2 ->
                            if (toSecond utc t2) >= (toSecond utc t) + 100 then
                                Just (LayerIntMsg 1)
                            else
                                Nothing
                        _ ->
                            Nothing
                in 
                Just (LayerMsgDelayedOnce cond2)
            _ ->
                Nothing
   (model, [(LayerName "A", LayerMsgDelayedOnce cond)], env)

this will start counting time after next Tick.

Component and Game Component Settings

Use a separate file named ComponentSettings (similar to game components) to manage all the components' data.

For the Setting file,
Structure:

-- list all the data types
type ComponentType
    = ...

-- define a general type for all components
type alias ComponentT =
    Component ComponentType

-- detail data type and null data for every component
type alias SampleData = 
    {...}
nullSampleData : SampleData
nullSampleData = 
    {...}

Then users can modify their data type in this file.
For game components, alive : bool is set in the data type by default.

Advantages

  • Users can easily define every component's data type separately instead of using Dict
  • DefinedType and Parser for them is no longer needed
  • Separate the uid logic. Users cannot modify the uid in initmodel, instead, they need to set the uid when generate the component

Disadvantages

  • All the components, including the sub components whose directory is set under another component, should set their data type equally in ComponentSettings.elm
  • Users cannot directly copy the component from one project to another
    alternative plan: add an option --copy-from -c in CLI command messenger component, receiving a string with format path-of-target-project@target-component, which help users copy a component automatically.

SOM design

Every ObjectMsg should derive from SOM message, i.e. they are able to do top-level calls directly.
Otherwise it is almost impossible for component writer to write a usable and general component.

type MsgBase a = SOMMsg SOM | OtherMsg a

Then,

type alias LayerMsg = MsgBase (LayerMsg_)
type alias ComponentMsg = MsgBase (ComponentMsg_)

And finally let messenger handle SOMMsg.
The side effect is that every component has the ability to call SOM APIs. (But you can still ban them in scene level)

Integrate ObjectTarget into core

Currently the target is not a concrete type in core as layers/components have their own target.

We are thinking to use a uniform target data type including Parent, Name and ID.

Redesign GlobalData and Env

Currently user can modify globaldata which has a lot of internal data that we want to hide from users.

Some entries should be read-only (and some should be hidden?) from users.

A simple idea would be create a new type called globalDataOut (might be derived from globalData) and users can only modify things in it.

Mistake in dome codes

Here in the documentation as followed

image

The demo codes are

-- /src/Scenes/Home/Model.elm
init env msg =
...
    , layers =
        [ MainLayer.layer envcd NullLayerMsg
        ]
    }

However, the error occures as

Type mismatch error. Expected: `Env SceneCommonData UserData` Found: `LayerMsg`

So, it should be changed as

-- 
init env msg =
...
    , layers =
        [ MainLayer.layer NullLayerMsg envcd
        ]
    }

BRAND-NEW bug in v14.0.0

Environment

  • OS: Windows 11
  • Web browser: Firefox (127.0.2), Chrome (126.0.6478.127) and Edge (126.0.2592.81)

Detailed explanation of the problem

Under Firefox, some values in messenger are not properly initialized, such as the real width and height of the web-page. These values are 0 when the page is opened, however they returned to normal after changing the window size. This problem prevents all functions involving posToReal and lengthToReal from working properly. This was not the case in previous versions of messenger.
I think this is due to a change in Messenger.UI.Init.init. Comparing Line 91~94 in 14.0.0/src/Messenger/UI/Init.elm and Line 93~94 in 12.1.0/src/Messenger/UI/Init.elm, we can conclude that 14.0.0 should rely on the "change window size" message sent by the browser when initializing a web page. Although Chrome and Edge do this, it seems that Firefox does not. I think this incompatibility with some browsers is dangerous and should be fixed ASAP.

Update Documentation

The documentation is far behind the current messenger version, we should update it.

A general model for update in layer

the update function of layers with components or game components can be modelled in a general way.
The update function can be divided into 4 parts:

  • update basic data (remove dead game components, etc.)
  • update component list by themselves
  • decide the msg that need to be sent and distribute them (collisions, etc.)
  • handle all the component msg from the former steps

A distributor type : Env /*alias of Env C in Layer*/ -> Model -> list (ComponentTarget, ComponentMsg) is designed for part 3. Specifically, is will be implement by using a distributor and upateobjectswithtarget func
Finally, the update function will be: updatebasic -> updatecomponents -> updatecomponentsbydistributor -> handlecomponentmsgs, and for users, they only need to deal with updatebasic, distributors and handler.
Basically it is not recommend for users to put both GameComponent and Component in one layer.

Redesign Env & EnvC

Combine them into one thing.

E.g.

type alias Env = EnvC ()

type alias EnvC a = {
...
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.