åå ãã²ãŒã ãµãŒããŒã§ã®Akkaã®äœ¿çšã«ã€ããŠæŠèª¬ããŸããã
次ã«ãåçŽã§ã¯ãããããã§ãåäœãããµãŒããŒã®äŸãåæããŸãã
å 責äºé
äž»é¡ã«ææ¢ããã人ã¯ã説æã«äžæ£ç¢ºããšåçŽåãèŠã€ãããããããŸããã ã ãããããã¯èæ¡ãããŸããã ç§ã¯ããããäœã§ãããã©ã®ããã«äœ¿çšã§ããããç¥ããªã人ã«äžè¬çãªãã€ã³ãã瀺ãããã£ãã äžããããäŸã¯ãå®çšŒåã®æºåãã§ããã³ãŒããšèŠãªãããã¹ãã§ã¯ãããŸããã ããããå®éšã®äœæ¥çšãã³ãã¬ãŒããšããŠã
åã®èšäºã§ãakkaãåªããŠããçç±ã«ã€ããŠã¯ãã§ã«æŠèª¬ããŸããã
ãããã£ãŠãããã«ãµãŒããŒã®äœæãéå§ããŸãã
建ç¯
ç§ãã¡ã®ä»äºã¯ããã«ããã¬ã€ã€ãŒã²ãŒã ãäœæããããšã§ãã
ãœãŒã¹ã®githubã«ã¯ããµãŒããŒãšã¯ã©ã€ã¢ã³ãã®äž¡æ¹ããããŸãã ãã ããããã§ã¯ãµãŒããŒã®ã¿ãèæ ®ããŸãã
ãµãŒããŒèªäœã¯ããã€ãã®ãµãŒãã¹ã§æ§æãããŸãã
åãµãŒãã¹ã¯ãã¡ãã»ãŒãžãåä¿¡ããã¢ã¯ã¿ãŒã§ãã å®éã®ã·ã¹ãã ã§ã¯ããã®ã¢ã¯ã¿ãŒã¯ãã¡ãã»ãŒãžãçŽæ¥åŠçããã¢ã¯ã¿ãŒã®ã¹ãŒããŒãã€ã¶ãŒã«ãªãå¯èœæ§ããããŸãã ã€ãŸã ãµãŒãã¹ã®ã¢ã¯ã¿ãŒèªäœã¯äœãããŸããã
圌ã¯ã¢ã¯ã¿ãŒã®äœæ¥ãéå§ããå¿ èŠã«å¿ããŠåèµ·åãããªã©ãäœæ¥ãç£èŠããŸãã ç§ãã¡ã®ç¶æ³ã¯åçŽåãããŠããŸãã ãããã£ãŠã俳åªã¯ãã¹ãŠã®äœæ¥ãèªåã§è¡ããŸãã
ããã§ã¯ãæåã«ç§ãã¡ãäœãããããæããŸãããã
ããã¯ç§ãã¡ã®èŠåœéãã®ã¯ã©ã€ã¢ã³ãã§ãã ã¡ãªã¿ã«ããã«3DïŒ
ãããŠããããµãŒããŒã§ãïŒ
ç¢å°ã¯ãã¢ã¯ã¿ãŒéã®ã¡ãã»ãŒãžãããŒã瀺ããŸãã
1. TCPãµãŒãã¹ -ã¯ã©ã€ã¢ã³ãã®æ¥ç¶ãæ åœãããµãŒãã¹ã TCPãåããããŒãžã§ã³ããããŸãã
2. ã»ãã·ã§ã³ -ã²ãŒã ã»ãã·ã§ã³ã®ã¢ã¯ã¿ãŒã ã¯ã©ã€ã¢ã³ããšã®ã¡ãã»ãŒãžã³ã°ãæ åœããŸãã
3. ã¿ã¹ã¯ãµãŒãã¹ -äžè¬çãªã¿ã¹ã¯ãå®è¡ããããã®ãµãŒãã¹ã
4. èªèšŒãµãŒãã¹ -ãã¬ãŒã€ãŒãèªèšŒãããµãŒãã¹ã
5. GMãµãŒãã¹ -ã²ãŒã ã¡ã«ããã¯ã¹ãµãŒãã¹ã éšå±ãšäžè¬çãªã²ãŒã ã¢ã¯ãã£ããã£ã®ç®¡çãæ åœããŸã...
6. éšå± -ãããã¯ã²ãŒã ãè¡ãããéšå±ãšããŠæ©èœãã俳åªã§ãã
7. ã¹ãã¬ãŒãž -ããŒã¿ã¹ãã¬ãŒãžãæäœããããã®ãµãŒãã¹ã SQLããŒã¿ããŒã¹ãŸãã¯ä»ã®äœãã
ååŸãããã®ããã詳现ã«èšè¿°ããŸãã
ããã§ã¯ã³ãŒãã®äžéšã®ã¿ãæäŸããŸãã ãã¹ãŠã®ã³ãŒãã¯githubã«æçš¿ãããŸããã
TCPãµãŒãã¹
Akkaã¯çŸåšãæšæºã§TCPããã³UDPæ¥ç¶ããµããŒãããŠããŸãã ãŸããå®éšãã©ã³ãã«ã¯WebSocketããããŸãã TCPã䜿çšããŸãã Akkaã®ãããã¯ãŒã¯ã¹ã¿ãã¯ã¯ããã®ã«ãŒããSprayããåã£ãŠãããããšãã°Nettyãããå¹ççã«æ©èœããŸãã Nettyã¯ãåæã«ããå€ãã®æ©èœãåããŠããŸãã
ãããã£ãŠãã¯ã©ã€ã¢ã³ãã¯TCPãµãŒãã¹ã«æ¥ç¶ããŸã ã æ¥ç¶ã¢ã¯ã¿ãŒãäœæãããæ¥ç¶ãçŽæ¥æ åœããŸãã æ¥ç¶ã確ç«ããããã ã»ãã·ã§ã³ã¢ã¯ã¿ãŒãäœæããŸãããã®ã»ãã·ã§ã³ã¢ã¯ã¿ãŒã¯ã²ãŒã ã»ãã·ã§ã³ãæ åœãã connectionãä»ããŠã¯ã©ã€ã¢ã³ããšã¡ãã»ãŒãžã亀æããŸãã
TCPã䜿çšããå Žåãããã€ãã®ãã¥ã¢ã³ã¹ããããŸãã TCPã¯æ°žç¶çãªæ¥ç¶ã§ãã ãŸããã·ã¹ãã ãã¯ã©ã€ã¢ã³ãããŸã æ¥ç¶ãããŠãããã©ããã確èªã§ãããšã¯éããŸããã
ãããã£ãŠãã¯ã©ã€ã¢ã³ãã確èªããã«ã¯ãããããããŒãããŒãã䜿çšããŸãã ãµãŒããŒã¯ãæ¥ç¶ããŸã ãããã©ãããç解ããããã«ã空ã®ãã±ããã§å®æçã«ã¯ã©ã€ã¢ã³ãã«pingãéä¿¡ããŸãã
ãããè¡ãã«ã¯ã ã»ãã·ã§ã³ã§Shedullerãéå§ããŸãããã®å Žåã10ç§ããšã«ã¯ã©ã€ã¢ã³ãã«pingãéä¿¡ããŸãã
scheduler = context.system.scheduler.schedule(10.seconds, 10.seconds, self, Heartbeat)
ããã«ãã¯ã©ã€ã¢ã³ããšã®æ¥ç¶ã確ç«ããããšããã«ããµãŒããŒã«èªèšŒã³ãã³ããéä¿¡ããŸãã ã¢ã¯ã¿ãŒSessionãå¿ èŠã§ãã
ã»ãã·ã§ã³ã¯ãã¡ãã»ãŒãžãã¿ã¹ã¯ãµãŒãã¹ã«ãªãã€ã¬ã¯ãããŸãã 圌ã¯ãããã©ããªçš®é¡ã®ã¡ãã»ãŒãžã§ããããããã©ãããããç解ããã ããã 次ã®ããã«ãªããŸãã
case class CommandTask(session: ActorRef, comm: PacketMSG)
ã¯ãã説æããã®ãå¿ããŸããã ãã©ã³ã¹ããŒããšããŠProtobufã䜿çšããŸãã ãããã£ãŠã PacketMSGã¯protobuffãªããžã§ã¯ãã§ãããã¯ã©ã€ã¢ã³ãããã®ã¡ãã»ãŒãžã§ãã ã»ãã·ã§ã³ã¯ããã¬ãŒã€ãŒã»ãã·ã§ã³ã¢ã¯ã¿ãŒãžã®ãªã³ã¯ã§ãã
ã¿ã¹ã¯ãµãŒãã¹
ãã®ãµãŒãã¹ã¯ããµãŒããŒã§å®è¡ãããäžè¬çãªã¿ã¹ã¯ãæ åœããŸãã ç§ãã¡ã®å Žåãããã¯ã¯ã©ã€ã¢ã³ãããã®ã³ãã³ãã®ã¡ã€ã³ã«ãŒã¿ãŒã§ãã ããããããã¯ãã¡ãããç¹å¹è¬ã§ã¯ãããŸããã Akkaã®ã¡ãã»ãŒãžã³ã°ã·ã¹ãã ã¯éåžžã«æè»ã§ãã ãŸããçµã¿èŸŒã¿ããŒã«ã䜿çšããŠãéåžžã«å·§åŠã«ã¡ãã»ãŒãžã«ãŒãã£ã³ã°ãæ§æã§ããŸãã ãã ããåçŽãªãã®ããè€éãªãã®ã«ç§»è¡ããå¿ èŠããããŸãã ããã«ãã¹ãŠã®å¯èœæ§ãã«ããŒããããã§ã¯ãããŸããã
äžè¬ã«ãå®ãµãŒããŒã®ã¿ã¹ã¯ãµãŒãã¹ã¯ããèªäœäœãããŸããã ãã§ã«ãã¹ãŠã®äœæ¥ãå®è¡ããå俳åªã®ã¿ãèµ·åããŸãã ãŸãã¯ãç¬èªã®åã¢ã¯ã¿ãŒãçæããŠç¹å®ã®ã¢ã¯ã·ã§ã³ãå®è¡ããããšãã§ããŸãã äžè¬ã«ããã§ã«å€ãã®ãªãã·ã§ã³ããããŸãã ãã®å Žåã ã¿ã¹ã¯ãµãŒãã¹ã¯ãããèªèšŒèŠæ±ã§ãããšå€æããæå®ãããèªèšŒãã©ã¡ãŒã¿ãŒãæã€ãã¬ãŒã€ãŒãååšãããã©ããã確èªããã¿ã¹ã¯ã䜿çšããŠã AuthãµãŒãã¹ã«ã¡ãã»ãŒãžãéä¿¡ããŸãã
def handlePacket(task: CommandTask) = { task.comm.getCmd match { case Cmd.Auth.code => authService ! Authenticate(task.session, task.comm) case Cmd.Join.code => gameService ! JoinGame(task.session) case Cmd.Move.code => gameService ! PlayerMove(task.session, task.comm) case _ => log.info("Crazy message") } }
èªèšŒãµãŒãã¹
èªèšŒãæ åœãããµãŒãã¹ã éåžžã«åå§çã§ãã ãŠãŒã¶ãŒã®ããŒã¿ããŒã¹ã«ã®ã¿ã¢ã¯ã»ã¹ã§ããŸãã
override def receive = { case task: Authenticate => handleAuth(task) case task: SomePlayer => handleAuthenticated(task) case task: AuthenticatedFailed => handleFailed(task) case _ => log.info("unknown message") }
圌ãAuthenticateãåãåã£ãå ŽåãããŒã¿ããŒã¹ã«ã¢ã¯ã»ã¹ããŠç¢ºèªããå¿ èŠããããŸãã
case class GetPlayerByName(session: ActorRef, comm: PacketMSG)
SomePlayerãåä¿¡ããå ŽåãèªèšŒã¯æåãããã®è¯ããã¥ãŒã¹ãé¢å¿ã®ãããã¹ãŠã®äººã«äŒããããšãã§ããŸãã ãã¬ã€ã€ãŒãšGMã
task.session ! Send(Cmd.AuthResp, login.build().toByteArray) gameService ! task
ãããŠãAuthenticatedFailedã®å Žåããã¬ãŒã€ãŒãèŠã€ãããªãã£ãããããã®æ²ãããã¥ãŒã¹ã¯ãã¹ãŠã®é¢ä¿è ã«å ±åããå¿ èŠããããŸãã ãã®å Žåããã¬ãŒã€ãŒã®ã¿ã ã¡ãªã¿ã«ãå®éã®ãµãŒããŒã§ã¯ããã®ãããªè©Šã¿ãèæ ®ããæ°žç¶çã«åŠçœ°ããããšãã§ããŸãã
task.session ! Send(Cmd.AuthErr, Array[Byte]())
å®éã«ã誰ããããå®å šã«å°ç¡ãã«ããªãã§ãããŸããŸãªèªèšŒãªãã·ã§ã³ãæäŸããŸãã
ä¿ç®¡
Akkaã§ã®ããŒã¿ããŒã¹ã®æäœã¯å¥ã®ãããã¯ã§ãã ãªããªã å éšã§ã¯ãéåžžã®ã¹ã¬ããã§äœæ¥ãè¡ãããŸãã ã¢ã¯ã¿ãŒçšã®ãé·æéã«ããããã¿ã¹ã¯ãå€æ°äœæããããšã«ãããã·ã¹ãã å šäœãäžæåæ¢ã§ããŸãã ã¢ã¯ã¿ãŒã¯è»œéã§ãªããã°ãªããŸããã éåžžã®ãªã¹ãããDBããšããŠäœ¿çšããŸãã ãããã£ãŠãäœãé ããªããŸããã ããããå®éã®ããŒã¿ããŒã¹ã¯é·ãéãããŒããããã¯ããŸãã ãããã£ãŠãå®éã®ãããžã§ã¯ãã§ã¯ãããŒã¿ããŒã¹ãæäœããã¢ã¯ã¿ãŒã«åå¥ã®ã¹ã¬ãããŸãã¯ã¹ã¬ããã®ããŒã«ãå²ãåœãŠããããããã·ã¹ãã å šäœã®é床ãäœäžããããšã¯ãããŸããã
ãã¬ãŒã€ãŒãèŠã€ãã£ãå ŽåãèªèšŒã«æåããã¡ãã»ãŒãžãã»ãã·ã§ã³ã¢ã¯ã¿ãŒã«éä¿¡ãããŸãã ã»ãã·ã§ã³ã¢ã¯ã¿ãŒã¯æ¢ã«ãããããã¯ããŠã¯ã©ã€ã¢ã³ãã«éä¿¡ããŸã
ããŠãã²ãŒã ã«åå ããŸããã
次ã«ãã¯ã©ã€ã¢ã³ãã¯ãã²ãŒã ãéå§ããŠãã ããããšããã¡ãã»ãŒãžãéä¿¡ããŸãã ã¿ã¹ã¯ãµãŒãã¹ã¯ GMãµãŒãã¹ã¡ãã»ãŒãžããªãã€ã¬ã¯ãããã«ãŒã ãäœæããŠãã¬ãŒã€ãŒãé 眮ããŸãã
ãã®åŸã圌ã¯ã¯ã©ã€ã¢ã³ãã«ã²ãŒã ã®éå§ãéç¥ããŸãã
ãã ããå®è£ ã¯ç°¡åãªã®ã§ãæåã®ãã¬ãŒã€ãŒãæ¥ç¶ãããšããã«ããµãŒããŒã¯èªåçã«éšå±ãäœæãããã®éšå±ã«ãã¬ãŒã€ãŒãé 眮ããŸãã ãããã£ãŠãæ¥ç¶ãããŠãããã¹ãŠãåãéšå±ã«ãªããŸãã
GMãµãŒãã¹
ãããã²ãŒã ã®ã¡ã€ã³ãµãŒãã¹ã§ãã 圌ã¯ãæ¥ç¶ãããŠãããã¹ãŠã®ãã¬ãŒã€ãŒã«ã€ããŠç¥ã£ãŠããŸãã 圌ã¯èªåãäœæããéšå±ã®æ°ãç¥ã£ãŠãããè² è·åæ£ã·ã¹ãã ã®äžéšãšããŠæ©èœã§ããŸãã ã»ãã·ã§ã³ã²ãŒã ããããããã²ãŒã ã®ä»çµã¿ã¯ãã¹ãŠéšå±ã§èšç®ãããŸãã ã«ãŒã ã¢ã¯ã¿ãŒã¯åœŒãã®ããã«äœæãããŸããã
ãããŠåŸ®åŠãªéãããããŸãã ã²ãŒã ãã¿ãŒã³ããŒã¹ã®å Žåã ãŸãããã§ãã«ãŒãã«ãŒãã®ããã«ã ã€ãŸããäžè¬ã«ãéšå±å šäœã«è² è·ãåæ£ããããã«ãäœãããå¿ èŠã¯ãããŸããã å©çšå¯èœãªéè³æºã¯ãã¹ãŠãAkkaã«ãã£ãŠåçã«åŠåãããŸãã
ç§ãã¡ã®ã²ãŒã ããªã¢ã«ã¿ã€ã ã§ããå Žåãæé©åãè¡ãããšãã§ããŸãã
å®éã®ãšãããè² è·ã¯ãããã§ããã ãã¬ã€ã€ãŒãå°ãªãããã²ãŒã ã®ä»çµã¿ãç°¡åãªå Žåãã¹ã¬ããã®äžè¬çãªããŒã«ã§ã®ã²ãŒã ã®ä»çµã¿ã®èšç®ãé ããªãããšã¯ãããŸããã ããããè² è·ãå¢å ãããšããã«ãé 延ãé¡èã«ãªããŸãã
次ã«ãããã§äœãã§ãããã説æããŸãã
ãããŸã§ã®éãã«ãŒã ãç«ã¡äžããŠãã¬ãŒã€ãŒãè¿œå ããŸããã ã²ãŒã ã¯ãªã¢ã«ã¿ã€ã ã§ãããããã²ãŒã ã®ç¶æ ã®å€åã«ã€ããŠãã¬ã€ã€ãŒã«å®æçã«éç¥ããå¿ èŠããããŸãã ããŠã100msããšã«èšã£ãŠã¿ãŸãããã ãã¡ããããã®æéã¯ã²ãŒã ããšã«ç°ãªããŸãã
ãªã¢ã«ã¿ã€ã ã²ãŒã ãç¹ã«ç©çã·ã¥ãŒãã£ã³ã°ã²ãŒã ã®äžçã¯ã決å®è«çã«èšç®ãããŸãã ã¹ããããã€ã¹ãããã ãã®ã¹ãããã§ã¯ãã²ãŒã ã¯ãŒã«ããååŸãããã®æç¹ã§åãåã£ããã¬ã€ã€ãŒã®ã³ãã³ããé©çšããç©çåŠãè¡çªãããããã²ãŒã å ã€ãã³ããNPCãªã©ãèšç®ããŸãããããã£ãŠãã²ãŒã ã®ç¶æ³ã®èšç®ãéããªãã»ã©ãããå€ãã®ãã¬ãŒã ãµãŒããŒãé ãã ãããŠãã²ãŒã ãããã¹ã ãŒãºã«é²ã¿ãŸãã
ãããè¡ãããã«ã100msããšã«ããã£ãã¯ããéä¿¡ããã·ã§ããŒãéå§ããŸãã
ã²ãŒã ã®ç¶æ³ãå確èªããæãæ¥ãããšãæå³ããã€ãã³ãã
scheduler = context.system.scheduler.schedule(100.millisecond, 100.millisecond, self, Tick)
åéšå±èªäœãå®æçã«ãã²ãŒã ãåéèšããæéã§ãããšèšãããšãããããŸãã
åèšç®çµæã¯ãã«ãŒã å ã®æ¥ç¶ãããŠãããã¹ãŠã®ãã¬ãŒã€ãŒã«éä¿¡ãããŸãã
ç§ãã¡ã®å Žåããã¬ã€ã€ãŒã®åãã®ã¿ãèæ ®ãããŸãã
players.keySet.map(p => getPoint(move, p)) players.values.map(s => s ! Send(Cmd.Move, move.build().toByteArray))
å®éãåºæ¬çãªããšãã«ããŒããã·ã³ãã«ãªã²ãŒã ãµãŒããŒãäœæããŸããã æ¥ç¶ãèªèšŒãããŒã¿ããŒã¹ã®æäœãéšå±ã
ã³ãŒããèŠãçµéšè±å¯ãªèªè ã¯æ¬¡ã®ããã«èšããŸãã
-Semyon Semenychãã¯ããåé¡ãªãã·ã³ãã«ãªã¹ã¬ããã§åãããšãååŸããŸãã
ãŸããäžè¬çã«ã¯ããã§ãã ã¡ãã»ãŒãžã·ã¹ãã ã¯ãæ°æéã§èã®äžã«æžãããŸãã Nettyãæ¥ç¶ãã次ã®å€æãã«åãã£ãŠé²ã¿ãŸãã åãµãŒãã¹ãã¹ããªãŒã ã«å²ãåœãŠãã³ã¬ã¯ã·ã§ã³ãä»ããŠã¡ãã»ãŒãžã亀æããŸãã
ãªãããçš®ã®è€éãªAkkaã䜿çšããã®ã§ããïŒ
ãããããã®å ŽåãAkkaã¯äœãæäŸã§ããŸããïŒ..
ããŠããã¹ãŠã®ã³ãŒããéåžžã«ã·ã³ãã«ã§ã·ã³ã°ã«ã¹ã¬ããã§ãããšããäºå®ã«ã€ããŠã ãããŠãä»ã®Akkaã®ã¢ã¡ããã£ã«ã€ããŠã¯ããã§ã«æžããŠããŸãã ç¹°ãè¿ããŸããã
äžè¬ã«ãåçŽãªå®è£ ã¯å®éã®ã¢ããªã±ãŒã·ã§ã³ã®åé¡ã®å€ããåæ ããŠããªããããæªãã§ãã ããšãã°ã1ã€ã®ã¹ã¬ããã§ãã®ãµãŒããŒã«æžã蟌ãããšãã§ããŸãã ãããŠãåœåã®éã圌ã¯åããŸãã
ããŠãããšãã°ãä»äºã§CPUã«è² è·ããããããšãã§ããïŒãããŠã»ãšãã©ã®å Žåã«ïŒéšå±ã§ãã éåžžã®ããŒãžã§ã³ã§ã¯ãéšå±ãã¹ããªãŒã ã«åå²ããå¿ èŠãããå Žåãããã«ã€ããŠèããå¿ èŠããããŸãã ãã®åé¢ã®ããã®ã³ãŒããèããŠèšè¿°ããŠãã ããã
ä»äœãããã®ïŒ
éšå±ãããã¯åçŽãªã¯ã©ã¹ã俳åªã§ãã 圌ã¯ãšãŠãã·ã³ãã«ã§ãã ãã¹ãŠã®ã³ãŒãã¯ãå ±éã®ã¹ã¬ããããŒã«ã§å®è¡ãããŸãã äžå¯Ÿã®ãã¬ãŒã€ãŒã«ãããã¹ãã§ã¯ãããŒã«ã«ã§ã¯ãããã¯ããã»ã©æããããŸããã
ãã ããããã§ã¯ãããšãã°50人ã®ãã¬ãŒã€ãŒã§ãµãŒããŒãæ¢ã«ãã¹ãããå¿ èŠããããŸãã åéšå±ãã¹ããªãŒã ã«å²ãåœãŠãããšã«ããŸããã ãããè¡ãã«ã¯ããã®ã¢ã¯ã¿ãŒãå ±æããŒã«ã§ã¯ãªãå¥ã®ã¹ã¬ããã䜿çšããããšã瀺ãå¿ èŠããããŸãã ããã ãã§ããåæã«ã€ããŠã¯èããŸããã§ãããäžè¬çãªããŒã¿ã«ã€ããŠã¯èããŸããã§ããã ããã«ãAkkaã«ã¯ããã«äœ¿çšã§ããã¯ã©ã¹ã¿ãŒããããŸãã ã€ãŸãããããã¯ãŒã¯äžã®åã ã®ãã·ã³ã«éšå±ã移åããããšã¯å€§ããªåé¡ã«ã¯ãªããŸããã éšå±èªäœã®ã³ãŒãã¯ãŸã£ããå€æŽãããŸããã ããã¯åã俳åªã§ããã圌ã ããå¥ã®ãã·ã³ã§äœæ¥ããŸãã
åã¢ã¯ã¿ãŒã«ã¯ã¢ãã¬ã¹ããããŸãã ãããŠã圌ãšã®ãã¹ãŠã®ä»äºã¯åœŒãéããŠè¡ãããŸãã ã·ã¹ãã å šäœã¯ããã®ã¢ã¯ã¿ãŒãã©ãã§æ©èœããããæ°ã«ããŸããã å ±æããŒã«ãå¥ã®ã¹ã¬ãããå¥ã®ãã·ã³ããŸãã¯å¥ã®ãã·ã³ã ã¡ãã»ãŒãžã®éä¿¡å ã¢ãã¬ã¹ãããããã®èåŸã«ãããã®ã¯ãèšå®ã§ã¹ããªãŒã ããã·ã³ããŸãã¯ã¯ã©ã¹ã¿ãŒããã§ã«æ±ºå®ããŠããŸãã ããã«ãããäžæ¹ã§ã²ãŒã ãçªç¶èžã¿ã«ããããã²ãŒã ã®ä»çµã¿ã䜿ã£ãŠãµãŒããŒãè¿ éã«äžããå¿ èŠãããå Žåã䟿å©ã§é«éãªã¹ã±ãŒã©ããªãã£ãåŸãããŸãã äžæ¹ãéçºã®å©äŸ¿æ§ã 1ã€ã®éçºè ã®ãã·ã³ãšã¯ã©ã¹ã¿ãŒã®äž¡æ¹ã§ã¯ã©ã¹ã¿ãŒå šäœãäžããããšãã§ããŸãã ããã¯ãèšå®ã«ãã£ãŠã®ã¿æ±ºå®ãããŸãã
ã€ãŸã ã·ã¹ãã å ã®ä»»æã®ã¢ã¯ã¿ãŒãŸãã¯ã¢ã¯ã¿ãŒã°ã«ãŒãã¯ãäžè¬çãªã¹ã¬ããããŒã«ãåå¥ã®ã¹ã¬ãããåå¥ã®ã¹ã¬ããããŸãã¯æ§æãå€æŽããã ãã§åå¥ã®ãã·ã³ã®äž¡æ¹ã§èµ·åã§ããŸãã ã·ã³ãã«ãªã·ã³ã°ã«ã¹ã¬ããã³ãŒããç¶æããªããã
ã²ãŒã ãµãŒããŒã®å Žåãããã¯éåžžã«å€§ããªãã©ã¹ã§ãã Akkaã¯éåžžã«å€§ããªå±€ã®ä»äºãåŒãåããŸãã ãããŠåæã«ãå®éã«ã¯éçºè ãå¶éããŸããã å®éãé©åãªãã£ã¹ãããã£ãã«ãŒã¿ãŒããŸãã¯ã¡ãŒã«ããã¯ã¹ããªããã°ããã€ã§ãç¬èªã®å®è£ ãäœæã§ããŸãã ç¹å®ã®æ©äŒã«æé©ã§ãã
ãããã¯ãèå³æ·±ãå Žåã¯ããªãã¡ã¯ã¿ãªã³ã°ãç¶è¡ããŠãã³ãŒããããå®éã®çç£ã«è¿ã¥ããããšãã§ããŸãã
ãµãŒããŒãšã¯ã©ã€ã¢ã³ããå«ããã¹ãŠã®ã³ãŒãã¯GitHubã«æçš¿ãããŸã ã